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}
);
}