import { useState, useRef, useEffect, type ReactNode } from 'react' import { createPortal } from 'react-dom' import { MoreHorizontal } from 'lucide-react' import { cn } from '@/lib/utils' export interface ActionMenuItem { label: string icon?: ReactNode onClick: () => void destructive?: boolean disabled?: boolean } interface ActionMenuProps { items: ActionMenuItem[] } export function ActionMenu({ items }: ActionMenuProps) { const [open, setOpen] = useState(false) const buttonRef = useRef(null) const menuRef = useRef(null) const [menuPosition, setMenuPosition] = useState({ top: 0, right: 0 }) // Calculate menu position when opened useEffect(() => { if (open && buttonRef.current) { const rect = buttonRef.current.getBoundingClientRect() setMenuPosition({ top: rect.bottom + window.scrollY + 4, // 4px gap (mt-1) right: window.innerWidth - rect.right + window.scrollX, }) } }, [open]) // Close menu when clicking outside useEffect(() => { if (!open) return const handler = (e: MouseEvent) => { if ( buttonRef.current && !buttonRef.current.contains(e.target as Node) && menuRef.current && !menuRef.current.contains(e.target as Node) ) { setOpen(false) } } document.addEventListener('mousedown', handler) return () => document.removeEventListener('mousedown', handler) }, [open]) return ( <> {open && createPortal(
{items.map((item) => ( ))}
, document.body )} ) } export default ActionMenu