@astryxdesign/core 0.4.7 → 0.5.0-canary.32a62fd

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 (554) hide show
  1. package/CHANGELOG.md +161 -1
  2. package/dist/AppShell/AppShell.d.ts.map +1 -1
  3. package/dist/AppShell/AppShell.js +3 -2
  4. package/dist/AspectRatio/AspectRatio.d.ts +24 -0
  5. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  6. package/dist/AspectRatio/AspectRatio.js +23 -4
  7. package/dist/Avatar/Avatar.d.ts +25 -1
  8. package/dist/Avatar/Avatar.d.ts.map +1 -1
  9. package/dist/Avatar/Avatar.js +58 -19
  10. package/dist/Avatar/index.d.ts +2 -2
  11. package/dist/Avatar/index.d.ts.map +1 -1
  12. package/dist/Avatar/index.js +1 -1
  13. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  14. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  15. package/dist/AvatarGroup/AvatarGroup.js +8 -4
  16. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  17. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  19. package/dist/AvatarGroup/AvatarGroupOverflow.js +10 -6
  20. package/dist/Banner/Banner.d.ts +40 -15
  21. package/dist/Banner/Banner.d.ts.map +1 -1
  22. package/dist/Banner/Banner.js +51 -18
  23. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  24. package/dist/BottomSheet/BottomSheet.js +17 -4
  25. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  26. package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
  27. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  28. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
  29. package/dist/Button/Button.d.ts.map +1 -1
  30. package/dist/Button/Button.js +5 -4
  31. package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
  32. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  33. package/dist/ButtonGroup/ButtonGroup.js +26 -7
  34. package/dist/Calendar/Calendar.d.ts +3 -1
  35. package/dist/Calendar/Calendar.d.ts.map +1 -1
  36. package/dist/Calendar/Calendar.js +13 -14
  37. package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
  38. package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
  39. package/dist/Calendar/getInitialFocusDate.js +62 -0
  40. package/dist/Carousel/Carousel.d.ts.map +1 -1
  41. package/dist/Carousel/Carousel.js +3 -3
  42. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  43. package/dist/Chat/ChatComposerInput.js +2 -3
  44. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  45. package/dist/Chat/ChatLayout.js +3 -3
  46. package/dist/Chat/ChatMessageList.d.ts +22 -3
  47. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  48. package/dist/Chat/ChatMessageList.js +6 -3
  49. package/dist/Chat/ChatTokenizedText.d.ts +2 -0
  50. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  51. package/dist/Chat/ChatTokenizedText.js +11 -6
  52. package/dist/Chat/useChatComposerTokens.js +1 -1
  53. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  54. package/dist/CheckboxInput/CheckboxInput.js +10 -3
  55. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  56. package/dist/ClickableCard/ClickableCard.js +3 -3
  57. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  58. package/dist/CodeBlock/CodeBlock.js +15 -4
  59. package/dist/CodeBlock/highlightRanges.js +1 -1
  60. package/dist/CodeBlock/highlightStyles.js +13 -13
  61. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  62. package/dist/CommandPalette/CommandPaletteInput.js +3 -2
  63. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  64. package/dist/CommandPalette/CommandPaletteItem.js +3 -2
  65. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  66. package/dist/ContextMenu/ContextMenu.js +4 -3
  67. package/dist/DateInput/DateInput.d.ts +43 -0
  68. package/dist/DateInput/DateInput.d.ts.map +1 -1
  69. package/dist/DateInput/DateInput.js +22 -2
  70. package/dist/DateInput/NativeDateField.d.ts +10 -0
  71. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  72. package/dist/DateInput/NativeDateField.js +477 -0
  73. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  74. package/dist/DateInput/TouchDateField.js +38 -4
  75. package/dist/DateInput/index.d.ts +1 -1
  76. package/dist/DateInput/index.d.ts.map +1 -1
  77. package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
  78. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  79. package/dist/DateTimeInput/DateTimeInput.js +406 -12
  80. package/dist/DateTimeInput/index.d.ts +1 -1
  81. package/dist/DateTimeInput/index.d.ts.map +1 -1
  82. package/dist/Dialog/Dialog.d.ts +7 -1
  83. package/dist/Dialog/Dialog.d.ts.map +1 -1
  84. package/dist/Dialog/Dialog.js +89 -58
  85. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  86. package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
  87. package/dist/Field/FieldLabel.d.ts.map +1 -1
  88. package/dist/Field/FieldLabel.js +9 -1
  89. package/dist/FileInput/FileInput.d.ts.map +1 -1
  90. package/dist/FileInput/FileInput.js +3 -2
  91. package/dist/Heading/Heading.d.ts.map +1 -1
  92. package/dist/Heading/Heading.js +6 -2
  93. package/dist/HoverCard/HoverCard.d.ts +6 -0
  94. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  95. package/dist/HoverCard/HoverCard.js +52 -3
  96. package/dist/HoverCard/useHoverCard.d.ts +16 -2
  97. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  98. package/dist/HoverCard/useHoverCard.js +74 -26
  99. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  100. package/dist/Indicator/CheckboxIndicator.js +6 -2
  101. package/dist/Item/Item.d.ts.map +1 -1
  102. package/dist/Item/Item.js +4 -2
  103. package/dist/Kbd/Kbd.d.ts.map +1 -1
  104. package/dist/Kbd/Kbd.js +2 -19
  105. package/dist/Layer/LayerDepthContext.d.ts +52 -0
  106. package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
  107. package/dist/Layer/LayerDepthContext.js +66 -0
  108. package/dist/Layer/index.d.ts +3 -0
  109. package/dist/Layer/index.d.ts.map +1 -1
  110. package/dist/Layer/index.js +4 -0
  111. package/dist/Layer/layerStack.d.ts +98 -0
  112. package/dist/Layer/layerStack.d.ts.map +1 -0
  113. package/dist/Layer/layerStack.js +306 -0
  114. package/dist/Layer/useLayerDismissal.d.ts +93 -0
  115. package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
  116. package/dist/Layer/useLayerDismissal.js +91 -0
  117. package/dist/Lightbox/Lightbox.d.ts +1 -0
  118. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  119. package/dist/Lightbox/Lightbox.js +103 -81
  120. package/dist/Markdown/index.d.ts +1 -1
  121. package/dist/Markdown/index.d.ts.map +1 -1
  122. package/dist/Markdown/parser.d.ts +38 -1
  123. package/dist/Markdown/parser.d.ts.map +1 -1
  124. package/dist/Markdown/parser.js +177 -29
  125. package/dist/MobileNav/MobileNav.d.ts +6 -1
  126. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  127. package/dist/MobileNav/MobileNav.js +61 -36
  128. package/dist/MultiSelector/MultiSelector.d.ts +15 -1
  129. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  130. package/dist/MultiSelector/MultiSelector.js +17 -6
  131. package/dist/MultiSelector/index.d.ts +1 -1
  132. package/dist/MultiSelector/index.d.ts.map +1 -1
  133. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  134. package/dist/NavIcon/NavIcon.js +5 -1
  135. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  136. package/dist/NavMenu/NavHeadingMenu.js +3 -2
  137. package/dist/NumberInput/NumberInput.d.ts +1 -0
  138. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  139. package/dist/NumberInput/NumberInput.js +27 -37
  140. package/dist/NumberInput/numberParser.d.ts +43 -0
  141. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  142. package/dist/NumberInput/numberParser.js +293 -0
  143. package/dist/Outline/Outline.d.ts.map +1 -1
  144. package/dist/Outline/Outline.js +3 -2
  145. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  146. package/dist/OverflowList/OverflowList.js +3 -2
  147. package/dist/Overlay/Overlay.d.ts.map +1 -1
  148. package/dist/Overlay/Overlay.js +3 -2
  149. package/dist/Popover/usePopover.d.ts.map +1 -1
  150. package/dist/Popover/usePopover.js +20 -17
  151. package/dist/PowerSearch/PowerSearch.d.ts +8 -2
  152. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  153. package/dist/PowerSearch/PowerSearch.js +19 -6
  154. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
  155. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  156. package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
  157. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
  158. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  159. package/dist/PowerSearch/PowerSearchValueEditor.js +19 -9
  160. package/dist/PowerSearch/types.d.ts +2 -0
  161. package/dist/PowerSearch/types.d.ts.map +1 -1
  162. package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
  163. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  164. package/dist/PowerSearch/usePowerSearchSource.js +14 -5
  165. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  166. package/dist/ProgressBar/ProgressBar.js +18 -5
  167. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  168. package/dist/Resizable/ResizeHandle.js +3 -2
  169. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  170. package/dist/SegmentedControl/SegmentedControl.js +3 -2
  171. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  172. package/dist/SelectableCard/SelectableCard.js +3 -3
  173. package/dist/Selector/Selector.d.ts.map +1 -1
  174. package/dist/Selector/Selector.js +5 -0
  175. package/dist/SideNav/SideNav.d.ts.map +1 -1
  176. package/dist/SideNav/SideNav.js +4 -3
  177. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  178. package/dist/SideNav/SideNavHeading.js +8 -7
  179. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  180. package/dist/SideNav/SideNavItem.js +4 -3
  181. package/dist/Slider/Slider.d.ts.map +1 -1
  182. package/dist/Slider/Slider.js +3 -3
  183. package/dist/Spinner/Spinner.d.ts +3 -3
  184. package/dist/Spinner/Spinner.d.ts.map +1 -1
  185. package/dist/Spinner/Spinner.js +130 -78
  186. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  187. package/dist/StatusDot/StatusDot.js +6 -1
  188. package/dist/Stepper/Step.d.ts +140 -0
  189. package/dist/Stepper/Step.d.ts.map +1 -0
  190. package/dist/Stepper/Step.js +1045 -0
  191. package/dist/Stepper/StepStatus.d.ts +24 -0
  192. package/dist/Stepper/StepStatus.d.ts.map +1 -0
  193. package/dist/Stepper/StepStatus.js +1 -0
  194. package/dist/Stepper/Stepper.d.ts +93 -0
  195. package/dist/Stepper/Stepper.d.ts.map +1 -0
  196. package/dist/Stepper/Stepper.js +184 -0
  197. package/dist/Stepper/StepperContext.d.ts +41 -0
  198. package/dist/Stepper/StepperContext.d.ts.map +1 -0
  199. package/dist/Stepper/StepperContext.js +34 -0
  200. package/dist/Stepper/index.d.ts +8 -0
  201. package/dist/Stepper/index.d.ts.map +1 -0
  202. package/dist/Stepper/index.js +7 -0
  203. package/dist/Stepper/stepper.stylex.d.ts +15 -0
  204. package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
  205. package/dist/Stepper/stepper.stylex.js +20 -0
  206. package/dist/Switch/Switch.d.ts.map +1 -1
  207. package/dist/Switch/Switch.js +8 -3
  208. package/dist/TabList/Tab.d.ts +15 -2
  209. package/dist/TabList/Tab.d.ts.map +1 -1
  210. package/dist/TabList/Tab.js +32 -7
  211. package/dist/TabList/TabList.d.ts +46 -7
  212. package/dist/TabList/TabList.d.ts.map +1 -1
  213. package/dist/TabList/TabList.js +353 -23
  214. package/dist/TabList/TabListContext.d.ts +11 -1
  215. package/dist/TabList/TabListContext.d.ts.map +1 -1
  216. package/dist/TabList/TabListContext.js +11 -2
  217. package/dist/TabList/TabMenu.d.ts.map +1 -1
  218. package/dist/TabList/TabMenu.js +3 -2
  219. package/dist/TabList/index.d.ts +2 -2
  220. package/dist/TabList/index.d.ts.map +1 -1
  221. package/dist/Table/BaseTable.d.ts.map +1 -1
  222. package/dist/Table/BaseTable.js +10 -2
  223. package/dist/Table/Table.d.ts.map +1 -1
  224. package/dist/Table/Table.js +3 -6
  225. package/dist/Table/TableRow.d.ts +16 -5
  226. package/dist/Table/TableRow.d.ts.map +1 -1
  227. package/dist/Table/TableRow.js +16 -5
  228. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  229. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +20 -8
  230. package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
  231. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  232. package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
  233. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  234. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  235. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  236. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
  237. package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
  238. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  239. package/dist/Table/plugins/selection/useTableSelection.js +19 -5
  240. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  241. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  242. package/dist/Table/types.d.ts +22 -4
  243. package/dist/Table/types.d.ts.map +1 -1
  244. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  245. package/dist/Table/useBaseTablePlugins.js +5 -0
  246. package/dist/Text/Text.d.ts.map +1 -1
  247. package/dist/Text/Text.js +6 -2
  248. package/dist/TextArea/TextArea.d.ts.map +1 -1
  249. package/dist/TextArea/TextArea.js +9 -3
  250. package/dist/TextInput/TextInput.d.ts.map +1 -1
  251. package/dist/TextInput/TextInput.js +3 -2
  252. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  253. package/dist/TimeInput/TimeInput.js +3 -2
  254. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  255. package/dist/Timestamp/Timestamp.js +5 -3
  256. package/dist/Token/TokenLink.d.ts.map +1 -1
  257. package/dist/Token/TokenLink.js +2 -2
  258. package/dist/Tokenizer/Tokenizer.d.ts +3 -1
  259. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  260. package/dist/Tokenizer/Tokenizer.js +2 -0
  261. package/dist/Tooltip/Tooltip.d.ts +5 -0
  262. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  263. package/dist/Tooltip/useTooltip.d.ts +5 -0
  264. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  265. package/dist/Tooltip/useTooltip.js +39 -24
  266. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  267. package/dist/TopNav/TopNavHeading.js +5 -4
  268. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  269. package/dist/TopNav/TopNavMegaMenu.js +3 -3
  270. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  271. package/dist/TopNav/TopNavMenu.js +4 -3
  272. package/dist/Typeahead/BaseTypeahead.d.ts +2 -0
  273. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  274. package/dist/Typeahead/BaseTypeahead.js +68 -29
  275. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  276. package/dist/Typeahead/Typeahead.js +3 -2
  277. package/dist/astryx.css +94 -7
  278. package/dist/hooks/index.d.ts +1 -0
  279. package/dist/hooks/index.d.ts.map +1 -1
  280. package/dist/hooks/index.js +1 -0
  281. package/dist/hooks/useFocusTrap.d.ts +7 -4
  282. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  283. package/dist/hooks/useFocusTrap.js +60 -95
  284. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  285. package/dist/hooks/useHotkeys.js +3 -18
  286. package/dist/hooks/useMergedRefs.d.ts +18 -0
  287. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  288. package/dist/hooks/useMergedRefs.js +25 -0
  289. package/dist/index.d.ts +1 -0
  290. package/dist/index.d.ts.map +1 -1
  291. package/dist/index.js +1 -0
  292. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  293. package/dist/theme/derivedVarRegistry.js +24 -4
  294. package/dist/theme/syntax/tokens.d.ts +1 -1
  295. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  296. package/dist/theme/syntax/tokens.js +5 -2
  297. package/dist/utils/groupItems.d.ts +5 -1
  298. package/dist/utils/groupItems.d.ts.map +1 -1
  299. package/dist/utils/groupItems.js +9 -9
  300. package/dist/utils/index.d.ts +1 -1
  301. package/dist/utils/index.d.ts.map +1 -1
  302. package/dist/utils/isApplePlatform.d.ts +18 -0
  303. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  304. package/dist/utils/isApplePlatform.js +37 -0
  305. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  306. package/dist/utils/sharedResizeObserver.js +10 -1
  307. package/dist/utils/timeParser.d.ts +1 -1
  308. package/dist/utils/timeParser.d.ts.map +1 -1
  309. package/dist/utils/timeParser.js +26 -12
  310. package/locales/en.json +31 -7
  311. package/locales/pseudo.json +18 -0
  312. package/package.json +8 -3
  313. package/src/AppShell/AppShell.tsx +3 -2
  314. package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
  315. package/src/AspectRatio/AspectRatio.test.tsx +57 -10
  316. package/src/AspectRatio/AspectRatio.tsx +40 -1
  317. package/src/Avatar/Avatar.doc.mjs +14 -3
  318. package/src/Avatar/Avatar.test.tsx +97 -0
  319. package/src/Avatar/Avatar.tsx +125 -52
  320. package/src/Avatar/index.ts +2 -2
  321. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  322. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  323. package/src/AvatarGroup/AvatarGroup.tsx +15 -6
  324. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  325. package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
  326. package/src/Banner/Banner.doc.mjs +13 -11
  327. package/src/Banner/Banner.test.tsx +102 -15
  328. package/src/Banner/Banner.tsx +72 -25
  329. package/src/BottomSheet/BottomSheet.test.tsx +123 -0
  330. package/src/BottomSheet/BottomSheet.tsx +17 -4
  331. package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
  332. package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
  333. package/src/Button/Button.doc.mjs +22 -0
  334. package/src/Button/Button.test.tsx +13 -0
  335. package/src/Button/Button.tsx +5 -4
  336. package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
  337. package/src/ButtonGroup/ButtonGroup.test.tsx +391 -1
  338. package/src/ButtonGroup/ButtonGroup.tsx +23 -5
  339. package/src/Calendar/Calendar.doc.mjs +4 -3
  340. package/src/Calendar/Calendar.test.tsx +52 -0
  341. package/src/Calendar/Calendar.tsx +18 -15
  342. package/src/Calendar/getInitialFocusDate.test.ts +94 -0
  343. package/src/Calendar/getInitialFocusDate.ts +93 -0
  344. package/src/Carousel/Carousel.tsx +3 -2
  345. package/src/Chat/ChatComposerInput.tsx +5 -1
  346. package/src/Chat/ChatLayout.tsx +3 -2
  347. package/src/Chat/ChatMessageList.doc.mjs +9 -1
  348. package/src/Chat/ChatMessageList.test.tsx +46 -0
  349. package/src/Chat/ChatMessageList.tsx +28 -4
  350. package/src/Chat/ChatTokenizedText.tsx +17 -10
  351. package/src/Chat/useChatComposerTokens.ts +1 -1
  352. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  353. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  354. package/src/CheckboxInput/CheckboxInput.tsx +8 -2
  355. package/src/ClickableCard/ClickableCard.tsx +3 -2
  356. package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
  357. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  358. package/src/CodeBlock/CodeBlock.tsx +20 -4
  359. package/src/CodeBlock/highlightRanges.ts +1 -1
  360. package/src/CodeBlock/highlightStyles.ts +13 -13
  361. package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
  362. package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
  363. package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
  364. package/src/ContextMenu/ContextMenu.tsx +4 -3
  365. package/src/DateInput/DateInput.doc.mjs +16 -0
  366. package/src/DateInput/DateInput.tsx +55 -2
  367. package/src/DateInput/DateInputTouch.test.tsx +68 -9
  368. package/src/DateInput/NativeDateField.test.tsx +565 -0
  369. package/src/DateInput/NativeDateField.tsx +623 -0
  370. package/src/DateInput/TouchDateField.tsx +38 -4
  371. package/src/DateInput/index.ts +1 -0
  372. package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
  373. package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
  374. package/src/DateTimeInput/DateTimeInput.tsx +556 -24
  375. package/src/DateTimeInput/index.ts +1 -0
  376. package/src/Dialog/Dialog.doc.mjs +8 -3
  377. package/src/Dialog/Dialog.test.tsx +261 -1
  378. package/src/Dialog/Dialog.tsx +109 -58
  379. package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
  380. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
  381. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
  382. package/src/Field/Field.doc.mjs +13 -2
  383. package/src/Field/FieldLabel.test.tsx +29 -0
  384. package/src/Field/FieldLabel.tsx +7 -0
  385. package/src/FileInput/FileInput.tsx +3 -2
  386. package/src/Heading/Heading.test.tsx +23 -1
  387. package/src/Heading/Heading.tsx +6 -2
  388. package/src/HoverCard/HoverCard.doc.mjs +13 -2
  389. package/src/HoverCard/HoverCard.test.tsx +101 -4
  390. package/src/HoverCard/HoverCard.tsx +71 -3
  391. package/src/HoverCard/useHoverCard.tsx +101 -33
  392. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  393. package/src/Indicator/Indicator.doc.mjs +2 -0
  394. package/src/Item/Item.tsx +5 -4
  395. package/src/Kbd/Kbd.tsx +2 -19
  396. package/src/Layer/LayerDepthContext.tsx +62 -0
  397. package/src/Layer/index.ts +9 -0
  398. package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
  399. package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
  400. package/src/Layer/layerStack.ts +362 -0
  401. package/src/Layer/useLayerDismissal.test.tsx +469 -0
  402. package/src/Layer/useLayerDismissal.ts +173 -0
  403. package/src/Layout/Layout.doc.mjs +2 -2
  404. package/src/Lightbox/Lightbox.doc.mjs +12 -0
  405. package/src/Lightbox/Lightbox.tsx +124 -102
  406. package/src/Link/Link.doc.mjs +39 -0
  407. package/src/Markdown/Markdown.doc.mjs +5 -0
  408. package/src/Markdown/incremental.test.ts +16 -2
  409. package/src/Markdown/index.ts +1 -0
  410. package/src/Markdown/parser.perf.test.ts +96 -1
  411. package/src/Markdown/parser.test.ts +145 -2
  412. package/src/Markdown/parser.ts +244 -29
  413. package/src/MobileNav/MobileNav.tsx +62 -36
  414. package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
  415. package/src/MultiSelector/MultiSelector.doc.mjs +27 -0
  416. package/src/MultiSelector/MultiSelector.test.tsx +106 -0
  417. package/src/MultiSelector/MultiSelector.tsx +50 -6
  418. package/src/MultiSelector/index.ts +1 -0
  419. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  420. package/src/NavIcon/NavIcon.test.tsx +9 -0
  421. package/src/NavIcon/NavIcon.tsx +5 -1
  422. package/src/NavMenu/NavHeadingMenu.tsx +3 -2
  423. package/src/NumberInput/NumberInput.doc.mjs +20 -0
  424. package/src/NumberInput/NumberInput.tsx +28 -29
  425. package/src/NumberInput/numberParser.test.ts +137 -0
  426. package/src/NumberInput/numberParser.ts +346 -0
  427. package/src/Outline/Outline.tsx +3 -2
  428. package/src/OverflowList/OverflowList.tsx +3 -2
  429. package/src/Overlay/Overlay.tsx +3 -2
  430. package/src/Popover/usePopover.tsx +31 -28
  431. package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
  432. package/src/PowerSearch/PowerSearch.test.tsx +240 -1
  433. package/src/PowerSearch/PowerSearch.tsx +34 -5
  434. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +201 -0
  435. package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
  436. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +47 -1
  437. package/src/PowerSearch/PowerSearchValueEditor.tsx +15 -0
  438. package/src/PowerSearch/types.ts +2 -0
  439. package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
  440. package/src/PowerSearch/usePowerSearchSource.ts +13 -3
  441. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  442. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  443. package/src/ProgressBar/ProgressBar.tsx +28 -8
  444. package/src/Resizable/ResizeHandle.tsx +3 -2
  445. package/src/SegmentedControl/SegmentedControl.tsx +3 -2
  446. package/src/SelectableCard/SelectableCard.tsx +3 -2
  447. package/src/Selector/Selector.doc.mjs +12 -1
  448. package/src/Selector/Selector.test.tsx +45 -1
  449. package/src/Selector/Selector.tsx +11 -1
  450. package/src/SideNav/SideNav.doc.mjs +6 -6
  451. package/src/SideNav/SideNav.tsx +4 -2
  452. package/src/SideNav/SideNavHeading.tsx +12 -12
  453. package/src/SideNav/SideNavItem.tsx +4 -2
  454. package/src/Slider/Slider.tsx +3 -2
  455. package/src/Spinner/Spinner.test.tsx +147 -1
  456. package/src/Spinner/Spinner.tsx +120 -101
  457. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  458. package/src/StatusDot/StatusDot.test.tsx +9 -0
  459. package/src/StatusDot/StatusDot.tsx +7 -1
  460. package/src/Stepper/Step.doc.mjs +98 -0
  461. package/src/Stepper/Step.tsx +1638 -0
  462. package/src/Stepper/StepStatus.ts +26 -0
  463. package/src/Stepper/Stepper.doc.mjs +370 -0
  464. package/src/Stepper/Stepper.test.tsx +1024 -0
  465. package/src/Stepper/Stepper.tsx +258 -0
  466. package/src/Stepper/StepperContext.ts +71 -0
  467. package/src/Stepper/index.ts +18 -0
  468. package/src/Stepper/stepper.stylex.ts +19 -0
  469. package/src/Switch/Switch.doc.mjs +2 -0
  470. package/src/Switch/Switch.test.tsx +10 -0
  471. package/src/Switch/Switch.tsx +6 -2
  472. package/src/TabList/Tab.doc.mjs +13 -1
  473. package/src/TabList/Tab.tsx +67 -7
  474. package/src/TabList/TabList.doc.mjs +22 -6
  475. package/src/TabList/TabList.test.tsx +559 -0
  476. package/src/TabList/TabList.tsx +490 -22
  477. package/src/TabList/TabListContext.ts +13 -2
  478. package/src/TabList/TabMenu.tsx +3 -2
  479. package/src/TabList/index.ts +6 -2
  480. package/src/Table/BaseTable.tsx +12 -4
  481. package/src/Table/Table.doc.mjs +9 -2
  482. package/src/Table/Table.test.tsx +132 -14
  483. package/src/Table/Table.tsx +3 -8
  484. package/src/Table/TableBody.doc.mjs +40 -0
  485. package/src/Table/TableFooter.doc.mjs +40 -0
  486. package/src/Table/TableHeader.doc.mjs +40 -0
  487. package/src/Table/TableRow.tsx +16 -5
  488. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
  489. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
  490. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +17 -8
  491. package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
  492. package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
  493. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
  494. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
  495. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
  496. package/src/Table/plugins/selection/useTableSelection.test.tsx +76 -0
  497. package/src/Table/plugins/selection/useTableSelection.tsx +40 -7
  498. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  499. package/src/Table/types.ts +22 -4
  500. package/src/Table/useBaseTablePlugins.ts +5 -0
  501. package/src/Table/useTableGroupedRows.doc.mjs +5 -4
  502. package/src/Table/useTablePagination.doc.mjs +7 -0
  503. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  504. package/src/Table/useTableSelection.doc.mjs +31 -0
  505. package/src/Text/Text.test.tsx +23 -1
  506. package/src/Text/Text.tsx +6 -2
  507. package/src/TextArea/TextArea.doc.mjs +8 -2
  508. package/src/TextArea/TextArea.test.tsx +11 -0
  509. package/src/TextArea/TextArea.tsx +15 -8
  510. package/src/TextInput/TextInput.doc.mjs +10 -0
  511. package/src/TextInput/TextInput.tsx +3 -2
  512. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  513. package/src/TimeInput/TimeInput.tsx +2 -2
  514. package/src/Timestamp/Timestamp.tsx +4 -2
  515. package/src/Toast/Toast.doc.mjs +6 -0
  516. package/src/Token/TokenLink.tsx +2 -2
  517. package/src/Tokenizer/Tokenizer.doc.mjs +27 -0
  518. package/src/Tokenizer/Tokenizer.tsx +4 -0
  519. package/src/Toolbar/Toolbar.doc.mjs +5 -0
  520. package/src/Tooltip/Tooltip.doc.mjs +5 -0
  521. package/src/Tooltip/Tooltip.test.tsx +32 -0
  522. package/src/Tooltip/Tooltip.tsx +5 -0
  523. package/src/Tooltip/useTooltip.tsx +47 -24
  524. package/src/TopNav/TopNavHeading.tsx +5 -4
  525. package/src/TopNav/TopNavMegaMenu.tsx +3 -2
  526. package/src/TopNav/TopNavMenu.tsx +4 -3
  527. package/src/Typeahead/BaseTypeahead.doc.mjs +11 -0
  528. package/src/Typeahead/BaseTypeahead.tsx +85 -33
  529. package/src/Typeahead/Typeahead.doc.mjs +5 -0
  530. package/src/Typeahead/Typeahead.test.tsx +49 -0
  531. package/src/Typeahead/Typeahead.tsx +3 -2
  532. package/src/hooks/index.ts +2 -0
  533. package/src/hooks/useContainerReveal.doc.mjs +2 -2
  534. package/src/hooks/useFocusTrap.test.tsx +14 -0
  535. package/src/hooks/useFocusTrap.ts +62 -111
  536. package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
  537. package/src/hooks/useHotkeys.ts +3 -18
  538. package/src/hooks/useMergedRefs.doc.mjs +79 -0
  539. package/src/hooks/useMergedRefs.test.tsx +62 -0
  540. package/src/hooks/useMergedRefs.ts +36 -0
  541. package/src/index.ts +1 -0
  542. package/src/theme/MediaTheme.doc.mjs +5 -5
  543. package/src/theme/derivedVarRegistry.test.ts +19 -3
  544. package/src/theme/derivedVarRegistry.ts +23 -4
  545. package/src/theme/generateThemeRules.test.ts +37 -0
  546. package/src/theme/syntax/tokens.ts +5 -2
  547. package/src/utils/groupItems.ts +12 -6
  548. package/src/utils/index.ts +1 -1
  549. package/src/utils/isApplePlatform.test.ts +61 -0
  550. package/src/utils/isApplePlatform.ts +37 -0
  551. package/src/utils/sharedResizeObserver.ts +10 -2
  552. package/src/utils/timeParser.test.ts +6 -1
  553. package/src/utils/timeParser.ts +35 -13
  554. package/src/__tests__/inputWidthContract.test.tsx +0 -69
@@ -77,12 +77,30 @@ export const docs = {
77
77
  ],
78
78
  theming: {
79
79
  targets: [
80
- {className: 'astryx-progressbar', visualProps: ['variant']},
81
- {className: 'astryx-progressbar-fill', visualProps: ['variant']},
82
- {className: 'astryx-progressbar-track'},
80
+ {className: 'astryx-progress-bar', visualProps: ['variant']},
81
+ {className: 'astryx-progress-bar-fill', visualProps: ['variant']},
82
+ {className: 'astryx-progress-bar-track'},
83
+ {
84
+ className: 'astryx-progress-bar-mark',
85
+ visualProps: ['variant', 'placement'],
86
+ },
87
+ // Still emitted beside the names above, so themes written against
88
+ // them keep working. Drop in the next major.
89
+ {
90
+ className: 'astryx-progressbar',
91
+ visualProps: ['variant'],
92
+ deprecatedFor: 'progress-bar',
93
+ },
94
+ {
95
+ className: 'astryx-progressbar-fill',
96
+ visualProps: ['variant'],
97
+ deprecatedFor: 'progress-bar-fill',
98
+ },
99
+ {className: 'astryx-progressbar-track', deprecatedFor: 'progress-bar-track'},
83
100
  {
84
101
  className: 'astryx-progressbar-mark',
85
102
  visualProps: ['variant', 'placement'],
103
+ deprecatedFor: 'progress-bar-mark',
86
104
  },
87
105
  ],
88
106
  vars: [
@@ -182,12 +200,30 @@ export const docsZh = {
182
200
  ],
183
201
  theming: {
184
202
  targets: [
185
- {className: 'astryx-progressbar', visualProps: ['variant']},
186
- {className: 'astryx-progressbar-fill', visualProps: ['variant']},
187
- {className: 'astryx-progressbar-track'},
203
+ {className: 'astryx-progress-bar', visualProps: ['variant']},
204
+ {className: 'astryx-progress-bar-fill', visualProps: ['variant']},
205
+ {className: 'astryx-progress-bar-track'},
206
+ {
207
+ className: 'astryx-progress-bar-mark',
208
+ visualProps: ['variant', 'placement'],
209
+ },
210
+ // Still emitted beside the names above, so themes written against
211
+ // them keep working. Drop in the next major.
212
+ {
213
+ className: 'astryx-progressbar',
214
+ visualProps: ['variant'],
215
+ deprecatedFor: 'progress-bar',
216
+ },
217
+ {
218
+ className: 'astryx-progressbar-fill',
219
+ visualProps: ['variant'],
220
+ deprecatedFor: 'progress-bar-fill',
221
+ },
222
+ {className: 'astryx-progressbar-track', deprecatedFor: 'progress-bar-track'},
188
223
  {
189
224
  className: 'astryx-progressbar-mark',
190
225
  visualProps: ['variant', 'placement'],
226
+ deprecatedFor: 'progress-bar-mark',
191
227
  },
192
228
  ],
193
229
  vars: [
@@ -839,3 +839,27 @@ describe('ProgressBar', () => {
839
839
  });
840
840
  });
841
841
  });
842
+
843
+ describe('ProgressBar theme target names', () => {
844
+ it('renders the deprecated classes beside the current ones', () => {
845
+ const {container} = render(
846
+ <ProgressBar
847
+ value={50}
848
+ label="Progress"
849
+ marks={[{value: 80, label: 'M'}]}
850
+ />,
851
+ );
852
+ expect(container.querySelector('.astryx-progress-bar')).toHaveClass(
853
+ 'astryx-progressbar',
854
+ );
855
+ expect(container.querySelector('.astryx-progress-bar-track')).toHaveClass(
856
+ 'astryx-progressbar-track',
857
+ );
858
+ expect(container.querySelector('.astryx-progress-bar-fill')).toHaveClass(
859
+ 'astryx-progressbar-fill',
860
+ );
861
+ expect(container.querySelector('.astryx-progress-bar-mark')).toHaveClass(
862
+ 'astryx-progressbar-mark',
863
+ );
864
+ });
865
+ });
@@ -479,7 +479,13 @@ export function ProgressBar({
479
479
  <div
480
480
  ref={ref}
481
481
  {...mergeProps(
482
- themeProps('progressbar', {variant}),
482
+ themeProps(
483
+ 'progress-bar',
484
+ {variant},
485
+ // `progressbar` ran the compound name together; themes styling it
486
+ // keep working until the next major.
487
+ {legacyNames: ['progressbar']},
488
+ ),
483
489
  stylex.props(styles.container, xstyle),
484
490
  className,
485
491
  style,
@@ -524,13 +530,19 @@ export function ProgressBar({
524
530
  aria-labelledby={labelId}
525
531
  aria-valuetext={isIndeterminate ? undefined : valueText}
526
532
  {...mergeProps(
527
- themeProps('progressbar-track'),
533
+ themeProps('progress-bar-track', undefined, {
534
+ legacyNames: ['progressbar-track'],
535
+ }),
528
536
  stylex.props(styles.track, isIndeterminate && styles.trackClipped),
529
537
  )}>
530
538
  {isIndeterminate ? (
531
539
  <div
532
540
  {...mergeProps(
533
- themeProps('progressbar-fill', {variant: fillVariant}),
541
+ themeProps(
542
+ 'progress-bar-fill',
543
+ {variant: fillVariant},
544
+ {legacyNames: ['progressbar-fill']},
545
+ ),
534
546
  stylex.props(
535
547
  styles.indeterminateFill,
536
548
  variantStyles[fillVariant],
@@ -540,7 +552,11 @@ export function ProgressBar({
540
552
  ) : (
541
553
  <div
542
554
  {...mergeProps(
543
- themeProps('progressbar-fill', {variant: fillVariant}),
555
+ themeProps(
556
+ 'progress-bar-fill',
557
+ {variant: fillVariant},
558
+ {legacyNames: ['progressbar-fill']},
559
+ ),
544
560
  stylex.props(styles.fill, variantStyles[fillVariant]),
545
561
  )}
546
562
  style={{width: `${percentage}%`}}
@@ -569,10 +585,14 @@ export function ProgressBar({
569
585
  <span
570
586
  tabIndex={0}
571
587
  {...mergeProps(
572
- themeProps('progressbar-mark', {
573
- variant: fillVariant,
574
- placement: mark.isOnFill ? 'fill' : 'track',
575
- }),
588
+ themeProps(
589
+ 'progress-bar-mark',
590
+ {
591
+ variant: fillVariant,
592
+ placement: mark.isOnFill ? 'fill' : 'track',
593
+ },
594
+ {legacyNames: ['progressbar-mark']},
595
+ ),
576
596
  stylex.props(
577
597
  focusOutlineStyles.focusVisible,
578
598
  styles.mark,
@@ -35,11 +35,12 @@ import {
35
35
  spacingVars,
36
36
  } from '../theme/tokens.stylex';
37
37
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
38
- import {mergeProps, mergeRefs, rtlStyles} from '../utils';
38
+ import {mergeProps, rtlStyles} from '../utils';
39
39
  import type {ResizableProps} from './useResizable';
40
40
  import {themeProps} from '../utils/themeProps';
41
41
  import {useTranslator} from '../i18n';
42
42
 
43
+ import {useMergedRefs} from '../hooks/useMergedRefs';
43
44
  const KEYBOARD_STEP = 10;
44
45
  const KEYBOARD_LARGE_STEP = 50;
45
46
 
@@ -549,7 +550,7 @@ export function ResizeHandle({
549
550
 
550
551
  return (
551
552
  <div
552
- ref={mergeRefs(ref, handleRef)}
553
+ ref={useMergedRefs(ref, handleRef)}
553
554
  role="separator"
554
555
  aria-orientation={isHorizontal ? 'vertical' : 'horizontal'}
555
556
  aria-valuenow={ariaValueNow}
@@ -26,11 +26,12 @@ import type {
26
26
  SegmentedControlSize,
27
27
  SegmentedControlLayout,
28
28
  } from './SegmentedControlContext';
29
- import {mergeProps, mergeRefs, composeEventHandlers} from '../utils';
29
+ import {mergeProps, composeEventHandlers} from '../utils';
30
30
  import {useSize} from '../SizeContext/SizeContext';
31
31
  import type {BaseProps} from '../BaseProps';
32
32
  import {themeProps} from '../utils/themeProps';
33
33
 
34
+ import {useMergedRefs} from '../hooks/useMergedRefs';
34
35
  export interface SegmentedControlProps extends Omit<
35
36
  BaseProps<HTMLDivElement>,
36
37
  'onChange'
@@ -258,7 +259,7 @@ export function SegmentedControl({
258
259
  return (
259
260
  <SegmentedControlContext value={contextValue}>
260
261
  <div
261
- ref={mergeRefs(ref, listRef, disabledMessageTooltip.ref)}
262
+ ref={useMergedRefs(ref, listRef, disabledMessageTooltip.ref)}
262
263
  {...rest}
263
264
  role="radiogroup"
264
265
  aria-label={label}
@@ -40,7 +40,7 @@ import * as stylex from '@stylexjs/stylex';
40
40
  import type {StyleXStyles} from '@stylexjs/stylex';
41
41
  import {colorVars, durationVars, easeVars} from '../theme/tokens.stylex';
42
42
  import type {Elevation, SizeValue, SpacingStep} from '../utils/types';
43
- import {mergeProps, mergeRefs} from '../utils';
43
+ import {mergeProps} from '../utils';
44
44
  import {Card} from '../Card/Card';
45
45
  import type {CardVariant} from '../Card/Card';
46
46
  import {useClickableContainer} from '../hooks/useClickableContainer';
@@ -48,6 +48,7 @@ import type {BaseProps} from '../BaseProps';
48
48
  import {themeProps} from '../utils/themeProps';
49
49
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
50
50
 
51
+ import {useMergedRefs} from '../hooks/useMergedRefs';
51
52
  // =============================================================================
52
53
  // Styles — selection + interaction; Card handles the rest
53
54
  // =============================================================================
@@ -346,7 +347,7 @@ export function SelectableCard({
346
347
 
347
348
  return (
348
349
  <Card
349
- ref={mergeRefs(ref, containerRef)}
350
+ ref={useMergedRefs(ref, containerRef)}
350
351
  width={width}
351
352
  height={height}
352
353
  maxWidth={maxWidth}
@@ -171,7 +171,7 @@ export const docs = {
171
171
  name: 'renderValue',
172
172
  type: '(option: SelectorOptionData) => ReactNode',
173
173
  description:
174
- 'Custom render function for the selected option inside the closed trigger. The trigger is sized by padding, so it is the size token for a one-line value (28/32/36) and exactly one text line taller for a two-line one (48/52/56) — always on the 4px rhythm, always aligned with the buttons and inputs beside it. Inside an InputGroup the group owns the row height: a SelectorOption folds onto one line and ellipsizes, and any taller node is cut off at the row.',
174
+ 'Custom render function for the selected option inside the closed trigger. The trigger is sized by padding, so it is the size token for a one-line value (28/32/36) and exactly one text line taller for a two-line one (48/52/56), always on the 4px rhythm, always aligned with the buttons and inputs beside it. Inside an InputGroup the group owns the row height: a SelectorOption folds onto one line and ellipsizes, and any taller node is cut off at the row.',
175
175
  },
176
176
  {
177
177
  name: 'indicatorPosition',
@@ -186,6 +186,17 @@ export const docs = {
186
186
  description:
187
187
  'Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.',
188
188
  },
189
+ {
190
+ name: 'startIcon',
191
+ type: 'IconType | ReactNode',
192
+ description: 'Icon displayed at the start of the selector trigger.',
193
+ },
194
+ {
195
+ name: 'isLoading',
196
+ type: 'boolean',
197
+ description: 'Shows a loading spinner in the trigger.',
198
+ default: 'false',
199
+ },
189
200
  {
190
201
  name: 'xstyle',
191
202
  type: 'StyleXStyles',
@@ -961,7 +961,7 @@ describe('Selector', () => {
961
961
  expect(onChange).toHaveBeenCalledWith('Banana');
962
962
  });
963
963
 
964
- it('closes dropdown on Tab without preventing default focus movement', async () => {
964
+ it('closes the search dropdown on Tab without preventing default focus movement', async () => {
965
965
  const user = userEvent.setup();
966
966
  render(
967
967
  <>
@@ -1253,6 +1253,29 @@ describe('Selector', () => {
1253
1253
  });
1254
1254
 
1255
1255
  describe('keyboard accessibility', () => {
1256
+ it('Tab from the open listbox moves focus to the next control', async () => {
1257
+ const user = userEvent.setup();
1258
+ render(
1259
+ <>
1260
+ <Selector
1261
+ label="Fruit"
1262
+ options={OPTIONS}
1263
+ value="Apple"
1264
+ onChange={() => {}}
1265
+ />
1266
+ <button type="button">Next</button>
1267
+ </>,
1268
+ );
1269
+
1270
+ const trigger = screen.getByRole('combobox');
1271
+ await user.click(trigger);
1272
+ expect(trigger).toHaveAttribute('aria-expanded', 'true');
1273
+
1274
+ await user.keyboard('{Tab}');
1275
+ expect(trigger).toHaveAttribute('aria-expanded', 'false');
1276
+ expect(screen.getByRole('button', {name: 'Next'})).toHaveFocus();
1277
+ });
1278
+
1256
1279
  it('trigger is focusable via Tab when enabled', async () => {
1257
1280
  const user = userEvent.setup();
1258
1281
  render(<Selector label="Fruit" options={OPTIONS} />);
@@ -2484,6 +2507,27 @@ describe('Selector section headings', () => {
2484
2507
  // visible heading must not announce it a second time.
2485
2508
  expect(heading).toHaveAttribute('aria-hidden', 'true');
2486
2509
  });
2510
+
2511
+ it('hides a standalone divider from the accessibility tree (#4994)', async () => {
2512
+ const user = userEvent.setup();
2513
+ render(
2514
+ <Selector
2515
+ label="Fruit"
2516
+ options={['Apple', {type: 'divider'}, 'Banana']}
2517
+ value={undefined}
2518
+ onChange={() => {}}
2519
+ />,
2520
+ );
2521
+ await user.click(screen.getByRole('combobox'));
2522
+
2523
+ // role="listbox" only permits option/group children. The divider still
2524
+ // renders role="separator" (unchanged visual/DOM), but must be excluded
2525
+ // from the accessibility tree so it never reaches the listbox's exposed
2526
+ // children (axe aria-required-children).
2527
+ const divider = document.querySelector('[role="separator"]');
2528
+ expect(divider).toBeTruthy();
2529
+ expect(divider).toHaveAttribute('aria-hidden', 'true');
2530
+ });
2487
2531
  });
2488
2532
 
2489
2533
  describe('Selector search focus ring', () => {
@@ -1344,7 +1344,17 @@ export function Selector<T extends SelectorOptionType>(
1344
1344
  if (isSearching) {
1345
1345
  continue;
1346
1346
  }
1347
- elements.push(<Divider key={`divider-${i}`} xstyle={styles.divider} />);
1347
+ // role="listbox" only permits option/group children; the divider
1348
+ // carries no information the options don't, so it's hidden from the
1349
+ // accessibility tree entirely rather than exposing role="separator"
1350
+ // as a disallowed listbox child (axe aria-required-children).
1351
+ elements.push(
1352
+ <Divider
1353
+ key={`divider-${i}`}
1354
+ aria-hidden="true"
1355
+ xstyle={styles.divider}
1356
+ />,
1357
+ );
1348
1358
  } else if (isSection(option)) {
1349
1359
  const sectionItems: ReactNode[] = [];
1350
1360
  for (const opt of option.options) {
@@ -131,8 +131,8 @@ export const docs = {
131
131
  bestPractices: [
132
132
  {guidance: true, description: 'Use sections to group related navigation items and help users scan for their destination.'},
133
133
  {guidance: true, description: 'Pair outline and filled icon variants so the selected state is visually distinct.'},
134
- {guidance: true, description: 'Mark the current page with isSelected — it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
135
- {guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short — they are the accessible name in both expanded and icon-only modes.'},
134
+ {guidance: true, description: 'Mark the current page with isSelected: it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
135
+ {guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short; they are the accessible name in both expanded and icon-only modes.'},
136
136
  {guidance: true, description: 'While the nav is collapsed, an item with children shows them in a submenu flyout. On a device that can hover, pointing at the item opens it after a short delay and moving away closes it; a flyout opened by clicking stays open until it is dismissed. On touch, it opens on tap. Do not put an action in there that has no other route to it.'},
137
137
  {guidance: false, description: 'Include a SideNavHeading when a TopNav is already providing app identity; this duplicates branding.'},
138
138
  {guidance: false, description: 'Use for filtering content; use tabs or filter buttons instead.'},
@@ -153,8 +153,8 @@ export const docsZh = {
153
153
  bestPractices: [
154
154
  {guidance: true, description: 'Use sections to group related navigation items and help users scan for their destination.'},
155
155
  {guidance: true, description: 'Pair outline and filled icon variants so the selected state is visually distinct.'},
156
- {guidance: true, description: 'Mark the current page with isSelected — it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
157
- {guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short — they are the accessible name in both expanded and icon-only modes.'},
156
+ {guidance: true, description: 'Mark the current page with isSelected: it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
157
+ {guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short; they are the accessible name in both expanded and icon-only modes.'},
158
158
  {guidance: true, description: 'While the nav is collapsed, an item with children shows them in a submenu flyout. On a device that can hover, pointing at the item opens it after a short delay and moving away closes it; a flyout opened by clicking stays open until it is dismissed. On touch, it opens on tap. Do not put an action in there that has no other route to it.'},
159
159
  {guidance: false, description: 'Include a SideNavHeading when a TopNav is already providing app identity; this duplicates branding.'},
160
160
  {guidance: false, description: 'Use for filtering content; use tabs or filter buttons instead.'},
@@ -175,8 +175,8 @@ export const docsDense = {
175
175
  bestPractices: [
176
176
  {guidance: true, description: 'Use sections to group related navigation items and help users scan for their destination.'},
177
177
  {guidance: true, description: 'Pair outline and filled icon variants so the selected state is visually distinct.'},
178
- {guidance: true, description: 'Mark the current page with isSelected — it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
179
- {guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short — they are the accessible name in both expanded and icon-only modes.'},
178
+ {guidance: true, description: 'Mark the current page with isSelected: it sets aria-current="page", so the current destination is announced rather than carried by color alone.'},
179
+ {guidance: true, description: 'SideNav renders a navigation landmark, and a collapsible item follows the WAI-ARIA APG Disclosure pattern (https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/): the toggle carries aria-expanded and aria-controls, and the group it owns is inert while collapsed. Keep item labels short; they are the accessible name in both expanded and icon-only modes.'},
180
180
  {guidance: true, description: 'While the nav is collapsed, an item with children shows them in a submenu flyout. On a device that can hover, pointing at the item opens it after a short delay and moving away closes it; a flyout opened by clicking stays open until it is dismissed. On touch, it opens on tap. Do not put an action in there that has no other route to it.'},
181
181
  {guidance: false, description: 'Include a SideNavHeading when a TopNav is already providing app identity; this duplicates branding.'},
182
182
  {guidance: false, description: 'Use for filtering content; use tabs or filter buttons instead.'},
@@ -32,7 +32,7 @@ import type {BaseProps} from '../BaseProps';
32
32
  import * as stylex from '@stylexjs/stylex';
33
33
  import type {StyleXStyles} from '@stylexjs/stylex';
34
34
  import {spacingVars} from '../theme/tokens.stylex';
35
- import {mergeProps, mergeRefs} from '../utils';
35
+ import {mergeProps} from '../utils';
36
36
  import {
37
37
  SideNavCollapseContext,
38
38
  type SideNavCollapseState,
@@ -49,6 +49,7 @@ import {themeProps} from '../utils/themeProps';
49
49
  import {SizeProvider} from '../SizeContext/SizeContext';
50
50
  import {useTranslator} from '../i18n';
51
51
 
52
+ import {useMergedRefs} from '../hooks/useMergedRefs';
52
53
  // =============================================================================
53
54
  // Constants
54
55
  // =============================================================================
@@ -349,6 +350,7 @@ export function SideNav({
349
350
  useState(defaultIsCollapsed);
350
351
  const collapsed = isControlled ? controlledCollapsed : uncontrolledCollapsed;
351
352
  const navRef = useRef<HTMLElement>(null);
353
+ const mergedNavRef = useMergedRefs(ref, navRef);
352
354
  const collapseStateRef = useRef<SideNavCollapseState>({
353
355
  isCollapsed: collapsed,
354
356
  toggle: () => {},
@@ -517,7 +519,7 @@ export function SideNav({
517
519
 
518
520
  const navElement = (
519
521
  <nav
520
- ref={mergeRefs(ref, navRef)}
522
+ ref={mergedNavRef}
521
523
  role="navigation"
522
524
  aria-label={t('@astryx.sideNav.label')}
523
525
  data-testid={testId}
@@ -40,7 +40,8 @@ import {focusOutlineProps} from '../utils/focusOutline.stylex';
40
40
  import {useSideNavCollapse} from './SideNavCollapseContext';
41
41
  import {useLinkComponent} from '../Link/useLinkComponent';
42
42
  import type {LinkComponentType} from '../Link/types';
43
- import {mergeProps, mergeRefs} from '../utils';
43
+ import {mergeProps} from '../utils';
44
+ import {useMergedRefs} from '../hooks/useMergedRefs';
44
45
  import type {BaseProps} from '../BaseProps';
45
46
  import {useMenuHover} from '../hooks/useMenuHover';
46
47
  import {NavHeadingCloseContext} from '../NavMenu/NavMenuContext';
@@ -59,7 +60,7 @@ const styles = stylex.create({
59
60
  minHeight: spacingVars['--spacing-8'],
60
61
  paddingInlineStart: {
61
62
  default: spacingVars['--spacing-2'],
62
- ':has(.astryx-navicon)': 0,
63
+ ':has(.astryx-nav-icon)': 0,
63
64
  },
64
65
  paddingInlineEnd: spacingVars['--spacing-2'],
65
66
  paddingBlock: 0,
@@ -211,7 +212,7 @@ const styles = stylex.create({
211
212
  minHeight: spacingVars['--spacing-8'],
212
213
  paddingInlineStart: {
213
214
  default: spacingVars['--spacing-2'],
214
- ':has(.astryx-navicon)': 0,
215
+ ':has(.astryx-nav-icon)': 0,
215
216
  },
216
217
  paddingInlineEnd: spacingVars['--spacing-2'],
217
218
  paddingBlock: 0,
@@ -399,11 +400,18 @@ export function SideNavHeading({
399
400
  // setTriggerEl belongs on the chevron button, not this root: it is the
400
401
  // focus-restore target and a <div> cannot take focus. triggerRef stays here
401
402
  // because the panel anchors to the whole heading.
402
- const setRef = mergeRefs<HTMLDivElement>(
403
+ const setRef = useMergedRefs<HTMLDivElement>(
403
404
  rootRef,
404
405
  ref,
405
406
  menu ? popover.triggerRef : undefined,
406
407
  );
408
+ const collapsedSetRef = useMergedRefs<HTMLElement>(
409
+ collapsedItemRef,
410
+ ref,
411
+ // Collapsed, this button is the trigger, so it takes both roles.
412
+ menu ? popover.triggerRef : undefined,
413
+ menu ? setTriggerEl : undefined,
414
+ );
407
415
 
408
416
  // In collapsed mode: hide if no icon, show icon-only if has icon
409
417
  if (isCollapsed && !icon) {
@@ -412,14 +420,6 @@ export function SideNavHeading({
412
420
  if (isCollapsed && icon) {
413
421
  const collapsedIcon = <span {...stylex.props(styles.icon)}>{icon}</span>;
414
422
 
415
- const collapsedSetRef = mergeRefs<HTMLElement>(
416
- collapsedItemRef,
417
- ref,
418
- // Collapsed, this button is the trigger, so it takes both roles.
419
- menu ? popover.triggerRef : undefined,
420
- menu ? setTriggerEl : undefined,
421
- );
422
-
423
423
  let collapsedElement: ReactNode;
424
424
 
425
425
  if (headingHref) {
@@ -47,7 +47,7 @@ import {useLinkComponent} from '../Link/useLinkComponent';
47
47
  import type {LinkComponentType} from '../Link/types';
48
48
  import {usePopover} from '../Popover/usePopover';
49
49
  import {useMenuHover} from '../hooks/useMenuHover';
50
- import {mergeProps, mergeRefs} from '../utils';
50
+ import {mergeProps} from '../utils';
51
51
  import type {BaseProps} from '../BaseProps';
52
52
  import {Tooltip} from '../Tooltip';
53
53
  import {navItemStyles, type NavItemSize} from '../NavItem/navItemStyles.stylex';
@@ -61,6 +61,7 @@ import {useAppShellMobile} from '../AppShell/AppShellMobileContext';
61
61
  import {themeProps} from '../utils/themeProps';
62
62
  import {useTranslator} from '../i18n';
63
63
 
64
+ import {useMergedRefs} from '../hooks/useMergedRefs';
64
65
  // =============================================================================
65
66
  // Styles
66
67
  // =============================================================================
@@ -408,6 +409,7 @@ export function SideNavItem({
408
409
  hasCloseButton: false,
409
410
  dialogLabel: t('@astryx.sideNavItem.submenuLabel', {label}),
410
411
  });
412
+ const mergedTriggerRef = useMergedRefs(ref, popover.triggerRef);
411
413
 
412
414
  // Collapse state for items with children
413
415
  const itemCollapsibleConfig = useMemo(
@@ -524,7 +526,7 @@ export function SideNavItem({
524
526
  return (
525
527
  <div {...stylex.props(styles.root, xstyle)}>
526
528
  <button
527
- ref={mergeRefs(ref, popover.triggerRef)}
529
+ ref={mergedTriggerRef}
528
530
  type="button"
529
531
  {...rest}
530
532
  {...hoverTriggerProps}
@@ -40,13 +40,14 @@ import {Tooltip} from '../Tooltip/Tooltip';
40
40
  import {useTooltip} from '../Tooltip';
41
41
  import {VisuallyHidden} from '../VisuallyHidden';
42
42
  import type {InputStatus} from '../Field/types';
43
- import {mergeProps, mergeRefs, rtlStyles} from '../utils';
43
+ import {mergeProps, rtlStyles} from '../utils';
44
44
  import {focusOutlineStyles} from '../utils/focusOutline.stylex';
45
45
  import {isRtlElement} from '../hooks/isRtlElement';
46
46
  import type {BaseProps} from '../BaseProps';
47
47
  import type {SizeValue} from '../utils/types';
48
48
  import {themeProps} from '../utils/themeProps';
49
49
 
50
+ import {useMergedRefs} from '../hooks/useMergedRefs';
50
51
  // =============================================================================
51
52
  // Types
52
53
  // =============================================================================
@@ -964,7 +965,7 @@ export function Slider({ref, ...props}: SliderProps) {
964
965
  />
965
966
  ))}
966
967
  <div
967
- ref={mergeRefs(ref, trackRef, disabledMessageTooltip.ref)}
968
+ ref={useMergedRefs(ref, trackRef, disabledMessageTooltip.ref)}
968
969
  {...(isRange
969
970
  ? {role: 'group', 'aria-labelledby': labelID}
970
971
  : undefined)}