-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathContextMenu.tsx
51 lines (45 loc) · 1.44 KB
/
ContextMenu.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import React, { useMemo, useRef } from "react";
import { ContextMenuContext } from "context/ContextMenuContext";
import { usePopper } from "react-popper";
import { VirtualElement } from "@popperjs/core";
interface Props {
children?: React.ReactNode;
}
function ContextMenu({ children }: Props) {
const [showPopper, setShowPopper] = React.useState(null);
const [popperElement, setPopperElement] = React.useState<HTMLDivElement>();
const virtualReference = useRef<VirtualElement>();
const { styles, attributes } = usePopper(virtualReference.current, popperElement, { placement: "bottom-start" });
const context = useMemo(
() => ({
getRect: () => {
if (virtualReference.current == null) {
return { top: 0, left: 0, right: 0, bottom: 0, width: 0, height: 0 };
}
return virtualReference.current.getBoundingClientRect();
},
hide: () => {
setShowPopper(null);
},
show: (foo: any) => {
setShowPopper(foo);
},
setRect: (bbox: any) => {
virtualReference.current = {
getBoundingClientRect: () => bbox,
};
},
setPopperElement,
}),
[]
);
return (
<ContextMenuContext.Provider value={context}>
{children}
<div ref={node => node && setPopperElement(node)} style={styles.popper} {...attributes.popper}>
{showPopper}
</div>
</ContextMenuContext.Provider>
);
}
export default ContextMenu;