import React, { createContext, useContext, useState, useRef, useEffect, } from "react"; import { cn } from "@/lib/utils"; const DropdownContext = createContext(null); export function DropdownMenu({ children }) { const [open, setOpen] = useState(false); const triggerRef = useRef(null); // Close on outside click useEffect(() => { if (!open) return; function handleClick(e) { if (!triggerRef.current) return; if (!triggerRef.current.parentElement.contains(e.target)) { setOpen(false); } } document.addEventListener("mousedown", handleClick); return () => document.removeEventListener("mousedown", handleClick); }, [open]); return (
{children}
); } export function DropdownMenuTrigger({ asChild, children }) { const { setOpen, triggerRef } = useContext(DropdownContext); const handleClick = (e) => { e.stopPropagation(); setOpen((o) => !o); }; if (asChild && React.isValidElement(children)) { return React.cloneElement(children, { ref: triggerRef, onClick: (e) => { children.props.onClick?.(e); handleClick(e); }, }); } return ( ); } export function DropdownMenuContent({ className, align = "end", ...props }) { const { open } = useContext(DropdownContext); if (!open) return null; const alignment = align === "end" ? "right-0 origin-top-right" : align === "start" ? "left-0 origin-top-left" : "left-1/2 -translate-x-1/2 origin-top"; return (
); } export function DropdownMenuItem({ className, onClick, ...props }) { const { setOpen } = useContext(DropdownContext); const handleClick = (e) => { onClick?.(e); setOpen(false); }; return (
); } export function DropdownMenuSeparator({ className }) { return (
); }