mirror of
https://github.com/hazemKrimi/crimson-quirks-ui.git
synced 2026-05-02 02:30:29 +00:00
Update context menu component
This commit is contained in:
@@ -1,7 +1,71 @@
|
|||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { Wrapper } from './styles';
|
import { Wrapper } from './styles';
|
||||||
|
import { Text } from '..';
|
||||||
|
|
||||||
const ContextMenu = () => {
|
type ContextMenuProps = {
|
||||||
return <Wrapper></Wrapper>;
|
className?: string;
|
||||||
|
items: Array<{ label: string; action: () => void }>;
|
||||||
|
component: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ContextMenu = ({ items, component, className }: ContextMenuProps) => {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const openMenu = () => setOpen(true);
|
||||||
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
|
if (ref.current && !ref.current.contains(event.target as Node)) {
|
||||||
|
setOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', handleClickOutside);
|
||||||
|
(document.querySelector(`#${component}`) as HTMLElement)?.addEventListener(
|
||||||
|
'mouseenter',
|
||||||
|
openMenu
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousedown', handleClickOutside);
|
||||||
|
(document.querySelector(
|
||||||
|
`#${component}`
|
||||||
|
) as HTMLElement)?.removeEventListener('mouseenter', openMenu);
|
||||||
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line
|
||||||
|
}, [ref]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper
|
||||||
|
ref={ref}
|
||||||
|
className={className}
|
||||||
|
top={
|
||||||
|
(document.querySelector(`#${component}`) as HTMLElement)?.offsetTop + 30
|
||||||
|
}
|
||||||
|
left={
|
||||||
|
(document.querySelector(`#${component}`) as HTMLElement)?.offsetLeft +
|
||||||
|
10
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{open && (
|
||||||
|
<ul>
|
||||||
|
{items.map(({ label, action }) => (
|
||||||
|
// eslint-disable-next-line
|
||||||
|
<li
|
||||||
|
onClick={() => {
|
||||||
|
setOpen(false);
|
||||||
|
action();
|
||||||
|
}}
|
||||||
|
key={label}
|
||||||
|
>
|
||||||
|
<Text variant='caption'>{label}</Text>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ContextMenu;
|
export default ContextMenu;
|
||||||
|
|||||||
@@ -1,3 +1,25 @@
|
|||||||
import styled, { css } from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
export const Wrapper = styled.div``;
|
type WrapperProps = {
|
||||||
|
top: number;
|
||||||
|
left: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Wrapper = styled.div<WrapperProps>`
|
||||||
|
ul {
|
||||||
|
position: fixed;
|
||||||
|
top: ${({ top }) => top}px;
|
||||||
|
left: ${({ left }) => left}px;
|
||||||
|
background: #1f1b1b;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto;
|
||||||
|
row-gap: 0.5rem;
|
||||||
|
color: ${({ theme }) => theme.colors.white.main};
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 5px 20px 5px 10px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user