"use client"; import React, { useEffect, useRef } from "react"; export interface MenuItem { label: string; icon?: string | React.ReactNode; danger?: boolean; divider?: boolean; onClick?: () => void; } interface ContextMenuProps { x: number; y: number; items: MenuItem[]; onClose: () => void; } export function ContextMenu({ x, y, items, onClose }: ContextMenuProps) { const menuRef = useRef(null); useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(e.target as Node)) { onClose(); } }; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }; document.addEventListener("mousedown", handleClickOutside); document.addEventListener("keydown", handleKeyDown); return () => { document.removeEventListener("mousedown", handleClickOutside); document.removeEventListener("keydown", handleKeyDown); }; }, [onClose]); // Adjust coordinates so menu stays inside viewport const adjustedX = typeof window !== "undefined" ? Math.min(x, window.innerWidth - 180) : x; const adjustedY = typeof window !== "undefined" ? Math.min(y, window.innerHeight - 250) : y; return (
e.stopPropagation()} onContextMenu={(e) => e.preventDefault()} > {items.map((item, i) => { if (item.divider) { return
; } return (
{ if (item.onClick) item.onClick(); onClose(); }} > {item.icon && {item.icon}} {item.label}
); })}
); }