{"version":3,"file":"Accordion.cjs","names":[],"sources":["../../../src/components/Accordion/Accordion.tsx"],"sourcesContent":["import { useCallback, useId, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./Accordion.module.css\";\n\nexport interface AccordionItem {\n    /** Stable identifier. */\n    id: string;\n    title: ReactNode;\n    children: ReactNode;\n    disabled?: boolean;\n}\n\nexport interface AccordionProps {\n    items: AccordionItem[];\n    /** When `true` multiple items can be open simultaneously. Default `false`. */\n    multiple?: boolean;\n    /** Controlled open ids. */\n    value?: string[];\n    /** Uncontrolled default open ids. */\n    defaultValue?: string[];\n    onChange?: (openIds: string[]) => void;\n    className?: string;\n}\n\n/**\n * Accessible accordion. Each item collapses/expands its content. Single-mode by\n * default — pass `multiple` to allow more than one item open at a time. Can be\n * controlled via `value` + `onChange`, or uncontrolled via `defaultValue`.\n */\nexport function Accordion({\n    items,\n    multiple = false,\n    value,\n    defaultValue = [],\n    onChange,\n    className,\n}: AccordionProps) {\n    const reactId = useId();\n    const isControlled = value !== undefined;\n    const [internalOpen, setInternalOpen] = useState<string[]>(defaultValue);\n    const openIds = isControlled ? value : internalOpen;\n\n    const toggle = useCallback(\n        (id: string): void => {\n            const isOpen = openIds.includes(id);\n            const next = multiple\n                ? isOpen\n                    ? openIds.filter((x) => x !== id)\n                    : [...openIds, id]\n                : isOpen\n                  ? []\n                  : [id];\n            if (!isControlled) setInternalOpen(next);\n            onChange?.(next);\n        },\n        [openIds, multiple, isControlled, onChange],\n    );\n\n    return (\n        <div className={cn(styles.accordion, className)}>\n            {items.map((item) => {\n                const open = openIds.includes(item.id);\n                const panelId = `${reactId}-${item.id}-panel`;\n                const triggerId = `${reactId}-${item.id}-trigger`;\n                return (\n                    <div key={item.id} className={cn(styles.item, open && styles.open)}>\n                        <h3 className={styles.header}>\n                            <button\n                                type=\"button\"\n                                id={triggerId}\n                                className={styles.trigger}\n                                aria-expanded={open}\n                                aria-controls={panelId}\n                                disabled={item.disabled}\n                                onClick={() => toggle(item.id)}\n                            >\n                                <span>{item.title}</span>\n                                <ChevronIcon className={styles.chevron} />\n                            </button>\n                        </h3>\n                        {open && (\n                            <div\n                                id={panelId}\n                                role=\"region\"\n                                aria-labelledby={triggerId}\n                                className={styles.panel}\n                            >\n                                {item.children}\n                            </div>\n                        )}\n                    </div>\n                );\n            })}\n        </div>\n    );\n}\n\nfunction ChevronIcon({ className }: { className?: string }) {\n    return (\n        <svg\n            className={className}\n            width=\"16\"\n            height=\"16\"\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            aria-hidden\n        >\n            <path\n                d=\"M6 9l6 6 6-6\"\n                stroke=\"currentColor\"\n                strokeWidth=\"2\"\n                strokeLinecap=\"round\"\n                strokeLinejoin=\"round\"\n            />\n        </svg>\n    );\n}\n"],"mappings":"gIA8BA,SAAgB,EAAU,CACtB,QACA,WAAW,GACX,QACA,eAAe,CAAC,EAChB,WACA,aACe,CACf,IAAM,GAAA,EAAU,EAAA,MAAA,CAAM,EAChB,EAAe,IAAU,IAAA,GACzB,CAAC,EAAc,IAAA,EAAmB,EAAA,SAAA,CAAmB,CAAY,EACjE,EAAU,EAAe,EAAQ,EAEjC,GAAA,EAAS,EAAA,YAAA,CACV,GAAqB,CAClB,IAAM,EAAS,EAAQ,SAAS,CAAE,EAC5B,EAAO,EACP,EACI,EAAQ,OAAQ,GAAM,IAAM,CAAE,EAC9B,CAAC,GAAG,EAAS,CAAE,EACnB,EACE,CAAC,EACD,CAAC,CAAE,EACN,GAAc,EAAgB,CAAI,EACvC,IAAW,CAAI,CACnB,EACA,CAAC,EAAS,EAAU,EAAc,CAAQ,CAC9C,EAEA,OACI,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAA,GAAG,EAAA,QAAO,UAAW,CAAS,EACzC,SAAA,EAAM,IAAK,GAAS,CACjB,IAAM,EAAO,EAAQ,SAAS,EAAK,EAAE,EAC/B,EAAU,GAAG,EAAQ,GAAG,EAAK,GAAG,QAChC,EAAY,GAAG,EAAQ,GAAG,EAAK,GAAG,UACxC,OACI,EAAA,EAAA,KAAA,CAAC,MAAD,CAAmB,UAAW,EAAA,GAAG,EAAA,QAAO,KAAM,GAAQ,EAAA,QAAO,IAAI,EAAjE,SAAA,EACI,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAA,QAAO,OAClB,UAAA,EAAA,EAAA,KAAA,CAAC,SAAD,CACI,KAAK,SACL,GAAI,EACJ,UAAW,EAAA,QAAO,QAClB,gBAAe,EACf,gBAAe,EACf,SAAU,EAAK,SACf,YAAe,EAAO,EAAK,EAAE,EAPjC,SAAA,EASI,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SAAO,EAAK,KAAY,CAAA,GACxB,EAAA,EAAA,IAAA,CAAC,EAAD,CAAa,UAAW,EAAA,QAAO,OAAU,CAAA,CACrC,GACR,CAAA,EACH,IACG,EAAA,EAAA,IAAA,CAAC,MAAD,CACI,GAAI,EACJ,KAAK,SACL,kBAAiB,EACjB,UAAW,EAAA,QAAO,MAEjB,SAAA,EAAK,QACL,CAAA,CAER,CAzBK,EAAA,EAAK,EAyBV,CAEb,CAAC,CACA,CAAA,CAEb,CAEA,SAAS,EAAY,CAAE,aAAqC,CACxD,OACI,EAAA,EAAA,IAAA,CAAC,MAAD,CACe,YACX,MAAM,KACN,OAAO,KACP,QAAQ,YACR,KAAK,OACL,cAAA,GAEA,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CACI,EAAE,eACF,OAAO,eACP,YAAY,IACZ,cAAc,QACd,eAAe,OAClB,CAAA,CACA,CAAA,CAEb"}