@astryxdesign/core 0.1.3 → 0.1.4-canary.01e5b29

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 (642) hide show
  1. package/CHANGELOG.md +51 -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.js +3 -3
  6. package/dist/AppShell/AppShell.d.ts +1 -1
  7. package/dist/AppShell/AppShell.d.ts.map +1 -1
  8. package/dist/AppShell/AppShell.js +55 -53
  9. package/dist/AspectRatio/AspectRatio.js +5 -5
  10. package/dist/Avatar/Avatar.d.ts.map +1 -1
  11. package/dist/Avatar/Avatar.js +27 -25
  12. package/dist/Avatar/AvatarStatusDot.js +5 -5
  13. package/dist/AvatarGroup/AvatarGroup.js +5 -5
  14. package/dist/AvatarGroup/AvatarGroupOverflow.js +5 -5
  15. package/dist/Badge/Badge.js +3 -3
  16. package/dist/Banner/Banner.d.ts.map +1 -1
  17. package/dist/Banner/Banner.js +32 -25
  18. package/dist/Blockquote/Blockquote.js +7 -7
  19. package/dist/Breadcrumbs/BreadcrumbItem.js +17 -17
  20. package/dist/Breadcrumbs/Breadcrumbs.js +7 -7
  21. package/dist/Button/Button.d.ts.map +1 -1
  22. package/dist/Button/Button.js +47 -26
  23. package/dist/ButtonGroup/ButtonGroup.js +7 -7
  24. package/dist/Calendar/Calendar.d.ts.map +1 -1
  25. package/dist/Calendar/Calendar.js +108 -64
  26. package/dist/Calendar/dayCellUtils.d.ts +67 -5
  27. package/dist/Calendar/dayCellUtils.d.ts.map +1 -1
  28. package/dist/Calendar/dayCellUtils.js +139 -18
  29. package/dist/Calendar/styles.d.ts +2 -2
  30. package/dist/Calendar/styles.d.ts.map +1 -1
  31. package/dist/Calendar/styles.js +2 -2
  32. package/dist/Card/Card.d.ts +4 -2
  33. package/dist/Card/Card.d.ts.map +1 -1
  34. package/dist/Card/Card.js +18 -10
  35. package/dist/Carousel/Carousel.d.ts.map +1 -1
  36. package/dist/Carousel/Carousel.js +20 -19
  37. package/dist/Center/Center.js +3 -3
  38. package/dist/Chat/ChatComposer.js +23 -23
  39. package/dist/Chat/ChatComposerDrawer.js +14 -14
  40. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  41. package/dist/Chat/ChatComposerInput.js +27 -15
  42. package/dist/Chat/ChatDictationButton.d.ts +1 -1
  43. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  44. package/dist/Chat/ChatDictationButton.js +13 -11
  45. package/dist/Chat/ChatLayout.js +17 -17
  46. package/dist/Chat/ChatLayoutScrollButton.d.ts +1 -1
  47. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  48. package/dist/Chat/ChatLayoutScrollButton.js +12 -10
  49. package/dist/Chat/ChatMessage.js +12 -12
  50. package/dist/Chat/ChatMessageBubble.js +7 -7
  51. package/dist/Chat/ChatMessageList.js +14 -14
  52. package/dist/Chat/ChatMessageMetadata.d.ts +1 -1
  53. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  54. package/dist/Chat/ChatMessageMetadata.js +14 -12
  55. package/dist/Chat/ChatPastedTextToken.js +13 -13
  56. package/dist/Chat/ChatSendButton.js +3 -3
  57. package/dist/Chat/ChatSystemMessage.d.ts +1 -1
  58. package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
  59. package/dist/Chat/ChatSystemMessage.js +17 -17
  60. package/dist/Chat/ChatTokenizedText.d.ts +1 -1
  61. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  62. package/dist/Chat/ChatTokenizedText.js +24 -15
  63. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  64. package/dist/Chat/ChatToolCalls.js +81 -74
  65. package/dist/Chat/index.d.ts +1 -1
  66. package/dist/Chat/index.d.ts.map +1 -1
  67. package/dist/Chat/useTriggerMenu.js +15 -15
  68. package/dist/CheckboxInput/CheckboxInput.d.ts +6 -1
  69. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  70. package/dist/CheckboxInput/CheckboxInput.js +32 -24
  71. package/dist/CheckboxList/CheckboxList.js +9 -9
  72. package/dist/CheckboxList/CheckboxListItem.d.ts +1 -1
  73. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  74. package/dist/CheckboxList/CheckboxListItem.js +8 -6
  75. package/dist/Citation/Citation.js +10 -10
  76. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  77. package/dist/ClickableCard/ClickableCard.js +32 -9
  78. package/dist/Code/Code.d.ts +15 -1
  79. package/dist/Code/Code.d.ts.map +1 -1
  80. package/dist/Code/Code.js +35 -5
  81. package/dist/Code/index.d.ts +1 -1
  82. package/dist/Code/index.d.ts.map +1 -1
  83. package/dist/CodeBlock/CodeBlock.d.ts +10 -1
  84. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  85. package/dist/CodeBlock/CodeBlock.js +88 -52
  86. package/dist/CodeBlock/index.d.ts +1 -1
  87. package/dist/CodeBlock/index.d.ts.map +1 -1
  88. package/dist/Collapsible/Collapsible.d.ts +9 -3
  89. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  90. package/dist/Collapsible/Collapsible.js +110 -22
  91. package/dist/Collapsible/CollapsibleGroup.d.ts +39 -7
  92. package/dist/Collapsible/CollapsibleGroup.d.ts.map +1 -1
  93. package/dist/Collapsible/CollapsibleGroup.js +73 -12
  94. package/dist/Collapsible/CollapsibleGroupContext.d.ts +31 -0
  95. package/dist/Collapsible/CollapsibleGroupContext.d.ts.map +1 -1
  96. package/dist/Collapsible/CollapsibleGroupContext.js +33 -3
  97. package/dist/Collapsible/index.d.ts +1 -0
  98. package/dist/Collapsible/index.d.ts.map +1 -1
  99. package/dist/Collapsible/useCollapsible.d.ts +4 -1
  100. package/dist/Collapsible/useCollapsible.d.ts.map +1 -1
  101. package/dist/Collapsible/useCollapsible.js +20 -6
  102. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  103. package/dist/CommandPalette/CommandPalette.js +36 -34
  104. package/dist/CommandPalette/CommandPaletteEmpty.d.ts +1 -1
  105. package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
  106. package/dist/CommandPalette/CommandPaletteEmpty.js +27 -7
  107. package/dist/CommandPalette/CommandPaletteFooter.js +16 -16
  108. package/dist/CommandPalette/CommandPaletteGroup.js +5 -5
  109. package/dist/CommandPalette/CommandPaletteInput.js +13 -13
  110. package/dist/CommandPalette/CommandPaletteItem.js +3 -3
  111. package/dist/CommandPalette/CommandPaletteList.js +3 -3
  112. package/dist/ContextMenu/ContextMenu.d.ts +9 -1
  113. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  114. package/dist/ContextMenu/ContextMenu.js +16 -11
  115. package/dist/DateInput/DateInput.js +18 -18
  116. package/dist/DateRangeInput/DateRangeInput.js +23 -23
  117. package/dist/DateTimeInput/DateTimeInput.d.ts +5 -7
  118. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  119. package/dist/DateTimeInput/DateTimeInput.js +30 -26
  120. package/dist/DateTimeInput/index.d.ts +1 -1
  121. package/dist/DateTimeInput/index.d.ts.map +1 -1
  122. package/dist/Dialog/Dialog.js +9 -9
  123. package/dist/Dialog/DialogHeader.js +16 -16
  124. package/dist/Dialog/useImperativeDialog.js +3 -3
  125. package/dist/Divider/Divider.d.ts +0 -22
  126. package/dist/Divider/Divider.d.ts.map +1 -1
  127. package/dist/Divider/Divider.js +7 -7
  128. package/dist/DropdownMenu/DropdownMenu.js +10 -10
  129. package/dist/DropdownMenu/DropdownMenuItem.d.ts +2 -17
  130. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  131. package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
  132. package/dist/DropdownMenu/renderDropdownItems.js +10 -10
  133. package/dist/EmptyState/EmptyState.js +9 -9
  134. package/dist/Field/Field.js +17 -17
  135. package/dist/Field/FieldLabel.js +15 -15
  136. package/dist/Field/InputClearButton.js +5 -5
  137. package/dist/FieldStatus/FieldStatus.js +3 -3
  138. package/dist/FileInput/FileInput.js +29 -29
  139. package/dist/FormLayout/FormLayout.js +5 -5
  140. package/dist/Grid/Grid.d.ts +4 -3
  141. package/dist/Grid/Grid.d.ts.map +1 -1
  142. package/dist/Grid/Grid.js +29 -12
  143. package/dist/Grid/GridSpan.js +3 -3
  144. package/dist/HStack/HStack.js +3 -3
  145. package/dist/Heading/Heading.js +10 -10
  146. package/dist/HoverCard/HoverCard.js +9 -9
  147. package/dist/HoverCard/useHoverCard.js +3 -3
  148. package/dist/Icon/Icon.d.ts.map +1 -1
  149. package/dist/Icon/Icon.js +16 -12
  150. package/dist/Icon/defaultIcons.js +116 -116
  151. package/dist/IconButton/IconButton.js +3 -3
  152. package/dist/InputGroup/InputGroup.js +11 -11
  153. package/dist/InputGroup/InputGroupText.js +3 -3
  154. package/dist/Item/Item.js +18 -18
  155. package/dist/Kbd/Kbd.js +5 -5
  156. package/dist/Layer/LayerProvider.js +7 -7
  157. package/dist/Layer/useLayer.js +5 -5
  158. package/dist/Layout/Layout.js +21 -21
  159. package/dist/Layout/LayoutContent.js +3 -3
  160. package/dist/Layout/LayoutFooter.js +5 -5
  161. package/dist/Layout/LayoutHeader.js +5 -5
  162. package/dist/Layout/LayoutPanel.js +3 -3
  163. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  164. package/dist/Lightbox/Lightbox.js +55 -31
  165. package/dist/Lightbox/useLightbox.js +3 -3
  166. package/dist/Link/Link.js +15 -15
  167. package/dist/Link/LinkProvider.js +3 -3
  168. package/dist/Link/useLinkify.js +3 -3
  169. package/dist/List/List.js +11 -11
  170. package/dist/List/ListItem.js +11 -11
  171. package/dist/Markdown/Markdown.d.ts.map +1 -1
  172. package/dist/Markdown/Markdown.js +102 -102
  173. package/dist/Markdown/parser.d.ts +7 -0
  174. package/dist/Markdown/parser.d.ts.map +1 -1
  175. package/dist/Markdown/parser.js +300 -6
  176. package/dist/MetadataList/MetadataList.js +10 -10
  177. package/dist/MetadataList/MetadataListItem.js +15 -15
  178. package/dist/MobileNav/MobileNav.js +15 -15
  179. package/dist/MobileNav/MobileNavToggle.js +5 -5
  180. package/dist/MoreMenu/MoreMenu.js +3 -3
  181. package/dist/MultiSelector/MultiSelector.d.ts +7 -1
  182. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  183. package/dist/MultiSelector/MultiSelector.js +64 -55
  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.js +3 -3
  194. package/dist/Pagination/Pagination.d.ts +1 -1
  195. package/dist/Pagination/Pagination.d.ts.map +1 -1
  196. package/dist/Pagination/Pagination.js +125 -72
  197. package/dist/Popover/Popover.js +16 -16
  198. package/dist/Popover/usePopover.js +7 -7
  199. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  200. package/dist/PowerSearch/PowerSearch.js +110 -92
  201. package/dist/PowerSearch/PowerSearchEditPopover.js +84 -84
  202. package/dist/PowerSearch/PowerSearchFilterEditor.js +3 -3
  203. package/dist/PowerSearch/PowerSearchToken.js +5 -5
  204. package/dist/PowerSearch/PowerSearchValueEditor.js +54 -54
  205. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  206. package/dist/ProgressBar/ProgressBar.js +25 -18
  207. package/dist/RadioList/RadioList.d.ts +7 -1
  208. package/dist/RadioList/RadioList.d.ts.map +1 -1
  209. package/dist/RadioList/RadioList.js +10 -8
  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 +30 -22
  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.d.ts +6 -0
  224. package/dist/Selector/Selector.d.ts.map +1 -1
  225. package/dist/Selector/Selector.js +54 -45
  226. package/dist/Selector/SelectorOption.js +3 -3
  227. package/dist/SideNav/SideNav.d.ts.map +1 -1
  228. package/dist/SideNav/SideNav.js +38 -34
  229. package/dist/SideNav/SideNavCollapseButton.d.ts +1 -1
  230. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  231. package/dist/SideNav/SideNavCollapseButton.js +8 -6
  232. package/dist/SideNav/SideNavHeading.js +87 -87
  233. package/dist/SideNav/SideNavItem.js +42 -42
  234. package/dist/SideNav/SideNavSection.d.ts +1 -1
  235. package/dist/SideNav/SideNavSection.d.ts.map +1 -1
  236. package/dist/SideNav/SideNavSection.js +18 -16
  237. package/dist/Skeleton/Skeleton.js +3 -3
  238. package/dist/Slider/Slider.d.ts +6 -0
  239. package/dist/Slider/Slider.d.ts.map +1 -1
  240. package/dist/Slider/Slider.js +31 -22
  241. package/dist/Spinner/Spinner.d.ts.map +1 -1
  242. package/dist/Spinner/Spinner.js +10 -10
  243. package/dist/StatusDot/StatusDot.js +5 -5
  244. package/dist/Switch/Switch.d.ts +13 -4
  245. package/dist/Switch/Switch.d.ts.map +1 -1
  246. package/dist/Switch/Switch.js +41 -30
  247. package/dist/TabList/Tab.js +18 -18
  248. package/dist/TabList/TabList.js +5 -5
  249. package/dist/TabList/TabMenu.d.ts.map +1 -1
  250. package/dist/TabList/TabMenu.js +57 -30
  251. package/dist/TabList/tab.markers.stylex.d.ts +1 -1
  252. package/dist/Table/BaseTable.d.ts.map +1 -1
  253. package/dist/Table/BaseTable.js +51 -39
  254. package/dist/Table/Table.js +7 -7
  255. package/dist/Table/TableBody.d.ts +1 -1
  256. package/dist/Table/TableBody.d.ts.map +1 -1
  257. package/dist/Table/TableBody.js +9 -5
  258. package/dist/Table/TableCell.d.ts.map +1 -1
  259. package/dist/Table/TableCell.js +76 -7
  260. package/dist/Table/TableFooter.d.ts +1 -1
  261. package/dist/Table/TableFooter.d.ts.map +1 -1
  262. package/dist/Table/TableFooter.js +9 -5
  263. package/dist/Table/TableHeader.d.ts +1 -1
  264. package/dist/Table/TableHeader.d.ts.map +1 -1
  265. package/dist/Table/TableHeader.js +9 -5
  266. package/dist/Table/TableHeaderCell.js +3 -3
  267. package/dist/Table/TableRow.js +5 -5
  268. package/dist/Table/index.d.ts +2 -0
  269. package/dist/Table/index.d.ts.map +1 -1
  270. package/dist/Table/index.js +1 -0
  271. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  272. package/dist/Table/plugins/columnResize/useTableColumnResize.js +14 -11
  273. package/dist/Table/plugins/filtering/useTableFiltering.js +71 -71
  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/index.d.ts +3 -0
  278. package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -0
  279. package/dist/Table/plugins/rowExpansion/index.js +3 -0
  280. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +90 -0
  281. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -0
  282. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +398 -0
  283. package/dist/Table/plugins/selection/useTableSelection.js +18 -18
  284. package/dist/Table/plugins/selection/useTableSelectionState.d.ts.map +1 -1
  285. package/dist/Table/plugins/selection/useTableSelectionState.js +11 -1
  286. package/dist/Table/plugins/sortable/useTableSortable.js +17 -17
  287. package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
  288. package/dist/Table/plugins/sortable/useTableSortableState.js +8 -4
  289. package/dist/Table/tableContextMenu.d.ts +5 -1
  290. package/dist/Table/tableContextMenu.d.ts.map +1 -1
  291. package/dist/Table/tableContextMenu.js +19 -12
  292. package/dist/Text/Text.d.ts +1 -1
  293. package/dist/Text/Text.d.ts.map +1 -1
  294. package/dist/Text/Text.js +14 -13
  295. package/dist/Text/text.stylex.d.ts +35 -0
  296. package/dist/Text/text.stylex.d.ts.map +1 -1
  297. package/dist/Text/text.stylex.js +52 -1
  298. package/dist/TextArea/TextArea.js +14 -14
  299. package/dist/TextInput/TextInput.js +15 -15
  300. package/dist/Thumbnail/Thumbnail.d.ts +3 -2
  301. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  302. package/dist/Thumbnail/Thumbnail.js +30 -29
  303. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  304. package/dist/TimeInput/TimeInput.js +26 -21
  305. package/dist/Timestamp/Timestamp.d.ts +1 -1
  306. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  307. package/dist/Timestamp/Timestamp.js +37 -26
  308. package/dist/Toast/Toast.d.ts.map +1 -1
  309. package/dist/Toast/Toast.js +25 -17
  310. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  311. package/dist/Toast/ToastViewport.js +23 -11
  312. package/dist/Toast/useToast.js +4 -4
  313. package/dist/ToggleButton/ToggleButton.js +12 -12
  314. package/dist/ToggleButton/ToggleButtonGroup.js +5 -5
  315. package/dist/Token/Token.js +21 -21
  316. package/dist/Tokenizer/Tokenizer.d.ts +6 -1
  317. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  318. package/dist/Tokenizer/Tokenizer.js +38 -29
  319. package/dist/Toolbar/Toolbar.js +18 -18
  320. package/dist/Tooltip/Tooltip.js +11 -11
  321. package/dist/Tooltip/useTooltip.js +3 -3
  322. package/dist/TopNav/TopNav.js +32 -32
  323. package/dist/TopNav/TopNavHeading.js +67 -67
  324. package/dist/TopNav/TopNavItem.js +5 -5
  325. package/dist/TopNav/TopNavMegaMenu.js +30 -30
  326. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +1 -1
  327. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
  328. package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +25 -14
  329. package/dist/TopNav/TopNavMegaMenuItem.js +16 -16
  330. package/dist/TopNav/TopNavMenu.js +32 -32
  331. package/dist/TreeList/TreeList.js +8 -8
  332. package/dist/TreeList/TreeListBranches.js +11 -11
  333. package/dist/TreeList/TreeListItem.js +30 -30
  334. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  335. package/dist/Typeahead/BaseTypeahead.js +23 -20
  336. package/dist/Typeahead/Typeahead.js +12 -12
  337. package/dist/Typeahead/TypeaheadItem.js +10 -10
  338. package/dist/VStack/VStack.js +3 -3
  339. package/dist/astryx.css +23 -0
  340. package/dist/astryx.umd.js +60 -58
  341. package/dist/astryx.umd.js.map +4 -4
  342. package/dist/docs-types.d.ts +13 -1
  343. package/dist/docs-types.d.ts.map +1 -1
  344. package/dist/hooks/focusableSelector.d.ts +1 -1
  345. package/dist/hooks/focusableSelector.d.ts.map +1 -1
  346. package/dist/hooks/focusableSelector.js +1 -1
  347. package/dist/hooks/index.d.ts +2 -0
  348. package/dist/hooks/index.d.ts.map +1 -1
  349. package/dist/hooks/index.js +1 -0
  350. package/dist/hooks/useFocusTrap.d.ts +3 -0
  351. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  352. package/dist/hooks/useFocusTrap.js +38 -1
  353. package/dist/hooks/useHotkeys.d.ts +51 -0
  354. package/dist/hooks/useHotkeys.d.ts.map +1 -0
  355. package/dist/hooks/useHotkeys.js +160 -0
  356. package/dist/hooks/useInteractiveRole.d.ts +6 -2
  357. package/dist/hooks/useInteractiveRole.d.ts.map +1 -1
  358. package/dist/hooks/useInteractiveRole.js +6 -2
  359. package/dist/hooks/useKeyboardHint.js +9 -9
  360. package/dist/hooks/useStreamingText.d.ts +3 -1
  361. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  362. package/dist/hooks/useStreamingText.js +14 -5
  363. package/dist/theme/MediaTheme.js +3 -3
  364. package/dist/theme/Theme.js +7 -7
  365. package/dist/theme/defineTheme.d.ts +1 -1
  366. package/dist/theme/defineTheme.d.ts.map +1 -1
  367. package/dist/theme/expandColorScale.d.ts.map +1 -1
  368. package/dist/theme/expandColorScale.js +10 -3
  369. package/dist/theme/hct.d.ts +0 -15
  370. package/dist/theme/hct.d.ts.map +1 -1
  371. package/dist/theme/hct.js +9 -9
  372. package/dist/theme/syntax/SyntaxTheme.js +5 -5
  373. package/dist/theme/tokens.d.ts +10 -2
  374. package/dist/theme/tokens.d.ts.map +1 -1
  375. package/dist/theme/tokens.js +220 -4
  376. package/dist/utils/color.d.ts +42 -0
  377. package/dist/utils/color.d.ts.map +1 -0
  378. package/dist/utils/color.js +150 -0
  379. package/dist/utils/composeEventHandlers.d.ts +30 -0
  380. package/dist/utils/composeEventHandlers.d.ts.map +1 -0
  381. package/dist/utils/composeEventHandlers.js +40 -0
  382. package/dist/utils/index.d.ts +3 -0
  383. package/dist/utils/index.d.ts.map +1 -1
  384. package/dist/utils/index.js +3 -1
  385. package/dist/utils/timeParser.d.ts.map +1 -1
  386. package/dist/utils/timeParser.js +8 -5
  387. package/package.json +3 -3
  388. package/src/AlertDialog/AlertDialog.tsx +2 -0
  389. package/src/AppShell/AppShell.tsx +2 -0
  390. package/src/AspectRatio/AspectRatio.doc.mjs +1 -1
  391. package/src/Avatar/Avatar.doc.mjs +13 -2
  392. package/src/Avatar/Avatar.test.tsx +32 -1
  393. package/src/Avatar/Avatar.tsx +12 -20
  394. package/src/Banner/Banner.doc.mjs +8 -0
  395. package/src/Banner/Banner.test.tsx +38 -0
  396. package/src/Banner/Banner.tsx +8 -1
  397. package/src/Button/Button.tsx +39 -6
  398. package/src/ButtonGroup/ButtonGroup.doc.mjs +1 -1
  399. package/src/Calendar/Calendar.doc.mjs +1 -1
  400. package/src/Calendar/Calendar.test.tsx +201 -17
  401. package/src/Calendar/Calendar.tsx +79 -26
  402. package/src/Calendar/dayCellUtils.test.ts +306 -1
  403. package/src/Calendar/dayCellUtils.ts +206 -13
  404. package/src/Calendar/styles.ts +12 -2
  405. package/src/Card/Card.doc.mjs +1 -1
  406. package/src/Card/Card.tsx +16 -6
  407. package/src/Carousel/Carousel.doc.mjs +12 -12
  408. package/src/Carousel/Carousel.test.tsx +13 -0
  409. package/src/Carousel/Carousel.tsx +1 -0
  410. package/src/Chat/Chat.doc.mjs +1 -1
  411. package/src/Chat/ChatComposerInput.test.tsx +24 -0
  412. package/src/Chat/ChatComposerInput.tsx +17 -1
  413. package/src/Chat/ChatDictationButton.test.tsx +43 -0
  414. package/src/Chat/ChatDictationButton.tsx +4 -4
  415. package/src/Chat/ChatLayoutScrollButton.test.tsx +33 -0
  416. package/src/Chat/ChatLayoutScrollButton.tsx +3 -1
  417. package/src/Chat/ChatMessageMetadata.test.tsx +32 -0
  418. package/src/Chat/ChatMessageMetadata.tsx +4 -6
  419. package/src/Chat/ChatSystemMessage.test.tsx +26 -11
  420. package/src/Chat/ChatSystemMessage.tsx +7 -7
  421. package/src/Chat/ChatTokenizedText.test.tsx +29 -16
  422. package/src/Chat/ChatTokenizedText.tsx +15 -8
  423. package/src/Chat/ChatToolCalls.test.tsx +55 -0
  424. package/src/Chat/ChatToolCalls.tsx +10 -12
  425. package/src/Chat/index.ts +1 -4
  426. package/src/Chat/useChatNewMessages.test.tsx +4 -4
  427. package/src/CheckboxInput/CheckboxInput.doc.mjs +12 -4
  428. package/src/CheckboxInput/CheckboxInput.test.tsx +103 -0
  429. package/src/CheckboxInput/CheckboxInput.tsx +13 -0
  430. package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
  431. package/src/CheckboxList/CheckboxList.test.tsx +19 -0
  432. package/src/CheckboxList/CheckboxListItem.tsx +11 -2
  433. package/src/Citation/Citation.doc.mjs +5 -0
  434. package/src/ClickableCard/ClickableCard.tsx +45 -2
  435. package/src/Code/Code.test.tsx +54 -0
  436. package/src/Code/Code.tsx +48 -4
  437. package/src/Code/index.ts +1 -1
  438. package/src/CodeBlock/CodeBlock.doc.mjs +7 -2
  439. package/src/CodeBlock/CodeBlock.test.tsx +122 -3
  440. package/src/CodeBlock/CodeBlock.tsx +62 -4
  441. package/src/CodeBlock/index.ts +1 -1
  442. package/src/Collapsible/Collapsible.doc.mjs +8 -4
  443. package/src/Collapsible/Collapsible.test.tsx +405 -0
  444. package/src/Collapsible/Collapsible.tsx +86 -10
  445. package/src/Collapsible/CollapsibleGroup.doc.mjs +27 -3
  446. package/src/Collapsible/CollapsibleGroup.test.tsx +318 -0
  447. package/src/Collapsible/CollapsibleGroup.tsx +107 -9
  448. package/src/Collapsible/CollapsibleGroupContext.tsx +42 -2
  449. package/src/Collapsible/index.ts +4 -0
  450. package/src/Collapsible/useCollapsible.ts +20 -6
  451. package/src/CommandPalette/CommandPalette.tsx +5 -3
  452. package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +5 -0
  453. package/src/CommandPalette/CommandPaletteEmpty.tsx +15 -1
  454. package/src/CommandPalette/CommandPaletteGroup.doc.mjs +10 -0
  455. package/src/CommandPalette/CommandPaletteInput.doc.mjs +6 -0
  456. package/src/CommandPalette/CommandPaletteItem.doc.mjs +6 -0
  457. package/src/CommandPalette/CommandPaletteList.doc.mjs +9 -0
  458. package/src/ContextMenu/ContextMenu.doc.mjs +15 -0
  459. package/src/ContextMenu/ContextMenu.test.tsx +15 -0
  460. package/src/ContextMenu/ContextMenu.tsx +19 -1
  461. package/src/ContextMenu/ContextMenuItem.doc.mjs +6 -0
  462. package/src/DateInput/DateInput.doc.mjs +6 -1
  463. package/src/DateInput/DateInput.test.tsx +11 -20
  464. package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
  465. package/src/DateRangeInput/DateRangeInput.test.tsx +31 -44
  466. package/src/DateRangeInput/DateRangeInput.tsx +2 -2
  467. package/src/DateTimeInput/DateTimeInput.doc.mjs +4 -3
  468. package/src/DateTimeInput/DateTimeInput.test.tsx +118 -16
  469. package/src/DateTimeInput/DateTimeInput.tsx +9 -8
  470. package/src/DateTimeInput/index.ts +1 -0
  471. package/src/Dialog/DialogHeader.doc.mjs +45 -0
  472. package/src/Divider/Divider.tsx +1 -23
  473. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -1
  474. package/src/DropdownMenu/DropdownMenu.test.tsx +5 -3
  475. package/src/DropdownMenu/DropdownMenuItem.tsx +5 -17
  476. package/src/EmptyState/EmptyState.doc.mjs +1 -1
  477. package/src/Field/Field.doc.mjs +1 -1
  478. package/src/Field/FieldLabel.test.tsx +2 -2
  479. package/src/FieldStatus/FieldStatus.test.tsx +282 -0
  480. package/src/FileInput/FileInput.doc.mjs +1 -1
  481. package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +0 -3
  482. package/src/Grid/Grid.doc.mjs +3 -3
  483. package/src/Grid/Grid.test.tsx +43 -18
  484. package/src/Grid/Grid.tsx +26 -9
  485. package/src/Icon/Icon.test.tsx +41 -29
  486. package/src/Icon/Icon.tsx +6 -2
  487. package/src/InputGroup/InputGroup.tsx +2 -2
  488. package/src/InteractiveRoleContext/InteractiveRoleContext.test.tsx +185 -0
  489. package/src/Item/Item.tsx +1 -1
  490. package/src/Layout/Layout.test.tsx +285 -0
  491. package/src/Layout/LayoutContent.doc.mjs +12 -0
  492. package/src/Layout/LayoutPanel.doc.mjs +40 -0
  493. package/src/Layout/LayoutSlots.test.tsx +364 -0
  494. package/src/Layout/__tests__/edgeCompensation.test.tsx +72 -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/Markdown/Markdown.test.tsx +23 -0
  499. package/src/Markdown/Markdown.tsx +9 -7
  500. package/src/Markdown/incremental.test.ts +36 -0
  501. package/src/Markdown/parser.perf.test.ts +34 -12
  502. package/src/Markdown/parser.test.ts +210 -0
  503. package/src/Markdown/parser.ts +301 -6
  504. package/src/MobileNav/MobileNav.doc.mjs +20 -0
  505. package/src/MultiSelector/MultiSelector.doc.mjs +14 -1
  506. package/src/MultiSelector/MultiSelector.test.tsx +33 -0
  507. package/src/MultiSelector/MultiSelector.tsx +20 -0
  508. package/src/NavMenu/NavMenu.doc.mjs +15 -0
  509. package/src/NumberInput/NumberInput.test.tsx +48 -3
  510. package/src/NumberInput/NumberInput.tsx +32 -15
  511. package/src/Outline/parseOutlineFromMarkdown.test.ts +80 -0
  512. package/src/OverflowList/OverflowList.test.tsx +416 -0
  513. package/src/Overlay/Overlay.doc.mjs +6 -0
  514. package/src/Overlay/Overlay.test.tsx +356 -0
  515. package/src/Pagination/Pagination.test.tsx +162 -0
  516. package/src/Pagination/Pagination.tsx +80 -26
  517. package/src/Popover/Popover.test.tsx +65 -0
  518. package/src/PowerSearch/PowerSearch.doc.mjs +4 -4
  519. package/src/PowerSearch/PowerSearch.test.tsx +109 -1
  520. package/src/PowerSearch/PowerSearch.tsx +37 -16
  521. package/src/ProgressBar/ProgressBar.test.tsx +30 -0
  522. package/src/ProgressBar/ProgressBar.tsx +12 -5
  523. package/src/RadioList/RadioList.doc.mjs +7 -1
  524. package/src/RadioList/RadioList.test.tsx +65 -0
  525. package/src/RadioList/RadioList.tsx +10 -1
  526. package/src/RadioList/RadioListItem.tsx +13 -4
  527. package/src/Resizable/ResizeHandle.test.tsx +218 -0
  528. package/src/Resizable/ResizeHandle.tsx +22 -4
  529. package/src/Section/Section.test.tsx +4 -10
  530. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  531. package/src/SegmentedControl/SegmentedControl.test.tsx +192 -0
  532. package/src/SegmentedControl/SegmentedControl.tsx +27 -5
  533. package/src/SegmentedControl/SegmentedControlItem.tsx +9 -4
  534. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  535. package/src/Selector/Selector.doc.mjs +12 -1
  536. package/src/Selector/Selector.test.tsx +30 -0
  537. package/src/Selector/Selector.tsx +18 -0
  538. package/src/SideNav/SideNav.doc.mjs +7 -1
  539. package/src/SideNav/SideNav.test.tsx +66 -0
  540. package/src/SideNav/SideNav.tsx +6 -2
  541. package/src/SideNav/SideNavCollapseButton.tsx +4 -3
  542. package/src/SideNav/SideNavSection.tsx +6 -4
  543. package/src/SizeContext/SizeContext.test.tsx +226 -0
  544. package/src/Slider/Slider.doc.mjs +14 -2
  545. package/src/Slider/Slider.test.tsx +30 -0
  546. package/src/Slider/Slider.tsx +20 -0
  547. package/src/Spinner/Spinner.tsx +1 -0
  548. package/src/Switch/Switch.doc.mjs +21 -9
  549. package/src/Switch/Switch.test.tsx +137 -0
  550. package/src/Switch/Switch.tsx +32 -7
  551. package/src/TabList/TabList.doc.mjs +3 -3
  552. package/src/TabList/TabList.test.tsx +185 -1
  553. package/src/TabList/TabMenu.tsx +45 -9
  554. package/src/Table/BaseTable.tsx +16 -3
  555. package/src/Table/Table.test.tsx +87 -0
  556. package/src/Table/TableBody.tsx +15 -2
  557. package/src/Table/TableCell.tsx +87 -8
  558. package/src/Table/TableFooter.tsx +15 -2
  559. package/src/Table/TableHeader.tsx +15 -2
  560. package/src/Table/index.ts +5 -0
  561. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +13 -0
  562. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +3 -1
  563. package/src/Table/plugins/pagination/paginateData.ts +5 -1
  564. package/src/Table/plugins/pagination/useTablePagination.test.tsx +13 -0
  565. package/src/Table/plugins/rowExpansion/index.ts +7 -0
  566. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +155 -0
  567. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +590 -0
  568. package/src/Table/plugins/selection/useTableSelectionState.test.tsx +23 -0
  569. package/src/Table/plugins/selection/useTableSelectionState.tsx +11 -6
  570. package/src/Table/plugins/sortable/useTableSortableState.test.tsx +35 -1
  571. package/src/Table/plugins/sortable/useTableSortableState.tsx +8 -4
  572. package/src/Table/tableContextMenu.test.tsx +27 -3
  573. package/src/Table/tableContextMenu.tsx +20 -2
  574. package/src/Table/useTablePagination.doc.mjs +4 -1
  575. package/src/Table/useTableRowExpansion.doc.mjs +80 -0
  576. package/src/Table/useTableSortable.doc.mjs +4 -1
  577. package/src/Text/Text.doc.mjs +2 -2
  578. package/src/Text/Text.test.tsx +11 -0
  579. package/src/Text/Text.tsx +4 -2
  580. package/src/Text/text.stylex.ts +41 -0
  581. package/src/TextArea/TextArea.doc.mjs +1 -1
  582. package/src/TextArea/TextArea.test.tsx +3 -3
  583. package/src/TextInput/TextInput.doc.mjs +1 -1
  584. package/src/TextInput/TextInput.test.tsx +3 -3
  585. package/src/Thumbnail/Thumbnail.test.tsx +36 -2
  586. package/src/Thumbnail/Thumbnail.tsx +4 -2
  587. package/src/TimeInput/TimeInput.doc.mjs +11 -6
  588. package/src/TimeInput/TimeInput.test.tsx +37 -0
  589. package/src/TimeInput/TimeInput.tsx +11 -1
  590. package/src/Timestamp/Timestamp.doc.mjs +1 -1
  591. package/src/Timestamp/Timestamp.test.tsx +52 -0
  592. package/src/Timestamp/Timestamp.tsx +30 -16
  593. package/src/Toast/Toast.tsx +11 -3
  594. package/src/Toast/ToastViewport.test.tsx +64 -0
  595. package/src/Toast/ToastViewport.tsx +12 -0
  596. package/src/ToggleButton/ToggleButton.doc.mjs +1 -0
  597. package/src/Tokenizer/Tokenizer.doc.mjs +16 -4
  598. package/src/Tokenizer/Tokenizer.test.tsx +33 -0
  599. package/src/Tokenizer/Tokenizer.tsx +19 -0
  600. package/src/Toolbar/Toolbar.test.tsx +1 -1
  601. package/src/TopNav/TopNav.doc.mjs +1 -1
  602. package/src/TopNav/TopNav.test.tsx +18 -0
  603. package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +9 -2
  604. package/src/TreeList/TreeList.doc.mjs +2 -2
  605. package/src/Typeahead/BaseTypeahead.doc.mjs +19 -0
  606. package/src/Typeahead/BaseTypeahead.tsx +5 -2
  607. package/src/Typeahead/Typeahead.doc.mjs +7 -2
  608. package/src/Typeahead/Typeahead.test.tsx +45 -1
  609. package/src/__tests__/TestIcon.tsx +26 -0
  610. package/src/__tests__/fastRoleQueries.ts +66 -0
  611. package/src/docPropReferences.test.ts +178 -0
  612. package/src/docs-types.ts +14 -0
  613. package/src/hooks/focusableSelector.ts +1 -1
  614. package/src/hooks/index.ts +3 -0
  615. package/src/hooks/useFocusTrap.doc.mjs +4 -2
  616. package/src/hooks/useFocusTrap.test.tsx +149 -1
  617. package/src/hooks/useFocusTrap.ts +50 -1
  618. package/src/hooks/useHotkeys.doc.mjs +52 -0
  619. package/src/hooks/useHotkeys.test.ts +245 -0
  620. package/src/hooks/useHotkeys.ts +203 -0
  621. package/src/hooks/useInteractiveRole.ts +12 -4
  622. package/src/hooks/useKeyboardHint.doc.mjs +6 -6
  623. package/src/hooks/useStreamingText.test.ts +54 -19
  624. package/src/hooks/useStreamingText.ts +16 -5
  625. package/src/theme/SyntaxTheme.doc.mjs +4 -4
  626. package/src/theme/defineTheme.ts +4 -13
  627. package/src/theme/derivedVarRegistry.test.ts +2 -2
  628. package/src/theme/expandColorScale.test.ts +29 -0
  629. package/src/theme/expandColorScale.ts +11 -6
  630. package/src/theme/hct.ts +9 -17
  631. package/src/theme/tokens.test.ts +182 -9
  632. package/src/theme/tokens.ts +239 -4
  633. package/src/theme/useTheme.test.tsx +20 -0
  634. package/src/utils/color.test.ts +133 -0
  635. package/src/utils/color.ts +148 -0
  636. package/src/utils/composeEventHandlers.test.ts +71 -0
  637. package/src/utils/composeEventHandlers.ts +44 -0
  638. package/src/utils/index.ts +4 -0
  639. package/src/utils/mergeProps.test.ts +166 -0
  640. package/src/utils/sharedResizeObserver.test.ts +2 -2
  641. package/src/utils/timeParser.test.ts +13 -0
  642. package/src/utils/timeParser.ts +8 -5
@@ -503,13 +503,21 @@ export function NumberInput({
503
503
  const handleBlur = useCallback(
504
504
  (e: FocusEvent<HTMLInputElement>) => {
505
505
  if (pendingInput !== null) {
506
- const parsed = parseNumberInput(pendingInput, {
507
- min,
508
- max,
509
- isIntegerOnly,
510
- });
511
- if (parsed !== null && parsed !== value) {
512
- onChange(parsed);
506
+ if (hasClear && pendingInput.trim() === '') {
507
+ // Keyboard clearing honors the clearable contract: an emptied
508
+ // input commits null instead of silently reverting on blur.
509
+ if (value != null) {
510
+ onChange(null);
511
+ }
512
+ } else {
513
+ const parsed = parseNumberInput(pendingInput, {
514
+ min,
515
+ max,
516
+ isIntegerOnly,
517
+ });
518
+ if (parsed !== null && parsed !== value) {
519
+ onChange(parsed);
520
+ }
513
521
  }
514
522
  }
515
523
 
@@ -517,7 +525,7 @@ export function NumberInput({
517
525
  setPendingInput(null);
518
526
  onBlur?.(e);
519
527
  },
520
- [pendingInput, value, onChange, min, max, isIntegerOnly, onBlur],
528
+ [pendingInput, value, onChange, min, max, isIntegerOnly, onBlur, hasClear],
521
529
  );
522
530
 
523
531
  // Handle keyboard events
@@ -526,13 +534,21 @@ export function NumberInput({
526
534
  if (e.key === 'Enter') {
527
535
  // Validate and commit on Enter
528
536
  if (pendingInput !== null) {
529
- const parsed = parseNumberInput(pendingInput, {
530
- min,
531
- max,
532
- isIntegerOnly,
533
- });
534
- if (parsed !== null && parsed !== value) {
535
- onChange(parsed);
537
+ if (hasClear && pendingInput.trim() === '') {
538
+ // Same clearable contract as blur: Enter on an emptied input
539
+ // commits null instead of reverting.
540
+ if (value != null) {
541
+ onChange(null);
542
+ }
543
+ } else {
544
+ const parsed = parseNumberInput(pendingInput, {
545
+ min,
546
+ max,
547
+ isIntegerOnly,
548
+ });
549
+ if (parsed !== null && parsed !== value) {
550
+ onChange(parsed);
551
+ }
536
552
  }
537
553
  }
538
554
  onEnter?.();
@@ -548,6 +564,7 @@ export function NumberInput({
548
564
  isIntegerOnly,
549
565
  onEnter,
550
566
  onKeyDown,
567
+ hasClear,
551
568
  ],
552
569
  );
553
570
 
@@ -0,0 +1,80 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import {describe, expect, it} from 'vitest';
4
+ import {parseOutlineFromMarkdown} from './parseOutlineFromMarkdown';
5
+
6
+ describe('parseOutlineFromMarkdown', () => {
7
+ it('returns an empty outline for content with no headings', () => {
8
+ expect(parseOutlineFromMarkdown('just a paragraph of text')).toEqual([]);
9
+ expect(parseOutlineFromMarkdown('')).toEqual([]);
10
+ });
11
+
12
+ it('extracts headings with their level and slugified id', () => {
13
+ const outline = parseOutlineFromMarkdown('# Getting Started');
14
+ expect(outline).toEqual([
15
+ {id: 'getting-started', label: 'Getting Started', level: 1},
16
+ ]);
17
+ });
18
+
19
+ it('captures heading levels distinctly', () => {
20
+ const outline = parseOutlineFromMarkdown(
21
+ ['# One', '## Two', '### Three'].join('\n\n'),
22
+ );
23
+ expect(outline.map(i => i.level)).toEqual([1, 2, 3]);
24
+ expect(outline.map(i => i.label)).toEqual(['One', 'Two', 'Three']);
25
+ });
26
+
27
+ it('slugifies punctuation and spaces into single hyphens', () => {
28
+ const outline = parseOutlineFromMarkdown('# Hello, World! Again');
29
+ expect(outline[0].id).toBe('hello-world-again');
30
+ });
31
+
32
+ it('strips quotes rather than converting them to hyphens', () => {
33
+ const outline = parseOutlineFromMarkdown(`# The "Best" Way`);
34
+ expect(outline[0].id).toBe('the-best-way');
35
+ });
36
+
37
+ it('trims leading and trailing hyphens from the slug', () => {
38
+ const outline = parseOutlineFromMarkdown('# ...leading and trailing...');
39
+ expect(outline[0].id).not.toMatch(/^-/);
40
+ expect(outline[0].id).not.toMatch(/-$/);
41
+ });
42
+
43
+ it('deduplicates repeated slugs with a numeric suffix', () => {
44
+ const outline = parseOutlineFromMarkdown(
45
+ ['# Setup', '# Setup', '# Setup'].join('\n\n'),
46
+ );
47
+ expect(outline.map(i => i.id)).toEqual(['setup', 'setup-1', 'setup-2']);
48
+ // labels stay unchanged even as ids are disambiguated
49
+ expect(outline.every(i => i.label === 'Setup')).toBe(true);
50
+ });
51
+
52
+ it('falls back to "section" when a heading slugifies to empty', () => {
53
+ const outline = parseOutlineFromMarkdown(['# !!!', '# @@@'].join('\n\n'));
54
+ expect(outline.map(i => i.id)).toEqual(['section', 'section-1']);
55
+ });
56
+
57
+ it('flattens inline formatting into the label text', () => {
58
+ const outline = parseOutlineFromMarkdown('# **Bold** and _italic_ text');
59
+ expect(outline[0].label).toBe('Bold and italic text');
60
+ expect(outline[0].id).toBe('bold-and-italic-text');
61
+ });
62
+
63
+ it('includes inline code content in the label', () => {
64
+ const outline = parseOutlineFromMarkdown('# The `useState` hook');
65
+ expect(outline[0].label).toBe('The useState hook');
66
+ });
67
+
68
+ it('does not treat fenced code block content as headings', () => {
69
+ const md = ['# Real Heading', '', '```', '# not a heading', '```'].join(
70
+ '\n',
71
+ );
72
+ const outline = parseOutlineFromMarkdown(md);
73
+ expect(outline.map(i => i.label)).toEqual(['Real Heading']);
74
+ });
75
+
76
+ it('trims surrounding whitespace from labels', () => {
77
+ const outline = parseOutlineFromMarkdown('# Spaced Out ');
78
+ expect(outline[0].label).toBe('Spaced Out');
79
+ });
80
+ });
@@ -0,0 +1,416 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file OverflowList.test.tsx
5
+ * @input Uses vitest, @testing-library/react, OverflowList component
6
+ * @output Characterization coverage for OverflowList's fit/overflow behavior
7
+ * @position Testing; validates OverflowList.tsx
8
+ *
9
+ * jsdom reports every element as 0px wide and lacks ResizeObserver, so these
10
+ * tests install a minimal ResizeObserver stub and drive layout math through a
11
+ * `data-w` attribute read by a mocked `offsetWidth`. Each item declares its
12
+ * pixel width via `data-w`; the visible container's available width is the
13
+ * `data-w` passed straight through to it. This lets the real fit algorithm run
14
+ * deterministically instead of collapsing to the trivial all-fit case.
15
+ *
16
+ * SYNC: When OverflowList.tsx changes, update tests to match new behavior
17
+ */
18
+
19
+ import {describe, it, expect, beforeAll, afterAll, vi} from 'vitest';
20
+ import {render, screen, within} from '@testing-library/react';
21
+ import {OverflowList} from './OverflowList';
22
+
23
+ const originalOffsetWidth = Object.getOwnPropertyDescriptor(
24
+ HTMLElement.prototype,
25
+ 'offsetWidth',
26
+ );
27
+ const originalResizeObserver = (
28
+ globalThis as unknown as {ResizeObserver?: unknown}
29
+ ).ResizeObserver;
30
+
31
+ /** No-op ResizeObserver — the shared observer fires its initial callback
32
+ * synchronously on observe(), so the algorithm still measures on mount. */
33
+ class StubResizeObserver {
34
+ observe(): void {}
35
+ unobserve(): void {}
36
+ disconnect(): void {}
37
+ }
38
+
39
+ beforeAll(() => {
40
+ (globalThis as unknown as {ResizeObserver: unknown}).ResizeObserver =
41
+ StubResizeObserver;
42
+ Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
43
+ configurable: true,
44
+ get(this: HTMLElement): number {
45
+ const own = this.getAttribute('data-w');
46
+ if (own != null) {
47
+ return Number(own);
48
+ }
49
+ // The overflow indicator is wrapped in a measurement <div>; read the
50
+ // width off its child so the reserved indicator space is measurable.
51
+ const child = this.firstElementChild;
52
+ if (child) {
53
+ return Number(child.getAttribute('data-w') ?? 0);
54
+ }
55
+ return 0;
56
+ },
57
+ });
58
+ });
59
+
60
+ afterAll(() => {
61
+ if (originalOffsetWidth) {
62
+ Object.defineProperty(
63
+ HTMLElement.prototype,
64
+ 'offsetWidth',
65
+ originalOffsetWidth,
66
+ );
67
+ }
68
+ (globalThis as unknown as {ResizeObserver?: unknown}).ResizeObserver =
69
+ originalResizeObserver;
70
+ });
71
+
72
+ /** The visible (non-measurement) container, identified by its stable class. */
73
+ function visibleContainer(): HTMLElement {
74
+ return screen.getByTestId('ov');
75
+ }
76
+
77
+ /** The hidden measurement container (the only inert element rendered). */
78
+ function measureContainer(): HTMLElement {
79
+ return document.querySelector('[inert]') as HTMLElement;
80
+ }
81
+
82
+ const indicator =
83
+ (label: string, width = 40) =>
84
+ (items: {index: number}[]) => (
85
+ <span data-w={width}>
86
+ {label}
87
+ {items.map(i => i.index).join(',')}
88
+ </span>
89
+ );
90
+
91
+ describe('OverflowList', () => {
92
+ describe('when all items fit', () => {
93
+ it('renders every item and no overflow indicator', () => {
94
+ render(
95
+ <OverflowList
96
+ gap={0}
97
+ data-w="1000"
98
+ data-testid="ov"
99
+ overflowRenderer={indicator('more:')}>
100
+ <button type="button" data-w="40">
101
+ A
102
+ </button>
103
+ <button type="button" data-w="40">
104
+ B
105
+ </button>
106
+ <button type="button" data-w="40">
107
+ C
108
+ </button>
109
+ </OverflowList>,
110
+ );
111
+ const vis = visibleContainer();
112
+ expect(within(vis).getByText('A')).toBeInTheDocument();
113
+ expect(within(vis).getByText('B')).toBeInTheDocument();
114
+ expect(within(vis).getByText('C')).toBeInTheDocument();
115
+ // No overflow indicator when nothing is hidden.
116
+ expect(within(vis).queryByText(/^more:/)).not.toBeInTheDocument();
117
+ });
118
+ });
119
+
120
+ describe('when items overflow (collapseFrom="end", default)', () => {
121
+ it('hides trailing items and shows an indicator for them', () => {
122
+ render(
123
+ <OverflowList
124
+ gap={0}
125
+ data-w="100"
126
+ data-testid="ov"
127
+ overflowRenderer={indicator('more:')}>
128
+ <button type="button" data-w="40">
129
+ A
130
+ </button>
131
+ <button type="button" data-w="40">
132
+ B
133
+ </button>
134
+ <button type="button" data-w="40">
135
+ C
136
+ </button>
137
+ </OverflowList>,
138
+ );
139
+ const vis = visibleContainer();
140
+ // 100px fits one 40px item once 40px is reserved for the indicator.
141
+ expect(within(vis).getByText('A')).toBeInTheDocument();
142
+ expect(within(vis).queryByText('B')).not.toBeInTheDocument();
143
+ expect(within(vis).queryByText('C')).not.toBeInTheDocument();
144
+ // Indicator lists the hidden items by their original index (1 and 2).
145
+ expect(within(vis).getByText('more:1,2')).toBeInTheDocument();
146
+ });
147
+
148
+ it('fits more items as the available width grows', () => {
149
+ render(
150
+ <OverflowList
151
+ gap={0}
152
+ data-w="110"
153
+ data-testid="ov"
154
+ overflowRenderer={indicator('more:', 20)}>
155
+ <button type="button" data-w="40">
156
+ A
157
+ </button>
158
+ <button type="button" data-w="40">
159
+ B
160
+ </button>
161
+ <button type="button" data-w="40">
162
+ C
163
+ </button>
164
+ </OverflowList>,
165
+ );
166
+ const vis = visibleContainer();
167
+ // 110px fits two 40px items plus the 20px indicator reservation (100px),
168
+ // but not a third (120px) — so C collapses.
169
+ expect(within(vis).getByText('A')).toBeInTheDocument();
170
+ expect(within(vis).getByText('B')).toBeInTheDocument();
171
+ expect(within(vis).queryByText('C')).not.toBeInTheDocument();
172
+ expect(within(vis).getByText('more:2')).toBeInTheDocument();
173
+ });
174
+
175
+ it('places the indicator after the visible items', () => {
176
+ render(
177
+ <OverflowList
178
+ gap={0}
179
+ data-w="100"
180
+ data-testid="ov"
181
+ overflowRenderer={indicator('more:')}>
182
+ <button type="button" data-w="40">
183
+ A
184
+ </button>
185
+ <button type="button" data-w="40">
186
+ B
187
+ </button>
188
+ <button type="button" data-w="40">
189
+ C
190
+ </button>
191
+ </OverflowList>,
192
+ );
193
+ const vis = visibleContainer();
194
+ expect(vis.textContent).toBe('Amore:1,2');
195
+ });
196
+ });
197
+
198
+ describe('when items overflow (collapseFrom="start")', () => {
199
+ it('hides leading items and renders the indicator first', () => {
200
+ render(
201
+ <OverflowList
202
+ gap={0}
203
+ collapseFrom="start"
204
+ data-w="100"
205
+ data-testid="ov"
206
+ overflowRenderer={indicator('more:')}>
207
+ <button type="button" data-w="40">
208
+ A
209
+ </button>
210
+ <button type="button" data-w="40">
211
+ B
212
+ </button>
213
+ <button type="button" data-w="40">
214
+ C
215
+ </button>
216
+ </OverflowList>,
217
+ );
218
+ const vis = visibleContainer();
219
+ // The trailing item stays; the leading two collapse.
220
+ expect(within(vis).getByText('C')).toBeInTheDocument();
221
+ expect(within(vis).queryByText('A')).not.toBeInTheDocument();
222
+ expect(within(vis).queryByText('B')).not.toBeInTheDocument();
223
+ // Indicator carries the hidden indices 0 and 1, and comes first.
224
+ expect(within(vis).getByText('more:0,1')).toBeInTheDocument();
225
+ expect(vis.textContent).toBe('more:0,1C');
226
+ });
227
+ });
228
+
229
+ describe('minVisibleItems', () => {
230
+ it('keeps at least the requested number of items visible', () => {
231
+ render(
232
+ <OverflowList
233
+ gap={0}
234
+ minVisibleItems={2}
235
+ data-w="100"
236
+ data-testid="ov"
237
+ overflowRenderer={indicator('more:')}>
238
+ <button type="button" data-w="40">
239
+ A
240
+ </button>
241
+ <button type="button" data-w="40">
242
+ B
243
+ </button>
244
+ <button type="button" data-w="40">
245
+ C
246
+ </button>
247
+ </OverflowList>,
248
+ );
249
+ const vis = visibleContainer();
250
+ // Without the floor only one item would fit; the floor forces two.
251
+ expect(within(vis).getByText('A')).toBeInTheDocument();
252
+ expect(within(vis).getByText('B')).toBeInTheDocument();
253
+ expect(within(vis).queryByText('C')).not.toBeInTheDocument();
254
+ expect(within(vis).getByText('more:2')).toBeInTheDocument();
255
+ });
256
+ });
257
+
258
+ describe('without an overflow renderer', () => {
259
+ it('drops overflowing items but renders no indicator', () => {
260
+ render(
261
+ <OverflowList gap={0} data-w="100" data-testid="ov">
262
+ <button type="button" data-w="40">
263
+ A
264
+ </button>
265
+ <button type="button" data-w="40">
266
+ B
267
+ </button>
268
+ <button type="button" data-w="40">
269
+ C
270
+ </button>
271
+ </OverflowList>,
272
+ );
273
+ const vis = visibleContainer();
274
+ // With no indicator to reserve space for, two 40px items fit in 100px.
275
+ expect(within(vis).getByText('A')).toBeInTheDocument();
276
+ expect(within(vis).getByText('B')).toBeInTheDocument();
277
+ expect(within(vis).queryByText('C')).not.toBeInTheDocument();
278
+ });
279
+ });
280
+
281
+ describe('measurement container', () => {
282
+ it('renders a hidden, inert measurement copy of all children', () => {
283
+ render(
284
+ <OverflowList
285
+ gap={0}
286
+ data-w="100"
287
+ data-testid="ov"
288
+ overflowRenderer={indicator('more:')}>
289
+ <button type="button" data-w="40">
290
+ A
291
+ </button>
292
+ <button type="button" data-w="40">
293
+ B
294
+ </button>
295
+ <button type="button" data-w="40">
296
+ C
297
+ </button>
298
+ </OverflowList>,
299
+ );
300
+ const measure = measureContainer();
301
+ expect(measure).toHaveAttribute('aria-hidden', 'true');
302
+ expect(measure).toHaveAttribute('inert');
303
+ // Measures against every item, even the ones hidden from the visible row.
304
+ expect(within(measure).getByText('A')).toBeInTheDocument();
305
+ expect(within(measure).getByText('B')).toBeInTheDocument();
306
+ expect(within(measure).getByText('C')).toBeInTheDocument();
307
+ });
308
+
309
+ it('measures the indicator against all items (max width)', () => {
310
+ render(
311
+ <OverflowList
312
+ gap={0}
313
+ data-w="100"
314
+ data-testid="ov"
315
+ overflowRenderer={indicator('more:')}>
316
+ <button type="button" data-w="40">
317
+ A
318
+ </button>
319
+ <button type="button" data-w="40">
320
+ B
321
+ </button>
322
+ <button type="button" data-w="40">
323
+ C
324
+ </button>
325
+ </OverflowList>,
326
+ );
327
+ // The measurement indicator reflects every index (0,1,2), reserving the
328
+ // widest possible indicator; the visible one only lists hidden indices.
329
+ const measure = measureContainer();
330
+ expect(within(measure).getByText('more:0,1,2')).toBeInTheDocument();
331
+ });
332
+ });
333
+
334
+ describe('rendering contract', () => {
335
+ it('renders the stable astryx-overflow-list class on the visible container', () => {
336
+ render(
337
+ <OverflowList data-w="1000" data-testid="ov">
338
+ <button type="button" data-w="10">
339
+ A
340
+ </button>
341
+ </OverflowList>,
342
+ );
343
+ expect(visibleContainer()).toHaveClass('astryx-overflow-list');
344
+ });
345
+
346
+ it('forwards a ref to the visible container', () => {
347
+ const ref = vi.fn();
348
+ render(
349
+ <OverflowList ref={ref} data-w="1000" data-testid="ov">
350
+ <button type="button" data-w="10">
351
+ A
352
+ </button>
353
+ </OverflowList>,
354
+ );
355
+ expect(ref).toHaveBeenCalledWith(expect.any(HTMLDivElement));
356
+ const el = ref.mock.calls[0][0] as HTMLElement;
357
+ expect(el).toHaveClass('astryx-overflow-list');
358
+ });
359
+
360
+ it('applies a different gap class as the gap prop changes', () => {
361
+ const {rerender} = render(
362
+ <OverflowList gap={0} data-w="1000" data-testid="ov">
363
+ <button type="button" data-w="10">
364
+ A
365
+ </button>
366
+ </OverflowList>,
367
+ );
368
+ const gap0 = visibleContainer().getAttribute('class');
369
+
370
+ rerender(
371
+ <OverflowList gap={4} data-w="1000" data-testid="ov">
372
+ <button type="button" data-w="10">
373
+ A
374
+ </button>
375
+ </OverflowList>,
376
+ );
377
+ const gap4 = visibleContainer().getAttribute('class');
378
+ expect(gap4).not.toEqual(gap0);
379
+ });
380
+
381
+ it('renders nothing extra for an empty child list', () => {
382
+ render(
383
+ <OverflowList
384
+ data-w="1000"
385
+ data-testid="ov"
386
+ overflowRenderer={indicator('more:')}>
387
+ {null}
388
+ </OverflowList>,
389
+ );
390
+ const vis = visibleContainer();
391
+ expect(vis).toBeInTheDocument();
392
+ expect(vis).toBeEmptyDOMElement();
393
+ });
394
+
395
+ it('passes arbitrary DOM props through to the visible container', () => {
396
+ render(
397
+ <OverflowList
398
+ data-w="1000"
399
+ data-testid="ov"
400
+ aria-label="Toolbar actions">
401
+ <button type="button" data-w="10">
402
+ A
403
+ </button>
404
+ </OverflowList>,
405
+ );
406
+ expect(visibleContainer()).toHaveAttribute(
407
+ 'aria-label',
408
+ 'Toolbar actions',
409
+ );
410
+ });
411
+
412
+ it('exposes a displayName for devtools', () => {
413
+ expect(OverflowList.displayName).toBe('OverflowList');
414
+ });
415
+ });
416
+ });
@@ -180,6 +180,12 @@ export const docs = {
180
180
  description: 'Ref forwarded to the overlay root element.',
181
181
  },
182
182
  ],
183
+ theming: {
184
+ targets: [
185
+ {className: 'astryx-overlay'},
186
+ {className: 'astryx-overlay-scrim', visualProps: ['position']},
187
+ ],
188
+ },
183
189
  };
184
190
 
185
191
  /** @type {import('../docs-types').TranslationDoc} */