import React, { useState, useRef, useEffect } from 'react'; import type { ReactNode } from 'react'; interface PopoverProps { trigger: ReactNode; content: ReactNode; position?: 'top' | 'bottom' | 'left' | 'right'; } export default function Popover({ trigger, content, position = 'bottom' }: PopoverProps) { const [isOpen, setIsOpen] = useState(false); const containerRef = useRef(null); useEffect(() => { function handleClickOutside(event: MouseEvent) { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setIsOpen(false); } } if (isOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => document.removeEventListener('mousedown', handleClickOutside); }, [isOpen]); const positionClasses = { top: 'bottom-full left-1/2 -translate-x-1/2 mb-2', bottom: 'top-full left-1/2 -translate-x-1/2 mt-2', left: 'right-full top-1/2 -translate-y-1/2 mr-2', right: 'left-full top-1/2 -translate-y-1/2 ml-2', }; const arrowClasses = { top: 'bottom-[-4px] left-1/2 -translate-x-1/2 border-t-gray-200 border-x-transparent border-b-transparent', bottom: 'top-[-4px] left-1/2 -translate-x-1/2 border-b-gray-200 border-x-transparent border-t-transparent', left: 'right-[-4px] top-1/2 -translate-y-1/2 border-l-gray-200 border-y-transparent border-r-transparent', right: 'left-[-4px] top-1/2 -translate-y-1/2 border-r-gray-200 border-y-transparent border-l-transparent', }; return (
setIsOpen(!isOpen)} className="cursor-pointer"> {trigger}
{isOpen && (
{/* Arrow */}
{content}
)}
); }