'use client'; import { useEffect, useRef } from 'react'; import { useContextMenuStore } from '@/store/context-menu-store'; import { cn } from '@/lib/utils'; export function ContextMenu() { const { isOpen, position, items, hideContextMenu } = useContextMenuStore(); const menuRef = useRef(null); // Close menu when clicking outside useEffect(() => { if (!isOpen) return; const handleClickOutside = (e: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(e.target as Node)) { hideContextMenu(); } }; const handleEscape = (e: KeyboardEvent) => { if (e.key === 'Escape') { hideContextMenu(); } }; document.addEventListener('mousedown', handleClickOutside); document.addEventListener('keydown', handleEscape); return () => { document.removeEventListener('mousedown', handleClickOutside); document.removeEventListener('keydown', handleEscape); }; }, [isOpen, hideContextMenu]); // Adjust position to keep menu on screen useEffect(() => { if (!isOpen || !position || !menuRef.current) return; const menu = menuRef.current; const rect = menu.getBoundingClientRect(); const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; let { x, y } = position; // Adjust horizontal position if (x + rect.width > viewportWidth) { x = viewportWidth - rect.width - 8; } // Adjust vertical position if (y + rect.height > viewportHeight) { y = viewportHeight - rect.height - 8; } menu.style.left = `${Math.max(8, x)}px`; menu.style.top = `${Math.max(8, y)}px`; }, [isOpen, position]); if (!isOpen || !position) return null; return ( <> {/* Backdrop to capture clicks */}