UNPKG

lightswind

Version:

A professionally designed component library & templates market that brings together functionality, accessibility, and beautiful aesthetics for modern applications.

64 lines (63 loc) 3.92 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import * as React from "react"; import { ChevronDown } from "lucide-react"; import { cn } from "../lib/utils"; const AccordionContext = React.createContext(undefined); const AccordionItemContext = React.createContext(undefined); const Accordion = React.forwardRef(({ className, type = "multiple", value, defaultValue = [], onValueChange, children, ...props }, ref) => { // Always ensure values is an array, even if a single string is passed const [values, setValues] = React.useState(Array.isArray(value) ? value : value ? [value] : Array.isArray(defaultValue) ? defaultValue : defaultValue ? [defaultValue] : []); React.useEffect(() => { if (value !== undefined) { setValues(Array.isArray(value) ? value : value ? [value] : []); } }, [value]); const handleValueChange = React.useCallback((newValues) => { if (value === undefined) { setValues(newValues); } onValueChange?.(newValues); }, [onValueChange, value]); return (_jsx(AccordionContext.Provider, { value: { value: values, onValueChange: handleValueChange }, children: _jsx("div", { ref: ref, className: cn(className), ...props, children: children }) })); }); Accordion.displayName = "Accordion"; const AccordionItem = React.forwardRef(({ className, value, disabled = false, children, ...props }, ref) => { return (_jsx(AccordionItemContext.Provider, { value: { value }, children: _jsx("div", { ref: ref, className: cn("border-b", className), "data-state": disabled ? "disabled" : undefined, "data-value": value, ...props, children: children }) })); }); AccordionItem.displayName = "AccordionItem"; const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => { const context = React.useContext(AccordionContext); if (!context) throw new Error("AccordionTrigger must be used within an Accordion"); const itemContext = React.useContext(AccordionItemContext); if (!itemContext) throw new Error("AccordionTrigger must be used within an AccordionItem"); const { value: values, onValueChange } = context; const { value: itemValue } = itemContext; const isOpen = values.includes(itemValue); const handleToggle = () => { const newValues = isOpen ? values.filter(v => v !== itemValue) : [...values, itemValue]; onValueChange(newValues); }; return (_jsxs("button", { ref: ref, type: "button", className: cn("flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180", className), onClick: handleToggle, "data-state": isOpen ? "open" : "closed", ...props, children: [children, _jsx(ChevronDown, { className: "h-4 w-4 shrink-0 transition-transform duration-200" })] })); }); AccordionTrigger.displayName = "AccordionTrigger"; const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => { const context = React.useContext(AccordionContext); if (!context) throw new Error("AccordionContent must be used within an Accordion"); const itemContext = React.useContext(AccordionItemContext); if (!itemContext) throw new Error("AccordionContent must be used within an AccordionItem"); const { value: values } = context; const { value: itemValue } = itemContext; const isOpen = values.includes(itemValue); return (_jsx("div", { ref: ref, className: cn("overflow-hidden text-sm transition-all", isOpen ? "animate-accordion-down" : "animate-accordion-up h-0", className), "data-state": isOpen ? "open" : "closed", ...props, children: _jsx("div", { className: cn("pb-4 pt-0"), children: children }) })); }); AccordionContent.displayName = "AccordionContent"; export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };