@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
@@ -33,6 +33,31 @@ describe('Timestamp', () => {
33
33
  expect(screen.getByText('2 hours ago')).toBeInTheDocument();
34
34
  });
35
35
 
36
+ it('does not round a tier up past its own boundary', () => {
37
+ // Just under each threshold the count must stay within the tier, e.g.
38
+ // 59.98 minutes is "59 minutes ago", never "60 minutes ago".
39
+ const {rerender} = render(
40
+ <Timestamp value={Date.now() / 1000 - 3599} format="relative" />,
41
+ );
42
+ expect(screen.getByText('59 minutes ago')).toBeInTheDocument();
43
+
44
+ rerender(
45
+ <Timestamp value={Date.now() / 1000 - 86399} format="relative" />,
46
+ );
47
+ expect(screen.getByText('23 hours ago')).toBeInTheDocument();
48
+
49
+ rerender(
50
+ <Timestamp value={Date.now() / 1000 - 2591999} format="relative" />,
51
+ );
52
+ expect(screen.getByText('29 days ago')).toBeInTheDocument();
53
+
54
+ // Same guarantee on the future side.
55
+ rerender(
56
+ <Timestamp value={Date.now() / 1000 + 3599} format="relative" />,
57
+ );
58
+ expect(screen.getByText('in 59 minutes')).toBeInTheDocument();
59
+ });
60
+
36
61
  it('renders "now" for very recent times', () => {
37
62
  const fiveSecondsAgo = Date.now() / 1000 - 5;
38
63
  render(<Timestamp value={fiveSecondsAgo} format="relative" />);
@@ -290,4 +315,31 @@ describe('Timestamp', () => {
290
315
  const el = screen.getByRole('time');
291
316
  expect(el.textContent).not.toContain('ago');
292
317
  });
318
+
319
+ // --- Invalid values ---
320
+
321
+ it('renders nothing instead of crashing on an unparseable string value', () => {
322
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
323
+ try {
324
+ const {container} = render(
325
+ <Timestamp value="not-a-date" data-testid="ts" />,
326
+ );
327
+ expect(container).toBeEmptyDOMElement();
328
+ expect(warn).toHaveBeenCalledWith(
329
+ expect.stringContaining('could not parse value'),
330
+ );
331
+ } finally {
332
+ warn.mockRestore();
333
+ }
334
+ });
335
+
336
+ it('renders nothing instead of crashing on a NaN value', () => {
337
+ const warn = vi.spyOn(console, 'warn').mockImplementation(() => {});
338
+ try {
339
+ const {container} = render(<Timestamp value={NaN} data-testid="ts" />);
340
+ expect(container).toBeEmptyDOMElement();
341
+ } finally {
342
+ warn.mockRestore();
343
+ }
344
+ });
293
345
  });
@@ -180,22 +180,22 @@ function getRelativeTimeString(date: Date, now: Date): string {
180
180
  return 'in a few seconds';
181
181
  }
182
182
  if (absDiff < HOUR) {
183
- const mins = Math.round(absDiff / MINUTE);
183
+ const mins = Math.floor(absDiff / MINUTE);
184
184
  return `in ${mins} ${mins === 1 ? 'minute' : 'minutes'}`;
185
185
  }
186
186
  if (absDiff < DAY) {
187
- const hours = Math.round(absDiff / HOUR);
187
+ const hours = Math.floor(absDiff / HOUR);
188
188
  return `in ${hours} ${hours === 1 ? 'hour' : 'hours'}`;
189
189
  }
190
190
  if (absDiff < MONTH) {
191
- const days = Math.round(absDiff / DAY);
191
+ const days = Math.floor(absDiff / DAY);
192
192
  return `in ${days} ${days === 1 ? 'day' : 'days'}`;
193
193
  }
194
194
  if (absDiff < YEAR) {
195
- const months = Math.round(absDiff / MONTH);
195
+ const months = Math.floor(absDiff / MONTH);
196
196
  return `in ${months} ${months === 1 ? 'month' : 'months'}`;
197
197
  }
198
- const years = Math.round(absDiff / YEAR);
198
+ const years = Math.floor(absDiff / YEAR);
199
199
  return `in ${years} ${years === 1 ? 'year' : 'years'}`;
200
200
  }
201
201
 
@@ -203,25 +203,25 @@ function getRelativeTimeString(date: Date, now: Date): string {
203
203
  return `${diffSeconds} seconds ago`;
204
204
  }
205
205
  if (diffSeconds < HOUR) {
206
- const mins = Math.round(diffSeconds / MINUTE);
206
+ const mins = Math.floor(diffSeconds / MINUTE);
207
207
  return `${mins} ${mins === 1 ? 'minute' : 'minutes'} ago`;
208
208
  }
209
209
  if (diffSeconds < DAY) {
210
- const hours = Math.round(diffSeconds / HOUR);
210
+ const hours = Math.floor(diffSeconds / HOUR);
211
211
  return `${hours} ${hours === 1 ? 'hour' : 'hours'} ago`;
212
212
  }
213
213
  if (diffSeconds < 2 * DAY) {
214
214
  return 'yesterday';
215
215
  }
216
216
  if (diffSeconds < MONTH) {
217
- const days = Math.round(diffSeconds / DAY);
217
+ const days = Math.floor(diffSeconds / DAY);
218
218
  return `${days} days ago`;
219
219
  }
220
220
  if (diffSeconds < YEAR) {
221
- const months = Math.round(diffSeconds / MONTH);
221
+ const months = Math.floor(diffSeconds / MONTH);
222
222
  return `${months} ${months === 1 ? 'month' : 'months'} ago`;
223
223
  }
224
- const years = Math.round(diffSeconds / YEAR);
224
+ const years = Math.floor(diffSeconds / YEAR);
225
225
  return `${years} ${years === 1 ? 'year' : 'years'} ago`;
226
226
  }
227
227
 
@@ -360,7 +360,12 @@ export function Timestamp({
360
360
  const [now, setNow] = useState(() => new Date());
361
361
 
362
362
  const date = parseValue(value);
363
- const isoString = date.toISOString();
363
+ // An unparseable value (a malformed date string, or a NaN timestamp from
364
+ // missing data) yields an Invalid Date, and formatting one throws "Invalid
365
+ // time value" — crashing the whole tree. Compute nothing from it here and
366
+ // bail out below (after the hooks) instead.
367
+ const isValidDate = !Number.isNaN(date.getTime());
368
+ const isoString = isValidDate ? date.toISOString() : '';
364
369
 
365
370
  // Determine effective format
366
371
  const diffSeconds = Math.round((now.getTime() - date.getTime()) / 1000);
@@ -372,19 +377,20 @@ export function Timestamp({
372
377
  : format;
373
378
 
374
379
  // Format the display text
375
- const displayText =
376
- effectiveFormat === 'relative'
380
+ const displayText = !isValidDate
381
+ ? ''
382
+ : effectiveFormat === 'relative'
377
383
  ? getRelativeTimeString(date, now)
378
384
  : isAbsoluteFormat(effectiveFormat)
379
385
  ? formatTimestamp(date, effectiveFormat, isTimezoneShown)
380
386
  : '';
381
387
 
382
388
  // Full absolute text for tooltip and aria-label
383
- const fullAbsoluteText = getFullAbsoluteString(date);
389
+ const fullAbsoluteText = isValidDate ? getFullAbsoluteString(date) : '';
384
390
 
385
391
  // Live updates
386
392
  useEffect(() => {
387
- if (!isLive || effectiveFormat !== 'relative') {
393
+ if (!isLive || !isValidDate || effectiveFormat !== 'relative') {
388
394
  return;
389
395
  }
390
396
 
@@ -394,7 +400,15 @@ export function Timestamp({
394
400
  }, interval);
395
401
 
396
402
  return () => clearInterval(timer);
397
- }, [isLive, effectiveFormat, diffSeconds]);
403
+ }, [isLive, isValidDate, effectiveFormat, diffSeconds]);
404
+
405
+ // Placed after all hooks so the hook order stays stable across renders.
406
+ if (!isValidDate) {
407
+ console.warn(
408
+ `Timestamp: could not parse value ${JSON.stringify(value)} as a date. Rendering nothing.`,
409
+ );
410
+ return null;
411
+ }
398
412
 
399
413
  const showTooltip = hasTooltip && effectiveFormat === 'relative';
400
414
 
@@ -121,8 +121,14 @@ export function Toast({
121
121
  // Will be initialized by startTimer when actually used
122
122
  const startTimeRef = useRef<number | null>(null);
123
123
 
124
+ // Read onDismiss through a ref: the viewport re-creates it on every render
125
+ // (another toast arriving/exiting), and a startTimer that depends on it
126
+ // would restart — and un-pause — this toast's timer on unrelated renders.
127
+ const onDismissRef = useRef(onDismiss);
128
+ onDismissRef.current = onDismiss;
129
+
124
130
  const startTimer = useCallback(() => {
125
- if (!isAutoHide) {
131
+ if (!isAutoHide || isPausedRef.current) {
126
132
  return;
127
133
  }
128
134
  if (timerRef.current) {
@@ -130,9 +136,9 @@ export function Toast({
130
136
  }
131
137
  startTimeRef.current = Date.now();
132
138
  timerRef.current = setTimeout(() => {
133
- onDismiss('auto');
139
+ onDismissRef.current('auto');
134
140
  }, remainingRef.current);
135
- }, [isAutoHide, onDismiss]);
141
+ }, [isAutoHide]);
136
142
 
137
143
  const pauseTimer = useCallback(() => {
138
144
  if (!isAutoHide || isPausedRef.current) {
@@ -165,6 +171,8 @@ export function Toast({
165
171
  clearTimeout(timerRef.current);
166
172
  }
167
173
  };
174
+ // startTimer's identity is stable per isAutoHide, so this runs on mount
175
+ // and on a genuine duration change — not on unrelated viewport renders.
168
176
  }, [autoHideDuration, startTimer]);
169
177
 
170
178
  // Pause the auto-hide timer while the window is not focused, so a toast
@@ -212,3 +212,67 @@ describe('ToastViewport region ARIA', () => {
212
212
  expect(region).not.toHaveAttribute('aria-modal');
213
213
  });
214
214
  });
215
+
216
+ describe('toast timer lifecycle (#3589)', () => {
217
+ it('fires onHide exactly once when dismissed twice during the exit window', () => {
218
+ const onHide = vi.fn();
219
+ renderViewport(
220
+ <ShowToastButton options={{body: 'Once', onHide}} triggerLabel="Show" />,
221
+ );
222
+ act(() => {
223
+ fireEvent.click(screen.getByText('Show'));
224
+ });
225
+ const dismiss = screen.getByRole('button', {name: 'Dismiss notification'});
226
+ act(() => {
227
+ fireEvent.click(dismiss);
228
+ });
229
+ // The toast stays mounted during its exit transition; a second click
230
+ // lands on the same still-mounted button.
231
+ act(() => {
232
+ fireEvent.click(dismiss);
233
+ });
234
+ expect(onHide).toHaveBeenCalledTimes(1);
235
+ });
236
+
237
+ it('keeps a window-blur pause alive when another toast arrives', () => {
238
+ vi.useFakeTimers();
239
+ try {
240
+ const onHide = vi.fn();
241
+ renderViewport(
242
+ <>
243
+ <ShowToastButton
244
+ options={{body: 'Paused', autoHideDuration: 3000, onHide}}
245
+ triggerLabel="Show A"
246
+ />
247
+ <ShowToastButton options={INFO_B} triggerLabel="Show B" />
248
+ </>,
249
+ );
250
+ act(() => {
251
+ fireEvent.click(screen.getByText('Show A'));
252
+ });
253
+ act(() => {
254
+ fireEvent.blur(window);
255
+ });
256
+ // A second toast arriving re-renders the viewport; the paused timer
257
+ // must not silently restart.
258
+ act(() => {
259
+ fireEvent.click(screen.getByText('Show B'));
260
+ });
261
+ act(() => {
262
+ vi.advanceTimersByTime(60_000);
263
+ });
264
+ expect(onHide).not.toHaveBeenCalled();
265
+ // Focus returns: the remaining time resumes and completes normally.
266
+ act(() => {
267
+ fireEvent.focus(window);
268
+ });
269
+ act(() => {
270
+ vi.advanceTimersByTime(60_000);
271
+ });
272
+ expect(onHide).toHaveBeenCalledTimes(1);
273
+ expect(onHide).toHaveBeenCalledWith('auto');
274
+ } finally {
275
+ vi.useRealTimers();
276
+ }
277
+ });
278
+ });
@@ -114,6 +114,9 @@ export function ToastViewport({
114
114
 
115
115
  // Show the popover on mount so it enters the top layer.
116
116
  const viewportRef = useRef<HTMLDivElement>(null);
117
+ // Toast ids whose exit has begun — guards onHide from double-firing (see
118
+ // removeToast). Mirrors exitingIds state, readable synchronously.
119
+ const exitingIdsRef = useRef<Set<string>>(new Set());
117
120
  // The element that was focused before the user jumped into the viewport
118
121
  // (via F6). Used to restore focus once all toasts are dismissed so focus
119
122
  // never falls to <body>.
@@ -171,6 +174,14 @@ export function ToastViewport({
171
174
  }, []);
172
175
 
173
176
  const removeToast = useCallback((id: string, reason: ToastDismissReason) => {
177
+ // An exiting toast stays in toastsRef until its exit transition ends, so
178
+ // a second dismissal inside that window (double-click, auto-timer plus
179
+ // manual dismiss()) would re-fire onHide. Track exiting ids in a ref —
180
+ // the exitingIds state dedupe below runs too late to protect onHide.
181
+ if (exitingIdsRef.current.has(id)) {
182
+ return;
183
+ }
184
+ exitingIdsRef.current.add(id);
174
185
  const entry = toastsRef.current.find(t => t.id === id);
175
186
  if (entry) {
176
187
  entry.options.onHide?.(reason);
@@ -210,6 +221,7 @@ export function ToastViewport({
210
221
  }, []);
211
222
 
212
223
  const handleExited = useCallback((id: string) => {
224
+ exitingIdsRef.current.delete(id);
213
225
  setExitingIds(prev => {
214
226
  if (!prev.has(id)) {
215
227
  return prev;
@@ -17,6 +17,7 @@ export const docs = {
17
17
  theming: {
18
18
  targets: [
19
19
  {className: 'astryx-toggle-button-group'},
20
+ {className: 'astryx-toggle-button', states: ['isPressed']},
20
21
  ],
21
22
  },
22
23
  description: 'A button that toggles between pressed and unpressed states. Thin wrapper over Button with controlled toggle pattern, icon swap, and font weight emphasis.',
@@ -70,11 +70,17 @@ export const docs = {
70
70
  description: 'Disables the input and all token interactions.',
71
71
  default: 'false',
72
72
  },
73
+ {
74
+ name: 'htmlName',
75
+ type: 'string',
76
+ description:
77
+ 'The HTML name attribute for form submissions. Renders one hidden input per selected item id.',
78
+ },
73
79
  {
74
80
  name: 'disabledMessage',
75
81
  type: 'string',
76
82
  description:
77
- 'Explains why the tokenizer is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (input stays blocked). Use this instead of wrapping a disabled Tokenizer in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
83
+ 'Explains why the tokenizer is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (input stays blocked). Use this instead of wrapping a disabled Tokenizer in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
78
84
  },
79
85
  {
80
86
  name: 'status',
@@ -183,7 +189,7 @@ export const docs = {
183
189
  ],
184
190
  theming: {
185
191
  targets: [
186
- {className: 'astryx-tokenizer', visualProps: ['size']},
192
+ {className: 'astryx-tokenizer', visualProps: ['size', 'status']},
187
193
  ],
188
194
  },
189
195
  usage: {
@@ -277,11 +283,16 @@ export const docsZh = {
277
283
  description: '\u7981\u7528\u8f93\u5165\u6846\u548c\u6240\u6709\u6807\u8bb0\u4ea4\u4e92\u3002',
278
284
  default: 'false',
279
285
  },
286
+ {
287
+ name: 'htmlName',
288
+ type: 'string',
289
+ description: '用于表单提交的 HTML name 属性。为每个已选项目的 id 渲染一个隐藏输入。',
290
+ },
280
291
  {
281
292
  name: 'disabledMessage',
282
293
  type: 'string',
283
294
  description:
284
- 'Explains why the tokenizer is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (input stays blocked). Use this instead of wrapping a disabled Tokenizer in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
295
+ 'Explains why the tokenizer is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (input stays blocked). Use this instead of wrapping a disabled Tokenizer in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
285
296
  },
286
297
  {
287
298
  name: 'status',
@@ -379,7 +390,7 @@ export const docsZh = {
379
390
  ],
380
391
  theming: {
381
392
  targets: [
382
- {className: 'astryx-tokenizer', visualProps: ['size']},
393
+ {className: 'astryx-tokenizer', visualProps: ['size', 'status']},
383
394
  ],
384
395
  },
385
396
  usage: {
@@ -435,6 +446,7 @@ export const docsDense = {
435
446
  renderToken: 'Custom token render. Default renders Token w/ label+onRemove.',
436
447
  renderItem: 'Custom dropdown item render. Default renders TypeaheadItem.',
437
448
  isDisabled: 'Disables input+all token interactions.',
449
+ htmlName: 'HTML name attr; one hidden input per selected item id.',
438
450
  status: 'Validation status w/ type+message for error/warning/success.',
439
451
  isLabelHidden: 'Visually hides label; keeps a11y.',
440
452
  description: 'Helper text below label.',
@@ -867,4 +867,37 @@ describe('Tokenizer', () => {
867
867
  expect(screen.getByRole('combobox')).toBeDisabled();
868
868
  });
869
869
  });
870
+ describe('form participation', () => {
871
+ it('submits one entry per token id under htmlName', () => {
872
+ const {container} = render(
873
+ <form>
874
+ <Tokenizer
875
+ label="Users"
876
+ htmlName="users"
877
+ searchSource={userSource}
878
+ value={[users[0], users[1]]}
879
+ onChange={() => {}}
880
+ />
881
+ </form>,
882
+ );
883
+ const data = new FormData(container.querySelector('form')!);
884
+ expect(data.getAll('users')).toEqual([users[0].id, users[1].id]);
885
+ });
886
+
887
+ it('is excluded from form data when disabled', () => {
888
+ const {container} = render(
889
+ <form>
890
+ <Tokenizer
891
+ label="Users"
892
+ htmlName="users"
893
+ searchSource={userSource}
894
+ value={[users[0]]}
895
+ onChange={() => {}}
896
+ isDisabled
897
+ />
898
+ </form>,
899
+ );
900
+ expect([...new FormData(container.querySelector('form')!).keys()]).toEqual([]);
901
+ });
902
+ });
870
903
  });
@@ -128,6 +128,12 @@ export interface TokenizerProps<T extends SearchableItem> extends Omit<
128
128
  searchSource: SearchSource<T>;
129
129
  /** Currently selected items. */
130
130
  value: T[];
131
+
132
+ /**
133
+ * The HTML name attribute for form submissions. When set, hidden inputs
134
+ * carry one entry per selected item's id under this name.
135
+ */
136
+ htmlName?: string;
131
137
  /** Callback when selection changes. Includes change metadata. */
132
138
  onChange: (items: T[], change: TokenizerChange<T>) => void;
133
139
  /** Render function for dropdown items. Default: TypeaheadItem. */
@@ -377,6 +383,7 @@ export function Tokenizer<T extends SearchableItem>({
377
383
  maxMenuItems,
378
384
  emptySearchResultsText,
379
385
  isDisabled = false,
386
+ htmlName,
380
387
  disabledMessage,
381
388
  hasClear = false,
382
389
  endContent,
@@ -760,6 +767,18 @@ export function Tokenizer<T extends SearchableItem>({
760
767
  : undefined
761
768
  }
762
769
  />
770
+ {htmlName != null &&
771
+ value.map(item => (
772
+ <input
773
+ key={item.id}
774
+ type="hidden"
775
+ name={htmlName}
776
+ value={item.id}
777
+ // Disabled native controls are excluded from form submission;
778
+ // mirror that for the hidden carriers.
779
+ disabled={isDisabled}
780
+ />
781
+ ))}
763
782
  {(endContent || (hasClear && value.length > 0 && !isDisabled)) && (
764
783
  <div {...stylex.props(styles.endSection, endSectionSizeStyles[size])}>
765
784
  {endContent}
@@ -168,7 +168,7 @@ describe('Toolbar', () => {
168
168
 
169
169
  it('passes variant to Section', () => {
170
170
  const {container} = render(<Toolbar label="Actions" variant="muted" />);
171
- // Section renders with xds-section class containing the variant
171
+ // Section renders with astryx-section class containing the variant
172
172
  const sectionInner = container.querySelector('.astryx-section');
173
173
  expect(sectionInner).toBeInTheDocument();
174
174
  expect(sectionInner?.className).toContain('muted');
@@ -17,7 +17,7 @@ export const docs = {
17
17
  theming: {
18
18
  targets: [
19
19
  {className: 'astryx-top-nav', states: ['mode']},
20
- {className: 'astryx-top-nav-item', states: ['mode']},
20
+ {className: 'astryx-top-nav-item', states: ['mode', 'selected']},
21
21
  {className: 'astryx-top-nav-heading'},
22
22
  {className: 'astryx-top-nav-mega-menu', states: ['mode']},
23
23
  {className: 'astryx-top-nav-mega-menu-item', states: ['mode']},
@@ -16,6 +16,7 @@ import {TopNav} from './TopNav';
16
16
  import {TopNavHeading} from './TopNavHeading';
17
17
  import {NavIcon} from '../NavIcon';
18
18
  import {TopNavItem} from './TopNavItem';
19
+ import {TopNavMegaMenuFeaturedCard} from './TopNavMegaMenuFeaturedCard';
19
20
  import {LinkProvider} from '../Link/LinkProvider';
20
21
 
21
22
  function CustomLink({
@@ -398,4 +399,21 @@ describe('TopNavItem', () => {
398
399
  expect(link).toHaveAttribute('data-custom-link');
399
400
  expect(link).not.toHaveAttribute('data-another-link');
400
401
  });
402
+
403
+ describe('TopNavMegaMenuFeaturedCard rest forwarding', () => {
404
+ it('forwards data-testid, id, and aria-* to the root element', () => {
405
+ render(
406
+ <TopNavMegaMenuFeaturedCard
407
+ title="What's new"
408
+ description="Details"
409
+ data-testid="featured-card"
410
+ id="card-1"
411
+ aria-label="Featured"
412
+ />,
413
+ );
414
+ const card = screen.getByTestId('featured-card');
415
+ expect(card).toHaveAttribute('id', 'card-1');
416
+ expect(card).toHaveAttribute('aria-label', 'Featured');
417
+ });
418
+ });
401
419
  });
@@ -132,6 +132,10 @@ export function TopNavMegaMenuFeaturedCard({
132
132
  linkLabel,
133
133
  linkHref,
134
134
  children,
135
+ xstyle,
136
+ className,
137
+ style,
138
+ ...rest
135
139
  }: TopNavMegaMenuFeaturedCardProps) {
136
140
  const LinkComponent = useLinkComponent();
137
141
  return (
@@ -139,8 +143,11 @@ export function TopNavMegaMenuFeaturedCard({
139
143
  ref={ref}
140
144
  {...mergeProps(
141
145
  themeProps('top-nav-mega-menu-featured-card'),
142
- stylex.props(styles.root),
143
- )}>
146
+ stylex.props(styles.root, xstyle),
147
+ className,
148
+ style,
149
+ )}
150
+ {...rest}>
144
151
  {image && (
145
152
  <img src={image} alt={imageAlt ?? ''} {...stylex.props(styles.image)} />
146
153
  )}
@@ -25,7 +25,7 @@ export const docs = {
25
25
  theming: {
26
26
  targets: [
27
27
  {className: 'astryx-tree-list', visualProps: ['density']},
28
- {className: 'astryx-tree-list-item', states: ['selected', 'disabled']},
28
+ {className: 'astryx-tree-list-item', visualProps: ['density'], states: ['selected', 'disabled']},
29
29
  ],
30
30
  },
31
31
  components: [
@@ -89,7 +89,7 @@ export const docsZh = {
89
89
  theming: {
90
90
  targets: [
91
91
  {className: 'astryx-tree-list', visualProps: ['density']},
92
- {className: 'astryx-tree-list-item', states: ['selected', 'disabled']},
92
+ {className: 'astryx-tree-list-item', visualProps: ['density'], states: ['selected', 'disabled']},
93
93
  ],
94
94
  },
95
95
  components: [
@@ -8,6 +8,16 @@ export const docs = {
8
8
  displayName: 'Base Typeahead',
9
9
  isHiddenFromOverview: true,
10
10
  description: 'Unstyled combobox engine providing input, search, keyboard navigation, and dropdown. No wrapper div, no border styling, no token rendering. Used by Typeahead and Tokenizer for custom compositions.',
11
+ usage: {
12
+ description: 'Unstyled combobox engine providing input, search, keyboard navigation, and dropdown. No wrapper div, no border styling, no token rendering. Used by Typeahead and Tokenizer for custom compositions.',
13
+ bestPractices: [
14
+ { guidance: true, description: 'Use Typeahead or Tokenizer for standard fields; they wrap BaseTypeahead with the wrapper div, border styling, and token rendering it intentionally omits.' },
15
+ { guidance: true, description: 'Provide your own wrapper div with border and layout when composing directly, since BaseTypeahead renders no visual chrome of its own.' },
16
+ { guidance: true, description: 'Pass anchorRef pointing to your wrapper so the dropdown positions against your custom input chrome, not just the bare input element.' },
17
+ { guidance: false, description: 'Expect a wrapper div, border, or token rendering. BaseTypeahead is an engine only; all visual chrome is the caller\'s responsibility.' },
18
+ { guidance: false, description: 'Use BaseTypeahead when Typeahead or Tokenizer would suffice; the extra wrapper and styling work is only justified for truly custom compositions.' },
19
+ ],
20
+ },
11
21
  props: [
12
22
  {
13
23
  name: 'searchSource',
@@ -226,6 +236,15 @@ export const docsDense = {
226
236
  isHiddenFromOverview: true,
227
237
  displayName: 'Base Typeahead',
228
238
  description: 'Unstyled combobox engine; input+search+keyboard nav+dropdown. No wrapper/border/token. Used by Typeahead+Tokenizer.',
239
+ usage: {
240
+ bestPractices: [
241
+ { guidance: true, description: 'Use Typeahead or Tokenizer for standard fields; they add the wrapper, border, and token rendering BaseTypeahead omits.' },
242
+ { guidance: true, description: 'Provide your own wrapper div with border and layout when composing directly; BaseTypeahead renders no chrome.' },
243
+ { guidance: true, description: 'Pass anchorRef to your wrapper so the dropdown positions against your input chrome, not the bare input.' },
244
+ { guidance: false, description: 'Expect wrapper, border, or token rendering. Engine only; chrome is the caller\'s job.' },
245
+ { guidance: false, description: 'Use BaseTypeahead when Typeahead or Tokenizer suffice; extra work only pays off for custom compositions.' },
246
+ ],
247
+ },
229
248
  propDescriptions: {
230
249
  searchSource: 'Data source w/ search+bootstrap methods.',
231
250
  value: 'Currently selected item.',
@@ -410,7 +410,10 @@ export const BaseTypeahead = function BaseTypeahead<T extends SearchableItem>({
410
410
  const performSearch = useCallback(
411
411
  async (searchQuery: string) => {
412
412
  searchSource.cancel?.();
413
- const gen = searchGenRef.current;
413
+ // Claim a new generation so overlapping searches can't race: an
414
+ // in-flight response for an older query fails the gen check below
415
+ // instead of overwriting the newer results.
416
+ const gen = ++searchGenRef.current;
414
417
  setIsLoading(true);
415
418
  setHasSearched(true);
416
419
  try {
@@ -451,7 +454,7 @@ export const BaseTypeahead = function BaseTypeahead<T extends SearchableItem>({
451
454
 
452
455
  // Perform bootstrap
453
456
  const performBootstrap = useCallback(async () => {
454
- const gen = searchGenRef.current;
457
+ const gen = ++searchGenRef.current;
455
458
  setIsLoading(true);
456
459
  try {
457
460
  const bootstrapResults = await searchSource.bootstrap();
@@ -75,7 +75,7 @@ export const docs = {
75
75
  name: 'disabledMessage',
76
76
  type: 'string',
77
77
  description:
78
- 'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the field focusable via aria-disabled (activation stays blocked). Use this instead of wrapping a disabled Typeahead in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
78
+ 'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the field focusable via aria-disabled (activation stays blocked). Use this instead of wrapping a disabled Typeahead in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
79
79
  },
80
80
  {
81
81
  name: 'maxMenuItems',
@@ -168,7 +168,7 @@ export const docs = {
168
168
  components: [{name: 'BaseTypeahead'}, {name: 'TypeaheadItem'}],
169
169
  theming: {
170
170
  targets: [
171
- {className: 'astryx-typeahead', visualProps: ['status']},
171
+ {className: 'astryx-typeahead', visualProps: ['status', 'size']},
172
172
  {className: 'astryx-typeahead-dropdown'},
173
173
  {className: 'astryx-typeahead-item'},
174
174
  ],
@@ -287,6 +287,11 @@ export const docsDense = {
287
287
  description:
288
288
  'Add a search delay for remote data sources to avoid excessive network requests.',
289
289
  },
290
+ {
291
+ guidance: true,
292
+ description:
293
+ 'Use inside InputGroup when the typeahead needs a single-line prefix or suffix addon.',
294
+ },
290
295
  {
291
296
  guidance: false,
292
297
  description: