@astryxdesign/core 0.1.4 → 0.1.5-canary.76e6697

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 (635) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +20 -18
  5. package/dist/AlertDialog/useImperativeAlertDialog.d.ts +0 -2
  6. package/dist/AlertDialog/useImperativeAlertDialog.d.ts.map +1 -1
  7. package/dist/AlertDialog/useImperativeAlertDialog.js +3 -5
  8. package/dist/AppShell/AppShell.d.ts +1 -1
  9. package/dist/AppShell/AppShell.d.ts.map +1 -1
  10. package/dist/AppShell/AppShell.js +55 -53
  11. package/dist/AspectRatio/AspectRatio.d.ts +48 -10
  12. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  13. package/dist/AspectRatio/AspectRatio.js +33 -12
  14. package/dist/AspectRatio/index.d.ts +1 -1
  15. package/dist/AspectRatio/index.d.ts.map +1 -1
  16. package/dist/Avatar/Avatar.d.ts.map +1 -1
  17. package/dist/Avatar/Avatar.js +28 -26
  18. package/dist/Avatar/AvatarStatusDot.js +6 -6
  19. package/dist/AvatarGroup/AvatarGroup.js +6 -6
  20. package/dist/AvatarGroup/AvatarGroupOverflow.js +7 -7
  21. package/dist/Badge/Badge.js +3 -3
  22. package/dist/Banner/Banner.d.ts.map +1 -1
  23. package/dist/Banner/Banner.js +32 -25
  24. package/dist/Blockquote/Blockquote.js +7 -7
  25. package/dist/Breadcrumbs/BreadcrumbItem.js +17 -17
  26. package/dist/Breadcrumbs/Breadcrumbs.js +7 -7
  27. package/dist/Button/Button.js +19 -19
  28. package/dist/ButtonGroup/ButtonGroup.js +7 -7
  29. package/dist/Calendar/Calendar.d.ts.map +1 -1
  30. package/dist/Calendar/Calendar.js +68 -48
  31. package/dist/Calendar/dayCellUtils.d.ts.map +1 -1
  32. package/dist/Calendar/styles.d.ts +2 -2
  33. package/dist/Calendar/styles.d.ts.map +1 -1
  34. package/dist/Calendar/styles.js +2 -2
  35. package/dist/Card/Card.d.ts +4 -2
  36. package/dist/Card/Card.d.ts.map +1 -1
  37. package/dist/Card/Card.js +18 -10
  38. package/dist/Carousel/Carousel.d.ts.map +1 -1
  39. package/dist/Carousel/Carousel.js +24 -21
  40. package/dist/Center/Center.js +3 -3
  41. package/dist/Chat/ChatComposer.js +23 -23
  42. package/dist/Chat/ChatComposerDrawer.js +14 -14
  43. package/dist/Chat/ChatComposerInput.d.ts +1 -1
  44. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  45. package/dist/Chat/ChatComposerInput.js +27 -15
  46. package/dist/Chat/ChatDictationButton.d.ts +1 -1
  47. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  48. package/dist/Chat/ChatDictationButton.js +13 -11
  49. package/dist/Chat/ChatLayout.js +17 -17
  50. package/dist/Chat/ChatLayoutScrollButton.d.ts +1 -1
  51. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  52. package/dist/Chat/ChatLayoutScrollButton.js +12 -10
  53. package/dist/Chat/ChatMessage.js +12 -12
  54. package/dist/Chat/ChatMessageBubble.js +7 -7
  55. package/dist/Chat/ChatMessageList.js +14 -14
  56. package/dist/Chat/ChatMessageMetadata.d.ts +1 -1
  57. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  58. package/dist/Chat/ChatMessageMetadata.js +14 -12
  59. package/dist/Chat/ChatPastedTextToken.js +13 -13
  60. package/dist/Chat/ChatSendButton.js +3 -3
  61. package/dist/Chat/ChatSystemMessage.d.ts +1 -1
  62. package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
  63. package/dist/Chat/ChatSystemMessage.js +17 -17
  64. package/dist/Chat/ChatTokenizedText.d.ts +1 -1
  65. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  66. package/dist/Chat/ChatTokenizedText.js +24 -15
  67. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  68. package/dist/Chat/ChatToolCalls.js +81 -74
  69. package/dist/Chat/index.d.ts +1 -1
  70. package/dist/Chat/index.d.ts.map +1 -1
  71. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  72. package/dist/Chat/useTriggerMenu.js +15 -15
  73. package/dist/CheckboxInput/CheckboxInput.d.ts +1 -1
  74. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  75. package/dist/CheckboxInput/CheckboxInput.js +25 -23
  76. package/dist/CheckboxList/CheckboxList.js +9 -9
  77. package/dist/CheckboxList/CheckboxListItem.d.ts +1 -1
  78. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  79. package/dist/CheckboxList/CheckboxListItem.js +8 -6
  80. package/dist/Citation/Citation.js +10 -10
  81. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  82. package/dist/ClickableCard/ClickableCard.js +32 -9
  83. package/dist/Code/Code.js +3 -3
  84. package/dist/CodeBlock/CodeBlock.d.ts +10 -1
  85. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  86. package/dist/CodeBlock/CodeBlock.js +88 -52
  87. package/dist/Collapsible/Collapsible.d.ts +9 -3
  88. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  89. package/dist/Collapsible/Collapsible.js +109 -22
  90. package/dist/Collapsible/CollapsibleGroup.d.ts +37 -7
  91. package/dist/Collapsible/CollapsibleGroup.d.ts.map +1 -1
  92. package/dist/Collapsible/CollapsibleGroup.js +64 -12
  93. package/dist/Collapsible/CollapsibleGroupContext.d.ts +24 -0
  94. package/dist/Collapsible/CollapsibleGroupContext.d.ts.map +1 -1
  95. package/dist/Collapsible/CollapsibleGroupContext.js +26 -3
  96. package/dist/Collapsible/index.d.ts +1 -0
  97. package/dist/Collapsible/index.d.ts.map +1 -1
  98. package/dist/Collapsible/useCollapsible.d.ts +4 -1
  99. package/dist/Collapsible/useCollapsible.d.ts.map +1 -1
  100. package/dist/Collapsible/useCollapsible.js +20 -6
  101. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  102. package/dist/CommandPalette/CommandPalette.js +36 -34
  103. package/dist/CommandPalette/CommandPaletteEmpty.js +3 -3
  104. package/dist/CommandPalette/CommandPaletteFooter.js +16 -16
  105. package/dist/CommandPalette/CommandPaletteGroup.js +5 -5
  106. package/dist/CommandPalette/CommandPaletteInput.js +13 -13
  107. package/dist/CommandPalette/CommandPaletteItem.js +3 -3
  108. package/dist/CommandPalette/CommandPaletteList.js +3 -3
  109. package/dist/ContextMenu/ContextMenu.d.ts +7 -2
  110. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  111. package/dist/ContextMenu/ContextMenu.js +76 -43
  112. package/dist/DateInput/DateInput.js +18 -18
  113. package/dist/DateRangeInput/DateRangeInput.js +21 -21
  114. package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
  115. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  116. package/dist/DateTimeInput/DateTimeInput.js +30 -26
  117. package/dist/DateTimeInput/index.d.ts +1 -1
  118. package/dist/DateTimeInput/index.d.ts.map +1 -1
  119. package/dist/Dialog/Dialog.js +9 -9
  120. package/dist/Dialog/DialogHeader.js +16 -16
  121. package/dist/Dialog/useImperativeDialog.js +3 -3
  122. package/dist/Divider/Divider.js +7 -7
  123. package/dist/DropdownMenu/DropdownMenu.js +10 -10
  124. package/dist/DropdownMenu/DropdownMenuItem.d.ts +2 -17
  125. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  126. package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
  127. package/dist/DropdownMenu/renderDropdownItems.js +10 -10
  128. package/dist/EmptyState/EmptyState.js +9 -9
  129. package/dist/Field/Field.js +17 -17
  130. package/dist/Field/FieldLabel.js +15 -15
  131. package/dist/Field/InputClearButton.js +5 -5
  132. package/dist/FieldStatus/FieldStatus.js +3 -3
  133. package/dist/FileInput/FileInput.js +29 -29
  134. package/dist/FormLayout/FormLayout.js +5 -5
  135. package/dist/Grid/Grid.d.ts +4 -3
  136. package/dist/Grid/Grid.d.ts.map +1 -1
  137. package/dist/Grid/Grid.js +29 -12
  138. package/dist/Grid/GridSpan.js +3 -3
  139. package/dist/HStack/HStack.js +3 -3
  140. package/dist/Heading/Heading.js +10 -10
  141. package/dist/HoverCard/HoverCard.js +9 -9
  142. package/dist/HoverCard/useHoverCard.d.ts +5 -1
  143. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  144. package/dist/HoverCard/useHoverCard.js +3 -3
  145. package/dist/Icon/Icon.d.ts.map +1 -1
  146. package/dist/Icon/Icon.js +16 -12
  147. package/dist/Icon/defaultIcons.js +116 -116
  148. package/dist/IconButton/IconButton.js +3 -3
  149. package/dist/InputGroup/InputGroup.js +11 -11
  150. package/dist/InputGroup/InputGroupText.js +3 -3
  151. package/dist/Item/Item.js +18 -18
  152. package/dist/Kbd/Kbd.js +5 -5
  153. package/dist/Layer/LayerProvider.js +7 -7
  154. package/dist/Layer/useLayer.d.ts +29 -2
  155. package/dist/Layer/useLayer.d.ts.map +1 -1
  156. package/dist/Layer/useLayer.js +44 -31
  157. package/dist/Layout/Layout.js +21 -21
  158. package/dist/Layout/LayoutContent.js +3 -3
  159. package/dist/Layout/LayoutFooter.js +5 -5
  160. package/dist/Layout/LayoutHeader.js +5 -5
  161. package/dist/Layout/LayoutPanel.js +3 -3
  162. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  163. package/dist/Lightbox/Lightbox.js +55 -31
  164. package/dist/Lightbox/useLightbox.d.ts +0 -1
  165. package/dist/Lightbox/useLightbox.d.ts.map +1 -1
  166. package/dist/Lightbox/useLightbox.js +3 -4
  167. package/dist/Link/Link.d.ts +0 -2
  168. package/dist/Link/Link.d.ts.map +1 -1
  169. package/dist/Link/Link.js +15 -17
  170. package/dist/Link/LinkProvider.js +3 -3
  171. package/dist/Link/useLinkify.js +3 -3
  172. package/dist/List/List.js +11 -11
  173. package/dist/List/ListItem.js +11 -11
  174. package/dist/Markdown/Markdown.d.ts.map +1 -1
  175. package/dist/Markdown/Markdown.js +102 -102
  176. package/dist/MetadataList/MetadataList.js +10 -10
  177. package/dist/MetadataList/MetadataListItem.js +15 -15
  178. package/dist/MobileNav/MobileNav.d.ts +1 -1
  179. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  180. package/dist/MobileNav/MobileNav.js +26 -23
  181. package/dist/MobileNav/MobileNavToggle.js +5 -5
  182. package/dist/MoreMenu/MoreMenu.js +3 -3
  183. package/dist/MultiSelector/MultiSelector.js +56 -56
  184. package/dist/NavIcon/NavIcon.js +3 -3
  185. package/dist/NavMenu/NavHeadingMenu.js +5 -5
  186. package/dist/NavMenu/NavHeadingMenuItem.js +8 -8
  187. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  188. package/dist/NumberInput/NumberInput.js +48 -32
  189. package/dist/Outline/Outline.js +15 -15
  190. package/dist/OverflowList/OverflowList.js +8 -8
  191. package/dist/Overlay/Overlay.js +3 -3
  192. package/dist/Overlay/OverlayScrim.js +5 -5
  193. package/dist/Overlay/useOverlay.d.ts +0 -3
  194. package/dist/Overlay/useOverlay.d.ts.map +1 -1
  195. package/dist/Overlay/useOverlay.js +3 -6
  196. package/dist/Pagination/Pagination.d.ts +1 -1
  197. package/dist/Pagination/Pagination.d.ts.map +1 -1
  198. package/dist/Pagination/Pagination.js +125 -72
  199. package/dist/Popover/Popover.js +16 -16
  200. package/dist/Popover/usePopover.js +7 -7
  201. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  202. package/dist/PowerSearch/PowerSearch.js +110 -92
  203. package/dist/PowerSearch/PowerSearchEditPopover.js +84 -84
  204. package/dist/PowerSearch/PowerSearchFilterEditor.js +3 -3
  205. package/dist/PowerSearch/PowerSearchToken.js +5 -5
  206. package/dist/PowerSearch/PowerSearchValueEditor.js +54 -54
  207. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  208. package/dist/ProgressBar/ProgressBar.js +25 -18
  209. package/dist/RadioList/RadioList.js +7 -7
  210. package/dist/RadioList/RadioListItem.d.ts +1 -1
  211. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  212. package/dist/RadioList/RadioListItem.js +24 -21
  213. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  214. package/dist/Resizable/ResizeHandle.js +28 -10
  215. package/dist/Section/Section.js +5 -5
  216. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  217. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  218. package/dist/SegmentedControl/SegmentedControl.js +32 -10
  219. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  220. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  221. package/dist/SegmentedControl/SegmentedControlItem.js +18 -12
  222. package/dist/SelectableCard/SelectableCard.js +5 -5
  223. package/dist/Selector/Selector.js +46 -46
  224. package/dist/Selector/SelectorOption.js +3 -3
  225. package/dist/SideNav/SideNav.d.ts.map +1 -1
  226. package/dist/SideNav/SideNav.js +38 -34
  227. package/dist/SideNav/SideNavCollapseButton.d.ts +1 -1
  228. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  229. package/dist/SideNav/SideNavCollapseButton.js +8 -6
  230. package/dist/SideNav/SideNavHeading.js +87 -87
  231. package/dist/SideNav/SideNavItem.js +42 -42
  232. package/dist/SideNav/SideNavSection.d.ts +1 -1
  233. package/dist/SideNav/SideNavSection.d.ts.map +1 -1
  234. package/dist/SideNav/SideNavSection.js +18 -16
  235. package/dist/Skeleton/Skeleton.js +3 -3
  236. package/dist/Slider/Slider.js +23 -23
  237. package/dist/Spinner/Spinner.js +9 -9
  238. package/dist/StatusDot/StatusDot.js +5 -5
  239. package/dist/Switch/Switch.d.ts +8 -4
  240. package/dist/Switch/Switch.d.ts.map +1 -1
  241. package/dist/Switch/Switch.js +34 -29
  242. package/dist/TabList/Tab.js +18 -18
  243. package/dist/TabList/TabList.js +5 -5
  244. package/dist/TabList/TabMenu.d.ts.map +1 -1
  245. package/dist/TabList/TabMenu.js +57 -30
  246. package/dist/TabList/tab.markers.stylex.d.ts +1 -1
  247. package/dist/Table/BaseTable.d.ts.map +1 -1
  248. package/dist/Table/BaseTable.js +50 -39
  249. package/dist/Table/Table.js +7 -7
  250. package/dist/Table/TableBody.d.ts +1 -1
  251. package/dist/Table/TableBody.d.ts.map +1 -1
  252. package/dist/Table/TableBody.js +9 -5
  253. package/dist/Table/TableCell.js +3 -3
  254. package/dist/Table/TableFooter.d.ts +1 -1
  255. package/dist/Table/TableFooter.d.ts.map +1 -1
  256. package/dist/Table/TableFooter.js +9 -5
  257. package/dist/Table/TableHeader.d.ts +1 -1
  258. package/dist/Table/TableHeader.d.ts.map +1 -1
  259. package/dist/Table/TableHeader.js +9 -5
  260. package/dist/Table/TableHeaderCell.js +3 -3
  261. package/dist/Table/TableRow.js +5 -5
  262. package/dist/Table/index.d.ts +2 -0
  263. package/dist/Table/index.d.ts.map +1 -1
  264. package/dist/Table/index.js +1 -0
  265. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  266. package/dist/Table/plugins/columnResize/useTableColumnResize.js +14 -11
  267. package/dist/Table/plugins/filtering/useTableFiltering.js +71 -71
  268. package/dist/Table/plugins/groupedRows/index.d.ts +3 -0
  269. package/dist/Table/plugins/groupedRows/index.d.ts.map +1 -0
  270. package/dist/Table/plugins/groupedRows/index.js +3 -0
  271. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +78 -0
  272. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -0
  273. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +250 -0
  274. package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
  275. package/dist/Table/plugins/pagination/paginateData.js +5 -1
  276. package/dist/Table/plugins/pagination/useTablePagination.js +7 -7
  277. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +1 -1
  278. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +23 -23
  279. package/dist/Table/plugins/selection/useTableSelection.js +18 -18
  280. package/dist/Table/plugins/selection/useTableSelectionState.d.ts.map +1 -1
  281. package/dist/Table/plugins/selection/useTableSelectionState.js +11 -1
  282. package/dist/Table/plugins/sortable/useTableSortable.js +17 -17
  283. package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
  284. package/dist/Table/plugins/sortable/useTableSortableState.js +8 -4
  285. package/dist/Table/tableContextMenu.js +9 -9
  286. package/dist/Text/Text.js +10 -10
  287. package/dist/TextArea/TextArea.js +14 -14
  288. package/dist/TextInput/TextInput.js +15 -15
  289. package/dist/Thumbnail/Thumbnail.d.ts +3 -2
  290. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  291. package/dist/Thumbnail/Thumbnail.js +30 -29
  292. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  293. package/dist/TimeInput/TimeInput.js +26 -21
  294. package/dist/Timestamp/Timestamp.d.ts +1 -1
  295. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  296. package/dist/Timestamp/Timestamp.js +37 -26
  297. package/dist/Toast/Toast.d.ts.map +1 -1
  298. package/dist/Toast/Toast.js +25 -17
  299. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  300. package/dist/Toast/ToastViewport.js +23 -11
  301. package/dist/Toast/useToast.d.ts.map +1 -1
  302. package/dist/Toast/useToast.js +44 -4
  303. package/dist/ToggleButton/ToggleButton.js +12 -12
  304. package/dist/ToggleButton/ToggleButtonGroup.js +5 -5
  305. package/dist/Token/Token.js +21 -21
  306. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  307. package/dist/Tokenizer/Tokenizer.js +36 -34
  308. package/dist/Toolbar/Toolbar.js +18 -18
  309. package/dist/Tooltip/Tooltip.js +11 -11
  310. package/dist/Tooltip/useTooltip.d.ts +5 -1
  311. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  312. package/dist/Tooltip/useTooltip.js +3 -3
  313. package/dist/TopNav/TopNav.js +32 -32
  314. package/dist/TopNav/TopNavHeading.js +67 -67
  315. package/dist/TopNav/TopNavItem.js +5 -5
  316. package/dist/TopNav/TopNavMegaMenu.js +30 -30
  317. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +1 -1
  318. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
  319. package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +25 -14
  320. package/dist/TopNav/TopNavMegaMenuItem.js +16 -16
  321. package/dist/TopNav/TopNavMenu.js +32 -32
  322. package/dist/TreeList/TreeList.js +8 -8
  323. package/dist/TreeList/TreeListBranches.js +11 -11
  324. package/dist/TreeList/TreeListItem.js +30 -30
  325. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  326. package/dist/Typeahead/BaseTypeahead.js +23 -20
  327. package/dist/Typeahead/Typeahead.js +12 -12
  328. package/dist/Typeahead/TypeaheadItem.js +10 -10
  329. package/dist/VStack/VStack.js +3 -3
  330. package/dist/VisuallyHidden/VisuallyHidden.d.ts +0 -3
  331. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -1
  332. package/dist/VisuallyHidden/VisuallyHidden.js +0 -3
  333. package/dist/astryx.css +7 -0
  334. package/dist/astryx.umd.js +63 -63
  335. package/dist/astryx.umd.js.map +4 -4
  336. package/dist/docs-types.d.ts +8 -2
  337. package/dist/docs-types.d.ts.map +1 -1
  338. package/dist/hooks/focusableSelector.d.ts +1 -1
  339. package/dist/hooks/focusableSelector.d.ts.map +1 -1
  340. package/dist/hooks/focusableSelector.js +1 -1
  341. package/dist/hooks/index.d.ts +2 -0
  342. package/dist/hooks/index.d.ts.map +1 -1
  343. package/dist/hooks/index.js +1 -0
  344. package/dist/hooks/useFocusTrap.d.ts +3 -0
  345. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  346. package/dist/hooks/useFocusTrap.js +38 -1
  347. package/dist/hooks/useHotkeys.d.ts +51 -0
  348. package/dist/hooks/useHotkeys.d.ts.map +1 -0
  349. package/dist/hooks/useHotkeys.js +160 -0
  350. package/dist/hooks/useInteractiveRole.d.ts +6 -2
  351. package/dist/hooks/useInteractiveRole.d.ts.map +1 -1
  352. package/dist/hooks/useInteractiveRole.js +6 -2
  353. package/dist/hooks/useKeyboardHint.js +9 -9
  354. package/dist/hooks/useStreamingText.d.ts +3 -1
  355. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  356. package/dist/hooks/useStreamingText.js +14 -5
  357. package/dist/theme/MediaTheme.js +3 -3
  358. package/dist/theme/Theme.js +7 -7
  359. package/dist/theme/defineTheme.d.ts +1 -1
  360. package/dist/theme/defineTheme.d.ts.map +1 -1
  361. package/dist/theme/expandColorScale.d.ts.map +1 -1
  362. package/dist/theme/expandColorScale.js +10 -3
  363. package/dist/theme/hct.d.ts +0 -15
  364. package/dist/theme/hct.d.ts.map +1 -1
  365. package/dist/theme/hct.js +9 -9
  366. package/dist/theme/syntax/SyntaxTheme.js +5 -5
  367. package/dist/theme/tokens.d.ts +10 -2
  368. package/dist/theme/tokens.d.ts.map +1 -1
  369. package/dist/theme/tokens.js +220 -4
  370. package/dist/theme/useTheme.d.ts +3 -2
  371. package/dist/theme/useTheme.d.ts.map +1 -1
  372. package/dist/theme/useTheme.js +73 -6
  373. package/dist/utils/color.d.ts +42 -0
  374. package/dist/utils/color.d.ts.map +1 -0
  375. package/dist/utils/color.js +150 -0
  376. package/dist/utils/composeEventHandlers.d.ts +30 -0
  377. package/dist/utils/composeEventHandlers.d.ts.map +1 -0
  378. package/dist/utils/composeEventHandlers.js +40 -0
  379. package/dist/utils/index.d.ts +3 -0
  380. package/dist/utils/index.d.ts.map +1 -1
  381. package/dist/utils/index.js +3 -1
  382. package/dist/utils/timeParser.d.ts.map +1 -1
  383. package/dist/utils/timeParser.js +8 -5
  384. package/package.json +4 -4
  385. package/src/AlertDialog/AlertDialog.doc.mjs +4 -0
  386. package/src/AlertDialog/AlertDialog.tsx +2 -0
  387. package/src/AlertDialog/useImperativeAlertDialog.tsx +0 -2
  388. package/src/AppShell/AppShell.tsx +2 -0
  389. package/src/AspectRatio/AspectRatio.doc.mjs +28 -1
  390. package/src/AspectRatio/AspectRatio.test.tsx +142 -1
  391. package/src/AspectRatio/AspectRatio.tsx +70 -10
  392. package/src/AspectRatio/index.ts +5 -1
  393. package/src/Avatar/Avatar.doc.mjs +11 -0
  394. package/src/Avatar/Avatar.test.tsx +32 -1
  395. package/src/Avatar/Avatar.tsx +14 -22
  396. package/src/Avatar/AvatarStatusDot.tsx +2 -2
  397. package/src/AvatarGroup/AvatarGroup.doc.mjs +1 -0
  398. package/src/AvatarGroup/AvatarGroup.tsx +2 -2
  399. package/src/AvatarGroup/AvatarGroupOverflow.tsx +2 -2
  400. package/src/Banner/Banner.doc.mjs +8 -0
  401. package/src/Banner/Banner.test.tsx +38 -0
  402. package/src/Banner/Banner.tsx +8 -1
  403. package/src/Calendar/Calendar.doc.mjs +1 -1
  404. package/src/Calendar/Calendar.test.tsx +122 -17
  405. package/src/Calendar/Calendar.tsx +26 -5
  406. package/src/Calendar/dayCellUtils.ts +3 -1
  407. package/src/Calendar/styles.ts +12 -2
  408. package/src/Card/Card.doc.mjs +1 -1
  409. package/src/Card/Card.tsx +16 -6
  410. package/src/Carousel/Carousel.doc.mjs +12 -12
  411. package/src/Carousel/Carousel.test.tsx +13 -0
  412. package/src/Carousel/Carousel.tsx +4 -2
  413. package/src/Chat/Chat.doc.mjs +1 -1
  414. package/src/Chat/ChatComposerInput.test.tsx +27 -1
  415. package/src/Chat/ChatComposerInput.tsx +20 -15
  416. package/src/Chat/ChatDictationButton.test.tsx +43 -0
  417. package/src/Chat/ChatDictationButton.tsx +4 -4
  418. package/src/Chat/ChatLayoutScrollButton.test.tsx +33 -0
  419. package/src/Chat/ChatLayoutScrollButton.tsx +3 -1
  420. package/src/Chat/ChatMessageMetadata.test.tsx +32 -0
  421. package/src/Chat/ChatMessageMetadata.tsx +4 -6
  422. package/src/Chat/ChatSystemMessage.test.tsx +26 -11
  423. package/src/Chat/ChatSystemMessage.tsx +7 -7
  424. package/src/Chat/ChatTokenizedText.test.tsx +29 -16
  425. package/src/Chat/ChatTokenizedText.tsx +15 -8
  426. package/src/Chat/ChatToolCalls.test.tsx +55 -0
  427. package/src/Chat/ChatToolCalls.tsx +10 -12
  428. package/src/Chat/index.ts +1 -4
  429. package/src/Chat/useTriggerMenu.tsx +1 -4
  430. package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -3
  431. package/src/CheckboxInput/CheckboxInput.test.tsx +71 -4
  432. package/src/CheckboxInput/CheckboxInput.tsx +2 -0
  433. package/src/CheckboxList/CheckboxList.test.tsx +19 -0
  434. package/src/CheckboxList/CheckboxListItem.tsx +11 -2
  435. package/src/Citation/Citation.doc.mjs +5 -0
  436. package/src/ClickableCard/ClickableCard.tsx +45 -2
  437. package/src/CodeBlock/CodeBlock.doc.mjs +7 -2
  438. package/src/CodeBlock/CodeBlock.test.tsx +122 -3
  439. package/src/CodeBlock/CodeBlock.tsx +62 -4
  440. package/src/Collapsible/Collapsible.doc.mjs +8 -4
  441. package/src/Collapsible/Collapsible.test.tsx +403 -0
  442. package/src/Collapsible/Collapsible.tsx +85 -10
  443. package/src/Collapsible/CollapsibleGroup.doc.mjs +27 -3
  444. package/src/Collapsible/CollapsibleGroup.test.tsx +314 -0
  445. package/src/Collapsible/CollapsibleGroup.tsx +97 -9
  446. package/src/Collapsible/CollapsibleGroupContext.tsx +34 -2
  447. package/src/Collapsible/index.ts +1 -0
  448. package/src/Collapsible/useCollapsible.ts +20 -6
  449. package/src/CommandPalette/CommandPalette.doc.mjs +5 -0
  450. package/src/CommandPalette/CommandPalette.tsx +5 -3
  451. package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +5 -0
  452. package/src/CommandPalette/CommandPaletteGroup.doc.mjs +10 -0
  453. package/src/CommandPalette/CommandPaletteInput.doc.mjs +6 -0
  454. package/src/CommandPalette/CommandPaletteItem.doc.mjs +6 -0
  455. package/src/CommandPalette/CommandPaletteList.doc.mjs +9 -0
  456. package/src/ContextMenu/ContextMenu.doc.mjs +15 -0
  457. package/src/ContextMenu/ContextMenu.test.tsx +87 -0
  458. package/src/ContextMenu/ContextMenu.tsx +87 -28
  459. package/src/ContextMenu/ContextMenuItem.doc.mjs +6 -0
  460. package/src/DateInput/DateInput.test.tsx +11 -20
  461. package/src/DateRangeInput/DateRangeInput.doc.mjs +9 -6
  462. package/src/DateRangeInput/DateRangeInput.test.tsx +31 -44
  463. package/src/DateTimeInput/DateTimeInput.doc.mjs +3 -2
  464. package/src/DateTimeInput/DateTimeInput.test.tsx +118 -16
  465. package/src/DateTimeInput/DateTimeInput.tsx +8 -2
  466. package/src/DateTimeInput/index.ts +1 -0
  467. package/src/Dialog/Dialog.doc.mjs +4 -0
  468. package/src/Dialog/DialogHeader.doc.mjs +45 -0
  469. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -1
  470. package/src/DropdownMenu/DropdownMenu.test.tsx +22 -2
  471. package/src/DropdownMenu/DropdownMenuItem.tsx +5 -17
  472. package/src/EmptyState/EmptyState.doc.mjs +1 -1
  473. package/src/Field/Field.test.tsx +1 -4
  474. package/src/Field/FieldLabel.test.tsx +2 -2
  475. package/src/FieldStatus/FieldStatus.test.tsx +282 -0
  476. package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +0 -3
  477. package/src/Grid/Grid.test.tsx +43 -18
  478. package/src/Grid/Grid.tsx +26 -9
  479. package/src/HoverCard/HoverCard.doc.mjs +6 -6
  480. package/src/HoverCard/useHoverCard.doc.mjs +5 -5
  481. package/src/HoverCard/useHoverCard.tsx +9 -2
  482. package/src/Icon/Icon.test.tsx +41 -29
  483. package/src/Icon/Icon.tsx +6 -2
  484. package/src/InputGroup/InputGroup.doc.mjs +1 -0
  485. package/src/InputGroup/InputGroup.tsx +2 -2
  486. package/src/InteractiveRoleContext/InteractiveRoleContext.test.tsx +185 -0
  487. package/src/Item/Item.tsx +1 -1
  488. package/src/Layer/useLayer.doc.mjs +2 -2
  489. package/src/Layer/useLayer.test.tsx +221 -2
  490. package/src/Layer/useLayer.tsx +69 -30
  491. package/src/Layout/Layout.test.tsx +285 -0
  492. package/src/Layout/LayoutContent.doc.mjs +12 -0
  493. package/src/Layout/LayoutPanel.doc.mjs +40 -0
  494. package/src/Layout/LayoutSlots.test.tsx +364 -0
  495. package/src/Lightbox/Lightbox.doc.mjs +5 -0
  496. package/src/Lightbox/Lightbox.test.tsx +123 -2
  497. package/src/Lightbox/Lightbox.tsx +29 -1
  498. package/src/Lightbox/useLightbox.tsx +0 -1
  499. package/src/Link/Link.tsx +0 -2
  500. package/src/Markdown/Markdown.tsx +9 -7
  501. package/src/Markdown/parser.perf.test.ts +34 -12
  502. package/src/MobileNav/MobileNav.test.tsx +56 -0
  503. package/src/MobileNav/MobileNav.tsx +13 -8
  504. package/src/NavMenu/NavMenu.doc.mjs +15 -0
  505. package/src/NumberInput/NumberInput.test.tsx +48 -3
  506. package/src/NumberInput/NumberInput.tsx +32 -15
  507. package/src/Outline/Outline.doc.mjs +2 -0
  508. package/src/Outline/parseOutlineFromMarkdown.test.ts +80 -0
  509. package/src/OverflowList/OverflowList.test.tsx +416 -0
  510. package/src/Overlay/Overlay.doc.mjs +6 -0
  511. package/src/Overlay/Overlay.test.tsx +356 -0
  512. package/src/Overlay/useOverlay.tsx +0 -3
  513. package/src/Pagination/Pagination.test.tsx +162 -0
  514. package/src/Pagination/Pagination.tsx +80 -26
  515. package/src/Popover/Popover.doc.mjs +6 -6
  516. package/src/Popover/Popover.test.tsx +65 -0
  517. package/src/Popover/usePopover.doc.mjs +1 -1
  518. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  519. package/src/PowerSearch/PowerSearch.test.tsx +109 -1
  520. package/src/PowerSearch/PowerSearch.tsx +37 -16
  521. package/src/ProgressBar/ProgressBar.doc.mjs +2 -0
  522. package/src/ProgressBar/ProgressBar.test.tsx +30 -0
  523. package/src/ProgressBar/ProgressBar.tsx +12 -5
  524. package/src/RadioList/RadioList.test.tsx +19 -0
  525. package/src/RadioList/RadioListItem.tsx +9 -4
  526. package/src/Resizable/ResizeHandle.test.tsx +218 -0
  527. package/src/Resizable/ResizeHandle.tsx +22 -4
  528. package/src/SegmentedControl/SegmentedControl.doc.mjs +1 -1
  529. package/src/SegmentedControl/SegmentedControl.test.tsx +192 -0
  530. package/src/SegmentedControl/SegmentedControl.tsx +27 -5
  531. package/src/SegmentedControl/SegmentedControlItem.tsx +9 -4
  532. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  533. package/src/Selector/Selector.test.tsx +27 -1
  534. package/src/SideNav/SideNav.doc.mjs +7 -1
  535. package/src/SideNav/SideNav.test.tsx +66 -0
  536. package/src/SideNav/SideNav.tsx +6 -2
  537. package/src/SideNav/SideNavCollapseButton.tsx +4 -3
  538. package/src/SideNav/SideNavSection.tsx +6 -4
  539. package/src/SizeContext/SizeContext.test.tsx +226 -0
  540. package/src/Switch/Switch.doc.mjs +7 -7
  541. package/src/Switch/Switch.test.tsx +102 -3
  542. package/src/Switch/Switch.tsx +20 -7
  543. package/src/TabList/TabList.test.tsx +185 -1
  544. package/src/TabList/TabMenu.tsx +45 -9
  545. package/src/Table/BaseTable.tsx +13 -2
  546. package/src/Table/Table.doc.mjs +6 -1
  547. package/src/Table/Table.test.tsx +87 -0
  548. package/src/Table/TableBody.tsx +15 -2
  549. package/src/Table/TableFooter.tsx +15 -2
  550. package/src/Table/TableHeader.tsx +15 -2
  551. package/src/Table/index.ts +5 -0
  552. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +13 -0
  553. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +3 -1
  554. package/src/Table/plugins/groupedRows/index.ts +7 -0
  555. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +231 -0
  556. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +349 -0
  557. package/src/Table/plugins/pagination/paginateData.ts +5 -1
  558. package/src/Table/plugins/pagination/useTablePagination.test.tsx +13 -0
  559. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +1 -1
  560. package/src/Table/plugins/selection/useTableSelectionState.test.tsx +23 -0
  561. package/src/Table/plugins/selection/useTableSelectionState.tsx +11 -6
  562. package/src/Table/plugins/sortable/useTableSortableState.test.tsx +35 -1
  563. package/src/Table/plugins/sortable/useTableSortableState.tsx +8 -4
  564. package/src/Table/useTableGroupedRows.doc.mjs +71 -0
  565. package/src/TextArea/TextArea.test.tsx +3 -3
  566. package/src/TextInput/TextInput.test.tsx +3 -3
  567. package/src/Thumbnail/Thumbnail.test.tsx +36 -2
  568. package/src/Thumbnail/Thumbnail.tsx +4 -2
  569. package/src/TimeInput/TimeInput.test.tsx +37 -0
  570. package/src/TimeInput/TimeInput.tsx +11 -1
  571. package/src/Timestamp/Timestamp.doc.mjs +1 -1
  572. package/src/Timestamp/Timestamp.test.tsx +52 -0
  573. package/src/Timestamp/Timestamp.tsx +30 -16
  574. package/src/Toast/Toast.tsx +11 -3
  575. package/src/Toast/ToastViewport.test.tsx +64 -0
  576. package/src/Toast/ToastViewport.tsx +12 -0
  577. package/src/Toast/useToast.test.tsx +258 -0
  578. package/src/Toast/useToast.tsx +41 -0
  579. package/src/ToggleButton/ToggleButton.doc.mjs +1 -0
  580. package/src/Tokenizer/Tokenizer.doc.mjs +2 -2
  581. package/src/Tokenizer/Tokenizer.test.tsx +54 -0
  582. package/src/Tokenizer/Tokenizer.tsx +5 -4
  583. package/src/Tooltip/Tooltip.doc.mjs +6 -6
  584. package/src/Tooltip/useTooltip.doc.mjs +5 -5
  585. package/src/Tooltip/useTooltip.tsx +12 -2
  586. package/src/TopNav/TopNav.doc.mjs +1 -1
  587. package/src/TopNav/TopNav.test.tsx +23 -7
  588. package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +9 -2
  589. package/src/TreeList/TreeList.doc.mjs +2 -2
  590. package/src/Typeahead/BaseTypeahead.doc.mjs +19 -0
  591. package/src/Typeahead/BaseTypeahead.tsx +5 -2
  592. package/src/Typeahead/Typeahead.doc.mjs +1 -1
  593. package/src/Typeahead/Typeahead.test.tsx +45 -1
  594. package/src/VisuallyHidden/VisuallyHidden.tsx +0 -3
  595. package/src/__tests__/TestIcon.tsx +26 -0
  596. package/src/__tests__/fastRoleQueries.ts +66 -0
  597. package/src/docPropReferences.test.ts +178 -0
  598. package/src/docs-types.ts +9 -1
  599. package/src/hooks/focusableSelector.ts +1 -1
  600. package/src/hooks/index.ts +3 -0
  601. package/src/hooks/useFocusTrap.doc.mjs +4 -2
  602. package/src/hooks/useFocusTrap.test.tsx +149 -1
  603. package/src/hooks/useFocusTrap.ts +50 -1
  604. package/src/hooks/useHotkeys.doc.mjs +52 -0
  605. package/src/hooks/useHotkeys.test.ts +245 -0
  606. package/src/hooks/useHotkeys.ts +203 -0
  607. package/src/hooks/useInteractiveRole.ts +12 -4
  608. package/src/hooks/useStreamingText.test.ts +54 -19
  609. package/src/hooks/useStreamingText.ts +16 -5
  610. package/src/hooks/useTreeFocus.test.tsx +1 -3
  611. package/src/reset.css +29 -0
  612. package/src/theme/SyntaxTheme.doc.mjs +4 -4
  613. package/src/theme/defineTheme.ts +4 -13
  614. package/src/theme/derivedVarRegistry.test.ts +2 -2
  615. package/src/theme/expandColorScale.test.ts +29 -0
  616. package/src/theme/expandColorScale.ts +11 -6
  617. package/src/theme/hct.ts +9 -17
  618. package/src/theme/themingTargets.test.ts +353 -0
  619. package/src/theme/tokens.test.ts +182 -9
  620. package/src/theme/tokens.ts +239 -4
  621. package/src/theme/useTheme.test.tsx +126 -2
  622. package/src/theme/useTheme.ts +87 -6
  623. package/src/utils/color.test.ts +133 -0
  624. package/src/utils/color.ts +148 -0
  625. package/src/utils/composeEventHandlers.test.ts +71 -0
  626. package/src/utils/composeEventHandlers.ts +44 -0
  627. package/src/utils/index.ts +4 -0
  628. package/src/utils/mergeProps.test.ts +166 -0
  629. package/src/utils/sharedResizeObserver.test.ts +2 -2
  630. package/src/utils/timeParser.test.ts +13 -0
  631. package/src/utils/timeParser.ts +8 -5
  632. package/dist/Carousel/carousel.markers.stylex.d.ts +0 -7
  633. package/dist/Carousel/carousel.markers.stylex.d.ts.map +0 -1
  634. package/dist/Carousel/carousel.markers.stylex.js +0 -12
  635. package/src/Carousel/carousel.markers.stylex.ts +0 -10
@@ -167,6 +167,59 @@ describe('CheckboxInput', () => {
167
167
  expect(handleChange).not.toHaveBeenCalled();
168
168
  });
169
169
 
170
+ it('forwards data-testid to the input', () => {
171
+ render(
172
+ <CheckboxInput
173
+ label="Accept terms"
174
+ value={false}
175
+ onChange={() => {}}
176
+ data-testid="accept-terms-checkbox"
177
+ />,
178
+ );
179
+ expect(screen.getByTestId('accept-terms-checkbox')).toBe(
180
+ screen.getByRole('checkbox'),
181
+ );
182
+ });
183
+
184
+ it('forwards arbitrary data-* attributes to the input', () => {
185
+ render(
186
+ <CheckboxInput
187
+ label="Accept terms"
188
+ value={false}
189
+ onChange={() => {}}
190
+ data-tracking-id="checkbox-42"
191
+ />,
192
+ );
193
+ expect(screen.getByRole('checkbox')).toHaveAttribute(
194
+ 'data-tracking-id',
195
+ 'checkbox-42',
196
+ );
197
+ });
198
+
199
+ it('does not let rest props override checked, disabled, or type', () => {
200
+ // Not part of CheckboxInputProps; spread (rather than named attributes)
201
+ // to sidestep JSX excess-property checks the same way a real caller's
202
+ // spread rest-props object would arrive untyped at runtime.
203
+ const foreignAttrs: Record<string, unknown> = {
204
+ checked: false,
205
+ disabled: false,
206
+ type: 'text',
207
+ };
208
+ render(
209
+ <CheckboxInput
210
+ {...foreignAttrs}
211
+ label="Accept terms"
212
+ value={true}
213
+ onChange={() => {}}
214
+ isDisabled
215
+ />,
216
+ );
217
+ const checkbox = screen.getByRole('checkbox');
218
+ expect(checkbox).toBeChecked();
219
+ expect(checkbox).toBeDisabled();
220
+ expect(checkbox).toHaveAttribute('type', 'checkbox');
221
+ });
222
+
170
223
  it('forwards ref correctly', () => {
171
224
  const ref = vi.fn();
172
225
  render(
@@ -396,7 +449,12 @@ describe('CheckboxInput', () => {
396
449
  it('submits under htmlName when checked', () => {
397
450
  const {container} = render(
398
451
  <form>
399
- <CheckboxInput label="Terms" htmlName="terms" value={true} onChange={() => {}} />
452
+ <CheckboxInput
453
+ label="Terms"
454
+ htmlName="terms"
455
+ value={true}
456
+ onChange={() => {}}
457
+ />
400
458
  </form>,
401
459
  );
402
460
  const data = new FormData(container.querySelector('form')!);
@@ -416,16 +474,25 @@ describe('CheckboxInput', () => {
416
474
  />
417
475
  </form>,
418
476
  );
419
- expect([...new FormData(container.querySelector('form')!).keys()]).toEqual([]);
477
+ expect([
478
+ ...new FormData(container.querySelector('form')!).keys(),
479
+ ]).toEqual([]);
420
480
  });
421
481
 
422
482
  it('submits nothing when unchecked', () => {
423
483
  const {container} = render(
424
484
  <form>
425
- <CheckboxInput label="Terms" htmlName="terms" value={false} onChange={() => {}} />
485
+ <CheckboxInput
486
+ label="Terms"
487
+ htmlName="terms"
488
+ value={false}
489
+ onChange={() => {}}
490
+ />
426
491
  </form>,
427
492
  );
428
- expect([...new FormData(container.querySelector('form')!).keys()]).toEqual([]);
493
+ expect([
494
+ ...new FormData(container.querySelector('form')!).keys(),
495
+ ]).toEqual([]);
429
496
  });
430
497
  });
431
498
  });
@@ -395,6 +395,7 @@ export function CheckboxInput({
395
395
  className,
396
396
  style,
397
397
  ref,
398
+ ...rest
398
399
  }: CheckboxInputProps) {
399
400
  const id = useId();
400
401
  const descriptionID = useId();
@@ -484,6 +485,7 @@ export function CheckboxInput({
484
485
  )}>
485
486
  <div {...stylex.props(styles.checkboxWrapper, wrapperSizeStyles[size])}>
486
487
  <input
488
+ {...rest}
487
489
  ref={mergeRefs(
488
490
  ref,
489
491
  indeterminateRef,
@@ -135,6 +135,25 @@ describe('CheckboxList', () => {
135
135
  expect(handleChange).toHaveBeenCalledWith(['b']);
136
136
  });
137
137
 
138
+ it('fires a consumer onClick on an item in addition to toggling', async () => {
139
+ const user = userEvent.setup();
140
+ const handleChange = vi.fn();
141
+ const handleClick = vi.fn();
142
+ render(
143
+ <CheckboxList label="Preferences" value={['a']} onChange={handleChange}>
144
+ <CheckboxListItem label="Option A" value="a" />
145
+ <CheckboxListItem label="Option B" value="b" onClick={handleClick} />
146
+ </CheckboxList>,
147
+ );
148
+
149
+ // Click the interactive row (invisible-button pattern), which is where the
150
+ // composed onClick lives — not the inner checkbox.
151
+ await user.click(screen.getByRole('button', {name: 'Option B'}));
152
+
153
+ expect(handleClick).toHaveBeenCalledTimes(1);
154
+ expect(handleChange).toHaveBeenCalledWith(['a', 'b']);
155
+ });
156
+
138
157
  it('disables all checkboxes when group isDisabled is true', () => {
139
158
  render(
140
159
  <CheckboxList
@@ -16,11 +16,12 @@
16
16
  * - /packages/cli/templates/blocks/components/CheckboxList/ (showcase blocks)
17
17
  */
18
18
 
19
- import {use, type ReactNode} from 'react';
19
+ import {use, type MouseEvent, type ReactNode} from 'react';
20
20
  import * as stylex from '@stylexjs/stylex';
21
21
  import type {StyleXStyles} from '@stylexjs/stylex';
22
22
  import {colorVars} from '../theme/tokens.stylex';
23
23
  import type {BaseProps} from '../BaseProps';
24
+ import {composeEventHandlers} from '../utils';
24
25
  import {CheckboxInput} from '../CheckboxInput/CheckboxInput';
25
26
  import {ListItem} from '../List/ListItem';
26
27
  import {ListContext} from '../List/ListContext';
@@ -128,6 +129,7 @@ export function CheckboxListItem({
128
129
  xstyle,
129
130
  className,
130
131
  style,
132
+ onClick: onClickProp,
131
133
  ...restProps
132
134
  }: CheckboxListItemProps) {
133
135
  const ctx = use(CheckboxListContext);
@@ -200,7 +202,14 @@ export function CheckboxListItem({
200
202
  description={description}
201
203
  endContent={endContent}
202
204
  isDisabled={effectiveDisabled}
203
- onClick={isInteractive ? handleToggle : undefined}
205
+ onClick={
206
+ isInteractive || onClickProp
207
+ ? composeEventHandlers<MouseEvent>(
208
+ onClickProp as ((event: MouseEvent) => void) | undefined,
209
+ isInteractive ? handleToggle : undefined,
210
+ )
211
+ : undefined
212
+ }
204
213
  aria-busy={isBusy || undefined}
205
214
  xstyle={
206
215
  [
@@ -88,6 +88,11 @@ export const docs = {
88
88
  default: "'label'",
89
89
  },
90
90
  ],
91
+ theming: {
92
+ targets: [
93
+ {className: 'astryx-citation', visualProps: ['variant']},
94
+ ],
95
+ },
91
96
  };
92
97
 
93
98
  /** @type {import('../docs-types').TranslationDoc} */
@@ -31,7 +31,12 @@
31
31
  import {type ReactNode, type MouseEvent, useRef, type Ref} from 'react';
32
32
  import * as stylex from '@stylexjs/stylex';
33
33
  import type {StyleXStyles} from '@stylexjs/stylex';
34
- import {colorVars, durationVars, easeVars} from '../theme/tokens.stylex';
34
+ import {
35
+ borderVars,
36
+ colorVars,
37
+ durationVars,
38
+ easeVars,
39
+ } from '../theme/tokens.stylex';
35
40
  import type {SizeValue, SpacingStep} from '../utils/types';
36
41
  import {mergeProps, mergeRefs} from '../utils';
37
42
  import {Card} from '../Card/Card';
@@ -66,7 +71,6 @@ const styles = stylex.create({
66
71
  content: '""',
67
72
  position: 'absolute',
68
73
  inset: 0,
69
- borderRadius: 'inherit',
70
74
  pointerEvents: 'none',
71
75
  transitionProperty: 'background-color',
72
76
  transitionDuration: durationVars['--duration-fast'],
@@ -84,6 +88,38 @@ const styles = stylex.create({
84
88
  },
85
89
  },
86
90
  },
91
+ // Borderless variants (everything except `default`): drop the transparent
92
+ // 1px border Card applies. The overlay is inset to the padding box — inside
93
+ // that border — so a transparent border strip stays untinted on hover and
94
+ // reads as a faint ring. With no border, the overlay covers the full box
95
+ // edge-to-edge and the ring disappears.
96
+ borderless: {
97
+ borderWidth: 0,
98
+ },
99
+ // Bordered variant (`default`): draw the 1px border *within* the padding by
100
+ // subtracting the border width from every side. Total inset (border +
101
+ // padding) then equals the borderless variants' padding, so content geometry
102
+ // and outer dimensions stay identical across all variants. The border rests
103
+ // at the subtle token and emphasizes on hover.
104
+ bordered: {
105
+ borderColor: colorVars['--color-border'],
106
+ paddingInlineStart: `calc(var(--container-padding-inline-start) - ${borderVars['--border-width']})`,
107
+ paddingInlineEnd: `calc(var(--container-padding-inline-end) - ${borderVars['--border-width']})`,
108
+ paddingBlockStart: `calc(var(--container-padding-block-start) - ${borderVars['--border-width']})`,
109
+ paddingBlockEnd: `calc(var(--container-padding-block-end) - ${borderVars['--border-width']})`,
110
+ transitionProperty: 'border-color',
111
+ transitionDuration: durationVars['--duration-fast'],
112
+ transitionTimingFunction: easeVars['--ease-standard'],
113
+ },
114
+ // Emphasize the bordered variant's border on hover. Guarded by
115
+ // @media (hover: hover) so touch devices don't get a stuck hover state.
116
+ borderedHoverOnPointer: {
117
+ '@media (hover: hover)': {
118
+ ':hover': {
119
+ borderColor: colorVars['--color-border-emphasized'],
120
+ },
121
+ },
122
+ },
87
123
  disabled: {
88
124
  cursor: 'not-allowed',
89
125
  opacity: 0.5,
@@ -248,6 +284,11 @@ export function ClickableCard({
248
284
 
249
285
  const isLink = href != null;
250
286
 
287
+ // Only the `default` variant has a visible border. Card draws a transparent
288
+ // 1px border on every other variant purely to avoid layout jitter; we drop
289
+ // it here so the hover overlay covers the full box with no untinted ring.
290
+ const hasBorder = variant === 'default';
291
+
251
292
  return (
252
293
  <Card
253
294
  ref={mergeRefs(ref, containerRef)}
@@ -264,8 +305,10 @@ export function ClickableCard({
264
305
  [
265
306
  styles.interactive,
266
307
  styles.focusWithin,
308
+ hasBorder ? styles.bordered : styles.borderless,
267
309
  !isDisabled && styles.overlay,
268
310
  !isDisabled && styles.hoverOnPointer,
311
+ !isDisabled && hasBorder && styles.borderedHoverOnPointer,
269
312
  isDisabled && styles.disabled,
270
313
  xstyleProp,
271
314
  ] as unknown as StyleXStyles
@@ -90,6 +90,11 @@ export const docs = {
90
90
  type: '(code: string, language: string) => Array<{type: string; start: number; end: number}>',
91
91
  description: 'Custom tokenizer override for unsupported languages.',
92
92
  },
93
+ {
94
+ name: 'syntaxTheme',
95
+ type: 'SyntaxThemeDefinition',
96
+ description: 'Per-instance syntax theme override. Shorthand for wrapping the block in <SyntaxTheme theme={...}>. Accepts a preset from @astryxdesign/core/theme/syntax or a theme created with defineSyntaxTheme(). Defaults to the nearest SyntaxTheme ancestor or the theme-level syntax colors.',
97
+ },
93
98
  {
94
99
  name: 'isCollapsible',
95
100
  type: 'boolean',
@@ -135,8 +140,8 @@ export const docs = {
135
140
  },
136
141
  theming: {
137
142
  targets: [
138
- {className: 'astryx-code'},
139
- {className: 'astryx-codeblock', visualProps: ['size', 'language']},
143
+ {className: 'astryx-code', visualProps: ['color']},
144
+ {className: 'astryx-codeblock', visualProps: ['size', 'language', 'container']},
140
145
  ],
141
146
  },
142
147
  usage: {
@@ -3,15 +3,21 @@
3
3
  /**
4
4
  * @file CodeBlock.test.tsx
5
5
  * @input Uses vitest, @testing-library/react, CodeBlock component
6
- * @output Unit tests for CodeBlock (copy button, collapse, scroll region a11y)
6
+ * @output Unit tests for CodeBlock (copy button, collapse, scroll region a11y, syntaxTheme)
7
7
  * @position Testing; validates CodeBlock implementation
8
8
  *
9
9
  * SYNC: When CodeBlock.tsx changes, update tests to match new behavior
10
10
  */
11
11
 
12
- import {describe, it, expect, vi, beforeEach} from 'vitest';
13
- import {render, screen, fireEvent} from '@testing-library/react';
12
+ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
13
+ import {act, render, screen, fireEvent, waitFor} from '@testing-library/react';
14
14
  import {CodeBlock} from './CodeBlock';
15
+ import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
16
+ import {dracula} from '../theme/syntax';
17
+
18
+ function politeRegion(): HTMLElement | null {
19
+ return document.querySelector('[data-astryx-live-region="polite"]');
20
+ }
15
21
 
16
22
  // A code sample long enough to exceed the default collapsible threshold (10).
17
23
  const LONG_CODE = Array.from(
@@ -27,6 +33,10 @@ describe('CodeBlock', () => {
27
33
  });
28
34
  });
29
35
 
36
+ afterEach(() => {
37
+ __resetLiveRegionsForTest();
38
+ });
39
+
30
40
  it('renders the code', () => {
31
41
  render(<CodeBlock code="const x = 1;" language="javascript" />);
32
42
  expect(screen.getByText(/const/)).toBeInTheDocument();
@@ -53,6 +63,50 @@ describe('CodeBlock', () => {
53
63
  expect(navigator.clipboard.writeText).toHaveBeenCalledWith('const x = 1;');
54
64
  });
55
65
 
66
+ it('announces "Copied" to a polite live region after copying', async () => {
67
+ render(<CodeBlock code="const x = 1;" language="javascript" />);
68
+ const copyButton = screen.getByRole('button', {name: 'Copy code'});
69
+ fireEvent.click(copyButton);
70
+ await waitFor(() => {
71
+ expect(politeRegion()).toHaveTextContent('Copied');
72
+ });
73
+ });
74
+
75
+ it('keeps the copied indicator a full 2s after a rapid re-copy', async () => {
76
+ vi.useFakeTimers();
77
+ try {
78
+ render(<CodeBlock code="const x = 1;" language="javascript" />);
79
+ fireEvent.click(screen.getByRole('button', {name: 'Copy code'}));
80
+ // Flush the async clipboard write.
81
+ await act(async () => {});
82
+ expect(screen.getByRole('button', {name: 'Copied'})).toBeInTheDocument();
83
+
84
+ // 1.5s later the user copies again.
85
+ act(() => {
86
+ vi.advanceTimersByTime(1500);
87
+ });
88
+ fireEvent.click(screen.getByRole('button', {name: 'Copied'}));
89
+ await act(async () => {});
90
+
91
+ // 600ms after the second copy (2.1s after the first): the first
92
+ // click's timer must not have reverted the indicator early.
93
+ act(() => {
94
+ vi.advanceTimersByTime(600);
95
+ });
96
+ expect(screen.getByRole('button', {name: 'Copied'})).toBeInTheDocument();
97
+
98
+ // It resets 2s after the most recent copy.
99
+ act(() => {
100
+ vi.advanceTimersByTime(1400);
101
+ });
102
+ expect(
103
+ screen.getByRole('button', {name: 'Copy code'}),
104
+ ).toBeInTheDocument();
105
+ } finally {
106
+ vi.useRealTimers();
107
+ }
108
+ });
109
+
56
110
  it('does NOT collapse the block when the copy button is clicked', () => {
57
111
  render(
58
112
  <CodeBlock
@@ -112,4 +166,69 @@ describe('CodeBlock', () => {
112
166
  fireEvent.click(header);
113
167
  expect(header).toHaveAttribute('aria-expanded', 'false');
114
168
  });
169
+
170
+ it('links the collapsible header to its code region via aria-controls', () => {
171
+ render(
172
+ <CodeBlock
173
+ code={LONG_CODE}
174
+ language="javascript"
175
+ title="example"
176
+ isCollapsible
177
+ />,
178
+ );
179
+ const header = screen
180
+ .getAllByRole('button')
181
+ .find(el => el.hasAttribute('aria-expanded'))!;
182
+ const controlsId = header.getAttribute('aria-controls');
183
+ // aria-controls must be present and point at the real code region.
184
+ expect(controlsId).toBeTruthy();
185
+ const region = document.getElementById(controlsId as string);
186
+ expect(region).not.toBeNull();
187
+ // The region contains the scrollable code body (role="group").
188
+ expect(region).toContainElement(screen.getByRole('group'));
189
+ });
190
+
191
+ it('keeps aria-controls resolvable when collapsed (region stays mounted)', () => {
192
+ render(
193
+ <CodeBlock
194
+ code={LONG_CODE}
195
+ language="javascript"
196
+ title="example"
197
+ isCollapsible
198
+ />,
199
+ );
200
+ const header = screen
201
+ .getAllByRole('button')
202
+ .find(el => el.hasAttribute('aria-expanded'))!;
203
+ fireEvent.click(header);
204
+ expect(header).toHaveAttribute('aria-expanded', 'false');
205
+ // The code region uses a CSS grid animation to collapse, so it stays in
206
+ // the DOM — aria-controls stays a valid, resolvable reference (unlike a
207
+ // conditionally-mounted region, which would need a conditional attribute).
208
+ const controlsId = header.getAttribute('aria-controls');
209
+ expect(controlsId).toBeTruthy();
210
+ expect(document.getElementById(controlsId as string)).not.toBeNull();
211
+ });
212
+
213
+ it('applies a per-instance syntax theme via the syntaxTheme prop', () => {
214
+ const {container} = render(
215
+ <CodeBlock
216
+ code="const x = 1;"
217
+ language="javascript"
218
+ syntaxTheme={dracula}
219
+ />,
220
+ );
221
+ const wrapper = container.querySelector('[data-astryx-syntax-theme]');
222
+ expect(wrapper).not.toBeNull();
223
+ expect(wrapper).toHaveAttribute('data-astryx-syntax-theme', 'dracula');
224
+ expect(wrapper!.querySelector('pre')).not.toBeNull();
225
+ });
226
+
227
+ it('renders no syntax theme wrapper when syntaxTheme is not set', () => {
228
+ const {container} = render(
229
+ <CodeBlock code="const x = 1;" language="javascript" />,
230
+ );
231
+ expect(container.querySelector('[data-astryx-syntax-theme]')).toBeNull();
232
+ expect(container.firstElementChild?.tagName).toBe('PRE');
233
+ });
115
234
  });
@@ -3,7 +3,7 @@
3
3
  'use client';
4
4
  /**
5
5
  * @file CodeBlock.tsx
6
- * @input Uses React, StyleX, theme tokens, CSS Custom Highlight API
6
+ * @input Uses React, StyleX, theme tokens, CSS Custom Highlight API, SyntaxTheme provider
7
7
  * @output Exports CodeBlock component and CodeBlockProps
8
8
  * @position Core implementation; read-only syntax-highlighted code display
9
9
  */
@@ -11,6 +11,7 @@
11
11
  import {
12
12
  useInsertionEffect,
13
13
  useEffect,
14
+ useId,
14
15
  useRef,
15
16
  useState,
16
17
  useCallback,
@@ -32,6 +33,7 @@ import {
32
33
  easeVars,
33
34
  } from '../theme/tokens.stylex';
34
35
  import {mergeProps} from '../utils';
36
+ import {useAnnounce} from '../hooks/useAnnounce';
35
37
  import {Icon} from '../Icon';
36
38
  import {
37
39
  tokenize,
@@ -43,6 +45,7 @@ import type {SyntaxToken, TokenLine} from './tokenizer';
43
45
  import {ensureHighlightStyles} from './highlightStyles';
44
46
  import {applyHighlightRangesChunked} from './highlightRanges';
45
47
  import {themeProps} from '../utils/themeProps';
48
+ import {SyntaxTheme, type SyntaxThemeDefinition} from '../theme/syntax';
46
49
 
47
50
  // ---------------------------------------------------------------------------
48
51
  // Styles
@@ -173,6 +176,17 @@ const styles = stylex.create({
173
176
  headerCollapsible: {
174
177
  cursor: 'pointer',
175
178
  userSelect: 'none',
179
+ // Restore a keyboard-only focus ring with the standard token/offset so this
180
+ // disclosure control matches the rest of the system (Collapsible, TabMenu);
181
+ // otherwise it falls back to the inconsistent UA default outline.
182
+ outline: {
183
+ default: null,
184
+ ':focus-visible': `2px solid ${colorVars['--color-accent']}`,
185
+ },
186
+ outlineOffset: {
187
+ default: '0',
188
+ ':focus-visible': '2px',
189
+ },
176
190
  },
177
191
  gutter: {
178
192
  flexShrink: 0,
@@ -382,6 +396,14 @@ export interface CodeBlockProps extends BaseProps<HTMLPreElement> {
382
396
  language: string,
383
397
  ) => {type: string; start: number; end: number}[];
384
398
  highlightMode?: 'auto' | 'ranges' | 'spans';
399
+ /**
400
+ * Per-instance syntax theme override. Shorthand for wrapping this block in
401
+ * `<SyntaxTheme theme={...}>` — accepts a preset from
402
+ * `@astryxdesign/core/theme/syntax` or a theme created with
403
+ * `defineSyntaxTheme()`. Without it, the block uses the theme-level syntax
404
+ * colors from the nearest SyntaxTheme ancestor or `defineTheme({ syntax })`.
405
+ */
406
+ syntaxTheme?: SyntaxThemeDefinition;
385
407
  }
386
408
 
387
409
  // ---------------------------------------------------------------------------
@@ -633,6 +655,7 @@ export function CodeBlock({
633
655
  container = 'card',
634
656
  tokenizer: customTokenizer,
635
657
  highlightMode = 'auto',
658
+ syntaxTheme,
636
659
  xstyle,
637
660
  className,
638
661
  style,
@@ -640,6 +663,17 @@ export function CodeBlock({
640
663
  ...props
641
664
  }: CodeBlockProps) {
642
665
  const [copied, setCopied] = useState(false);
666
+ const copyResetTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
667
+ const announce = useAnnounce();
668
+
669
+ // Clear a pending "copied" reset when the block unmounts.
670
+ useEffect(() => {
671
+ return () => {
672
+ if (copyResetTimerRef.current != null) {
673
+ clearTimeout(copyResetTimerRef.current);
674
+ }
675
+ };
676
+ }, []);
643
677
 
644
678
  const useSpans =
645
679
  highlightMode === 'spans' ||
@@ -665,12 +699,23 @@ export function CodeBlock({
665
699
  try {
666
700
  await navigator.clipboard.writeText(code);
667
701
  setCopied(true);
702
+ // Swapping the button's aria-label alone isn't reliably announced by
703
+ // screen readers, so confirm the copy via a polite live region.
704
+ announce('Copied');
668
705
  onCopy?.();
669
- setTimeout(() => setCopied(false), 2000);
706
+ // Restart the reset timer on every copy — otherwise a rapid re-copy
707
+ // is reverted early by the previous click's timer.
708
+ if (copyResetTimerRef.current != null) {
709
+ clearTimeout(copyResetTimerRef.current);
710
+ }
711
+ copyResetTimerRef.current = setTimeout(() => {
712
+ copyResetTimerRef.current = null;
713
+ setCopied(false);
714
+ }, 2000);
670
715
  } catch {
671
716
  // Clipboard failures leave the copied state unchanged.
672
717
  }
673
- }, [code, onCopy]);
718
+ }, [code, onCopy, announce]);
674
719
 
675
720
  const sizeStyle = size === 'sm' ? styles.sizeSm : styles.sizeMd;
676
721
  const gutterSizeStyle = size === 'sm' ? styles.gutterSm : styles.gutterMd;
@@ -680,6 +725,11 @@ export function CodeBlock({
680
725
 
681
726
  const canCollapse = isCollapsible && lines.length >= collapsibleThreshold;
682
727
  const [isCollapsed, setIsCollapsed] = useState(false);
728
+ // Links the collapsible header to the code region it shows/hides so assistive
729
+ // tech can move from the button to its controlled content (disclosure
730
+ // pattern). The region stays mounted when collapsed (CSS grid animation), so
731
+ // this is always a resolvable reference — aria-controls can be unconditional.
732
+ const regionId = useId();
683
733
 
684
734
  const scrollContainerRef = useRef<HTMLDivElement>(null);
685
735
  const scrollStyle: CSSProperties | undefined = maxHeight
@@ -717,6 +767,7 @@ export function CodeBlock({
717
767
  role={canCollapse ? 'button' : undefined}
718
768
  tabIndex={canCollapse ? 0 : undefined}
719
769
  aria-expanded={canCollapse ? !isCollapsed : undefined}
770
+ aria-controls={canCollapse ? regionId : undefined}
720
771
  onClick={canCollapse ? () => setIsCollapsed(prev => !prev) : undefined}
721
772
  onKeyDown={
722
773
  canCollapse
@@ -802,7 +853,7 @@ export function CodeBlock({
802
853
  </div>
803
854
  );
804
855
 
805
- return (
856
+ const block = (
806
857
  <pre
807
858
  ref={ref}
808
859
  {...mergeProps(
@@ -820,6 +871,7 @@ export function CodeBlock({
820
871
  {headerEl}
821
872
  {canCollapse ? (
822
873
  <div
874
+ id={regionId}
823
875
  {...stylex.props(
824
876
  styles.collapseGrid,
825
877
  isCollapsed && styles.collapseGridCollapsed,
@@ -832,6 +884,12 @@ export function CodeBlock({
832
884
  {!showHeader && copyButtonEl}
833
885
  </pre>
834
886
  );
887
+
888
+ return syntaxTheme ? (
889
+ <SyntaxTheme theme={syntaxTheme}>{block}</SyntaxTheme>
890
+ ) : (
891
+ block
892
+ );
835
893
  }
836
894
 
837
895
  CodeBlock.displayName = 'CodeBlock';
@@ -16,7 +16,8 @@ export const docs = {
16
16
  },
17
17
  theming: {
18
18
  targets: [
19
- {className: 'astryx-collapsible'},
19
+ {className: 'astryx-collapsible', visualProps: ['density']},
20
+ {className: 'astryx-collapsible-group', visualProps: ['density']},
20
21
  ],
21
22
  },
22
23
  description: 'A primitive that makes any content collapsible: a trigger button toggles visibility of the content area, managing its own state or deferring to a parent CollapsibleGroup.',
@@ -69,7 +70,8 @@ export const docs = {
69
70
  usage: {
70
71
  description: 'Collapsible hides and reveals content behind a trigger button. Use it in settings panels, FAQ pages, or detail views to keep the page scannable while letting users drill into sections they care about. Wrap multiple collapsibles in CollapsibleGroup for accordion behavior. For custom collapsible components, use the `useCollapsible` hook directly (`astryx hook useCollapsible`).',
71
72
  bestPractices: [
72
- { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts.' },
73
+ { guidance: true, description: 'Use hasDividers on CollapsibleGroup for FAQ-style lists — built-in row hairlines with themed border tokens, no hand-rolled borders.' },
74
+ { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts, or use CollapsibleGroup\'s hasDividers for flat lists; don\'t combine both.' },
73
75
  { guidance: true, description: 'Use CollapsibleGroup with type="single" for settings or FAQ pages where only one section should be open at a time.' },
74
76
  { guidance: true, description: 'Use type="multiple" when users need to compare content across sections, like feature lists or pricing tiers.' },
75
77
  { guidance: true, description: 'Start sections open (defaultIsOpen) when the content is likely needed on first view; don\'t make users click to see essential info.' },
@@ -90,7 +92,8 @@ export const docsZh = {
90
92
  usage: {
91
93
  description: 'Collapsible hides and reveals content behind a trigger button. Use it in settings panels, FAQ pages, or detail views to keep the page scannable while letting users drill into sections they care about. Wrap multiple collapsibles in CollapsibleGroup for accordion behavior.',
92
94
  bestPractices: [
93
- { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts.' },
95
+ { guidance: true, description: 'Use hasDividers on CollapsibleGroup for FAQ-style lists — built-in row hairlines with themed border tokens, no hand-rolled borders.' },
96
+ { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts, or use CollapsibleGroup\'s hasDividers for flat lists; don\'t combine both.' },
94
97
  { guidance: true, description: 'Use CollapsibleGroup with type="single" for settings or FAQ pages where only one section should be open at a time.' },
95
98
  { guidance: true, description: 'Use type="multiple" when users need to compare content across sections, like feature lists or pricing tiers.' },
96
99
  { guidance: true, description: 'Start sections open (defaultIsOpen) when the content is likely needed on first view; don\'t make users click to see essential info.' },
@@ -107,7 +110,8 @@ export const docsDense = {
107
110
  usage: {
108
111
  description: 'Collapsible hides and reveals content behind a trigger button. Use in settings, FAQs, or detail views. Wrap in CollapsibleGroup for accordion behavior.',
109
112
  bestPractices: [
110
- { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation in accordion layouts.' },
113
+ { guidance: true, description: 'Use hasDividers on CollapsibleGroup for FAQ-style lists built-in row hairlines, no hand-rolled borders.' },
114
+ { guidance: true, description: 'Wrap each Collapsible in an Card for visual separation, or use CollapsibleGroup\'s hasDividers for flat lists; not both.' },
111
115
  { guidance: true, description: 'Use CollapsibleGroup with type="single" for settings or FAQ pages where only one section should be open at a time.' },
112
116
  { guidance: true, description: 'Use type="multiple" when users need to compare across sections.' },
113
117
  { guidance: true, description: 'Start sections open (defaultIsOpen) when content is needed on first view.' },