@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
@@ -354,4 +354,69 @@ describe('Popover', () => {
354
354
  expect(trigger).toHaveAttribute('aria-expanded', 'true');
355
355
  });
356
356
  });
357
+
358
+ describe('focus restoration', () => {
359
+ it('returns focus to the trigger when closed via Escape', () => {
360
+ render(
361
+ <Popover
362
+ content={
363
+ <button type="button" data-testid="inside-content">
364
+ Inside
365
+ </button>
366
+ }
367
+ label="Test">
368
+ <button type="button">Open</button>
369
+ </Popover>,
370
+ );
371
+ const trigger = screen.getByRole('button', {name: 'Open'});
372
+ trigger.focus();
373
+ expect(trigger).toHaveFocus();
374
+
375
+ fireEvent.click(trigger);
376
+ expect(trigger).toHaveAttribute('aria-expanded', 'true');
377
+
378
+ // Move focus into the open popover, as a keyboard user would.
379
+ const inside = screen.getByTestId('inside-content');
380
+ inside.focus();
381
+ expect(inside).toHaveFocus();
382
+
383
+ fireEvent.keyDown(document, {key: 'Escape'});
384
+ expect(trigger).toHaveAttribute('aria-expanded', 'false');
385
+ expect(trigger).toHaveFocus();
386
+ });
387
+
388
+ it('returns focus to the trigger on light dismiss', () => {
389
+ render(
390
+ <Popover
391
+ content={
392
+ <button type="button" data-testid="inside-content">
393
+ Inside
394
+ </button>
395
+ }
396
+ label="Test">
397
+ <button type="button">Open</button>
398
+ </Popover>,
399
+ );
400
+ const trigger = screen.getByRole('button', {name: 'Open'});
401
+ trigger.focus();
402
+
403
+ fireEvent.click(trigger);
404
+ expect(trigger).toHaveAttribute('aria-expanded', 'true');
405
+
406
+ const inside = screen.getByTestId('inside-content');
407
+ inside.focus();
408
+ expect(inside).toHaveFocus();
409
+
410
+ // Simulate the browser's light dismiss for popover="auto": clicking
411
+ // outside fires a `toggle` event with newState "closed".
412
+ const popoverEl = document.querySelector('[popover]');
413
+ expect(popoverEl).not.toBeNull();
414
+ const toggleEvent = new Event('toggle');
415
+ Object.defineProperty(toggleEvent, 'newState', {value: 'closed'});
416
+ fireEvent(popoverEl as HTMLElement, toggleEvent);
417
+
418
+ expect(trigger).toHaveAttribute('aria-expanded', 'false');
419
+ expect(trigger).toHaveFocus();
420
+ });
421
+ });
357
422
  });
@@ -75,7 +75,7 @@ export const docs = {
75
75
  name: 'disabledMessage',
76
76
  type: 'string',
77
77
  description:
78
- 'Explains why the search 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 PowerSearch in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
78
+ 'Explains why the search 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 PowerSearch in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
79
79
  },
80
80
  {
81
81
  name: 'status',
@@ -120,7 +120,7 @@ export const docs = {
120
120
  name: 'resultCount',
121
121
  type: 'number | string',
122
122
  description:
123
- 'Number of results matching the current filters. When a number, formatted as "N results". When a string, displayed as-is.',
123
+ 'Number of results matching the current filters. When a number, formatted as "N results". When a string, displayed as-is. Changes are announced to screen readers via a polite live region.',
124
124
  },
125
125
  {
126
126
  name: 'size',
@@ -223,7 +223,7 @@ export const docsZh = {
223
223
  name: 'disabledMessage',
224
224
  type: 'string',
225
225
  description:
226
- 'Explains why the search 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 PowerSearch in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
226
+ 'Explains why the search 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 PowerSearch in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
227
227
  },
228
228
  {
229
229
  name: 'status',
@@ -261,7 +261,7 @@ export const docsZh = {
261
261
  name: 'resultCount',
262
262
  type: 'number | string',
263
263
  description:
264
- '匹配当前过滤器的结果数量。数字类型时格式化为"N results"。字符串类型时按原样显示。',
264
+ '匹配当前过滤器的结果数量。数字类型时格式化为"N results"。字符串类型时按原样显示。数量变化会通过 polite 实时区域向屏幕阅读器播报。',
265
265
  },
266
266
  {
267
267
  name: 'size',
@@ -10,10 +10,11 @@
10
10
  */
11
11
 
12
12
  import {useState} from 'react';
13
- import {describe, it, expect, vi, beforeAll, afterAll} from 'vitest';
13
+ import {describe, it, expect, vi, beforeAll, afterAll, afterEach} from 'vitest';
14
14
  import {render, screen, act, fireEvent, waitFor} from '@testing-library/react';
15
15
  import userEvent from '@testing-library/user-event';
16
16
  import {PowerSearch} from './PowerSearch';
17
+ import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
17
18
  import type {PowerSearchConfig, PowerSearchFilter} from './types';
18
19
 
19
20
  // =============================================================================
@@ -59,6 +60,12 @@ afterAll(() => {
59
60
  (HTMLElement.prototype as any).matches = originalMatches;
60
61
  });
61
62
 
63
+ // Reset the singleton live regions between tests so result-count
64
+ // announcements from one test don't leak into the next.
65
+ afterEach(() => {
66
+ __resetLiveRegionsForTest();
67
+ });
68
+
62
69
  // =============================================================================
63
70
  // Fixtures
64
71
  // =============================================================================
@@ -295,4 +302,105 @@ describe('PowerSearch', () => {
295
302
  expect(screen.getByRole('combobox')).toBeDisabled();
296
303
  });
297
304
  });
305
+
306
+ describe('result count announcements', () => {
307
+ const politeRegion = () =>
308
+ document.querySelector('[data-astryx-live-region="polite"]');
309
+
310
+ it('announces the result count to a polite live region when it changes', async () => {
311
+ const {rerender} = render(
312
+ <PowerSearch
313
+ config={config}
314
+ filters={[]}
315
+ onChange={() => {}}
316
+ resultCount={0}
317
+ />,
318
+ );
319
+ rerender(
320
+ <PowerSearch
321
+ config={config}
322
+ filters={[]}
323
+ onChange={() => {}}
324
+ resultCount={5}
325
+ />,
326
+ );
327
+ await waitFor(() => {
328
+ expect(politeRegion()).toHaveTextContent('5 results');
329
+ });
330
+ });
331
+
332
+ it('announces "1 result" (singular) for a single match', async () => {
333
+ const {rerender} = render(
334
+ <PowerSearch
335
+ config={config}
336
+ filters={[]}
337
+ onChange={() => {}}
338
+ resultCount={0}
339
+ />,
340
+ );
341
+ rerender(
342
+ <PowerSearch
343
+ config={config}
344
+ filters={[]}
345
+ onChange={() => {}}
346
+ resultCount={1}
347
+ />,
348
+ );
349
+ await waitFor(() => {
350
+ expect(politeRegion()).toHaveTextContent('1 result');
351
+ });
352
+ expect(politeRegion()?.textContent).not.toMatch(/results/);
353
+ });
354
+
355
+ it('announces a string result count verbatim', async () => {
356
+ const {rerender} = render(
357
+ <PowerSearch
358
+ config={config}
359
+ filters={[]}
360
+ onChange={() => {}}
361
+ resultCount="0 items"
362
+ />,
363
+ );
364
+ rerender(
365
+ <PowerSearch
366
+ config={config}
367
+ filters={[]}
368
+ onChange={() => {}}
369
+ resultCount="Showing 1.2k matches"
370
+ />,
371
+ );
372
+ await waitFor(() => {
373
+ expect(politeRegion()).toHaveTextContent('Showing 1.2k matches');
374
+ });
375
+ });
376
+
377
+ it('does not announce the result count present on initial mount', async () => {
378
+ render(
379
+ <PowerSearch
380
+ config={config}
381
+ filters={[]}
382
+ onChange={() => {}}
383
+ resultCount={42}
384
+ />,
385
+ );
386
+ // Flush effects and any pending live-region rAF writes.
387
+ await act(async () => {
388
+ await new Promise(resolve => setTimeout(resolve, 50));
389
+ });
390
+ expect(politeRegion()?.textContent ?? '').not.toContain('42');
391
+ });
392
+
393
+ it('leaves Typeahead dropdown announcements intact and stays silent when no resultCount is set', async () => {
394
+ const user = userEvent.setup();
395
+ render(<PowerSearchWrapper config={config} />);
396
+ const input = screen.getByRole('combobox');
397
+ await user.click(input);
398
+ await user.type(input, 'Status');
399
+ // BaseTypeahead announces the dropdown suggestion count; PowerSearch adds
400
+ // no result-count announcement because resultCount is unset.
401
+ await waitFor(() => {
402
+ expect(politeRegion()?.textContent).toMatch(/\d+ results?/);
403
+ });
404
+ });
405
+ });
298
406
  });
@@ -16,6 +16,7 @@
16
16
 
17
17
  import React, {
18
18
  useCallback,
19
+ useEffect,
19
20
  useImperativeHandle,
20
21
  useMemo,
21
22
  useRef,
@@ -38,6 +39,7 @@ import type {IconType} from '../Icon';
38
39
  import type {IconName} from '../Icon/globalIconRegistry';
39
40
  import type {InputStatus} from '../Field';
40
41
  import {usePopover} from '../Popover/usePopover';
42
+ import {useAnnounce} from '../hooks/useAnnounce';
41
43
  import {
42
44
  spacingVars,
43
45
  colorVars,
@@ -945,23 +947,42 @@ export function PowerSearch({
945
947
  isReadOnly,
946
948
  ]);
947
949
 
950
+ // Plain-text form of the result count, shared by the visible label and the
951
+ // screen-reader announcement so the two never drift.
952
+ const resultCountText = useMemo((): string | null => {
953
+ if (resultCount == null) {
954
+ return null;
955
+ }
956
+ if (typeof resultCount === 'number') {
957
+ const formatted = new Intl.NumberFormat().format(resultCount);
958
+ return `${formatted} ${resultCount === 1 ? 'result' : 'results'}`;
959
+ }
960
+ return resultCount;
961
+ }, [resultCount]);
962
+
963
+ // Announce result-count changes to screen readers through a polite live
964
+ // region, mirroring the way Typeahead announces its dropdown result count.
965
+ // The count is otherwise only shown visually and stays silent to assistive
966
+ // tech. Skip the first run so the count already present on mount isn't
967
+ // announced unprompted — only user-driven changes are spoken.
968
+ const announce = useAnnounce();
969
+ const hasMountedRef = useRef(false);
970
+ useEffect(() => {
971
+ if (!hasMountedRef.current) {
972
+ hasMountedRef.current = true;
973
+ return;
974
+ }
975
+ if (resultCountText != null) {
976
+ announce(resultCountText);
977
+ }
978
+ }, [resultCountText, announce]);
979
+
948
980
  // Build combined endContent from resultCount + endContent props
949
981
  const combinedEndContent = useMemo((): React.ReactNode => {
950
- let resultCountNode: React.ReactNode = null;
951
- if (resultCount != null) {
952
- if (typeof resultCount === 'number') {
953
- const formatted = new Intl.NumberFormat().format(resultCount);
954
- resultCountNode = (
955
- <span {...stylex.props(resultCountStyles.text)}>
956
- {formatted} {resultCount === 1 ? 'result' : 'results'}
957
- </span>
958
- );
959
- } else {
960
- resultCountNode = (
961
- <span {...stylex.props(resultCountStyles.text)}>{resultCount}</span>
962
- );
963
- }
964
- }
982
+ const resultCountNode =
983
+ resultCountText != null ? (
984
+ <span {...stylex.props(resultCountStyles.text)}>{resultCountText}</span>
985
+ ) : null;
965
986
 
966
987
  if (resultCountNode && endContent) {
967
988
  return (
@@ -972,7 +993,7 @@ export function PowerSearch({
972
993
  );
973
994
  }
974
995
  return resultCountNode || endContent || undefined;
975
- }, [resultCount, endContent]);
996
+ }, [resultCountText, endContent]);
976
997
 
977
998
  return (
978
999
  <>
@@ -140,6 +140,36 @@ describe('ProgressBar', () => {
140
140
  expect(progressbar).toHaveAttribute('aria-valuemax', '0');
141
141
  });
142
142
 
143
+ it('treats a NaN value as empty progress instead of leaking "NaN"', () => {
144
+ // e.g. an upstream `loaded / total * 100` where total is still 0.
145
+ render(<ProgressBar value={NaN} label="Upload" hasValueLabel />);
146
+ const progressbar = screen.getByRole('progressbar');
147
+ expect(progressbar).toHaveAttribute('aria-valuenow', '0');
148
+ expect(progressbar.getAttribute('aria-valuetext')).toBe('0%');
149
+ expect(screen.queryByText(/NaN/)).not.toBeInTheDocument();
150
+ // The fill width must be a real percentage, not "NaN%".
151
+ const fill = progressbar.firstElementChild as HTMLElement;
152
+ expect(fill.style.width).toBe('0%');
153
+ });
154
+
155
+ it('treats a NaN max as an empty range instead of leaking "NaN"', () => {
156
+ render(<ProgressBar value={5} max={NaN} label="Steps" hasValueLabel />);
157
+ const progressbar = screen.getByRole('progressbar');
158
+ expect(progressbar).toHaveAttribute('aria-valuenow', '0');
159
+ expect(progressbar).toHaveAttribute('aria-valuemax', '0');
160
+ expect(screen.queryByText(/NaN/)).not.toBeInTheDocument();
161
+ });
162
+
163
+ it('does not render NaN in the value label when max is zero', () => {
164
+ render(<ProgressBar value={0} max={0} label="Empty" hasValueLabel />);
165
+ expect(screen.queryByText(/NaN|Infinity/)).not.toBeInTheDocument();
166
+ const progressbar = screen.getByRole('progressbar');
167
+ expect(progressbar.getAttribute('aria-valuetext') ?? '').not.toMatch(
168
+ /NaN|Infinity/,
169
+ );
170
+ expect(screen.getByText('0%')).toBeInTheDocument();
171
+ });
172
+
143
173
  // Disabled state
144
174
  describe('disabled state', () => {
145
175
  it('renders with isDisabled', () => {
@@ -228,7 +228,8 @@ const variantStyles = stylex.create({
228
228
  });
229
229
 
230
230
  function defaultFormatValueLabel(value: number, max: number): string {
231
- return `${Math.round((value / max) * 100)}%`;
231
+ const pct = max > 0 ? Math.round((value / max) * 100) : 0;
232
+ return `${pct}%`;
232
233
  }
233
234
 
234
235
  /**
@@ -272,9 +273,15 @@ export function ProgressBar({
272
273
  ...rest
273
274
  }: ProgressBarProps) {
274
275
  const labelId = useId();
275
- const clampedValue = Math.min(Math.max(0, value), max);
276
- const percentage = max > 0 ? (clampedValue / max) * 100 : 0;
277
- const valueText = formatValueLabel(clampedValue, max);
276
+ // A non-finite value or max (e.g. a NaN from an upstream `loaded / total`
277
+ // with total 0) would otherwise leak into aria-valuenow, the value label,
278
+ // and the fill width as the string "NaN". Treat it as empty progress,
279
+ // matching the max=0 handling below.
280
+ const safeValue = Number.isFinite(value) ? value : 0;
281
+ const safeMax = Number.isFinite(max) ? max : 0;
282
+ const clampedValue = Math.min(Math.max(0, safeValue), safeMax);
283
+ const percentage = safeMax > 0 ? (clampedValue / safeMax) * 100 : 0;
284
+ const valueText = formatValueLabel(clampedValue, safeMax);
278
285
 
279
286
  const showValueLabel = hasValueLabel && !isIndeterminate;
280
287
 
@@ -322,7 +329,7 @@ export function ProgressBar({
322
329
  role="progressbar"
323
330
  aria-valuenow={isIndeterminate ? undefined : clampedValue}
324
331
  aria-valuemin={isIndeterminate ? undefined : 0}
325
- aria-valuemax={isIndeterminate ? undefined : max}
332
+ aria-valuemax={isIndeterminate ? undefined : safeMax}
326
333
  aria-labelledby={labelId}
327
334
  aria-valuetext={isIndeterminate ? undefined : valueText}
328
335
  {...mergeProps(
@@ -74,11 +74,17 @@ export const docs = {
74
74
  description: 'Whether all radio items are disabled.',
75
75
  default: 'false',
76
76
  },
77
+ {
78
+ name: 'htmlName',
79
+ type: 'string',
80
+ description:
81
+ 'The HTML name attribute shared by the radio inputs, useful for form submissions. When omitted, a unique internal name still groups the radios.',
82
+ },
77
83
  {
78
84
  name: 'disabledMessage',
79
85
  type: 'string',
80
86
  description:
81
- 'Explains why the group is disabled. Applies to the whole-group disabled state (isDisabled), not per item. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the radios focusable via aria-disabled (selection stays blocked). Use this instead of wrapping a disabled RadioList in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
87
+ 'Explains why the group is disabled. Applies to the whole-group disabled state (isDisabled), not per item. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the radios focusable via aria-disabled (selection stays blocked). Use this instead of wrapping a disabled RadioList in Tooltip. Disabled controls swallow the hover events an external Tooltip needs.',
82
88
  },
83
89
  {
84
90
  name: 'isRequired',
@@ -576,4 +576,69 @@ describe('RadioList', () => {
576
576
  }
577
577
  });
578
578
  });
579
+ describe('form participation', () => {
580
+ it('submits the selected value under htmlName', () => {
581
+ const {container} = render(
582
+ <form>
583
+ <RadioList label="Preference" htmlName="pref" value="b" onChange={() => {}}>
584
+ <RadioListItem label="Option A" value="a" />
585
+ <RadioListItem label="Option B" value="b" />
586
+ </RadioList>
587
+ </form>,
588
+ );
589
+ const data = new FormData(container.querySelector('form')!);
590
+ expect(data.get('pref')).toBe('b');
591
+ });
592
+
593
+ it('is excluded from form data when disabled, even with a disabledMessage', () => {
594
+ const {container} = render(
595
+ <form>
596
+ <RadioList
597
+ label="Preference"
598
+ htmlName="pref"
599
+ value="a"
600
+ onChange={() => {}}
601
+ isDisabled
602
+ disabledMessage="Locked"
603
+ >
604
+ <RadioListItem label="Option A" value="a" />
605
+ </RadioList>
606
+ </form>,
607
+ );
608
+ expect([...new FormData(container.querySelector('form')!).keys()]).toEqual([]);
609
+ });
610
+
611
+ it('keeps working as an isolated group when htmlName is omitted', () => {
612
+ const {container} = render(
613
+ <form>
614
+ <RadioList label="Preference" value="a" onChange={() => {}}>
615
+ <RadioListItem label="Option A" value="a" />
616
+ </RadioList>
617
+ </form>,
618
+ );
619
+ // Auto-generated internal name still groups the radios, but the field
620
+ // name is not part of the public form contract.
621
+ const input = container.querySelector('input[type="radio"]')!;
622
+ expect(input.getAttribute('name')).toBeTruthy();
623
+ });
624
+ });
625
+
626
+ describe('RadioListItem rest forwarding', () => {
627
+ it('forwards data-testid, id, and aria-* to the item root element', () => {
628
+ render(
629
+ <RadioList label="Preference" value="" onChange={() => {}}>
630
+ <RadioListItem
631
+ label="Option A"
632
+ value="a"
633
+ data-testid="item-a"
634
+ id="item-a-id"
635
+ aria-label="First option"
636
+ />
637
+ </RadioList>,
638
+ );
639
+ const item = screen.getByTestId('item-a');
640
+ expect(item).toHaveAttribute('id', 'item-a-id');
641
+ expect(item).toHaveAttribute('aria-label', 'First option');
642
+ });
643
+ });
579
644
  });
@@ -111,6 +111,13 @@ export interface RadioListProps extends Omit<
111
111
  * @default false
112
112
  */
113
113
  isDisabled?: boolean;
114
+
115
+ /**
116
+ * The HTML name attribute shared by the radio inputs in the group.
117
+ * Useful for form submissions; when omitted, a unique internal name is
118
+ * generated so the group still roves correctly.
119
+ */
120
+ htmlName?: string;
114
121
  /**
115
122
  * Explains why the radio group is disabled. Applies to the whole-group
116
123
  * disabled state (`isDisabled`), not individual items. When set together with
@@ -199,9 +206,11 @@ export function RadioList({
199
206
  className,
200
207
  style,
201
208
  'data-testid': dataTestId,
209
+ htmlName,
202
210
  children,
203
211
  }: RadioListProps) {
204
- const name = useId();
212
+ const autoName = useId();
213
+ const name = htmlName ?? autoName;
205
214
  const inputID = useId();
206
215
  const labelID = useId();
207
216
  const descriptionID = useId();
@@ -220,7 +220,10 @@ export function RadioListItem({
220
220
  isDisabled: isItemDisabled = false,
221
221
  startContent,
222
222
  endContent,
223
- 'data-testid': dataTestId,
223
+ xstyle,
224
+ className,
225
+ style,
226
+ ...rest
224
227
  }: RadioListItemProps) {
225
228
  const context = use(RadioListContext);
226
229
  if (!context) {
@@ -254,6 +257,10 @@ export function RadioListItem({
254
257
  checked={isChecked}
255
258
  disabled={isDisabled && !keepsFocusableForMessage}
256
259
  aria-disabled={keepsFocusableForMessage ? 'true' : undefined}
260
+ // A focusable-disabled radio is not natively disabled, so detach it
261
+ // from the form instead: it keeps its name (grouping) but is excluded
262
+ // from submission, matching a natively disabled control.
263
+ form={keepsFocusableForMessage ? '' : undefined}
257
264
  required={context.isRequired}
258
265
  onChange={() => {
259
266
  if (isDisabled) {
@@ -309,11 +316,13 @@ export function RadioListItem({
309
316
  return (
310
317
  <div
311
318
  ref={ref}
312
- data-testid={dataTestId}
313
319
  {...mergeProps(
314
320
  themeProps('radio-list-item'),
315
- stylex.props(styles.container, !isDisabled && radioScope),
316
- )}>
321
+ stylex.props(styles.container, !isDisabled && radioScope, xstyle),
322
+ className,
323
+ style,
324
+ )}
325
+ {...rest}>
317
326
  <Item
318
327
  startContent={mediaContent}
319
328
  label={