import * as React from "react"; import { ChevronDown } from "lucide-react"; import { cn } from "~/client/lib/utils"; interface CollapsibleProps extends React.HTMLAttributes { open?: boolean; onOpenChange?: (open: boolean) => void; defaultOpen?: boolean; } const CollapsibleContext = React.createContext<{ open: boolean; setOpen: React.Dispatch>; }>({ open: false, setOpen: () => {}, }); const Collapsible = React.forwardRef( ({ className, open: controlledOpen, onOpenChange, defaultOpen = false, children, ...props }, ref) => { const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen); const isControlled = controlledOpen !== undefined; const open = isControlled ? controlledOpen : uncontrolledOpen; const setOpen = React.useCallback( (value: React.SetStateAction) => { const newValue = typeof value === "function" ? value(open) : value; if (!isControlled) { setUncontrolledOpen(newValue); } onOpenChange?.(newValue); }, [isControlled, open, onOpenChange], ); return (
{children}
); }, ); Collapsible.displayName = "Collapsible"; interface CollapsibleTriggerProps extends React.ButtonHTMLAttributes {} const CollapsibleTrigger = React.forwardRef( ({ className, children, ...props }, ref) => { const { open, setOpen } = React.useContext(CollapsibleContext); return ( ); }, ); CollapsibleTrigger.displayName = "CollapsibleTrigger"; interface CollapsibleContentProps extends React.HTMLAttributes {} const CollapsibleContent = React.forwardRef( ({ className, children, ...props }, ref) => { const { open } = React.useContext(CollapsibleContext); return ( ); }, ); CollapsibleContent.displayName = "CollapsibleContent"; export { Collapsible, CollapsibleTrigger, CollapsibleContent };