import { useState, useRef, useEffect } from 'react' import { MoreVertical } from 'lucide-react' import { cn } from '@/lib/utils' interface MenuAction { label: string icon?: React.ComponentType<{ className?: string }> onClick: () => void disabled?: boolean variant?: 'default' | 'destructive' } interface ActionMenuProps { actions: MenuAction[] align?: 'left' | 'right' // default 'right' } export function ActionMenu({ actions, align = 'right' }: ActionMenuProps) { const [isOpen, setIsOpen] = useState(false) const menuRef = useRef(null) useEffect(() => { if (!isOpen) return const handleClickOutside = (event: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(event.target as Node)) { setIsOpen(false) } } const handleEscape = (event: KeyboardEvent) => { if (event.key === 'Escape') { setIsOpen(false) } } document.addEventListener('mousedown', handleClickOutside) document.addEventListener('keydown', handleEscape) return () => { document.removeEventListener('mousedown', handleClickOutside) document.removeEventListener('keydown', handleEscape) } }, [isOpen]) const handleItemClick = (action: MenuAction) => { if (action.disabled) return action.onClick() setIsOpen(false) } return (
{isOpen && (
{actions.map((action, index) => { const Icon = action.icon return ( ) })}
)}
) } export type { MenuAction, ActionMenuProps } export default ActionMenu