@fragments-sdk/ui 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/components/Accordion/index.cjs +11 -4
  2. package/dist/components/Accordion/index.cjs.map +1 -1
  3. package/dist/components/Accordion/index.d.ts +3 -3
  4. package/dist/components/Accordion/index.d.ts.map +1 -1
  5. package/dist/components/Accordion/index.js +11 -4
  6. package/dist/components/Accordion/index.js.map +1 -1
  7. package/dist/components/Collapsible/index.cjs +45 -10
  8. package/dist/components/Collapsible/index.cjs.map +1 -1
  9. package/dist/components/Collapsible/index.d.ts +6 -12
  10. package/dist/components/Collapsible/index.d.ts.map +1 -1
  11. package/dist/components/Collapsible/index.js +45 -10
  12. package/dist/components/Collapsible/index.js.map +1 -1
  13. package/dist/components/Combobox/index.cjs +18 -9
  14. package/dist/components/Combobox/index.cjs.map +1 -1
  15. package/dist/components/Combobox/index.d.ts +8 -12
  16. package/dist/components/Combobox/index.d.ts.map +1 -1
  17. package/dist/components/Combobox/index.js +18 -9
  18. package/dist/components/Combobox/index.js.map +1 -1
  19. package/dist/components/Command/index.cjs +54 -21
  20. package/dist/components/Command/index.cjs.map +1 -1
  21. package/dist/components/Command/index.d.ts +2 -2
  22. package/dist/components/Command/index.d.ts.map +1 -1
  23. package/dist/components/Command/index.js +54 -21
  24. package/dist/components/Command/index.js.map +1 -1
  25. package/dist/components/DataTable/index.cjs +13 -1
  26. package/dist/components/DataTable/index.cjs.map +1 -1
  27. package/dist/components/DataTable/index.d.ts.map +1 -1
  28. package/dist/components/DataTable/index.js +13 -1
  29. package/dist/components/DataTable/index.js.map +1 -1
  30. package/dist/components/DatePicker/index.d.ts +2 -3
  31. package/dist/components/DatePicker/index.d.ts.map +1 -1
  32. package/dist/components/Dialog/index.cjs +12 -9
  33. package/dist/components/Dialog/index.cjs.map +1 -1
  34. package/dist/components/Dialog/index.d.ts +8 -12
  35. package/dist/components/Dialog/index.d.ts.map +1 -1
  36. package/dist/components/Dialog/index.js +12 -9
  37. package/dist/components/Dialog/index.js.map +1 -1
  38. package/dist/components/Drawer/index.cjs +12 -9
  39. package/dist/components/Drawer/index.cjs.map +1 -1
  40. package/dist/components/Drawer/index.d.ts +8 -12
  41. package/dist/components/Drawer/index.d.ts.map +1 -1
  42. package/dist/components/Drawer/index.js +12 -9
  43. package/dist/components/Drawer/index.js.map +1 -1
  44. package/dist/components/Menu/index.cjs +30 -16
  45. package/dist/components/Menu/index.cjs.map +1 -1
  46. package/dist/components/Menu/index.d.ts +17 -25
  47. package/dist/components/Menu/index.d.ts.map +1 -1
  48. package/dist/components/Menu/index.js +30 -16
  49. package/dist/components/Menu/index.js.map +1 -1
  50. package/dist/components/NavigationMenu/NavigationMenuContext.cjs.map +1 -1
  51. package/dist/components/NavigationMenu/NavigationMenuContext.d.ts +1 -0
  52. package/dist/components/NavigationMenu/NavigationMenuContext.d.ts.map +1 -1
  53. package/dist/components/NavigationMenu/NavigationMenuContext.js.map +1 -1
  54. package/dist/components/NavigationMenu/index.cjs +43 -11
  55. package/dist/components/NavigationMenu/index.cjs.map +1 -1
  56. package/dist/components/NavigationMenu/index.d.ts.map +1 -1
  57. package/dist/components/NavigationMenu/index.js +43 -11
  58. package/dist/components/NavigationMenu/index.js.map +1 -1
  59. package/dist/components/NavigationMenu/useNavigationMenu.cjs +2 -0
  60. package/dist/components/NavigationMenu/useNavigationMenu.cjs.map +1 -1
  61. package/dist/components/NavigationMenu/useNavigationMenu.d.ts +1 -0
  62. package/dist/components/NavigationMenu/useNavigationMenu.d.ts.map +1 -1
  63. package/dist/components/NavigationMenu/useNavigationMenu.js +2 -0
  64. package/dist/components/NavigationMenu/useNavigationMenu.js.map +1 -1
  65. package/dist/components/Popover/index.cjs +11 -10
  66. package/dist/components/Popover/index.cjs.map +1 -1
  67. package/dist/components/Popover/index.d.ts +8 -12
  68. package/dist/components/Popover/index.d.ts.map +1 -1
  69. package/dist/components/Popover/index.js +11 -10
  70. package/dist/components/Popover/index.js.map +1 -1
  71. package/dist/components/Select/index.cjs +7 -6
  72. package/dist/components/Select/index.cjs.map +1 -1
  73. package/dist/components/Select/index.d.ts +6 -9
  74. package/dist/components/Select/index.d.ts.map +1 -1
  75. package/dist/components/Select/index.js +7 -6
  76. package/dist/components/Select/index.js.map +1 -1
  77. package/dist/components/Sidebar/index.cjs +71 -24
  78. package/dist/components/Sidebar/index.cjs.map +1 -1
  79. package/dist/components/Sidebar/index.d.ts +21 -33
  80. package/dist/components/Sidebar/index.d.ts.map +1 -1
  81. package/dist/components/Sidebar/index.js +71 -24
  82. package/dist/components/Sidebar/index.js.map +1 -1
  83. package/dist/components/Tooltip/index.cjs +12 -6
  84. package/dist/components/Tooltip/index.cjs.map +1 -1
  85. package/dist/components/Tooltip/index.d.ts.map +1 -1
  86. package/dist/components/Tooltip/index.js +12 -6
  87. package/dist/components/Tooltip/index.js.map +1 -1
  88. package/dist/datepicker.cjs +24 -10
  89. package/dist/datepicker.cjs.map +1 -1
  90. package/dist/datepicker.js +24 -10
  91. package/dist/datepicker.js.map +1 -1
  92. package/fragments.json +1 -1
  93. package/package.json +2 -2
  94. package/src/components/Accordion/Accordion.test.tsx +33 -0
  95. package/src/components/Accordion/index.tsx +10 -3
  96. package/src/components/Collapsible/Collapsible.test.tsx +41 -0
  97. package/src/components/Collapsible/index.tsx +53 -16
  98. package/src/components/Combobox/Combobox.test.tsx +55 -0
  99. package/src/components/Combobox/index.tsx +23 -17
  100. package/src/components/Command/Command.test.tsx +93 -0
  101. package/src/components/Command/index.tsx +61 -18
  102. package/src/components/DataTable/DataTable.test.tsx +11 -2
  103. package/src/components/DataTable/index.tsx +22 -2
  104. package/src/components/DatePicker/DatePicker.test.tsx +79 -0
  105. package/src/components/DatePicker/index.tsx +29 -14
  106. package/src/components/Dialog/Dialog.test.tsx +23 -0
  107. package/src/components/Dialog/index.tsx +15 -16
  108. package/src/components/Drawer/Drawer.test.tsx +27 -0
  109. package/src/components/Drawer/index.tsx +15 -16
  110. package/src/components/Menu/index.tsx +35 -30
  111. package/src/components/NavigationMenu/NavigationMenu.fragment.tsx +1 -1
  112. package/src/components/NavigationMenu/NavigationMenu.test.tsx +40 -4
  113. package/src/components/NavigationMenu/NavigationMenuContext.ts +3 -0
  114. package/src/components/NavigationMenu/index.tsx +49 -13
  115. package/src/components/NavigationMenu/useNavigationMenu.ts +4 -0
  116. package/src/components/Popover/Popover.test.tsx +23 -0
  117. package/src/components/Popover/index.tsx +15 -18
  118. package/src/components/Select/Select.test.tsx +41 -0
  119. package/src/components/Select/index.tsx +10 -12
  120. package/src/components/Sidebar/Sidebar.test.tsx +83 -4
  121. package/src/components/Sidebar/index.tsx +87 -45
  122. package/src/components/Tooltip/Tooltip.test.tsx +17 -0
  123. package/src/components/Tooltip/index.tsx +46 -32
@@ -75,7 +75,7 @@ function AccordionRoot({
75
75
  setOpenItems(newItems);
76
76
  }
77
77
  if (onValueChange) {
78
- onValueChange(type === "single" ? newItems[0] ?? "" : newItems);
78
+ onValueChange(type === "single" ? newItems[0] : newItems);
79
79
  }
80
80
  }, [type, currentOpenItems, collapsible2, controlledOpenItems, onValueChange]);
81
81
  const classes = [Accordion_module.default.accordion, className].filter(Boolean).join(" ");
@@ -103,11 +103,15 @@ function AccordionItem({
103
103
  }
104
104
  function AccordionTrigger({
105
105
  children,
106
- className
106
+ className,
107
+ onClick,
108
+ ...htmlProps
107
109
  }) {
108
110
  const { toggle, headingLevel } = useAccordionContext();
109
111
  const { value, isOpen, disabled, triggerId, contentId } = useAccordionItemContext();
110
- const handleClick = () => {
112
+ const handleClick = (event) => {
113
+ onClick == null ? void 0 : onClick(event);
114
+ if (event.defaultPrevented) return;
111
115
  if (!disabled) {
112
116
  toggle(value);
113
117
  }
@@ -117,6 +121,7 @@ function AccordionTrigger({
117
121
  return /* @__PURE__ */ jsxRuntime.jsx(HeadingTag, { className: Accordion_module.default.heading, children: /* @__PURE__ */ jsxRuntime.jsxs(
118
122
  collapsible.Collapsible.Trigger,
119
123
  {
124
+ ...htmlProps,
120
125
  id: triggerId,
121
126
  className: classes,
122
127
  onClick: handleClick,
@@ -153,13 +158,15 @@ function AccordionTrigger({
153
158
  }
154
159
  function AccordionContent({
155
160
  children,
156
- className
161
+ className,
162
+ ...htmlProps
157
163
  }) {
158
164
  const { isOpen, triggerId, contentId } = useAccordionItemContext();
159
165
  const classes = [Accordion_module.default.content, className].filter(Boolean).join(" ");
160
166
  return /* @__PURE__ */ jsxRuntime.jsx(
161
167
  collapsible.Collapsible.Panel,
162
168
  {
169
+ ...htmlProps,
163
170
  id: contentId,
164
171
  className: classes,
165
172
  "data-state": isOpen ? "open" : "closed",
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/components/Accordion/index.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Collapsible as BaseCollapsible } from '@base-ui/react/collapsible';\nimport styles from './Accordion.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport type AccordionValue = string | string[];\n\nexport interface AccordionProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'defaultValue'> {\n children: React.ReactNode;\n /** Allow multiple items to be open at once */\n type?: 'single' | 'multiple';\n /** Controlled value - string for single, string[] for multiple */\n value?: AccordionValue;\n /** Default value for uncontrolled usage */\n defaultValue?: AccordionValue;\n /** Callback when value changes */\n onValueChange?: (value: AccordionValue) => void;\n /** Whether items can be fully collapsed (only for type=\"single\") */\n collapsible?: boolean;\n /**\n * Heading level for accordion triggers (for semantic HTML).\n * The trigger will be wrapped in an <h{level}> element.\n * @default 3\n */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n}\n\nexport interface AccordionItemProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Unique value for this item */\n value: string;\n /** Disable this item */\n disabled?: boolean;\n}\n\nexport interface AccordionTriggerProps extends React.HTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode;\n}\n\nexport interface AccordionContentProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n}\n\n// ============================================\n// Context\n// ============================================\n\ninterface AccordionContextValue {\n type: 'single' | 'multiple';\n openItems: string[];\n toggle: (value: string) => void;\n collapsible: boolean;\n headingLevel: 2 | 3 | 4 | 5 | 6;\n}\n\nconst AccordionContext = React.createContext<AccordionContextValue | null>(null);\n\ninterface AccordionItemContextValue {\n value: string;\n isOpen: boolean;\n disabled: boolean;\n triggerId: string;\n contentId: string;\n}\n\nconst AccordionItemContext = React.createContext<AccordionItemContextValue | null>(null);\n\nfunction useAccordionContext() {\n const context = React.useContext(AccordionContext);\n if (!context) {\n throw new Error('Accordion components must be used within an Accordion');\n }\n return context;\n}\n\nfunction useAccordionItemContext() {\n const context = React.useContext(AccordionItemContext);\n if (!context) {\n throw new Error('Accordion.Trigger/Content must be used within an Accordion.Item');\n }\n return context;\n}\n\n// ============================================\n// Components\n// ============================================\n\nfunction AccordionRoot({\n children,\n type = 'single',\n value,\n defaultValue,\n onValueChange,\n collapsible = false,\n headingLevel = 3,\n className,\n ...htmlProps\n}: AccordionProps) {\n // Normalize value to array for internal handling\n const normalizeValue = (val: AccordionValue | undefined): string[] => {\n if (val === undefined) return [];\n return Array.isArray(val) ? val : [val];\n };\n\n const [openItems, setOpenItems] = React.useState<string[]>(() =>\n normalizeValue(defaultValue)\n );\n\n // Use controlled value if provided\n const controlledOpenItems = value !== undefined ? normalizeValue(value) : undefined;\n const currentOpenItems = controlledOpenItems ?? openItems;\n\n const toggle = React.useCallback((itemValue: string) => {\n const newItems = (() => {\n if (type === 'single') {\n // For single, toggle or set new item\n if (currentOpenItems.includes(itemValue)) {\n return collapsible ? [] : currentOpenItems;\n }\n return [itemValue];\n } else {\n // For multiple, toggle item in array\n if (currentOpenItems.includes(itemValue)) {\n return currentOpenItems.filter(v => v !== itemValue);\n }\n return [...currentOpenItems, itemValue];\n }\n })();\n\n if (controlledOpenItems === undefined) {\n setOpenItems(newItems);\n }\n\n if (onValueChange) {\n onValueChange(type === 'single' ? (newItems[0] ?? '') : newItems);\n }\n }, [type, currentOpenItems, collapsible, controlledOpenItems, onValueChange]);\n\n const classes = [styles.accordion, className].filter(Boolean).join(' ');\n\n return (\n <AccordionContext.Provider value={{ type, openItems: currentOpenItems, toggle, collapsible, headingLevel }}>\n <div {...htmlProps} className={classes} data-orientation=\"vertical\" role=\"region\">\n {children}\n </div>\n </AccordionContext.Provider>\n );\n}\n\nfunction AccordionItem({\n children,\n value,\n disabled = false,\n className,\n ...htmlProps\n}: AccordionItemProps) {\n const { openItems } = useAccordionContext();\n const isOpen = openItems.includes(value);\n const baseId = React.useId();\n const triggerId = `accordion-trigger-${baseId}`;\n const contentId = `accordion-content-${baseId}`;\n\n const classes = [\n styles.item,\n isOpen && styles.itemOpen,\n disabled && styles.itemDisabled,\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <AccordionItemContext.Provider value={{ value, isOpen, disabled, triggerId, contentId }}>\n <BaseCollapsible.Root open={isOpen} disabled={disabled}>\n <div {...htmlProps} className={classes} data-state={isOpen ? 'open' : 'closed'} data-disabled={disabled || undefined}>\n {children}\n </div>\n </BaseCollapsible.Root>\n </AccordionItemContext.Provider>\n );\n}\n\nfunction AccordionTrigger({\n children,\n className,\n}: AccordionTriggerProps) {\n const { toggle, headingLevel } = useAccordionContext();\n const { value, isOpen, disabled, triggerId, contentId } = useAccordionItemContext();\n\n const handleClick = () => {\n if (!disabled) {\n toggle(value);\n }\n };\n\n const classes = [styles.trigger, className].filter(Boolean).join(' ');\n\n // Create the heading element dynamically based on headingLevel\n const HeadingTag = `h${headingLevel}` as 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\n return (\n <HeadingTag className={styles.heading}>\n <BaseCollapsible.Trigger\n id={triggerId}\n className={classes}\n onClick={handleClick}\n aria-expanded={isOpen}\n aria-controls={contentId}\n data-state={isOpen ? 'open' : 'closed'}\n disabled={disabled}\n >\n <span className={styles.triggerContent}>{children}</span>\n <svg\n className={styles.chevron}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </BaseCollapsible.Trigger>\n </HeadingTag>\n );\n}\n\nfunction AccordionContent({\n children,\n className,\n}: AccordionContentProps) {\n const { isOpen, triggerId, contentId } = useAccordionItemContext();\n\n const classes = [styles.content, className].filter(Boolean).join(' ');\n\n return (\n <BaseCollapsible.Panel\n id={contentId}\n className={classes}\n data-state={isOpen ? 'open' : 'closed'}\n role=\"region\"\n aria-labelledby={triggerId}\n >\n <div className={styles.contentInner}>\n {children}\n </div>\n </BaseCollapsible.Panel>\n );\n}\n\n// ============================================\n// Export compound component\n// ============================================\n\nexport const Accordion = Object.assign(AccordionRoot, {\n Item: AccordionItem,\n Trigger: AccordionTrigger,\n Content: AccordionContent,\n});\n\nexport { AccordionRoot, AccordionItem, AccordionTrigger, AccordionContent };\n"],"names":["React","collapsible","styles","jsx","BaseCollapsible","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/components/Accordion/index.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Collapsible as BaseCollapsible } from '@base-ui/react/collapsible';\nimport styles from './Accordion.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport type AccordionValue = string | string[];\n\nexport interface AccordionProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'defaultValue'> {\n children: React.ReactNode;\n /** Allow multiple items to be open at once */\n type?: 'single' | 'multiple';\n /** Controlled value - string for single, string[] for multiple */\n value?: AccordionValue;\n /** Default value for uncontrolled usage */\n defaultValue?: AccordionValue;\n /** Callback when value changes */\n onValueChange?: (value: AccordionValue | undefined) => void;\n /** Whether items can be fully collapsed (only for type=\"single\") */\n collapsible?: boolean;\n /**\n * Heading level for accordion triggers (for semantic HTML).\n * The trigger will be wrapped in an <h{level}> element.\n * @default 3\n */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n}\n\nexport interface AccordionItemProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Unique value for this item */\n value: string;\n /** Disable this item */\n disabled?: boolean;\n}\n\nexport interface AccordionTriggerProps extends React.HTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode;\n}\n\nexport interface AccordionContentProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n}\n\n// ============================================\n// Context\n// ============================================\n\ninterface AccordionContextValue {\n type: 'single' | 'multiple';\n openItems: string[];\n toggle: (value: string) => void;\n collapsible: boolean;\n headingLevel: 2 | 3 | 4 | 5 | 6;\n}\n\nconst AccordionContext = React.createContext<AccordionContextValue | null>(null);\n\ninterface AccordionItemContextValue {\n value: string;\n isOpen: boolean;\n disabled: boolean;\n triggerId: string;\n contentId: string;\n}\n\nconst AccordionItemContext = React.createContext<AccordionItemContextValue | null>(null);\n\nfunction useAccordionContext() {\n const context = React.useContext(AccordionContext);\n if (!context) {\n throw new Error('Accordion components must be used within an Accordion');\n }\n return context;\n}\n\nfunction useAccordionItemContext() {\n const context = React.useContext(AccordionItemContext);\n if (!context) {\n throw new Error('Accordion.Trigger/Content must be used within an Accordion.Item');\n }\n return context;\n}\n\n// ============================================\n// Components\n// ============================================\n\nfunction AccordionRoot({\n children,\n type = 'single',\n value,\n defaultValue,\n onValueChange,\n collapsible = false,\n headingLevel = 3,\n className,\n ...htmlProps\n}: AccordionProps) {\n // Normalize value to array for internal handling\n const normalizeValue = (val: AccordionValue | undefined): string[] => {\n if (val === undefined) return [];\n return Array.isArray(val) ? val : [val];\n };\n\n const [openItems, setOpenItems] = React.useState<string[]>(() =>\n normalizeValue(defaultValue)\n );\n\n // Use controlled value if provided\n const controlledOpenItems = value !== undefined ? normalizeValue(value) : undefined;\n const currentOpenItems = controlledOpenItems ?? openItems;\n\n const toggle = React.useCallback((itemValue: string) => {\n const newItems = (() => {\n if (type === 'single') {\n // For single, toggle or set new item\n if (currentOpenItems.includes(itemValue)) {\n return collapsible ? [] : currentOpenItems;\n }\n return [itemValue];\n } else {\n // For multiple, toggle item in array\n if (currentOpenItems.includes(itemValue)) {\n return currentOpenItems.filter(v => v !== itemValue);\n }\n return [...currentOpenItems, itemValue];\n }\n })();\n\n if (controlledOpenItems === undefined) {\n setOpenItems(newItems);\n }\n\n if (onValueChange) {\n onValueChange(type === 'single' ? newItems[0] : newItems);\n }\n }, [type, currentOpenItems, collapsible, controlledOpenItems, onValueChange]);\n\n const classes = [styles.accordion, className].filter(Boolean).join(' ');\n\n return (\n <AccordionContext.Provider value={{ type, openItems: currentOpenItems, toggle, collapsible, headingLevel }}>\n <div {...htmlProps} className={classes} data-orientation=\"vertical\" role=\"region\">\n {children}\n </div>\n </AccordionContext.Provider>\n );\n}\n\nfunction AccordionItem({\n children,\n value,\n disabled = false,\n className,\n ...htmlProps\n}: AccordionItemProps) {\n const { openItems } = useAccordionContext();\n const isOpen = openItems.includes(value);\n const baseId = React.useId();\n const triggerId = `accordion-trigger-${baseId}`;\n const contentId = `accordion-content-${baseId}`;\n\n const classes = [\n styles.item,\n isOpen && styles.itemOpen,\n disabled && styles.itemDisabled,\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <AccordionItemContext.Provider value={{ value, isOpen, disabled, triggerId, contentId }}>\n <BaseCollapsible.Root open={isOpen} disabled={disabled}>\n <div {...htmlProps} className={classes} data-state={isOpen ? 'open' : 'closed'} data-disabled={disabled || undefined}>\n {children}\n </div>\n </BaseCollapsible.Root>\n </AccordionItemContext.Provider>\n );\n}\n\nfunction AccordionTrigger({\n children,\n className,\n onClick,\n ...htmlProps\n}: AccordionTriggerProps) {\n const { toggle, headingLevel } = useAccordionContext();\n const { value, isOpen, disabled, triggerId, contentId } = useAccordionItemContext();\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n if (!disabled) {\n toggle(value);\n }\n };\n\n const classes = [styles.trigger, className].filter(Boolean).join(' ');\n\n // Create the heading element dynamically based on headingLevel\n const HeadingTag = `h${headingLevel}` as 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\n return (\n <HeadingTag className={styles.heading}>\n <BaseCollapsible.Trigger\n {...htmlProps}\n id={triggerId}\n className={classes}\n onClick={handleClick}\n aria-expanded={isOpen}\n aria-controls={contentId}\n data-state={isOpen ? 'open' : 'closed'}\n disabled={disabled}\n >\n <span className={styles.triggerContent}>{children}</span>\n <svg\n className={styles.chevron}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </BaseCollapsible.Trigger>\n </HeadingTag>\n );\n}\n\nfunction AccordionContent({\n children,\n className,\n ...htmlProps\n}: AccordionContentProps) {\n const { isOpen, triggerId, contentId } = useAccordionItemContext();\n\n const classes = [styles.content, className].filter(Boolean).join(' ');\n\n return (\n <BaseCollapsible.Panel\n {...htmlProps}\n id={contentId}\n className={classes}\n data-state={isOpen ? 'open' : 'closed'}\n role=\"region\"\n aria-labelledby={triggerId}\n >\n <div className={styles.contentInner}>\n {children}\n </div>\n </BaseCollapsible.Panel>\n );\n}\n\n// ============================================\n// Export compound component\n// ============================================\n\nexport const Accordion = Object.assign(AccordionRoot, {\n Item: AccordionItem,\n Trigger: AccordionTrigger,\n Content: AccordionContent,\n});\n\nexport { AccordionRoot, AccordionItem, AccordionTrigger, AccordionContent };\n"],"names":["React","collapsible","styles","jsx","BaseCollapsible","jsxs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA4DA,MAAM,mBAAmBA,iBAAM,cAA4C,IAAI;AAU/E,MAAM,uBAAuBA,iBAAM,cAAgD,IAAI;AAEvF,SAAS,sBAAsB;AAC7B,QAAM,UAAUA,iBAAM,WAAW,gBAAgB;AACjD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,SAAO;AACT;AAEA,SAAS,0BAA0B;AACjC,QAAM,UAAUA,iBAAM,WAAW,oBAAoB;AACrD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,iEAAiE;AAAA,EACnF;AACA,SAAO;AACT;AAMA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAAC,eAAc;AAAA,EACd,eAAe;AAAA,EACf;AAAA,EACA,GAAG;AACL,GAAmB;AAEjB,QAAM,iBAAiB,CAAC,QAA8C;AACpE,QAAI,QAAQ,OAAW,QAAO,CAAA;AAC9B,WAAO,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG;AAAA,EACxC;AAEA,QAAM,CAAC,WAAW,YAAY,IAAID,iBAAM;AAAA,IAAmB,MACzD,eAAe,YAAY;AAAA,EAAA;AAI7B,QAAM,sBAAsB,UAAU,SAAY,eAAe,KAAK,IAAI;AAC1E,QAAM,mBAAmB,uBAAuB;AAEhD,QAAM,SAASA,iBAAM,YAAY,CAAC,cAAsB;AACtD,UAAM,YAAY,MAAM;AACtB,UAAI,SAAS,UAAU;AAErB,YAAI,iBAAiB,SAAS,SAAS,GAAG;AACxC,iBAAOC,eAAc,CAAA,IAAK;AAAA,QAC5B;AACA,eAAO,CAAC,SAAS;AAAA,MACnB,OAAO;AAEL,YAAI,iBAAiB,SAAS,SAAS,GAAG;AACxC,iBAAO,iBAAiB,OAAO,CAAA,MAAK,MAAM,SAAS;AAAA,QACrD;AACA,eAAO,CAAC,GAAG,kBAAkB,SAAS;AAAA,MACxC;AAAA,IACF,GAAA;AAEA,QAAI,wBAAwB,QAAW;AACrC,mBAAa,QAAQ;AAAA,IACvB;AAEA,QAAI,eAAe;AACjB,oBAAc,SAAS,WAAW,SAAS,CAAC,IAAI,QAAQ;AAAA,IAC1D;AAAA,EACF,GAAG,CAAC,MAAM,kBAAkBA,cAAa,qBAAqB,aAAa,CAAC;AAE5E,QAAM,UAAU,CAACC,iBAAAA,QAAO,WAAW,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAEtE,SACEC,+BAAC,iBAAiB,UAAjB,EAA0B,OAAO,EAAE,MAAM,WAAW,kBAAkB,QAAQ,aAAAF,cAAa,aAAA,GAC1F,UAAAE,2BAAAA,IAAC,OAAA,EAAK,GAAG,WAAW,WAAW,SAAS,oBAAiB,YAAW,MAAK,UACtE,SAAA,CACH,EAAA,CACF;AAEJ;AAEA,SAAS,cAAc;AAAA,EACrB;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,GAAG;AACL,GAAuB;AACrB,QAAM,EAAE,UAAA,IAAc,oBAAA;AACtB,QAAM,SAAS,UAAU,SAAS,KAAK;AACvC,QAAM,SAASH,iBAAM,MAAA;AACrB,QAAM,YAAY,qBAAqB,MAAM;AAC7C,QAAM,YAAY,qBAAqB,MAAM;AAE7C,QAAM,UAAU;AAAA,IACdE,iBAAAA,QAAO;AAAA,IACP,UAAUA,iBAAAA,QAAO;AAAA,IACjB,YAAYA,iBAAAA,QAAO;AAAA,IACnB;AAAA,EAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,SACEC,2BAAAA,IAAC,qBAAqB,UAArB,EAA8B,OAAO,EAAE,OAAO,QAAQ,UAAU,WAAW,UAAA,GAC1E,UAAAA,2BAAAA,IAACC,YAAAA,YAAgB,MAAhB,EAAqB,MAAM,QAAQ,UAClC,UAAAD,2BAAAA,IAAC,OAAA,EAAK,GAAG,WAAW,WAAW,SAAS,cAAY,SAAS,SAAS,UAAU,iBAAe,YAAY,QACxG,SAAA,CACH,GACF,GACF;AAEJ;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,QAAM,EAAE,QAAQ,aAAA,IAAiB,oBAAA;AACjC,QAAM,EAAE,OAAO,QAAQ,UAAU,WAAW,UAAA,IAAc,wBAAA;AAE1D,QAAM,cAAc,CAAC,UAA+C;AAClE,uCAAU;AACV,QAAI,MAAM,iBAAkB;AAC5B,QAAI,CAAC,UAAU;AACb,aAAO,KAAK;AAAA,IACd;AAAA,EACF;AAEA,QAAM,UAAU,CAACD,iBAAAA,QAAO,SAAS,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAGpE,QAAM,aAAa,IAAI,YAAY;AAEnC,SACEC,2BAAAA,IAAC,YAAA,EAAW,WAAWD,iBAAAA,QAAO,SAC5B,UAAAG,2BAAAA;AAAAA,IAACD,YAAAA,YAAgB;AAAA,IAAhB;AAAA,MACE,GAAG;AAAA,MACJ,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,SAAS;AAAA,MACT,iBAAe;AAAA,MACf,iBAAe;AAAA,MACf,cAAY,SAAS,SAAS;AAAA,MAC9B;AAAA,MAEA,UAAA;AAAA,QAAAD,2BAAAA,IAAC,QAAA,EAAK,WAAWD,iBAAAA,QAAO,gBAAiB,UAAS;AAAA,QAClDC,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWD,iBAAAA,QAAO;AAAA,YAClB,OAAM;AAAA,YACN,QAAO;AAAA,YACP,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,eAAY;AAAA,YAEZ,UAAAC,2BAAAA;AAAAA,cAAC;AAAA,cAAA;AAAA,gBACC,GAAE;AAAA,gBACF,QAAO;AAAA,gBACP,aAAY;AAAA,gBACZ,eAAc;AAAA,gBACd,gBAAe;AAAA,cAAA;AAAA,YAAA;AAAA,UACjB;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA,GAEJ;AAEJ;AAEA,SAAS,iBAAiB;AAAA,EACxB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,QAAM,EAAE,QAAQ,WAAW,UAAA,IAAc,wBAAA;AAEzC,QAAM,UAAU,CAACD,iBAAAA,QAAO,SAAS,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAEpE,SACEC,2BAAAA;AAAAA,IAACC,YAAAA,YAAgB;AAAA,IAAhB;AAAA,MACE,GAAG;AAAA,MACJ,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,cAAY,SAAS,SAAS;AAAA,MAC9B,MAAK;AAAA,MACL,mBAAiB;AAAA,MAEjB,UAAAD,2BAAAA,IAAC,OAAA,EAAI,WAAWD,iBAAAA,QAAO,cACpB,SAAA,CACH;AAAA,IAAA;AAAA,EAAA;AAGN;AAMO,MAAM,YAAY,OAAO,OAAO,eAAe;AAAA,EACpD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AACX,CAAC;;;;;;"}
@@ -9,7 +9,7 @@ export interface AccordionProps extends Omit<React.HTMLAttributes<HTMLDivElement
9
9
  /** Default value for uncontrolled usage */
10
10
  defaultValue?: AccordionValue;
11
11
  /** Callback when value changes */
12
- onValueChange?: (value: AccordionValue) => void;
12
+ onValueChange?: (value: AccordionValue | undefined) => void;
13
13
  /** Whether items can be fully collapsed (only for type="single") */
14
14
  collapsible?: boolean;
15
15
  /**
@@ -34,8 +34,8 @@ export interface AccordionContentProps extends React.HTMLAttributes<HTMLDivEleme
34
34
  }
35
35
  declare function AccordionRoot({ children, type, value, defaultValue, onValueChange, collapsible, headingLevel, className, ...htmlProps }: AccordionProps): import("react/jsx-runtime").JSX.Element;
36
36
  declare function AccordionItem({ children, value, disabled, className, ...htmlProps }: AccordionItemProps): import("react/jsx-runtime").JSX.Element;
37
- declare function AccordionTrigger({ children, className, }: AccordionTriggerProps): import("react/jsx-runtime").JSX.Element;
38
- declare function AccordionContent({ children, className, }: AccordionContentProps): import("react/jsx-runtime").JSX.Element;
37
+ declare function AccordionTrigger({ children, className, onClick, ...htmlProps }: AccordionTriggerProps): import("react/jsx-runtime").JSX.Element;
38
+ declare function AccordionContent({ children, className, ...htmlProps }: AccordionContentProps): import("react/jsx-runtime").JSX.Element;
39
39
  export declare const Accordion: typeof AccordionRoot & {
40
40
  Item: typeof AccordionItem;
41
41
  Trigger: typeof AccordionTrigger;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Accordion/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE/C,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChG,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,8CAA8C;IAC9C,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,kEAAkE;IAClE,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,kCAAkC;IAClC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAChD,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,kBAAmB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC9E,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,iBAAiB,CAAC;IACpF,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACjF,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AA8CD,iBAAS,aAAa,CAAC,EACrB,QAAQ,EACR,IAAe,EACf,KAAK,EACL,YAAY,EACZ,aAAa,EACb,WAAmB,EACnB,YAAgB,EAChB,SAAS,EACT,GAAG,SAAS,EACb,EAAE,cAAc,2CAkDhB;AAED,iBAAS,aAAa,CAAC,EACrB,QAAQ,EACR,KAAK,EACL,QAAgB,EAChB,SAAS,EACT,GAAG,SAAS,EACb,EAAE,kBAAkB,2CAuBpB;AAED,iBAAS,gBAAgB,CAAC,EACxB,QAAQ,EACR,SAAS,GACV,EAAE,qBAAqB,2CA8CvB;AAED,iBAAS,gBAAgB,CAAC,EACxB,QAAQ,EACR,SAAS,GACV,EAAE,qBAAqB,2CAkBvB;AAMD,eAAO,MAAM,SAAS;;;;CAIpB,CAAC;AAEH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Accordion/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE/C,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChG,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,8CAA8C;IAC9C,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC7B,kEAAkE;IAClE,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,kCAAkC;IAClC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,KAAK,IAAI,CAAC;IAC5D,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,kBAAmB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC9E,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,iBAAiB,CAAC;IACpF,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAsB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACjF,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AA8CD,iBAAS,aAAa,CAAC,EACrB,QAAQ,EACR,IAAe,EACf,KAAK,EACL,YAAY,EACZ,aAAa,EACb,WAAmB,EACnB,YAAgB,EAChB,SAAS,EACT,GAAG,SAAS,EACb,EAAE,cAAc,2CAkDhB;AAED,iBAAS,aAAa,CAAC,EACrB,QAAQ,EACR,KAAK,EACL,QAAgB,EAChB,SAAS,EACT,GAAG,SAAS,EACb,EAAE,kBAAkB,2CAuBpB;AAED,iBAAS,gBAAgB,CAAC,EACxB,QAAQ,EACR,SAAS,EACT,OAAO,EACP,GAAG,SAAS,EACb,EAAE,qBAAqB,2CAiDvB;AAED,iBAAS,gBAAgB,CAAC,EACxB,QAAQ,EACR,SAAS,EACT,GAAG,SAAS,EACb,EAAE,qBAAqB,2CAmBvB;AAMD,eAAO,MAAM,SAAS;;;;CAIpB,CAAC;AAEH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
@@ -56,7 +56,7 @@ function AccordionRoot({
56
56
  setOpenItems(newItems);
57
57
  }
58
58
  if (onValueChange) {
59
- onValueChange(type === "single" ? newItems[0] ?? "" : newItems);
59
+ onValueChange(type === "single" ? newItems[0] : newItems);
60
60
  }
61
61
  }, [type, currentOpenItems, collapsible, controlledOpenItems, onValueChange]);
62
62
  const classes = [styles.accordion, className].filter(Boolean).join(" ");
@@ -84,11 +84,15 @@ function AccordionItem({
84
84
  }
85
85
  function AccordionTrigger({
86
86
  children,
87
- className
87
+ className,
88
+ onClick,
89
+ ...htmlProps
88
90
  }) {
89
91
  const { toggle, headingLevel } = useAccordionContext();
90
92
  const { value, isOpen, disabled, triggerId, contentId } = useAccordionItemContext();
91
- const handleClick = () => {
93
+ const handleClick = (event) => {
94
+ onClick == null ? void 0 : onClick(event);
95
+ if (event.defaultPrevented) return;
92
96
  if (!disabled) {
93
97
  toggle(value);
94
98
  }
@@ -98,6 +102,7 @@ function AccordionTrigger({
98
102
  return /* @__PURE__ */ jsx(HeadingTag, { className: styles.heading, children: /* @__PURE__ */ jsxs(
99
103
  Collapsible.Trigger,
100
104
  {
105
+ ...htmlProps,
101
106
  id: triggerId,
102
107
  className: classes,
103
108
  onClick: handleClick,
@@ -134,13 +139,15 @@ function AccordionTrigger({
134
139
  }
135
140
  function AccordionContent({
136
141
  children,
137
- className
142
+ className,
143
+ ...htmlProps
138
144
  }) {
139
145
  const { isOpen, triggerId, contentId } = useAccordionItemContext();
140
146
  const classes = [styles.content, className].filter(Boolean).join(" ");
141
147
  return /* @__PURE__ */ jsx(
142
148
  Collapsible.Panel,
143
149
  {
150
+ ...htmlProps,
144
151
  id: contentId,
145
152
  className: classes,
146
153
  "data-state": isOpen ? "open" : "closed",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/components/Accordion/index.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Collapsible as BaseCollapsible } from '@base-ui/react/collapsible';\nimport styles from './Accordion.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport type AccordionValue = string | string[];\n\nexport interface AccordionProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'defaultValue'> {\n children: React.ReactNode;\n /** Allow multiple items to be open at once */\n type?: 'single' | 'multiple';\n /** Controlled value - string for single, string[] for multiple */\n value?: AccordionValue;\n /** Default value for uncontrolled usage */\n defaultValue?: AccordionValue;\n /** Callback when value changes */\n onValueChange?: (value: AccordionValue) => void;\n /** Whether items can be fully collapsed (only for type=\"single\") */\n collapsible?: boolean;\n /**\n * Heading level for accordion triggers (for semantic HTML).\n * The trigger will be wrapped in an <h{level}> element.\n * @default 3\n */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n}\n\nexport interface AccordionItemProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Unique value for this item */\n value: string;\n /** Disable this item */\n disabled?: boolean;\n}\n\nexport interface AccordionTriggerProps extends React.HTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode;\n}\n\nexport interface AccordionContentProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n}\n\n// ============================================\n// Context\n// ============================================\n\ninterface AccordionContextValue {\n type: 'single' | 'multiple';\n openItems: string[];\n toggle: (value: string) => void;\n collapsible: boolean;\n headingLevel: 2 | 3 | 4 | 5 | 6;\n}\n\nconst AccordionContext = React.createContext<AccordionContextValue | null>(null);\n\ninterface AccordionItemContextValue {\n value: string;\n isOpen: boolean;\n disabled: boolean;\n triggerId: string;\n contentId: string;\n}\n\nconst AccordionItemContext = React.createContext<AccordionItemContextValue | null>(null);\n\nfunction useAccordionContext() {\n const context = React.useContext(AccordionContext);\n if (!context) {\n throw new Error('Accordion components must be used within an Accordion');\n }\n return context;\n}\n\nfunction useAccordionItemContext() {\n const context = React.useContext(AccordionItemContext);\n if (!context) {\n throw new Error('Accordion.Trigger/Content must be used within an Accordion.Item');\n }\n return context;\n}\n\n// ============================================\n// Components\n// ============================================\n\nfunction AccordionRoot({\n children,\n type = 'single',\n value,\n defaultValue,\n onValueChange,\n collapsible = false,\n headingLevel = 3,\n className,\n ...htmlProps\n}: AccordionProps) {\n // Normalize value to array for internal handling\n const normalizeValue = (val: AccordionValue | undefined): string[] => {\n if (val === undefined) return [];\n return Array.isArray(val) ? val : [val];\n };\n\n const [openItems, setOpenItems] = React.useState<string[]>(() =>\n normalizeValue(defaultValue)\n );\n\n // Use controlled value if provided\n const controlledOpenItems = value !== undefined ? normalizeValue(value) : undefined;\n const currentOpenItems = controlledOpenItems ?? openItems;\n\n const toggle = React.useCallback((itemValue: string) => {\n const newItems = (() => {\n if (type === 'single') {\n // For single, toggle or set new item\n if (currentOpenItems.includes(itemValue)) {\n return collapsible ? [] : currentOpenItems;\n }\n return [itemValue];\n } else {\n // For multiple, toggle item in array\n if (currentOpenItems.includes(itemValue)) {\n return currentOpenItems.filter(v => v !== itemValue);\n }\n return [...currentOpenItems, itemValue];\n }\n })();\n\n if (controlledOpenItems === undefined) {\n setOpenItems(newItems);\n }\n\n if (onValueChange) {\n onValueChange(type === 'single' ? (newItems[0] ?? '') : newItems);\n }\n }, [type, currentOpenItems, collapsible, controlledOpenItems, onValueChange]);\n\n const classes = [styles.accordion, className].filter(Boolean).join(' ');\n\n return (\n <AccordionContext.Provider value={{ type, openItems: currentOpenItems, toggle, collapsible, headingLevel }}>\n <div {...htmlProps} className={classes} data-orientation=\"vertical\" role=\"region\">\n {children}\n </div>\n </AccordionContext.Provider>\n );\n}\n\nfunction AccordionItem({\n children,\n value,\n disabled = false,\n className,\n ...htmlProps\n}: AccordionItemProps) {\n const { openItems } = useAccordionContext();\n const isOpen = openItems.includes(value);\n const baseId = React.useId();\n const triggerId = `accordion-trigger-${baseId}`;\n const contentId = `accordion-content-${baseId}`;\n\n const classes = [\n styles.item,\n isOpen && styles.itemOpen,\n disabled && styles.itemDisabled,\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <AccordionItemContext.Provider value={{ value, isOpen, disabled, triggerId, contentId }}>\n <BaseCollapsible.Root open={isOpen} disabled={disabled}>\n <div {...htmlProps} className={classes} data-state={isOpen ? 'open' : 'closed'} data-disabled={disabled || undefined}>\n {children}\n </div>\n </BaseCollapsible.Root>\n </AccordionItemContext.Provider>\n );\n}\n\nfunction AccordionTrigger({\n children,\n className,\n}: AccordionTriggerProps) {\n const { toggle, headingLevel } = useAccordionContext();\n const { value, isOpen, disabled, triggerId, contentId } = useAccordionItemContext();\n\n const handleClick = () => {\n if (!disabled) {\n toggle(value);\n }\n };\n\n const classes = [styles.trigger, className].filter(Boolean).join(' ');\n\n // Create the heading element dynamically based on headingLevel\n const HeadingTag = `h${headingLevel}` as 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\n return (\n <HeadingTag className={styles.heading}>\n <BaseCollapsible.Trigger\n id={triggerId}\n className={classes}\n onClick={handleClick}\n aria-expanded={isOpen}\n aria-controls={contentId}\n data-state={isOpen ? 'open' : 'closed'}\n disabled={disabled}\n >\n <span className={styles.triggerContent}>{children}</span>\n <svg\n className={styles.chevron}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </BaseCollapsible.Trigger>\n </HeadingTag>\n );\n}\n\nfunction AccordionContent({\n children,\n className,\n}: AccordionContentProps) {\n const { isOpen, triggerId, contentId } = useAccordionItemContext();\n\n const classes = [styles.content, className].filter(Boolean).join(' ');\n\n return (\n <BaseCollapsible.Panel\n id={contentId}\n className={classes}\n data-state={isOpen ? 'open' : 'closed'}\n role=\"region\"\n aria-labelledby={triggerId}\n >\n <div className={styles.contentInner}>\n {children}\n </div>\n </BaseCollapsible.Panel>\n );\n}\n\n// ============================================\n// Export compound component\n// ============================================\n\nexport const Accordion = Object.assign(AccordionRoot, {\n Item: AccordionItem,\n Trigger: AccordionTrigger,\n Content: AccordionContent,\n});\n\nexport { AccordionRoot, AccordionItem, AccordionTrigger, AccordionContent };\n"],"names":["BaseCollapsible"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/components/Accordion/index.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Collapsible as BaseCollapsible } from '@base-ui/react/collapsible';\nimport styles from './Accordion.module.scss';\n\n// ============================================\n// Types\n// ============================================\n\nexport type AccordionValue = string | string[];\n\nexport interface AccordionProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'defaultValue'> {\n children: React.ReactNode;\n /** Allow multiple items to be open at once */\n type?: 'single' | 'multiple';\n /** Controlled value - string for single, string[] for multiple */\n value?: AccordionValue;\n /** Default value for uncontrolled usage */\n defaultValue?: AccordionValue;\n /** Callback when value changes */\n onValueChange?: (value: AccordionValue | undefined) => void;\n /** Whether items can be fully collapsed (only for type=\"single\") */\n collapsible?: boolean;\n /**\n * Heading level for accordion triggers (for semantic HTML).\n * The trigger will be wrapped in an <h{level}> element.\n * @default 3\n */\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n}\n\nexport interface AccordionItemProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Unique value for this item */\n value: string;\n /** Disable this item */\n disabled?: boolean;\n}\n\nexport interface AccordionTriggerProps extends React.HTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode;\n}\n\nexport interface AccordionContentProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n}\n\n// ============================================\n// Context\n// ============================================\n\ninterface AccordionContextValue {\n type: 'single' | 'multiple';\n openItems: string[];\n toggle: (value: string) => void;\n collapsible: boolean;\n headingLevel: 2 | 3 | 4 | 5 | 6;\n}\n\nconst AccordionContext = React.createContext<AccordionContextValue | null>(null);\n\ninterface AccordionItemContextValue {\n value: string;\n isOpen: boolean;\n disabled: boolean;\n triggerId: string;\n contentId: string;\n}\n\nconst AccordionItemContext = React.createContext<AccordionItemContextValue | null>(null);\n\nfunction useAccordionContext() {\n const context = React.useContext(AccordionContext);\n if (!context) {\n throw new Error('Accordion components must be used within an Accordion');\n }\n return context;\n}\n\nfunction useAccordionItemContext() {\n const context = React.useContext(AccordionItemContext);\n if (!context) {\n throw new Error('Accordion.Trigger/Content must be used within an Accordion.Item');\n }\n return context;\n}\n\n// ============================================\n// Components\n// ============================================\n\nfunction AccordionRoot({\n children,\n type = 'single',\n value,\n defaultValue,\n onValueChange,\n collapsible = false,\n headingLevel = 3,\n className,\n ...htmlProps\n}: AccordionProps) {\n // Normalize value to array for internal handling\n const normalizeValue = (val: AccordionValue | undefined): string[] => {\n if (val === undefined) return [];\n return Array.isArray(val) ? val : [val];\n };\n\n const [openItems, setOpenItems] = React.useState<string[]>(() =>\n normalizeValue(defaultValue)\n );\n\n // Use controlled value if provided\n const controlledOpenItems = value !== undefined ? normalizeValue(value) : undefined;\n const currentOpenItems = controlledOpenItems ?? openItems;\n\n const toggle = React.useCallback((itemValue: string) => {\n const newItems = (() => {\n if (type === 'single') {\n // For single, toggle or set new item\n if (currentOpenItems.includes(itemValue)) {\n return collapsible ? [] : currentOpenItems;\n }\n return [itemValue];\n } else {\n // For multiple, toggle item in array\n if (currentOpenItems.includes(itemValue)) {\n return currentOpenItems.filter(v => v !== itemValue);\n }\n return [...currentOpenItems, itemValue];\n }\n })();\n\n if (controlledOpenItems === undefined) {\n setOpenItems(newItems);\n }\n\n if (onValueChange) {\n onValueChange(type === 'single' ? newItems[0] : newItems);\n }\n }, [type, currentOpenItems, collapsible, controlledOpenItems, onValueChange]);\n\n const classes = [styles.accordion, className].filter(Boolean).join(' ');\n\n return (\n <AccordionContext.Provider value={{ type, openItems: currentOpenItems, toggle, collapsible, headingLevel }}>\n <div {...htmlProps} className={classes} data-orientation=\"vertical\" role=\"region\">\n {children}\n </div>\n </AccordionContext.Provider>\n );\n}\n\nfunction AccordionItem({\n children,\n value,\n disabled = false,\n className,\n ...htmlProps\n}: AccordionItemProps) {\n const { openItems } = useAccordionContext();\n const isOpen = openItems.includes(value);\n const baseId = React.useId();\n const triggerId = `accordion-trigger-${baseId}`;\n const contentId = `accordion-content-${baseId}`;\n\n const classes = [\n styles.item,\n isOpen && styles.itemOpen,\n disabled && styles.itemDisabled,\n className,\n ].filter(Boolean).join(' ');\n\n return (\n <AccordionItemContext.Provider value={{ value, isOpen, disabled, triggerId, contentId }}>\n <BaseCollapsible.Root open={isOpen} disabled={disabled}>\n <div {...htmlProps} className={classes} data-state={isOpen ? 'open' : 'closed'} data-disabled={disabled || undefined}>\n {children}\n </div>\n </BaseCollapsible.Root>\n </AccordionItemContext.Provider>\n );\n}\n\nfunction AccordionTrigger({\n children,\n className,\n onClick,\n ...htmlProps\n}: AccordionTriggerProps) {\n const { toggle, headingLevel } = useAccordionContext();\n const { value, isOpen, disabled, triggerId, contentId } = useAccordionItemContext();\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented) return;\n if (!disabled) {\n toggle(value);\n }\n };\n\n const classes = [styles.trigger, className].filter(Boolean).join(' ');\n\n // Create the heading element dynamically based on headingLevel\n const HeadingTag = `h${headingLevel}` as 'h2' | 'h3' | 'h4' | 'h5' | 'h6';\n\n return (\n <HeadingTag className={styles.heading}>\n <BaseCollapsible.Trigger\n {...htmlProps}\n id={triggerId}\n className={classes}\n onClick={handleClick}\n aria-expanded={isOpen}\n aria-controls={contentId}\n data-state={isOpen ? 'open' : 'closed'}\n disabled={disabled}\n >\n <span className={styles.triggerContent}>{children}</span>\n <svg\n className={styles.chevron}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </BaseCollapsible.Trigger>\n </HeadingTag>\n );\n}\n\nfunction AccordionContent({\n children,\n className,\n ...htmlProps\n}: AccordionContentProps) {\n const { isOpen, triggerId, contentId } = useAccordionItemContext();\n\n const classes = [styles.content, className].filter(Boolean).join(' ');\n\n return (\n <BaseCollapsible.Panel\n {...htmlProps}\n id={contentId}\n className={classes}\n data-state={isOpen ? 'open' : 'closed'}\n role=\"region\"\n aria-labelledby={triggerId}\n >\n <div className={styles.contentInner}>\n {children}\n </div>\n </BaseCollapsible.Panel>\n );\n}\n\n// ============================================\n// Export compound component\n// ============================================\n\nexport const Accordion = Object.assign(AccordionRoot, {\n Item: AccordionItem,\n Trigger: AccordionTrigger,\n Content: AccordionContent,\n});\n\nexport { AccordionRoot, AccordionItem, AccordionTrigger, AccordionContent };\n"],"names":["BaseCollapsible"],"mappings":"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"}
@@ -3,6 +3,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const jsxRuntime = require("react/jsx-runtime");
4
4
  const React = require("react");
5
5
  const Collapsible_module = require("./Collapsible.module.scss.cjs");
6
+ function composeEventHandlers(userHandler, internalHandler) {
7
+ return (event) => {
8
+ userHandler == null ? void 0 : userHandler(event);
9
+ if (event.defaultPrevented) return;
10
+ internalHandler(event);
11
+ };
12
+ }
6
13
  const CollapsibleContext = React.createContext(null);
7
14
  function useCollapsibleContext() {
8
15
  const context = React.useContext(CollapsibleContext);
@@ -17,7 +24,8 @@ function CollapsibleRoot({
17
24
  open: controlledOpen,
18
25
  onOpenChange,
19
26
  disabled = false,
20
- className
27
+ className,
28
+ ...htmlProps
21
29
  }) {
22
30
  const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
23
31
  const isControlled = controlledOpen !== void 0;
@@ -47,6 +55,7 @@ function CollapsibleRoot({
47
55
  return /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
48
56
  "div",
49
57
  {
58
+ ...htmlProps,
50
59
  className: `${Collapsible_module.default.root} ${isOpen ? Collapsible_module.default.open : ""} ${disabled ? Collapsible_module.default.disabled : ""} ${className || ""}`,
51
60
  "data-state": isOpen ? "open" : "closed",
52
61
  "data-disabled": disabled || void 0,
@@ -59,7 +68,10 @@ function CollapsibleTrigger({
59
68
  className,
60
69
  showChevron = true,
61
70
  chevronPosition = "end",
62
- asChild = false
71
+ asChild = false,
72
+ onClick,
73
+ onKeyDown,
74
+ ...htmlProps
63
75
  }) {
64
76
  const { isOpen, toggle, contentId, triggerId, disabled } = useCollapsibleContext();
65
77
  const handleKeyDown = (e) => {
@@ -68,6 +80,9 @@ function CollapsibleTrigger({
68
80
  toggle();
69
81
  }
70
82
  };
83
+ const handleClick = () => {
84
+ toggle();
85
+ };
71
86
  const chevronIcon = showChevron && /* @__PURE__ */ jsxRuntime.jsx(
72
87
  "svg",
73
88
  {
@@ -90,26 +105,44 @@ function CollapsibleTrigger({
90
105
  }
91
106
  );
92
107
  if (asChild && React.isValidElement(children)) {
108
+ const childProps = children.props;
93
109
  return React.cloneElement(children, {
94
- id: triggerId,
110
+ ...htmlProps,
111
+ id: htmlProps.id ?? triggerId,
95
112
  "aria-expanded": isOpen,
96
113
  "aria-controls": contentId,
97
114
  "aria-disabled": disabled || void 0,
98
- onClick: toggle,
99
- onKeyDown: handleKeyDown
115
+ onClick: composeEventHandlers(
116
+ (event) => {
117
+ var _a;
118
+ (_a = childProps.onClick) == null ? void 0 : _a.call(childProps, event);
119
+ onClick == null ? void 0 : onClick(event);
120
+ },
121
+ () => handleClick()
122
+ ),
123
+ onKeyDown: composeEventHandlers(
124
+ (event) => {
125
+ var _a;
126
+ (_a = childProps.onKeyDown) == null ? void 0 : _a.call(childProps, event);
127
+ onKeyDown == null ? void 0 : onKeyDown(event);
128
+ },
129
+ (event) => handleKeyDown(event)
130
+ ),
131
+ className: [className, childProps.className].filter(Boolean).join(" ")
100
132
  });
101
133
  }
102
134
  return /* @__PURE__ */ jsxRuntime.jsxs(
103
135
  "button",
104
136
  {
137
+ ...htmlProps,
105
138
  type: "button",
106
- id: triggerId,
139
+ id: htmlProps.id ?? triggerId,
107
140
  className: `${Collapsible_module.default.trigger} ${className || ""}`,
108
141
  "aria-expanded": isOpen,
109
142
  "aria-controls": contentId,
110
143
  "aria-disabled": disabled || void 0,
111
- onClick: toggle,
112
- onKeyDown: handleKeyDown,
144
+ onClick: composeEventHandlers(onClick, handleClick),
145
+ onKeyDown: composeEventHandlers(onKeyDown, handleKeyDown),
113
146
  disabled,
114
147
  children: [
115
148
  chevronPosition === "start" && chevronIcon,
@@ -122,7 +155,8 @@ function CollapsibleTrigger({
122
155
  function CollapsibleContent({
123
156
  children,
124
157
  className,
125
- forceMount = false
158
+ forceMount = false,
159
+ ...htmlProps
126
160
  }) {
127
161
  const { isOpen, contentId, triggerId } = useCollapsibleContext();
128
162
  if (!forceMount && !isOpen) {
@@ -131,7 +165,8 @@ function CollapsibleContent({
131
165
  return /* @__PURE__ */ jsxRuntime.jsx(
132
166
  "div",
133
167
  {
134
- id: contentId,
168
+ ...htmlProps,
169
+ id: htmlProps.id ?? contentId,
135
170
  role: "region",
136
171
  "aria-labelledby": triggerId,
137
172
  className: `${Collapsible_module.default.content} ${isOpen ? Collapsible_module.default.contentOpen : Collapsible_module.default.contentClosed} ${className || ""}`,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../../src/components/Collapsible/index.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useCallback, useId, createContext, useContext } from 'react';\nimport styles from './Collapsible.module.scss';\n\n// Context for sharing state between compound components\ninterface CollapsibleContextValue {\n isOpen: boolean;\n toggle: () => void;\n contentId: string;\n triggerId: string;\n disabled?: boolean;\n}\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | null>(null);\n\nfunction useCollapsibleContext() {\n const context = useContext(CollapsibleContext);\n if (!context) {\n throw new Error('Collapsible compound components must be used within Collapsible.Root');\n }\n return context;\n}\n\n// Root component\nexport interface CollapsibleRootProps {\n children: React.ReactNode;\n /** Whether the collapsible is initially open */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Whether the collapsible is disabled */\n disabled?: boolean;\n /** Additional class name */\n className?: string;\n}\n\nfunction CollapsibleRoot({\n children,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n disabled = false,\n className,\n}: CollapsibleRootProps) {\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const uniqueId = useId();\n const contentId = `collapsible-content-${uniqueId}`;\n const triggerId = `collapsible-trigger-${uniqueId}`;\n\n const toggle = useCallback(() => {\n if (disabled) return;\n\n if (isControlled) {\n onOpenChange?.(!isOpen);\n } else {\n setInternalOpen((prev) => {\n const newValue = !prev;\n onOpenChange?.(newValue);\n return newValue;\n });\n }\n }, [disabled, isControlled, isOpen, onOpenChange]);\n\n const contextValue: CollapsibleContextValue = {\n isOpen,\n toggle,\n contentId,\n triggerId,\n disabled,\n };\n\n return (\n <CollapsibleContext.Provider value={contextValue}>\n <div\n className={`${styles.root} ${isOpen ? styles.open : ''} ${disabled ? styles.disabled : ''} ${className || ''}`}\n data-state={isOpen ? 'open' : 'closed'}\n data-disabled={disabled || undefined}\n >\n {children}\n </div>\n </CollapsibleContext.Provider>\n );\n}\n\n// Trigger component\nexport interface CollapsibleTriggerProps {\n children: React.ReactNode;\n /** Additional class name */\n className?: string;\n /** Show chevron indicator */\n showChevron?: boolean;\n /** Chevron position */\n chevronPosition?: 'start' | 'end';\n /** Render as child element (for custom triggers) */\n asChild?: boolean;\n}\n\nfunction CollapsibleTrigger({\n children,\n className,\n showChevron = true,\n chevronPosition = 'end',\n asChild = false,\n}: CollapsibleTriggerProps) {\n const { isOpen, toggle, contentId, triggerId, disabled } = useCollapsibleContext();\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n toggle();\n }\n };\n\n const chevronIcon = showChevron && (\n <svg\n className={`${styles.chevron} ${isOpen ? styles.chevronOpen : ''}`}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n\n if (asChild && React.isValidElement(children)) {\n return React.cloneElement(children as React.ReactElement<any>, {\n id: triggerId,\n 'aria-expanded': isOpen,\n 'aria-controls': contentId,\n 'aria-disabled': disabled || undefined,\n onClick: toggle,\n onKeyDown: handleKeyDown,\n });\n }\n\n return (\n <button\n type=\"button\"\n id={triggerId}\n className={`${styles.trigger} ${className || ''}`}\n aria-expanded={isOpen}\n aria-controls={contentId}\n aria-disabled={disabled || undefined}\n onClick={toggle}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n >\n {chevronPosition === 'start' && chevronIcon}\n <span className={styles.triggerContent}>{children}</span>\n {chevronPosition === 'end' && chevronIcon}\n </button>\n );\n}\n\n// Content component\nexport interface CollapsibleContentProps {\n children: React.ReactNode;\n /** Additional class name */\n className?: string;\n /** Force mount content even when closed (useful for animations) */\n forceMount?: boolean;\n}\n\nfunction CollapsibleContent({\n children,\n className,\n forceMount = false,\n}: CollapsibleContentProps) {\n const { isOpen, contentId, triggerId } = useCollapsibleContext();\n\n // If not force mounted and closed, don't render\n if (!forceMount && !isOpen) {\n return null;\n }\n\n return (\n <div\n id={contentId}\n role=\"region\"\n aria-labelledby={triggerId}\n className={`${styles.content} ${isOpen ? styles.contentOpen : styles.contentClosed} ${className || ''}`}\n data-state={isOpen ? 'open' : 'closed'}\n hidden={!isOpen && !forceMount}\n >\n <div className={styles.contentInner}>{children}</div>\n </div>\n );\n}\n\n// Compound component export\nexport const Collapsible = Object.assign(CollapsibleRoot, {\n Root: CollapsibleRoot,\n Trigger: CollapsibleTrigger,\n Content: CollapsibleContent,\n});\n\n// Named exports for direct imports\nexport {\n CollapsibleRoot,\n CollapsibleTrigger,\n CollapsibleContent,\n useCollapsibleContext,\n};\n\nexport type CollapsibleProps = CollapsibleRootProps;\n"],"names":["createContext","useContext","useState","useId","useCallback","jsx","styles","jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../../src/components/Collapsible/index.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useCallback, useId, createContext, useContext } from 'react';\nimport styles from './Collapsible.module.scss';\n\nfunction composeEventHandlers<E extends { defaultPrevented: boolean }>(\n userHandler: ((event: E) => void) | undefined,\n internalHandler: (event: E) => void\n) {\n return (event: E) => {\n userHandler?.(event);\n if (event.defaultPrevented) return;\n internalHandler(event);\n };\n}\n\n// Context for sharing state between compound components\ninterface CollapsibleContextValue {\n isOpen: boolean;\n toggle: () => void;\n contentId: string;\n triggerId: string;\n disabled?: boolean;\n}\n\nconst CollapsibleContext = createContext<CollapsibleContextValue | null>(null);\n\nfunction useCollapsibleContext() {\n const context = useContext(CollapsibleContext);\n if (!context) {\n throw new Error('Collapsible compound components must be used within Collapsible.Root');\n }\n return context;\n}\n\n// Root component\nexport interface CollapsibleRootProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Whether the collapsible is initially open */\n defaultOpen?: boolean;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Whether the collapsible is disabled */\n disabled?: boolean;\n}\n\nfunction CollapsibleRoot({\n children,\n defaultOpen = false,\n open: controlledOpen,\n onOpenChange,\n disabled = false,\n className,\n ...htmlProps\n}: CollapsibleRootProps) {\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : internalOpen;\n\n const uniqueId = useId();\n const contentId = `collapsible-content-${uniqueId}`;\n const triggerId = `collapsible-trigger-${uniqueId}`;\n\n const toggle = useCallback(() => {\n if (disabled) return;\n\n if (isControlled) {\n onOpenChange?.(!isOpen);\n } else {\n setInternalOpen((prev) => {\n const newValue = !prev;\n onOpenChange?.(newValue);\n return newValue;\n });\n }\n }, [disabled, isControlled, isOpen, onOpenChange]);\n\n const contextValue: CollapsibleContextValue = {\n isOpen,\n toggle,\n contentId,\n triggerId,\n disabled,\n };\n\n return (\n <CollapsibleContext.Provider value={contextValue}>\n <div\n {...htmlProps}\n className={`${styles.root} ${isOpen ? styles.open : ''} ${disabled ? styles.disabled : ''} ${className || ''}`}\n data-state={isOpen ? 'open' : 'closed'}\n data-disabled={disabled || undefined}\n >\n {children}\n </div>\n </CollapsibleContext.Provider>\n );\n}\n\n// Trigger component\nexport interface CollapsibleTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n children: React.ReactNode;\n /** Show chevron indicator */\n showChevron?: boolean;\n /** Chevron position */\n chevronPosition?: 'start' | 'end';\n /** Render as child element (for custom triggers) */\n asChild?: boolean;\n}\n\nfunction CollapsibleTrigger({\n children,\n className,\n showChevron = true,\n chevronPosition = 'end',\n asChild = false,\n onClick,\n onKeyDown,\n ...htmlProps\n}: CollapsibleTriggerProps) {\n const { isOpen, toggle, contentId, triggerId, disabled } = useCollapsibleContext();\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n toggle();\n }\n };\n\n const handleClick = () => {\n toggle();\n };\n\n const chevronIcon = showChevron && (\n <svg\n className={`${styles.chevron} ${isOpen ? styles.chevronOpen : ''}`}\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n\n if (asChild && React.isValidElement(children)) {\n const childProps = children.props as {\n className?: string;\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLElement>) => void;\n };\n\n return React.cloneElement(children as React.ReactElement<any>, {\n ...htmlProps,\n id: (htmlProps.id as string | undefined) ?? triggerId,\n 'aria-expanded': isOpen,\n 'aria-controls': contentId,\n 'aria-disabled': disabled || undefined,\n onClick: composeEventHandlers(\n (event: React.MouseEvent<HTMLElement>) => {\n childProps.onClick?.(event);\n onClick?.(event as unknown as React.MouseEvent<HTMLButtonElement>);\n },\n () => handleClick()\n ),\n onKeyDown: composeEventHandlers(\n (event: React.KeyboardEvent<HTMLElement>) => {\n childProps.onKeyDown?.(event);\n onKeyDown?.(event as unknown as React.KeyboardEvent<HTMLButtonElement>);\n },\n (event) => handleKeyDown(event as unknown as React.KeyboardEvent)\n ),\n className: [className, childProps.className].filter(Boolean).join(' '),\n });\n }\n\n return (\n <button\n {...htmlProps}\n type=\"button\"\n id={(htmlProps.id as string | undefined) ?? triggerId}\n className={`${styles.trigger} ${className || ''}`}\n aria-expanded={isOpen}\n aria-controls={contentId}\n aria-disabled={disabled || undefined}\n onClick={composeEventHandlers(onClick, handleClick)}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}\n disabled={disabled}\n >\n {chevronPosition === 'start' && chevronIcon}\n <span className={styles.triggerContent}>{children}</span>\n {chevronPosition === 'end' && chevronIcon}\n </button>\n );\n}\n\n// Content component\nexport interface CollapsibleContentProps extends React.HTMLAttributes<HTMLDivElement> {\n children: React.ReactNode;\n /** Force mount content even when closed (useful for animations) */\n forceMount?: boolean;\n}\n\nfunction CollapsibleContent({\n children,\n className,\n forceMount = false,\n ...htmlProps\n}: CollapsibleContentProps) {\n const { isOpen, contentId, triggerId } = useCollapsibleContext();\n\n // If not force mounted and closed, don't render\n if (!forceMount && !isOpen) {\n return null;\n }\n\n return (\n <div\n {...htmlProps}\n id={(htmlProps.id as string | undefined) ?? contentId}\n role=\"region\"\n aria-labelledby={triggerId}\n className={`${styles.content} ${isOpen ? styles.contentOpen : styles.contentClosed} ${className || ''}`}\n data-state={isOpen ? 'open' : 'closed'}\n hidden={!isOpen && !forceMount}\n >\n <div className={styles.contentInner}>{children}</div>\n </div>\n );\n}\n\n// Compound component export\nexport const Collapsible = Object.assign(CollapsibleRoot, {\n Root: CollapsibleRoot,\n Trigger: CollapsibleTrigger,\n Content: CollapsibleContent,\n});\n\n// Named exports for direct imports\nexport {\n CollapsibleRoot,\n CollapsibleTrigger,\n CollapsibleContent,\n useCollapsibleContext,\n};\n\nexport type CollapsibleProps = CollapsibleRootProps;\n"],"names":["createContext","useContext","useState","useId","useCallback","jsx","styles","jsxs"],"mappings":"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"}
@@ -7,7 +7,7 @@ interface CollapsibleContextValue {
7
7
  disabled?: boolean;
8
8
  }
9
9
  declare function useCollapsibleContext(): CollapsibleContextValue;
10
- export interface CollapsibleRootProps {
10
+ export interface CollapsibleRootProps extends React.HTMLAttributes<HTMLDivElement> {
11
11
  children: React.ReactNode;
12
12
  /** Whether the collapsible is initially open */
13
13
  defaultOpen?: boolean;
@@ -17,14 +17,10 @@ export interface CollapsibleRootProps {
17
17
  onOpenChange?: (open: boolean) => void;
18
18
  /** Whether the collapsible is disabled */
19
19
  disabled?: boolean;
20
- /** Additional class name */
21
- className?: string;
22
20
  }
23
- declare function CollapsibleRoot({ children, defaultOpen, open: controlledOpen, onOpenChange, disabled, className, }: CollapsibleRootProps): import("react/jsx-runtime").JSX.Element;
24
- export interface CollapsibleTriggerProps {
21
+ declare function CollapsibleRoot({ children, defaultOpen, open: controlledOpen, onOpenChange, disabled, className, ...htmlProps }: CollapsibleRootProps): import("react/jsx-runtime").JSX.Element;
22
+ export interface CollapsibleTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
25
23
  children: React.ReactNode;
26
- /** Additional class name */
27
- className?: string;
28
24
  /** Show chevron indicator */
29
25
  showChevron?: boolean;
30
26
  /** Chevron position */
@@ -32,15 +28,13 @@ export interface CollapsibleTriggerProps {
32
28
  /** Render as child element (for custom triggers) */
33
29
  asChild?: boolean;
34
30
  }
35
- declare function CollapsibleTrigger({ children, className, showChevron, chevronPosition, asChild, }: CollapsibleTriggerProps): import("react/jsx-runtime").JSX.Element;
36
- export interface CollapsibleContentProps {
31
+ declare function CollapsibleTrigger({ children, className, showChevron, chevronPosition, asChild, onClick, onKeyDown, ...htmlProps }: CollapsibleTriggerProps): import("react/jsx-runtime").JSX.Element;
32
+ export interface CollapsibleContentProps extends React.HTMLAttributes<HTMLDivElement> {
37
33
  children: React.ReactNode;
38
- /** Additional class name */
39
- className?: string;
40
34
  /** Force mount content even when closed (useful for animations) */
41
35
  forceMount?: boolean;
42
36
  }
43
- declare function CollapsibleContent({ children, className, forceMount, }: CollapsibleContentProps): import("react/jsx-runtime").JSX.Element | null;
37
+ declare function CollapsibleContent({ children, className, forceMount, ...htmlProps }: CollapsibleContentProps): import("react/jsx-runtime").JSX.Element | null;
44
38
  export declare const Collapsible: typeof CollapsibleRoot & {
45
39
  Root: typeof CollapsibleRoot;
46
40
  Trigger: typeof CollapsibleTrigger;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Collapsible/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAkE,MAAM,OAAO,CAAC;AAIvF,UAAU,uBAAuB;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID,iBAAS,qBAAqB,4BAM7B;AAGD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gDAAgD;IAChD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iBAAS,eAAe,CAAC,EACvB,QAAQ,EACR,WAAmB,EACnB,IAAI,EAAE,cAAc,EACpB,YAAY,EACZ,QAAgB,EAChB,SAAS,GACV,EAAE,oBAAoB,2CA0CtB;AAGD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uBAAuB;IACvB,eAAe,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAClC,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,iBAAS,kBAAkB,CAAC,EAC1B,QAAQ,EACR,SAAS,EACT,WAAkB,EAClB,eAAuB,EACvB,OAAe,GAChB,EAAE,uBAAuB,2CAyDzB;AAGD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,iBAAS,kBAAkB,CAAC,EAC1B,QAAQ,EACR,SAAS,EACT,UAAkB,GACnB,EAAE,uBAAuB,kDAoBzB;AAGD,eAAO,MAAM,WAAW;;;;CAItB,CAAC;AAGH,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,GACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Collapsible/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAkE,MAAM,OAAO,CAAC;AAevF,UAAU,uBAAuB;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID,iBAAS,qBAAqB,4BAM7B;AAGD,MAAM,WAAW,oBAAqB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAChF,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gDAAgD;IAChD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uCAAuC;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,iBAAS,eAAe,CAAC,EACvB,QAAQ,EACR,WAAmB,EACnB,IAAI,EAAE,cAAc,EACpB,YAAY,EACZ,QAAgB,EAChB,SAAS,EACT,GAAG,SAAS,EACb,EAAE,oBAAoB,2CA2CtB;AAGD,MAAM,WAAW,uBAAwB,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IAC5F,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,6BAA6B;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uBAAuB;IACvB,eAAe,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAClC,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,iBAAS,kBAAkB,CAAC,EAC1B,QAAQ,EACR,SAAS,EACT,WAAkB,EAClB,eAAuB,EACvB,OAAe,EACf,OAAO,EACP,SAAS,EACT,GAAG,SAAS,EACb,EAAE,uBAAuB,2CAkFzB;AAGD,MAAM,WAAW,uBAAwB,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IACnF,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,mEAAmE;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,iBAAS,kBAAkB,CAAC,EAC1B,QAAQ,EACR,SAAS,EACT,UAAkB,EAClB,GAAG,SAAS,EACb,EAAE,uBAAuB,kDAqBzB;AAGD,eAAO,MAAM,WAAW;;;;CAItB,CAAC;AAGH,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,GACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,CAAC"}
@@ -1,6 +1,13 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import React__default, { useState, useId, useCallback, createContext, useContext } from "react";
3
3
  import styles from "./Collapsible.module.scss.js";
4
+ function composeEventHandlers(userHandler, internalHandler) {
5
+ return (event) => {
6
+ userHandler == null ? void 0 : userHandler(event);
7
+ if (event.defaultPrevented) return;
8
+ internalHandler(event);
9
+ };
10
+ }
4
11
  const CollapsibleContext = createContext(null);
5
12
  function useCollapsibleContext() {
6
13
  const context = useContext(CollapsibleContext);
@@ -15,7 +22,8 @@ function CollapsibleRoot({
15
22
  open: controlledOpen,
16
23
  onOpenChange,
17
24
  disabled = false,
18
- className
25
+ className,
26
+ ...htmlProps
19
27
  }) {
20
28
  const [internalOpen, setInternalOpen] = useState(defaultOpen);
21
29
  const isControlled = controlledOpen !== void 0;
@@ -45,6 +53,7 @@ function CollapsibleRoot({
45
53
  return /* @__PURE__ */ jsx(CollapsibleContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(
46
54
  "div",
47
55
  {
56
+ ...htmlProps,
48
57
  className: `${styles.root} ${isOpen ? styles.open : ""} ${disabled ? styles.disabled : ""} ${className || ""}`,
49
58
  "data-state": isOpen ? "open" : "closed",
50
59
  "data-disabled": disabled || void 0,
@@ -57,7 +66,10 @@ function CollapsibleTrigger({
57
66
  className,
58
67
  showChevron = true,
59
68
  chevronPosition = "end",
60
- asChild = false
69
+ asChild = false,
70
+ onClick,
71
+ onKeyDown,
72
+ ...htmlProps
61
73
  }) {
62
74
  const { isOpen, toggle, contentId, triggerId, disabled } = useCollapsibleContext();
63
75
  const handleKeyDown = (e) => {
@@ -66,6 +78,9 @@ function CollapsibleTrigger({
66
78
  toggle();
67
79
  }
68
80
  };
81
+ const handleClick = () => {
82
+ toggle();
83
+ };
69
84
  const chevronIcon = showChevron && /* @__PURE__ */ jsx(
70
85
  "svg",
71
86
  {
@@ -88,26 +103,44 @@ function CollapsibleTrigger({
88
103
  }
89
104
  );
90
105
  if (asChild && React__default.isValidElement(children)) {
106
+ const childProps = children.props;
91
107
  return React__default.cloneElement(children, {
92
- id: triggerId,
108
+ ...htmlProps,
109
+ id: htmlProps.id ?? triggerId,
93
110
  "aria-expanded": isOpen,
94
111
  "aria-controls": contentId,
95
112
  "aria-disabled": disabled || void 0,
96
- onClick: toggle,
97
- onKeyDown: handleKeyDown
113
+ onClick: composeEventHandlers(
114
+ (event) => {
115
+ var _a;
116
+ (_a = childProps.onClick) == null ? void 0 : _a.call(childProps, event);
117
+ onClick == null ? void 0 : onClick(event);
118
+ },
119
+ () => handleClick()
120
+ ),
121
+ onKeyDown: composeEventHandlers(
122
+ (event) => {
123
+ var _a;
124
+ (_a = childProps.onKeyDown) == null ? void 0 : _a.call(childProps, event);
125
+ onKeyDown == null ? void 0 : onKeyDown(event);
126
+ },
127
+ (event) => handleKeyDown(event)
128
+ ),
129
+ className: [className, childProps.className].filter(Boolean).join(" ")
98
130
  });
99
131
  }
100
132
  return /* @__PURE__ */ jsxs(
101
133
  "button",
102
134
  {
135
+ ...htmlProps,
103
136
  type: "button",
104
- id: triggerId,
137
+ id: htmlProps.id ?? triggerId,
105
138
  className: `${styles.trigger} ${className || ""}`,
106
139
  "aria-expanded": isOpen,
107
140
  "aria-controls": contentId,
108
141
  "aria-disabled": disabled || void 0,
109
- onClick: toggle,
110
- onKeyDown: handleKeyDown,
142
+ onClick: composeEventHandlers(onClick, handleClick),
143
+ onKeyDown: composeEventHandlers(onKeyDown, handleKeyDown),
111
144
  disabled,
112
145
  children: [
113
146
  chevronPosition === "start" && chevronIcon,
@@ -120,7 +153,8 @@ function CollapsibleTrigger({
120
153
  function CollapsibleContent({
121
154
  children,
122
155
  className,
123
- forceMount = false
156
+ forceMount = false,
157
+ ...htmlProps
124
158
  }) {
125
159
  const { isOpen, contentId, triggerId } = useCollapsibleContext();
126
160
  if (!forceMount && !isOpen) {
@@ -129,7 +163,8 @@ function CollapsibleContent({
129
163
  return /* @__PURE__ */ jsx(
130
164
  "div",
131
165
  {
132
- id: contentId,
166
+ ...htmlProps,
167
+ id: htmlProps.id ?? contentId,
133
168
  role: "region",
134
169
  "aria-labelledby": triggerId,
135
170
  className: `${styles.content} ${isOpen ? styles.contentOpen : styles.contentClosed} ${className || ""}`,