import React, { createContext, useContext, useState, useRef, useEffect, } from "react"; import { cn } from "@/lib/utils"; const SelectContext = createContext(null); export function Select({ value, onValueChange, children }) { const [open, setOpen] = useState(false); const [items, setItems] = useState({}); 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]); const registerItem = (val, label) => { setItems((prev) => ({ ...prev, [val]: label })); }; return (
{children}
); } export function SelectTrigger({ className, children }) { const { setOpen, triggerRef } = useContext(SelectContext); return ( ); } export function SelectValue({ placeholder }) { const { value, items } = useContext(SelectContext); const label = value ? items[value] : null; return ( {label || placeholder} ); } export function SelectContent({ className, children }) { const { open } = useContext(SelectContext); if (!open) return null; return (
{children}
); } export function SelectItem({ value, children, className }) { const { onValueChange, setOpen, registerItem } = useContext(SelectContext); useEffect(() => { registerItem(value, typeof children === "string" ? children : String(children)); }, [value, children, registerItem]); const handleClick = () => { onValueChange?.(value); setOpen(false); }; return (
{children}
); }