mirror of
https://github.com/hazemKrimi/crimson-quirks-ui.git
synced 2026-05-01 18:20:28 +00:00
77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
import { useEffect, useRef, useState } from 'react';
|
|
import { Wrapper } from './styles';
|
|
import { Text } from '..';
|
|
|
|
type MenuProps = {
|
|
className?: string;
|
|
items: Array<{
|
|
icon: React.SVGProps<SVGSVGElement>;
|
|
avoid?: boolean;
|
|
label: string;
|
|
action?: () => void;
|
|
}>;
|
|
component: string;
|
|
};
|
|
|
|
const Menu = ({ items, component, className }: MenuProps) => {
|
|
const [open, setOpen] = useState(false);
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
|
|
useEffect(() => {
|
|
const wrapper = ref.current;
|
|
|
|
const openMenu = () => setOpen(true);
|
|
const closeMenu = () => setOpen(false);
|
|
|
|
(document.querySelector(`#${component}`) as HTMLElement)?.addEventListener(
|
|
'mouseenter',
|
|
openMenu
|
|
);
|
|
ref.current?.addEventListener('mouseleave', closeMenu);
|
|
|
|
return () => {
|
|
(document.querySelector(
|
|
`#${component}`
|
|
) as HTMLElement)?.removeEventListener('mouseenter', openMenu);
|
|
wrapper?.addEventListener('mouseleave', closeMenu);
|
|
};
|
|
|
|
// eslint-disable-next-line
|
|
}, [ref.current]);
|
|
|
|
return (
|
|
<Wrapper
|
|
ref={ref}
|
|
className={className}
|
|
top={
|
|
(document.querySelector(`#${component}`) as HTMLElement)?.offsetTop + 30
|
|
}
|
|
left={
|
|
(document.querySelector(`#${component}`) as HTMLElement)?.offsetLeft
|
|
}
|
|
>
|
|
{open && (
|
|
<ul>
|
|
{items.map(({ icon, label, avoid, action }) => (
|
|
// eslint-disable-next-line
|
|
<li
|
|
onClick={() => {
|
|
if (action) {
|
|
setOpen(false);
|
|
action();
|
|
}
|
|
}}
|
|
key={label}
|
|
>
|
|
<span className={`icon ${avoid ? 'avoid' : ''}`}>{icon}</span>
|
|
<Text color={avoid ? 'error' : undefined}>{label}</Text>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</Wrapper>
|
|
);
|
|
};
|
|
|
|
export default Menu;
|