Files
crimson-quirks-ui/src/components/ContextMenu/index.tsx
T
2023-04-06 16:49:36 +01:00

64 lines
1.7 KiB
TypeScript

import { useEffect, useRef, useState } from 'react';
import { Wrapper } from './styles';
import { Text } from '..';
type ContextMenuProps = {
className?: string;
items: Array<{ label: string; action?: () => void }>;
component: string;
};
const ContextMenu = ({ items, component, className }: ContextMenuProps) => {
const [open, setOpen] = useState(false);
const parentComponentRef = useRef<HTMLDivElement>();
useEffect(() => {
parentComponentRef.current = document.querySelector(`#${component}`) as HTMLDivElement;
const openMenu = () => setOpen(true);
const closeMenu = () => setOpen(false);
parentComponentRef.current?.addEventListener(
'mouseenter',
openMenu
);
parentComponentRef.current?.addEventListener(
'mouseleave',
closeMenu
);
return () => {
parentComponentRef.current?.removeEventListener('mouseenter', openMenu);
parentComponentRef.current?.removeEventListener('mouseleave', closeMenu);
};
}, []);
return (
<Wrapper
className={className}
top={(parentComponentRef.current as HTMLDivElement)?.getBoundingClientRect().top + 30}
left={(parentComponentRef.current as HTMLDivElement)?.getBoundingClientRect().left + 10}
>
{open && (
<ul>
{items.map(({ label, action }) => (
<li
onClick={() => {
if (action) {
setOpen(false);
action();
}
}}
key={label}
>
<Text variant='caption'>{label}</Text>
</li>
))}
</ul>
)}
</Wrapper>
);
};
export default ContextMenu;