'use client'; import { useState, useRef, useEffect, useCallback } from 'react'; import { ActionIcon } from './action-icon'; import type { IconName } from './action-icon'; export interface ActionMenuItem { icon: IconName; label: string; onClick: () => void; variant?: 'default' | 'danger'; disabled?: boolean; } interface ActionMenuProps { items: ActionMenuItem[]; } export function ActionMenu({ items }: ActionMenuProps) { const [open, setOpen] = useState(false); const menuRef = useRef(null); const close = useCallback(() => setOpen(false), []); useEffect(() => { if (!open) return; function handleClickOutside(e: MouseEvent) { if (menuRef.current && !menuRef.current.contains(e.target as Node)) { close(); } } function handleEscape(e: KeyboardEvent) { if (e.key === 'Escape') close(); } document.addEventListener('mousedown', handleClickOutside); document.addEventListener('keydown', handleEscape); return () => { document.removeEventListener('mousedown', handleClickOutside); document.removeEventListener('keydown', handleEscape); }; }, [open, close]); return (
{ e.stopPropagation(); setOpen((prev) => !prev); }} /> {open && (
{items.map((item, i) => ( ))}
)}
); }