import { useEffect, useRef } from 'react' import { createPortal } from 'react-dom' export default function ContextMenu({ x, y, items, onClose }) { const ref = useRef(null) useEffect(() => { const onMouseDown = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose() } const onKey = (e) => { if (e.key === 'Escape') onClose() } document.addEventListener('mousedown', onMouseDown) document.addEventListener('keydown', onKey) return () => { document.removeEventListener('mousedown', onMouseDown) document.removeEventListener('keydown', onKey) } }, [onClose]) // Keep menu inside viewport const W = 192 const H = items.length * 34 const adjX = Math.min(x, window.innerWidth - W - 8) const adjY = Math.min(y, window.innerHeight - H - 8) // Portal to document.body — escapes any CSS transform stacking context // (e.g. the Drawer slide-in animation uses translateX which traps fixed children) return createPortal(
{items.map((item, i) => item.separator ? (
) : ( ) )}
, document.body ) }