'use client'; import { ReactNode, useRef, useEffect, useState } from 'react'; import { cn } from '@/lib/helper'; interface DropdownProps { trigger: ReactNode; children: ReactNode; position?: | 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end'; align?: 'start' | 'center' | 'end'; hover?: boolean; className?: string; contentClassName?: string; } const Dropdown = ({ trigger, children, position = 'bottom', align = 'start', hover = false, className, contentClassName, }: DropdownProps) => { const [isOpen, setIsOpen] = useState(false); const dropdownRef = useRef(null); // Handle click outside to close dropdown useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) ) { setIsOpen(false); } }; if (isOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen]); // Build position classes const getPositionClasses = () => { const classes: string[] = []; // Handle combined positions like 'top-start' if (position.includes('-')) { const [pos, al] = position.split('-'); classes.push(`dropdown-${pos}`); classes.push(`dropdown-${al}`); } else { classes.push(`dropdown-${position}`); if (align !== 'start') { classes.push(`dropdown-${align}`); } } return classes.join(' '); }; const handleToggle = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); // alert('clicked'); setIsOpen(!isOpen); }; return (
{/* Trigger Button */}
{trigger}
{/* Dropdown Content - Only render when open */} {isOpen && (
setIsOpen(false)} // Close on item click > {children}
)}
); }; export default Dropdown;