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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (635) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +20 -18
  5. package/dist/AlertDialog/useImperativeAlertDialog.d.ts +0 -2
  6. package/dist/AlertDialog/useImperativeAlertDialog.d.ts.map +1 -1
  7. package/dist/AlertDialog/useImperativeAlertDialog.js +3 -5
  8. package/dist/AppShell/AppShell.d.ts +1 -1
  9. package/dist/AppShell/AppShell.d.ts.map +1 -1
  10. package/dist/AppShell/AppShell.js +55 -53
  11. package/dist/AspectRatio/AspectRatio.d.ts +48 -10
  12. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  13. package/dist/AspectRatio/AspectRatio.js +33 -12
  14. package/dist/AspectRatio/index.d.ts +1 -1
  15. package/dist/AspectRatio/index.d.ts.map +1 -1
  16. package/dist/Avatar/Avatar.d.ts.map +1 -1
  17. package/dist/Avatar/Avatar.js +28 -26
  18. package/dist/Avatar/AvatarStatusDot.js +6 -6
  19. package/dist/AvatarGroup/AvatarGroup.js +6 -6
  20. package/dist/AvatarGroup/AvatarGroupOverflow.js +7 -7
  21. package/dist/Badge/Badge.js +3 -3
  22. package/dist/Banner/Banner.d.ts.map +1 -1
  23. package/dist/Banner/Banner.js +32 -25
  24. package/dist/Blockquote/Blockquote.js +7 -7
  25. package/dist/Breadcrumbs/BreadcrumbItem.js +17 -17
  26. package/dist/Breadcrumbs/Breadcrumbs.js +7 -7
  27. package/dist/Button/Button.js +19 -19
  28. package/dist/ButtonGroup/ButtonGroup.js +7 -7
  29. package/dist/Calendar/Calendar.d.ts.map +1 -1
  30. package/dist/Calendar/Calendar.js +68 -48
  31. package/dist/Calendar/dayCellUtils.d.ts.map +1 -1
  32. package/dist/Calendar/styles.d.ts +2 -2
  33. package/dist/Calendar/styles.d.ts.map +1 -1
  34. package/dist/Calendar/styles.js +2 -2
  35. package/dist/Card/Card.d.ts +4 -2
  36. package/dist/Card/Card.d.ts.map +1 -1
  37. package/dist/Card/Card.js +18 -10
  38. package/dist/Carousel/Carousel.d.ts.map +1 -1
  39. package/dist/Carousel/Carousel.js +24 -21
  40. package/dist/Center/Center.js +3 -3
  41. package/dist/Chat/ChatComposer.js +23 -23
  42. package/dist/Chat/ChatComposerDrawer.js +14 -14
  43. package/dist/Chat/ChatComposerInput.d.ts +1 -1
  44. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  45. package/dist/Chat/ChatComposerInput.js +27 -15
  46. package/dist/Chat/ChatDictationButton.d.ts +1 -1
  47. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  48. package/dist/Chat/ChatDictationButton.js +13 -11
  49. package/dist/Chat/ChatLayout.js +17 -17
  50. package/dist/Chat/ChatLayoutScrollButton.d.ts +1 -1
  51. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  52. package/dist/Chat/ChatLayoutScrollButton.js +12 -10
  53. package/dist/Chat/ChatMessage.js +12 -12
  54. package/dist/Chat/ChatMessageBubble.js +7 -7
  55. package/dist/Chat/ChatMessageList.js +14 -14
  56. package/dist/Chat/ChatMessageMetadata.d.ts +1 -1
  57. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  58. package/dist/Chat/ChatMessageMetadata.js +14 -12
  59. package/dist/Chat/ChatPastedTextToken.js +13 -13
  60. package/dist/Chat/ChatSendButton.js +3 -3
  61. package/dist/Chat/ChatSystemMessage.d.ts +1 -1
  62. package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
  63. package/dist/Chat/ChatSystemMessage.js +17 -17
  64. package/dist/Chat/ChatTokenizedText.d.ts +1 -1
  65. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  66. package/dist/Chat/ChatTokenizedText.js +24 -15
  67. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  68. package/dist/Chat/ChatToolCalls.js +81 -74
  69. package/dist/Chat/index.d.ts +1 -1
  70. package/dist/Chat/index.d.ts.map +1 -1
  71. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  72. package/dist/Chat/useTriggerMenu.js +15 -15
  73. package/dist/CheckboxInput/CheckboxInput.d.ts +1 -1
  74. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  75. package/dist/CheckboxInput/CheckboxInput.js +25 -23
  76. package/dist/CheckboxList/CheckboxList.js +9 -9
  77. package/dist/CheckboxList/CheckboxListItem.d.ts +1 -1
  78. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  79. package/dist/CheckboxList/CheckboxListItem.js +8 -6
  80. package/dist/Citation/Citation.js +10 -10
  81. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  82. package/dist/ClickableCard/ClickableCard.js +32 -9
  83. package/dist/Code/Code.js +3 -3
  84. package/dist/CodeBlock/CodeBlock.d.ts +10 -1
  85. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  86. package/dist/CodeBlock/CodeBlock.js +88 -52
  87. package/dist/Collapsible/Collapsible.d.ts +9 -3
  88. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  89. package/dist/Collapsible/Collapsible.js +109 -22
  90. package/dist/Collapsible/CollapsibleGroup.d.ts +37 -7
  91. package/dist/Collapsible/CollapsibleGroup.d.ts.map +1 -1
  92. package/dist/Collapsible/CollapsibleGroup.js +64 -12
  93. package/dist/Collapsible/CollapsibleGroupContext.d.ts +24 -0
  94. package/dist/Collapsible/CollapsibleGroupContext.d.ts.map +1 -1
  95. package/dist/Collapsible/CollapsibleGroupContext.js +26 -3
  96. package/dist/Collapsible/index.d.ts +1 -0
  97. package/dist/Collapsible/index.d.ts.map +1 -1
  98. package/dist/Collapsible/useCollapsible.d.ts +4 -1
  99. package/dist/Collapsible/useCollapsible.d.ts.map +1 -1
  100. package/dist/Collapsible/useCollapsible.js +20 -6
  101. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  102. package/dist/CommandPalette/CommandPalette.js +36 -34
  103. package/dist/CommandPalette/CommandPaletteEmpty.js +3 -3
  104. package/dist/CommandPalette/CommandPaletteFooter.js +16 -16
  105. package/dist/CommandPalette/CommandPaletteGroup.js +5 -5
  106. package/dist/CommandPalette/CommandPaletteInput.js +13 -13
  107. package/dist/CommandPalette/CommandPaletteItem.js +3 -3
  108. package/dist/CommandPalette/CommandPaletteList.js +3 -3
  109. package/dist/ContextMenu/ContextMenu.d.ts +7 -2
  110. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  111. package/dist/ContextMenu/ContextMenu.js +76 -43
  112. package/dist/DateInput/DateInput.js +18 -18
  113. package/dist/DateRangeInput/DateRangeInput.js +21 -21
  114. package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
  115. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  116. package/dist/DateTimeInput/DateTimeInput.js +30 -26
  117. package/dist/DateTimeInput/index.d.ts +1 -1
  118. package/dist/DateTimeInput/index.d.ts.map +1 -1
  119. package/dist/Dialog/Dialog.js +9 -9
  120. package/dist/Dialog/DialogHeader.js +16 -16
  121. package/dist/Dialog/useImperativeDialog.js +3 -3
  122. package/dist/Divider/Divider.js +7 -7
  123. package/dist/DropdownMenu/DropdownMenu.js +10 -10
  124. package/dist/DropdownMenu/DropdownMenuItem.d.ts +2 -17
  125. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  126. package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
  127. package/dist/DropdownMenu/renderDropdownItems.js +10 -10
  128. package/dist/EmptyState/EmptyState.js +9 -9
  129. package/dist/Field/Field.js +17 -17
  130. package/dist/Field/FieldLabel.js +15 -15
  131. package/dist/Field/InputClearButton.js +5 -5
  132. package/dist/FieldStatus/FieldStatus.js +3 -3
  133. package/dist/FileInput/FileInput.js +29 -29
  134. package/dist/FormLayout/FormLayout.js +5 -5
  135. package/dist/Grid/Grid.d.ts +4 -3
  136. package/dist/Grid/Grid.d.ts.map +1 -1
  137. package/dist/Grid/Grid.js +29 -12
  138. package/dist/Grid/GridSpan.js +3 -3
  139. package/dist/HStack/HStack.js +3 -3
  140. package/dist/Heading/Heading.js +10 -10
  141. package/dist/HoverCard/HoverCard.js +9 -9
  142. package/dist/HoverCard/useHoverCard.d.ts +5 -1
  143. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  144. package/dist/HoverCard/useHoverCard.js +3 -3
  145. package/dist/Icon/Icon.d.ts.map +1 -1
  146. package/dist/Icon/Icon.js +16 -12
  147. package/dist/Icon/defaultIcons.js +116 -116
  148. package/dist/IconButton/IconButton.js +3 -3
  149. package/dist/InputGroup/InputGroup.js +11 -11
  150. package/dist/InputGroup/InputGroupText.js +3 -3
  151. package/dist/Item/Item.js +18 -18
  152. package/dist/Kbd/Kbd.js +5 -5
  153. package/dist/Layer/LayerProvider.js +7 -7
  154. package/dist/Layer/useLayer.d.ts +29 -2
  155. package/dist/Layer/useLayer.d.ts.map +1 -1
  156. package/dist/Layer/useLayer.js +44 -31
  157. package/dist/Layout/Layout.js +21 -21
  158. package/dist/Layout/LayoutContent.js +3 -3
  159. package/dist/Layout/LayoutFooter.js +5 -5
  160. package/dist/Layout/LayoutHeader.js +5 -5
  161. package/dist/Layout/LayoutPanel.js +3 -3
  162. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  163. package/dist/Lightbox/Lightbox.js +55 -31
  164. package/dist/Lightbox/useLightbox.d.ts +0 -1
  165. package/dist/Lightbox/useLightbox.d.ts.map +1 -1
  166. package/dist/Lightbox/useLightbox.js +3 -4
  167. package/dist/Link/Link.d.ts +0 -2
  168. package/dist/Link/Link.d.ts.map +1 -1
  169. package/dist/Link/Link.js +15 -17
  170. package/dist/Link/LinkProvider.js +3 -3
  171. package/dist/Link/useLinkify.js +3 -3
  172. package/dist/List/List.js +11 -11
  173. package/dist/List/ListItem.js +11 -11
  174. package/dist/Markdown/Markdown.d.ts.map +1 -1
  175. package/dist/Markdown/Markdown.js +102 -102
  176. package/dist/MetadataList/MetadataList.js +10 -10
  177. package/dist/MetadataList/MetadataListItem.js +15 -15
  178. package/dist/MobileNav/MobileNav.d.ts +1 -1
  179. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  180. package/dist/MobileNav/MobileNav.js +26 -23
  181. package/dist/MobileNav/MobileNavToggle.js +5 -5
  182. package/dist/MoreMenu/MoreMenu.js +3 -3
  183. package/dist/MultiSelector/MultiSelector.js +56 -56
  184. package/dist/NavIcon/NavIcon.js +3 -3
  185. package/dist/NavMenu/NavHeadingMenu.js +5 -5
  186. package/dist/NavMenu/NavHeadingMenuItem.js +8 -8
  187. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  188. package/dist/NumberInput/NumberInput.js +48 -32
  189. package/dist/Outline/Outline.js +15 -15
  190. package/dist/OverflowList/OverflowList.js +8 -8
  191. package/dist/Overlay/Overlay.js +3 -3
  192. package/dist/Overlay/OverlayScrim.js +5 -5
  193. package/dist/Overlay/useOverlay.d.ts +0 -3
  194. package/dist/Overlay/useOverlay.d.ts.map +1 -1
  195. package/dist/Overlay/useOverlay.js +3 -6
  196. package/dist/Pagination/Pagination.d.ts +1 -1
  197. package/dist/Pagination/Pagination.d.ts.map +1 -1
  198. package/dist/Pagination/Pagination.js +125 -72
  199. package/dist/Popover/Popover.js +16 -16
  200. package/dist/Popover/usePopover.js +7 -7
  201. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  202. package/dist/PowerSearch/PowerSearch.js +110 -92
  203. package/dist/PowerSearch/PowerSearchEditPopover.js +84 -84
  204. package/dist/PowerSearch/PowerSearchFilterEditor.js +3 -3
  205. package/dist/PowerSearch/PowerSearchToken.js +5 -5
  206. package/dist/PowerSearch/PowerSearchValueEditor.js +54 -54
  207. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  208. package/dist/ProgressBar/ProgressBar.js +25 -18
  209. package/dist/RadioList/RadioList.js +7 -7
  210. package/dist/RadioList/RadioListItem.d.ts +1 -1
  211. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  212. package/dist/RadioList/RadioListItem.js +24 -21
  213. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  214. package/dist/Resizable/ResizeHandle.js +28 -10
  215. package/dist/Section/Section.js +5 -5
  216. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  217. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  218. package/dist/SegmentedControl/SegmentedControl.js +32 -10
  219. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  220. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  221. package/dist/SegmentedControl/SegmentedControlItem.js +18 -12
  222. package/dist/SelectableCard/SelectableCard.js +5 -5
  223. package/dist/Selector/Selector.js +46 -46
  224. package/dist/Selector/SelectorOption.js +3 -3
  225. package/dist/SideNav/SideNav.d.ts.map +1 -1
  226. package/dist/SideNav/SideNav.js +38 -34
  227. package/dist/SideNav/SideNavCollapseButton.d.ts +1 -1
  228. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  229. package/dist/SideNav/SideNavCollapseButton.js +8 -6
  230. package/dist/SideNav/SideNavHeading.js +87 -87
  231. package/dist/SideNav/SideNavItem.js +42 -42
  232. package/dist/SideNav/SideNavSection.d.ts +1 -1
  233. package/dist/SideNav/SideNavSection.d.ts.map +1 -1
  234. package/dist/SideNav/SideNavSection.js +18 -16
  235. package/dist/Skeleton/Skeleton.js +3 -3
  236. package/dist/Slider/Slider.js +23 -23
  237. package/dist/Spinner/Spinner.js +9 -9
  238. package/dist/StatusDot/StatusDot.js +5 -5
  239. package/dist/Switch/Switch.d.ts +8 -4
  240. package/dist/Switch/Switch.d.ts.map +1 -1
  241. package/dist/Switch/Switch.js +34 -29
  242. package/dist/TabList/Tab.js +18 -18
  243. package/dist/TabList/TabList.js +5 -5
  244. package/dist/TabList/TabMenu.d.ts.map +1 -1
  245. package/dist/TabList/TabMenu.js +57 -30
  246. package/dist/TabList/tab.markers.stylex.d.ts +1 -1
  247. package/dist/Table/BaseTable.d.ts.map +1 -1
  248. package/dist/Table/BaseTable.js +50 -39
  249. package/dist/Table/Table.js +7 -7
  250. package/dist/Table/TableBody.d.ts +1 -1
  251. package/dist/Table/TableBody.d.ts.map +1 -1
  252. package/dist/Table/TableBody.js +9 -5
  253. package/dist/Table/TableCell.js +3 -3
  254. package/dist/Table/TableFooter.d.ts +1 -1
  255. package/dist/Table/TableFooter.d.ts.map +1 -1
  256. package/dist/Table/TableFooter.js +9 -5
  257. package/dist/Table/TableHeader.d.ts +1 -1
  258. package/dist/Table/TableHeader.d.ts.map +1 -1
  259. package/dist/Table/TableHeader.js +9 -5
  260. package/dist/Table/TableHeaderCell.js +3 -3
  261. package/dist/Table/TableRow.js +5 -5
  262. package/dist/Table/index.d.ts +2 -0
  263. package/dist/Table/index.d.ts.map +1 -1
  264. package/dist/Table/index.js +1 -0
  265. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  266. package/dist/Table/plugins/columnResize/useTableColumnResize.js +14 -11
  267. package/dist/Table/plugins/filtering/useTableFiltering.js +71 -71
  268. package/dist/Table/plugins/groupedRows/index.d.ts +3 -0
  269. package/dist/Table/plugins/groupedRows/index.d.ts.map +1 -0
  270. package/dist/Table/plugins/groupedRows/index.js +3 -0
  271. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +78 -0
  272. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -0
  273. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +250 -0
  274. package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
  275. package/dist/Table/plugins/pagination/paginateData.js +5 -1
  276. package/dist/Table/plugins/pagination/useTablePagination.js +7 -7
  277. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +1 -1
  278. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +23 -23
  279. package/dist/Table/plugins/selection/useTableSelection.js +18 -18
  280. package/dist/Table/plugins/selection/useTableSelectionState.d.ts.map +1 -1
  281. package/dist/Table/plugins/selection/useTableSelectionState.js +11 -1
  282. package/dist/Table/plugins/sortable/useTableSortable.js +17 -17
  283. package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
  284. package/dist/Table/plugins/sortable/useTableSortableState.js +8 -4
  285. package/dist/Table/tableContextMenu.js +9 -9
  286. package/dist/Text/Text.js +10 -10
  287. package/dist/TextArea/TextArea.js +14 -14
  288. package/dist/TextInput/TextInput.js +15 -15
  289. package/dist/Thumbnail/Thumbnail.d.ts +3 -2
  290. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  291. package/dist/Thumbnail/Thumbnail.js +30 -29
  292. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  293. package/dist/TimeInput/TimeInput.js +26 -21
  294. package/dist/Timestamp/Timestamp.d.ts +1 -1
  295. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  296. package/dist/Timestamp/Timestamp.js +37 -26
  297. package/dist/Toast/Toast.d.ts.map +1 -1
  298. package/dist/Toast/Toast.js +25 -17
  299. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  300. package/dist/Toast/ToastViewport.js +23 -11
  301. package/dist/Toast/useToast.d.ts.map +1 -1
  302. package/dist/Toast/useToast.js +44 -4
  303. package/dist/ToggleButton/ToggleButton.js +12 -12
  304. package/dist/ToggleButton/ToggleButtonGroup.js +5 -5
  305. package/dist/Token/Token.js +21 -21
  306. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  307. package/dist/Tokenizer/Tokenizer.js +36 -34
  308. package/dist/Toolbar/Toolbar.js +18 -18
  309. package/dist/Tooltip/Tooltip.js +11 -11
  310. package/dist/Tooltip/useTooltip.d.ts +5 -1
  311. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  312. package/dist/Tooltip/useTooltip.js +3 -3
  313. package/dist/TopNav/TopNav.js +32 -32
  314. package/dist/TopNav/TopNavHeading.js +67 -67
  315. package/dist/TopNav/TopNavItem.js +5 -5
  316. package/dist/TopNav/TopNavMegaMenu.js +30 -30
  317. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +1 -1
  318. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
  319. package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +25 -14
  320. package/dist/TopNav/TopNavMegaMenuItem.js +16 -16
  321. package/dist/TopNav/TopNavMenu.js +32 -32
  322. package/dist/TreeList/TreeList.js +8 -8
  323. package/dist/TreeList/TreeListBranches.js +11 -11
  324. package/dist/TreeList/TreeListItem.js +30 -30
  325. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  326. package/dist/Typeahead/BaseTypeahead.js +23 -20
  327. package/dist/Typeahead/Typeahead.js +12 -12
  328. package/dist/Typeahead/TypeaheadItem.js +10 -10
  329. package/dist/VStack/VStack.js +3 -3
  330. package/dist/VisuallyHidden/VisuallyHidden.d.ts +0 -3
  331. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -1
  332. package/dist/VisuallyHidden/VisuallyHidden.js +0 -3
  333. package/dist/astryx.css +7 -0
  334. package/dist/astryx.umd.js +63 -63
  335. package/dist/astryx.umd.js.map +4 -4
  336. package/dist/docs-types.d.ts +8 -2
  337. package/dist/docs-types.d.ts.map +1 -1
  338. package/dist/hooks/focusableSelector.d.ts +1 -1
  339. package/dist/hooks/focusableSelector.d.ts.map +1 -1
  340. package/dist/hooks/focusableSelector.js +1 -1
  341. package/dist/hooks/index.d.ts +2 -0
  342. package/dist/hooks/index.d.ts.map +1 -1
  343. package/dist/hooks/index.js +1 -0
  344. package/dist/hooks/useFocusTrap.d.ts +3 -0
  345. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  346. package/dist/hooks/useFocusTrap.js +38 -1
  347. package/dist/hooks/useHotkeys.d.ts +51 -0
  348. package/dist/hooks/useHotkeys.d.ts.map +1 -0
  349. package/dist/hooks/useHotkeys.js +160 -0
  350. package/dist/hooks/useInteractiveRole.d.ts +6 -2
  351. package/dist/hooks/useInteractiveRole.d.ts.map +1 -1
  352. package/dist/hooks/useInteractiveRole.js +6 -2
  353. package/dist/hooks/useKeyboardHint.js +9 -9
  354. package/dist/hooks/useStreamingText.d.ts +3 -1
  355. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  356. package/dist/hooks/useStreamingText.js +14 -5
  357. package/dist/theme/MediaTheme.js +3 -3
  358. package/dist/theme/Theme.js +7 -7
  359. package/dist/theme/defineTheme.d.ts +1 -1
  360. package/dist/theme/defineTheme.d.ts.map +1 -1
  361. package/dist/theme/expandColorScale.d.ts.map +1 -1
  362. package/dist/theme/expandColorScale.js +10 -3
  363. package/dist/theme/hct.d.ts +0 -15
  364. package/dist/theme/hct.d.ts.map +1 -1
  365. package/dist/theme/hct.js +9 -9
  366. package/dist/theme/syntax/SyntaxTheme.js +5 -5
  367. package/dist/theme/tokens.d.ts +10 -2
  368. package/dist/theme/tokens.d.ts.map +1 -1
  369. package/dist/theme/tokens.js +220 -4
  370. package/dist/theme/useTheme.d.ts +3 -2
  371. package/dist/theme/useTheme.d.ts.map +1 -1
  372. package/dist/theme/useTheme.js +73 -6
  373. package/dist/utils/color.d.ts +42 -0
  374. package/dist/utils/color.d.ts.map +1 -0
  375. package/dist/utils/color.js +150 -0
  376. package/dist/utils/composeEventHandlers.d.ts +30 -0
  377. package/dist/utils/composeEventHandlers.d.ts.map +1 -0
  378. package/dist/utils/composeEventHandlers.js +40 -0
  379. package/dist/utils/index.d.ts +3 -0
  380. package/dist/utils/index.d.ts.map +1 -1
  381. package/dist/utils/index.js +3 -1
  382. package/dist/utils/timeParser.d.ts.map +1 -1
  383. package/dist/utils/timeParser.js +8 -5
  384. package/package.json +4 -4
  385. package/src/AlertDialog/AlertDialog.doc.mjs +4 -0
  386. package/src/AlertDialog/AlertDialog.tsx +2 -0
  387. package/src/AlertDialog/useImperativeAlertDialog.tsx +0 -2
  388. package/src/AppShell/AppShell.tsx +2 -0
  389. package/src/AspectRatio/AspectRatio.doc.mjs +28 -1
  390. package/src/AspectRatio/AspectRatio.test.tsx +142 -1
  391. package/src/AspectRatio/AspectRatio.tsx +70 -10
  392. package/src/AspectRatio/index.ts +5 -1
  393. package/src/Avatar/Avatar.doc.mjs +11 -0
  394. package/src/Avatar/Avatar.test.tsx +32 -1
  395. package/src/Avatar/Avatar.tsx +14 -22
  396. package/src/Avatar/AvatarStatusDot.tsx +2 -2
  397. package/src/AvatarGroup/AvatarGroup.doc.mjs +1 -0
  398. package/src/AvatarGroup/AvatarGroup.tsx +2 -2
  399. package/src/AvatarGroup/AvatarGroupOverflow.tsx +2 -2
  400. package/src/Banner/Banner.doc.mjs +8 -0
  401. package/src/Banner/Banner.test.tsx +38 -0
  402. package/src/Banner/Banner.tsx +8 -1
  403. package/src/Calendar/Calendar.doc.mjs +1 -1
  404. package/src/Calendar/Calendar.test.tsx +122 -17
  405. package/src/Calendar/Calendar.tsx +26 -5
  406. package/src/Calendar/dayCellUtils.ts +3 -1
  407. package/src/Calendar/styles.ts +12 -2
  408. package/src/Card/Card.doc.mjs +1 -1
  409. package/src/Card/Card.tsx +16 -6
  410. package/src/Carousel/Carousel.doc.mjs +12 -12
  411. package/src/Carousel/Carousel.test.tsx +13 -0
  412. package/src/Carousel/Carousel.tsx +4 -2
  413. package/src/Chat/Chat.doc.mjs +1 -1
  414. package/src/Chat/ChatComposerInput.test.tsx +27 -1
  415. package/src/Chat/ChatComposerInput.tsx +20 -15
  416. package/src/Chat/ChatDictationButton.test.tsx +43 -0
  417. package/src/Chat/ChatDictationButton.tsx +4 -4
  418. package/src/Chat/ChatLayoutScrollButton.test.tsx +33 -0
  419. package/src/Chat/ChatLayoutScrollButton.tsx +3 -1
  420. package/src/Chat/ChatMessageMetadata.test.tsx +32 -0
  421. package/src/Chat/ChatMessageMetadata.tsx +4 -6
  422. package/src/Chat/ChatSystemMessage.test.tsx +26 -11
  423. package/src/Chat/ChatSystemMessage.tsx +7 -7
  424. package/src/Chat/ChatTokenizedText.test.tsx +29 -16
  425. package/src/Chat/ChatTokenizedText.tsx +15 -8
  426. package/src/Chat/ChatToolCalls.test.tsx +55 -0
  427. package/src/Chat/ChatToolCalls.tsx +10 -12
  428. package/src/Chat/index.ts +1 -4
  429. package/src/Chat/useTriggerMenu.tsx +1 -4
  430. package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -3
  431. package/src/CheckboxInput/CheckboxInput.test.tsx +71 -4
  432. package/src/CheckboxInput/CheckboxInput.tsx +2 -0
  433. package/src/CheckboxList/CheckboxList.test.tsx +19 -0
  434. package/src/CheckboxList/CheckboxListItem.tsx +11 -2
  435. package/src/Citation/Citation.doc.mjs +5 -0
  436. package/src/ClickableCard/ClickableCard.tsx +45 -2
  437. package/src/CodeBlock/CodeBlock.doc.mjs +7 -2
  438. package/src/CodeBlock/CodeBlock.test.tsx +122 -3
  439. package/src/CodeBlock/CodeBlock.tsx +62 -4
  440. package/src/Collapsible/Collapsible.doc.mjs +8 -4
  441. package/src/Collapsible/Collapsible.test.tsx +403 -0
  442. package/src/Collapsible/Collapsible.tsx +85 -10
  443. package/src/Collapsible/CollapsibleGroup.doc.mjs +27 -3
  444. package/src/Collapsible/CollapsibleGroup.test.tsx +314 -0
  445. package/src/Collapsible/CollapsibleGroup.tsx +97 -9
  446. package/src/Collapsible/CollapsibleGroupContext.tsx +34 -2
  447. package/src/Collapsible/index.ts +1 -0
  448. package/src/Collapsible/useCollapsible.ts +20 -6
  449. package/src/CommandPalette/CommandPalette.doc.mjs +5 -0
  450. package/src/CommandPalette/CommandPalette.tsx +5 -3
  451. package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +5 -0
  452. package/src/CommandPalette/CommandPaletteGroup.doc.mjs +10 -0
  453. package/src/CommandPalette/CommandPaletteInput.doc.mjs +6 -0
  454. package/src/CommandPalette/CommandPaletteItem.doc.mjs +6 -0
  455. package/src/CommandPalette/CommandPaletteList.doc.mjs +9 -0
  456. package/src/ContextMenu/ContextMenu.doc.mjs +15 -0
  457. package/src/ContextMenu/ContextMenu.test.tsx +87 -0
  458. package/src/ContextMenu/ContextMenu.tsx +87 -28
  459. package/src/ContextMenu/ContextMenuItem.doc.mjs +6 -0
  460. package/src/DateInput/DateInput.test.tsx +11 -20
  461. package/src/DateRangeInput/DateRangeInput.doc.mjs +9 -6
  462. package/src/DateRangeInput/DateRangeInput.test.tsx +31 -44
  463. package/src/DateTimeInput/DateTimeInput.doc.mjs +3 -2
  464. package/src/DateTimeInput/DateTimeInput.test.tsx +118 -16
  465. package/src/DateTimeInput/DateTimeInput.tsx +8 -2
  466. package/src/DateTimeInput/index.ts +1 -0
  467. package/src/Dialog/Dialog.doc.mjs +4 -0
  468. package/src/Dialog/DialogHeader.doc.mjs +45 -0
  469. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -1
  470. package/src/DropdownMenu/DropdownMenu.test.tsx +22 -2
  471. package/src/DropdownMenu/DropdownMenuItem.tsx +5 -17
  472. package/src/EmptyState/EmptyState.doc.mjs +1 -1
  473. package/src/Field/Field.test.tsx +1 -4
  474. package/src/Field/FieldLabel.test.tsx +2 -2
  475. package/src/FieldStatus/FieldStatus.test.tsx +282 -0
  476. package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +0 -3
  477. package/src/Grid/Grid.test.tsx +43 -18
  478. package/src/Grid/Grid.tsx +26 -9
  479. package/src/HoverCard/HoverCard.doc.mjs +6 -6
  480. package/src/HoverCard/useHoverCard.doc.mjs +5 -5
  481. package/src/HoverCard/useHoverCard.tsx +9 -2
  482. package/src/Icon/Icon.test.tsx +41 -29
  483. package/src/Icon/Icon.tsx +6 -2
  484. package/src/InputGroup/InputGroup.doc.mjs +1 -0
  485. package/src/InputGroup/InputGroup.tsx +2 -2
  486. package/src/InteractiveRoleContext/InteractiveRoleContext.test.tsx +185 -0
  487. package/src/Item/Item.tsx +1 -1
  488. package/src/Layer/useLayer.doc.mjs +2 -2
  489. package/src/Layer/useLayer.test.tsx +221 -2
  490. package/src/Layer/useLayer.tsx +69 -30
  491. package/src/Layout/Layout.test.tsx +285 -0
  492. package/src/Layout/LayoutContent.doc.mjs +12 -0
  493. package/src/Layout/LayoutPanel.doc.mjs +40 -0
  494. package/src/Layout/LayoutSlots.test.tsx +364 -0
  495. package/src/Lightbox/Lightbox.doc.mjs +5 -0
  496. package/src/Lightbox/Lightbox.test.tsx +123 -2
  497. package/src/Lightbox/Lightbox.tsx +29 -1
  498. package/src/Lightbox/useLightbox.tsx +0 -1
  499. package/src/Link/Link.tsx +0 -2
  500. package/src/Markdown/Markdown.tsx +9 -7
  501. package/src/Markdown/parser.perf.test.ts +34 -12
  502. package/src/MobileNav/MobileNav.test.tsx +56 -0
  503. package/src/MobileNav/MobileNav.tsx +13 -8
  504. package/src/NavMenu/NavMenu.doc.mjs +15 -0
  505. package/src/NumberInput/NumberInput.test.tsx +48 -3
  506. package/src/NumberInput/NumberInput.tsx +32 -15
  507. package/src/Outline/Outline.doc.mjs +2 -0
  508. package/src/Outline/parseOutlineFromMarkdown.test.ts +80 -0
  509. package/src/OverflowList/OverflowList.test.tsx +416 -0
  510. package/src/Overlay/Overlay.doc.mjs +6 -0
  511. package/src/Overlay/Overlay.test.tsx +356 -0
  512. package/src/Overlay/useOverlay.tsx +0 -3
  513. package/src/Pagination/Pagination.test.tsx +162 -0
  514. package/src/Pagination/Pagination.tsx +80 -26
  515. package/src/Popover/Popover.doc.mjs +6 -6
  516. package/src/Popover/Popover.test.tsx +65 -0
  517. package/src/Popover/usePopover.doc.mjs +1 -1
  518. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  519. package/src/PowerSearch/PowerSearch.test.tsx +109 -1
  520. package/src/PowerSearch/PowerSearch.tsx +37 -16
  521. package/src/ProgressBar/ProgressBar.doc.mjs +2 -0
  522. package/src/ProgressBar/ProgressBar.test.tsx +30 -0
  523. package/src/ProgressBar/ProgressBar.tsx +12 -5
  524. package/src/RadioList/RadioList.test.tsx +19 -0
  525. package/src/RadioList/RadioListItem.tsx +9 -4
  526. package/src/Resizable/ResizeHandle.test.tsx +218 -0
  527. package/src/Resizable/ResizeHandle.tsx +22 -4
  528. package/src/SegmentedControl/SegmentedControl.doc.mjs +1 -1
  529. package/src/SegmentedControl/SegmentedControl.test.tsx +192 -0
  530. package/src/SegmentedControl/SegmentedControl.tsx +27 -5
  531. package/src/SegmentedControl/SegmentedControlItem.tsx +9 -4
  532. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  533. package/src/Selector/Selector.test.tsx +27 -1
  534. package/src/SideNav/SideNav.doc.mjs +7 -1
  535. package/src/SideNav/SideNav.test.tsx +66 -0
  536. package/src/SideNav/SideNav.tsx +6 -2
  537. package/src/SideNav/SideNavCollapseButton.tsx +4 -3
  538. package/src/SideNav/SideNavSection.tsx +6 -4
  539. package/src/SizeContext/SizeContext.test.tsx +226 -0
  540. package/src/Switch/Switch.doc.mjs +7 -7
  541. package/src/Switch/Switch.test.tsx +102 -3
  542. package/src/Switch/Switch.tsx +20 -7
  543. package/src/TabList/TabList.test.tsx +185 -1
  544. package/src/TabList/TabMenu.tsx +45 -9
  545. package/src/Table/BaseTable.tsx +13 -2
  546. package/src/Table/Table.doc.mjs +6 -1
  547. package/src/Table/Table.test.tsx +87 -0
  548. package/src/Table/TableBody.tsx +15 -2
  549. package/src/Table/TableFooter.tsx +15 -2
  550. package/src/Table/TableHeader.tsx +15 -2
  551. package/src/Table/index.ts +5 -0
  552. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +13 -0
  553. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +3 -1
  554. package/src/Table/plugins/groupedRows/index.ts +7 -0
  555. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +231 -0
  556. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +349 -0
  557. package/src/Table/plugins/pagination/paginateData.ts +5 -1
  558. package/src/Table/plugins/pagination/useTablePagination.test.tsx +13 -0
  559. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +1 -1
  560. package/src/Table/plugins/selection/useTableSelectionState.test.tsx +23 -0
  561. package/src/Table/plugins/selection/useTableSelectionState.tsx +11 -6
  562. package/src/Table/plugins/sortable/useTableSortableState.test.tsx +35 -1
  563. package/src/Table/plugins/sortable/useTableSortableState.tsx +8 -4
  564. package/src/Table/useTableGroupedRows.doc.mjs +71 -0
  565. package/src/TextArea/TextArea.test.tsx +3 -3
  566. package/src/TextInput/TextInput.test.tsx +3 -3
  567. package/src/Thumbnail/Thumbnail.test.tsx +36 -2
  568. package/src/Thumbnail/Thumbnail.tsx +4 -2
  569. package/src/TimeInput/TimeInput.test.tsx +37 -0
  570. package/src/TimeInput/TimeInput.tsx +11 -1
  571. package/src/Timestamp/Timestamp.doc.mjs +1 -1
  572. package/src/Timestamp/Timestamp.test.tsx +52 -0
  573. package/src/Timestamp/Timestamp.tsx +30 -16
  574. package/src/Toast/Toast.tsx +11 -3
  575. package/src/Toast/ToastViewport.test.tsx +64 -0
  576. package/src/Toast/ToastViewport.tsx +12 -0
  577. package/src/Toast/useToast.test.tsx +258 -0
  578. package/src/Toast/useToast.tsx +41 -0
  579. package/src/ToggleButton/ToggleButton.doc.mjs +1 -0
  580. package/src/Tokenizer/Tokenizer.doc.mjs +2 -2
  581. package/src/Tokenizer/Tokenizer.test.tsx +54 -0
  582. package/src/Tokenizer/Tokenizer.tsx +5 -4
  583. package/src/Tooltip/Tooltip.doc.mjs +6 -6
  584. package/src/Tooltip/useTooltip.doc.mjs +5 -5
  585. package/src/Tooltip/useTooltip.tsx +12 -2
  586. package/src/TopNav/TopNav.doc.mjs +1 -1
  587. package/src/TopNav/TopNav.test.tsx +23 -7
  588. package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +9 -2
  589. package/src/TreeList/TreeList.doc.mjs +2 -2
  590. package/src/Typeahead/BaseTypeahead.doc.mjs +19 -0
  591. package/src/Typeahead/BaseTypeahead.tsx +5 -2
  592. package/src/Typeahead/Typeahead.doc.mjs +1 -1
  593. package/src/Typeahead/Typeahead.test.tsx +45 -1
  594. package/src/VisuallyHidden/VisuallyHidden.tsx +0 -3
  595. package/src/__tests__/TestIcon.tsx +26 -0
  596. package/src/__tests__/fastRoleQueries.ts +66 -0
  597. package/src/docPropReferences.test.ts +178 -0
  598. package/src/docs-types.ts +9 -1
  599. package/src/hooks/focusableSelector.ts +1 -1
  600. package/src/hooks/index.ts +3 -0
  601. package/src/hooks/useFocusTrap.doc.mjs +4 -2
  602. package/src/hooks/useFocusTrap.test.tsx +149 -1
  603. package/src/hooks/useFocusTrap.ts +50 -1
  604. package/src/hooks/useHotkeys.doc.mjs +52 -0
  605. package/src/hooks/useHotkeys.test.ts +245 -0
  606. package/src/hooks/useHotkeys.ts +203 -0
  607. package/src/hooks/useInteractiveRole.ts +12 -4
  608. package/src/hooks/useStreamingText.test.ts +54 -19
  609. package/src/hooks/useStreamingText.ts +16 -5
  610. package/src/hooks/useTreeFocus.test.tsx +1 -3
  611. package/src/reset.css +29 -0
  612. package/src/theme/SyntaxTheme.doc.mjs +4 -4
  613. package/src/theme/defineTheme.ts +4 -13
  614. package/src/theme/derivedVarRegistry.test.ts +2 -2
  615. package/src/theme/expandColorScale.test.ts +29 -0
  616. package/src/theme/expandColorScale.ts +11 -6
  617. package/src/theme/hct.ts +9 -17
  618. package/src/theme/themingTargets.test.ts +353 -0
  619. package/src/theme/tokens.test.ts +182 -9
  620. package/src/theme/tokens.ts +239 -4
  621. package/src/theme/useTheme.test.tsx +126 -2
  622. package/src/theme/useTheme.ts +87 -6
  623. package/src/utils/color.test.ts +133 -0
  624. package/src/utils/color.ts +148 -0
  625. package/src/utils/composeEventHandlers.test.ts +71 -0
  626. package/src/utils/composeEventHandlers.ts +44 -0
  627. package/src/utils/index.ts +4 -0
  628. package/src/utils/mergeProps.test.ts +166 -0
  629. package/src/utils/sharedResizeObserver.test.ts +2 -2
  630. package/src/utils/timeParser.test.ts +13 -0
  631. package/src/utils/timeParser.ts +8 -5
  632. package/dist/Carousel/carousel.markers.stylex.d.ts +0 -7
  633. package/dist/Carousel/carousel.markers.stylex.d.ts.map +0 -1
  634. package/dist/Carousel/carousel.markers.stylex.js +0 -12
  635. package/src/Carousel/carousel.markers.stylex.ts +0 -10
@@ -0,0 +1,218 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file ResizeHandle.test.tsx
5
+ * @input Uses vitest, @testing-library/react, useResizable, ResizeHandle
6
+ * @output Unit tests for ResizeHandle keyboard operability and ARIA state
7
+ * @position Testing; validates ResizeHandle.tsx implementation
8
+ *
9
+ * SYNC: When ResizeHandle.tsx changes, update tests to match new behavior
10
+ *
11
+ * These tests guard the WAI-ARIA window-splitter keyboard contract: the
12
+ * keydown handler must live on the focusable `role="separator"` element.
13
+ * Keyboard resizing is pure state math in useResizable (no layout
14
+ * measurement), so the observable effect asserted here is aria-valuenow,
15
+ * which is bound to the region's `_size`.
16
+ */
17
+
18
+ import {describe, it, expect, vi} from 'vitest';
19
+ import {render, screen, fireEvent, act} from '@testing-library/react';
20
+ import {ResizeHandle} from './ResizeHandle';
21
+ import type {ResizeHandleProps} from './ResizeHandle';
22
+ import {useResizable} from './useResizable';
23
+ import type {ResizableProps, UseResizableSingleConfig} from './useResizable';
24
+
25
+ const KEYBOARD_STEP = 10;
26
+ const KEYBOARD_LARGE_STEP = 50;
27
+
28
+ function Harness({
29
+ config,
30
+ handleProps,
31
+ }: {
32
+ config?: UseResizableSingleConfig;
33
+ handleProps?: Partial<ResizeHandleProps>;
34
+ }) {
35
+ const region = useResizable(
36
+ config ?? {defaultSize: 200, minSizePx: 100, maxSizePx: 400},
37
+ );
38
+ return (
39
+ <ResizeHandle resizable={region.props} label="Resize" {...handleProps} />
40
+ );
41
+ }
42
+
43
+ function getSeparator(): HTMLElement {
44
+ return screen.getByRole('separator');
45
+ }
46
+
47
+ describe('ResizeHandle', () => {
48
+ // --- ARIA wiring ---
49
+
50
+ it('exposes the region size and bounds via ARIA', () => {
51
+ render(<Harness />);
52
+ const separator = getSeparator();
53
+ expect(separator).toHaveAttribute('aria-valuenow', '200');
54
+ expect(separator).toHaveAttribute('aria-valuemin', '100');
55
+ expect(separator).toHaveAttribute('aria-valuemax', '400');
56
+ // Horizontal layout splits along the vertical axis.
57
+ expect(separator).toHaveAttribute('aria-orientation', 'vertical');
58
+ expect(separator).toHaveAttribute('aria-label', 'Resize');
59
+ });
60
+
61
+ it('makes the separator focusable', () => {
62
+ render(<Harness />);
63
+ const separator = getSeparator();
64
+ expect(separator).toHaveAttribute('tabindex', '0');
65
+ act(() => separator.focus());
66
+ expect(separator).toHaveFocus();
67
+ });
68
+
69
+ // --- Keyboard resizing (the fix: handler lives on the focused separator) ---
70
+
71
+ it('grows the panel by a step on ArrowRight', () => {
72
+ render(<Harness />);
73
+ const separator = getSeparator();
74
+ act(() => separator.focus());
75
+ fireEvent.keyDown(separator, {key: 'ArrowRight'});
76
+ expect(separator).toHaveAttribute(
77
+ 'aria-valuenow',
78
+ String(200 + KEYBOARD_STEP),
79
+ );
80
+ });
81
+
82
+ it('shrinks the panel by a step on ArrowLeft', () => {
83
+ render(<Harness />);
84
+ const separator = getSeparator();
85
+ act(() => separator.focus());
86
+ fireEvent.keyDown(separator, {key: 'ArrowLeft'});
87
+ expect(separator).toHaveAttribute(
88
+ 'aria-valuenow',
89
+ String(200 - KEYBOARD_STEP),
90
+ );
91
+ });
92
+
93
+ it('uses the large step when Shift is held', () => {
94
+ render(<Harness />);
95
+ const separator = getSeparator();
96
+ act(() => separator.focus());
97
+ fireEvent.keyDown(separator, {key: 'ArrowRight', shiftKey: true});
98
+ expect(separator).toHaveAttribute(
99
+ 'aria-valuenow',
100
+ String(200 + KEYBOARD_LARGE_STEP),
101
+ );
102
+ });
103
+
104
+ it('jumps to the minimum on Home', () => {
105
+ render(<Harness />);
106
+ const separator = getSeparator();
107
+ act(() => separator.focus());
108
+ fireEvent.keyDown(separator, {key: 'Home'});
109
+ expect(separator).toHaveAttribute('aria-valuenow', '100');
110
+ });
111
+
112
+ it('jumps to the maximum on End', () => {
113
+ render(<Harness />);
114
+ const separator = getSeparator();
115
+ act(() => separator.focus());
116
+ fireEvent.keyDown(separator, {key: 'End'});
117
+ expect(separator).toHaveAttribute('aria-valuenow', '400');
118
+ });
119
+
120
+ it('resizes along the block axis for a vertical handle', () => {
121
+ render(
122
+ <Harness
123
+ config={{defaultSize: 200, minSizePx: 100, maxSizePx: 400}}
124
+ handleProps={{direction: 'vertical'}}
125
+ />,
126
+ );
127
+ const separator = getSeparator();
128
+ expect(separator).toHaveAttribute('aria-orientation', 'horizontal');
129
+ act(() => separator.focus());
130
+ fireEvent.keyDown(separator, {key: 'ArrowDown'});
131
+ expect(separator).toHaveAttribute(
132
+ 'aria-valuenow',
133
+ String(200 + KEYBOARD_STEP),
134
+ );
135
+ fireEvent.keyDown(separator, {key: 'ArrowUp'});
136
+ expect(separator).toHaveAttribute('aria-valuenow', '200');
137
+ });
138
+
139
+ it('collapses on Enter when the region is collapsible', () => {
140
+ render(
141
+ <Harness
142
+ config={{
143
+ defaultSize: 200,
144
+ minSizePx: 100,
145
+ maxSizePx: 400,
146
+ collapsible: true,
147
+ }}
148
+ />,
149
+ );
150
+ const separator = getSeparator();
151
+ act(() => separator.focus());
152
+ fireEvent.keyDown(separator, {key: 'Enter'});
153
+ expect(separator).toHaveAttribute('aria-valuenow', '0');
154
+ });
155
+
156
+ // --- Disabled guard ---
157
+
158
+ it('ignores keyboard input when disabled', () => {
159
+ render(<Harness handleProps={{isDisabled: true}} />);
160
+ const separator = getSeparator();
161
+ expect(separator).toHaveAttribute('tabindex', '-1');
162
+ fireEvent.keyDown(separator, {key: 'ArrowRight'});
163
+ expect(separator).toHaveAttribute('aria-valuenow', '200');
164
+ });
165
+
166
+ // --- Drag listener lifecycle ---
167
+
168
+ it('stops driving the region and releases window listeners when unmounted mid-drag', () => {
169
+ const resizable: ResizableProps = {
170
+ _size: 200,
171
+ _isCollapsed: false,
172
+ _onResizeStart: vi.fn(),
173
+ _onResizeMove: vi.fn(),
174
+ _onResizeEnd: vi.fn(),
175
+ _minSizePx: 100,
176
+ _maxSizePx: 400,
177
+ _snaps: [],
178
+ _collapsedSize: 40,
179
+ _collapsible: false,
180
+ _isResizableProps: true,
181
+ };
182
+ const {unmount} = render(
183
+ <ResizeHandle resizable={resizable} label="Resize" />,
184
+ );
185
+ const separator = screen.getByRole('separator');
186
+ const hitArea = separator.firstElementChild as HTMLElement;
187
+
188
+ // Start a drag and confirm moves reach the region.
189
+ fireEvent.pointerDown(hitArea, {clientX: 0, clientY: 0});
190
+ expect(resizable._onResizeStart).toHaveBeenCalledTimes(1);
191
+ fireEvent.pointerMove(window, {clientX: 10, clientY: 0});
192
+ expect(resizable._onResizeMove).toHaveBeenCalledTimes(1);
193
+
194
+ // Unmount mid-drag: the window listeners must be torn down, so further
195
+ // pointer moves no longer resize the (still-mounted) region, and the
196
+ // body cursor/user-select overrides are released.
197
+ unmount();
198
+ fireEvent.pointerMove(window, {clientX: 50, clientY: 0});
199
+ expect(resizable._onResizeMove).toHaveBeenCalledTimes(1);
200
+ expect(document.body.style.cursor).toBe('');
201
+ expect(document.body.style.userSelect).toBe('');
202
+ });
203
+
204
+ // --- Prop composition (ordering choice: handler sits after {...props}) ---
205
+
206
+ it('runs a consumer onKeyDown alongside keyboard resizing', () => {
207
+ const onKeyDown = vi.fn();
208
+ render(<Harness handleProps={{onKeyDown}} />);
209
+ const separator = getSeparator();
210
+ act(() => separator.focus());
211
+ fireEvent.keyDown(separator, {key: 'ArrowRight'});
212
+ expect(onKeyDown).toHaveBeenCalledTimes(1);
213
+ expect(separator).toHaveAttribute(
214
+ 'aria-valuenow',
215
+ String(200 + KEYBOARD_STEP),
216
+ );
217
+ });
218
+ });
@@ -316,6 +316,9 @@ export function ResizeHandle({
316
316
  ...props
317
317
  }: ResizeHandleProps) {
318
318
  const handleRef = useRef<HTMLDivElement>(null);
319
+ // Removes the in-flight drag's window listeners (and resets body styles).
320
+ // Held in a ref so unmount can tear down a drag that never got a pointerup.
321
+ const dragCleanupRef = useRef<(() => void) | null>(null);
319
322
  const [isDragging, setIsDragging] = useState(false);
320
323
  const [isHovered, setIsHovered] = useState(false);
321
324
  const [isFocused, setIsFocused] = useState(false);
@@ -375,10 +378,12 @@ export function ResizeHandle({
375
378
  window.removeEventListener('pointermove', onMove);
376
379
  window.removeEventListener('pointerup', onUp);
377
380
  window.removeEventListener('pointercancel', onCancel);
381
+ dragCleanupRef.current = null;
378
382
  }
379
383
  window.addEventListener('pointermove', onMove);
380
384
  window.addEventListener('pointerup', onUp);
381
385
  window.addEventListener('pointercancel', onCancel);
386
+ dragCleanupRef.current = cleanup;
382
387
  },
383
388
  [isDisabled, resizable, isHorizontal, getRTLMultiplier, sign],
384
389
  );
@@ -454,14 +459,19 @@ export function ResizeHandle({
454
459
  }, [isDisabled, resizable]);
455
460
 
456
461
  // --- Cleanup on unmount ---
462
+ // A drag in flight when the handle unmounts never gets its pointerup, so
463
+ // tear down the window listeners here too — otherwise every pointermove
464
+ // keeps driving the (still-mounted) region's resize state after the handle
465
+ // is gone, and the body cursor/user-select overrides stick.
457
466
  useEffect(() => {
458
467
  return () => {
459
- if (isDragging) {
468
+ if (dragCleanupRef.current) {
469
+ dragCleanupRef.current();
460
470
  document.body.style.cursor = '';
461
471
  document.body.style.userSelect = '';
462
472
  }
463
473
  };
464
- }, [isDragging]);
474
+ }, []);
465
475
 
466
476
  // --- ARIA ---
467
477
  const ariaValueNow = resizable ? resizable._size : undefined;
@@ -510,7 +520,16 @@ export function ResizeHandle({
510
520
  ),
511
521
  className,
512
522
  )}
513
- {...props}>
523
+ {...props}
524
+ // Keyboard resizing must fire from the focusable separator, not a child:
525
+ // keydown fires on the focused element and bubbles up, so a handler on a
526
+ // descendant never runs (per the WAI-ARIA window-splitter pattern).
527
+ // Placed after {...props} and composed with any consumer onKeyDown so
528
+ // this accessibility-critical handler can't be clobbered by a passed prop.
529
+ onKeyDown={e => {
530
+ props.onKeyDown?.(e);
531
+ handleKeyDown(e);
532
+ }}>
514
533
  {/* Wider invisible hit area for pointer interaction */}
515
534
  <div
516
535
  {...stylex.props(
@@ -528,7 +547,6 @@ export function ResizeHandle({
528
547
  setIsHovered(false);
529
548
  }
530
549
  }}
531
- onKeyDown={handleKeyDown}
532
550
  />
533
551
  {/* Pill grip indicator — themed via .astryx-resize-handle-pill */}
534
552
  {children ?? (
@@ -16,7 +16,7 @@ export const docs = {
16
16
  theming: {
17
17
  targets: [
18
18
  {className: 'astryx-segmented-control', visualProps: ['size']},
19
- {className: 'astryx-segmented-control-item'},
19
+ {className: 'astryx-segmented-control-item', visualProps: ['size'], states: ['selected', 'disabled']},
20
20
  ],
21
21
  vars: [
22
22
  {name: '--_segmented-control-radius', description: 'Border radius of the segmented control', default: 'var(--radius-element)', private: true},
@@ -259,6 +259,56 @@ describe('SegmentedControl', () => {
259
259
  });
260
260
 
261
261
  describe('SegmentedControl keyboard navigation', () => {
262
+ describe('tab-through is a pure focus move (#3597)', () => {
263
+ it('does not fire onChange when tabbing in with an unmatched value', async () => {
264
+ const user = userEvent.setup();
265
+ const onChange = vi.fn();
266
+ render(
267
+ <>
268
+ <button type="button">before</button>
269
+ <SegmentedControl label="View" value="archived" onChange={onChange}>
270
+ <SegmentedControlItem value="grid" label="Grid" />
271
+ <SegmentedControlItem value="list" label="List" />
272
+ </SegmentedControl>
273
+ </>,
274
+ );
275
+ screen.getByText('before').focus();
276
+ await user.tab();
277
+ expect(onChange).not.toHaveBeenCalled();
278
+ });
279
+
280
+ it('does not fire onChange when tabbing in while the selected item is disabled', async () => {
281
+ const user = userEvent.setup();
282
+ const onChange = vi.fn();
283
+ render(
284
+ <>
285
+ <button type="button">before</button>
286
+ <SegmentedControl label="View" value="list" onChange={onChange}>
287
+ <SegmentedControlItem value="grid" label="Grid" />
288
+ <SegmentedControlItem value="list" label="List" isDisabled />
289
+ </SegmentedControl>
290
+ </>,
291
+ );
292
+ screen.getByText('before').focus();
293
+ await user.tab();
294
+ expect(onChange).not.toHaveBeenCalled();
295
+ });
296
+
297
+ it('still selects on arrow-key navigation within the group', async () => {
298
+ const user = userEvent.setup();
299
+ const onChange = vi.fn();
300
+ render(
301
+ <SegmentedControl label="View" value="grid" onChange={onChange}>
302
+ <SegmentedControlItem value="grid" label="Grid" />
303
+ <SegmentedControlItem value="list" label="List" />
304
+ </SegmentedControl>,
305
+ );
306
+ screen.getByRole('radio', {name: 'Grid'}).focus();
307
+ await user.keyboard('{ArrowRight}');
308
+ expect(onChange).toHaveBeenCalledWith('list');
309
+ });
310
+ });
311
+
262
312
  it('navigates with ArrowRight and selects', async () => {
263
313
  const user = userEvent.setup();
264
314
  const handleChange = vi.fn();
@@ -588,3 +638,145 @@ describe('SegmentedControl disabled state', () => {
588
638
  });
589
639
  });
590
640
  });
641
+
642
+ describe('SegmentedControl data-testid forwarding', () => {
643
+ it('forwards data-testid to the radiogroup', () => {
644
+ render(
645
+ <SegmentedControl
646
+ value="grid"
647
+ onChange={() => {}}
648
+ label="View mode"
649
+ data-testid="view-toggle">
650
+ <SegmentedControlItem value="grid" label="Grid" />
651
+ <SegmentedControlItem value="list" label="List" />
652
+ </SegmentedControl>,
653
+ );
654
+
655
+ expect(screen.getByTestId('view-toggle')).toBe(
656
+ screen.getByRole('radiogroup'),
657
+ );
658
+ });
659
+
660
+ it('forwards data-testid to an individual item button', () => {
661
+ render(
662
+ <SegmentedControl value="grid" onChange={() => {}} label="View mode">
663
+ <SegmentedControlItem
664
+ value="grid"
665
+ label="Grid"
666
+ data-testid="opt-grid"
667
+ />
668
+ <SegmentedControlItem
669
+ value="list"
670
+ label="List"
671
+ data-testid="opt-list"
672
+ />
673
+ </SegmentedControl>,
674
+ );
675
+
676
+ expect(screen.getByTestId('opt-grid')).toBe(
677
+ screen.getByRole('radio', {name: 'Grid'}),
678
+ );
679
+ expect(screen.getByTestId('opt-list')).toBe(
680
+ screen.getByRole('radio', {name: 'List'}),
681
+ );
682
+ });
683
+
684
+ it('does not let a forwarded prop override the computed role', () => {
685
+ render(
686
+ // A consumer-supplied role must not clobber the component's own
687
+ // radiogroup role (the computed role is applied after {...rest}).
688
+ <SegmentedControl
689
+ value="grid"
690
+ onChange={() => {}}
691
+ label="View mode"
692
+ role="tablist"
693
+ data-testid="view-toggle">
694
+ <SegmentedControlItem value="grid" label="Grid" />
695
+ </SegmentedControl>,
696
+ );
697
+
698
+ expect(screen.getByTestId('view-toggle')).toHaveAttribute(
699
+ 'role',
700
+ 'radiogroup',
701
+ );
702
+ });
703
+ });
704
+
705
+ describe('SegmentedControlItem onClick composition', () => {
706
+ it('calls a consumer onClick in addition to selecting the item', () => {
707
+ const onChange = vi.fn();
708
+ const onClick = vi.fn();
709
+ render(
710
+ <SegmentedControl value="grid" onChange={onChange} label="View mode">
711
+ <SegmentedControlItem value="list" label="List" onClick={onClick} />
712
+ </SegmentedControl>,
713
+ );
714
+
715
+ fireEvent.click(screen.getByRole('radio', {name: 'List'}));
716
+
717
+ expect(onClick).toHaveBeenCalledTimes(1);
718
+ expect(onChange).toHaveBeenCalledWith('list');
719
+ });
720
+
721
+ it('lets a consumer onClick opt out of selection via preventDefault', () => {
722
+ const onChange = vi.fn();
723
+ render(
724
+ <SegmentedControl value="grid" onChange={onChange} label="View mode">
725
+ <SegmentedControlItem
726
+ value="list"
727
+ label="List"
728
+ onClick={e => e.preventDefault()}
729
+ />
730
+ </SegmentedControl>,
731
+ );
732
+
733
+ fireEvent.click(screen.getByRole('radio', {name: 'List'}));
734
+
735
+ expect(onChange).not.toHaveBeenCalled();
736
+ });
737
+ });
738
+
739
+ describe('SegmentedControl container handler forwarding', () => {
740
+ it('forwards a consumer onKeyDown while keeping arrow-key navigation', async () => {
741
+ const user = userEvent.setup();
742
+ const onKeyDown = vi.fn();
743
+ const onChange = vi.fn();
744
+ render(
745
+ <SegmentedControl
746
+ value="grid"
747
+ onChange={onChange}
748
+ label="View mode"
749
+ onKeyDown={onKeyDown}>
750
+ <SegmentedControlItem value="grid" label="Grid" />
751
+ <SegmentedControlItem value="list" label="List" />
752
+ </SegmentedControl>,
753
+ );
754
+
755
+ screen.getByRole('radio', {name: 'Grid'}).focus();
756
+ await user.keyboard('{ArrowRight}');
757
+
758
+ expect(onKeyDown).toHaveBeenCalled();
759
+ // Built-in navigation still ran.
760
+ expect(onChange).toHaveBeenCalledWith('list');
761
+ });
762
+
763
+ it('lets a consumer onKeyDown opt out of built-in navigation via preventDefault', async () => {
764
+ const user = userEvent.setup();
765
+ const onChange = vi.fn();
766
+ render(
767
+ <SegmentedControl
768
+ value="grid"
769
+ onChange={onChange}
770
+ label="View mode"
771
+ onKeyDown={e => e.preventDefault()}>
772
+ <SegmentedControlItem value="grid" label="Grid" />
773
+ <SegmentedControlItem value="list" label="List" />
774
+ </SegmentedControl>,
775
+ );
776
+
777
+ screen.getByRole('radio', {name: 'Grid'}).focus();
778
+ await user.keyboard('{ArrowRight}');
779
+
780
+ expect(onChange).not.toHaveBeenCalled();
781
+ });
782
+ });
@@ -26,7 +26,7 @@ import type {
26
26
  SegmentedControlSize,
27
27
  SegmentedControlLayout,
28
28
  } from './SegmentedControlContext';
29
- import {mergeProps, mergeRefs} from '../utils';
29
+ import {mergeProps, mergeRefs, composeEventHandlers} from '../utils';
30
30
  import {useSize} from '../SizeContext/SizeContext';
31
31
  import type {BaseProps} from '../BaseProps';
32
32
  import {themeProps} from '../utils/themeProps';
@@ -152,6 +152,10 @@ export function SegmentedControl({
152
152
  xstyle,
153
153
  className,
154
154
  style,
155
+ onKeyDown: onKeyDownProp,
156
+ onFocus: onFocusProp,
157
+ onBlur: onBlurProp,
158
+ ...rest
155
159
  }: SegmentedControlProps) {
156
160
  const size = useSize(sizeProp, 'md');
157
161
 
@@ -188,10 +192,14 @@ export function SegmentedControl({
188
192
 
189
193
  const handleContainerKeyDown = useCallback(
190
194
  (e: React.KeyboardEvent<HTMLDivElement>) => {
195
+ onKeyDownProp?.(e);
196
+ if (e.defaultPrevented) {
197
+ return;
198
+ }
191
199
  hint.onKeyDown(e);
192
200
  handleKeyDown(e);
193
201
  },
194
- [hint, handleKeyDown],
202
+ [onKeyDownProp, hint, handleKeyDown],
195
203
  );
196
204
 
197
205
  // Selection-follows-focus (APG radiogroup): useListFocus only *moves* focus,
@@ -202,12 +210,25 @@ export function SegmentedControl({
202
210
  // and the already-selected value is skipped so an initial Tab-in (or a click
203
211
  // on the current segment) is a no-op, matching click behavior.
204
212
  const handleContainerFocus = useCallback(
205
- (e: React.FocusEvent) => {
213
+ (e: React.FocusEvent<HTMLDivElement>) => {
214
+ onFocusProp?.(e);
215
+ if (e.defaultPrevented) {
216
+ return;
217
+ }
206
218
  hint.onFocus(e);
207
219
  handleFocus(e);
208
220
  if (isDisabled) {
209
221
  return;
210
222
  }
223
+ // Only select when focus moved WITHIN the group (arrow/Home/End — APG
224
+ // selection-follows-focus). When focus is entering from outside, Tab
225
+ // must stay a pure focus move: with an unmatched or disabled-selected
226
+ // value the roving tab stop falls back to the first enabled radio, and
227
+ // selecting it here would rewrite the form value on mere traversal.
228
+ // Clicks are unaffected: the item's own handleClick selects.
229
+ if (!e.currentTarget.contains(e.relatedTarget)) {
230
+ return;
231
+ }
211
232
  const focused = (e.target as HTMLElement | null)?.closest<HTMLElement>(
212
233
  '[role="radio"][data-value]',
213
234
  );
@@ -219,7 +240,7 @@ export function SegmentedControl({
219
240
  onChange(nextValue);
220
241
  }
221
242
  },
222
- [hint, handleFocus, isDisabled, onChange, value],
243
+ [onFocusProp, hint, handleFocus, isDisabled, onChange, value],
223
244
  );
224
245
 
225
246
  const contextValue = useMemo(
@@ -238,6 +259,7 @@ export function SegmentedControl({
238
259
  <SegmentedControlContext value={contextValue}>
239
260
  <div
240
261
  ref={mergeRefs(ref, listRef, disabledMessageTooltip.ref)}
262
+ {...rest}
241
263
  role="radiogroup"
242
264
  aria-label={label}
243
265
  aria-disabled={isDisabled || undefined}
@@ -246,7 +268,7 @@ export function SegmentedControl({
246
268
  }
247
269
  onKeyDown={handleContainerKeyDown}
248
270
  onFocus={handleContainerFocus}
249
- onBlur={hint.onBlur}
271
+ onBlur={composeEventHandlers(onBlurProp, hint.onBlur)}
250
272
  {...mergeProps(
251
273
  themeProps('segmented-control', {size}),
252
274
  stylex.props(
@@ -15,7 +15,7 @@
15
15
  * - /packages/cli/templates/blocks/components/SegmentedControl/ (showcase blocks)
16
16
  */
17
17
 
18
- import React, {useCallback, type ReactNode} from 'react';
18
+ import React, {type ReactNode} from 'react';
19
19
  import * as stylex from '@stylexjs/stylex';
20
20
  import {
21
21
  colorVars,
@@ -29,7 +29,7 @@ import {
29
29
  } from '../theme/tokens.stylex';
30
30
  import {useSegmentedControlContext} from './SegmentedControlContext';
31
31
  import type {SegmentedControlSize} from './SegmentedControlContext';
32
- import {mergeProps} from '../utils';
32
+ import {mergeProps, composeEventHandlers} from '../utils';
33
33
  import type {BaseProps} from '../BaseProps';
34
34
  import {themeProps} from '../utils/themeProps';
35
35
 
@@ -168,6 +168,8 @@ export function SegmentedControlItem({
168
168
  isLabelHidden = false,
169
169
  icon,
170
170
  isDisabled = false,
171
+ onClick: onClickProp,
172
+ ...rest
171
173
  }: SegmentedControlItemProps) {
172
174
  const ctx = useSegmentedControlContext();
173
175
 
@@ -182,11 +184,13 @@ export function SegmentedControlItem({
182
184
  const size: SegmentedControlSize = ctx.size;
183
185
  const isFill = ctx.layout === 'fill';
184
186
 
185
- const handleClick = useCallback(() => {
187
+ // Consumer-first: a consumer onClick can call preventDefault() to opt out of
188
+ // selection; otherwise selection proceeds when enabled and not selected.
189
+ const handleClick = composeEventHandlers(onClickProp, () => {
186
190
  if (!isItemDisabled && !isSelected) {
187
191
  ctx.onChange(value);
188
192
  }
189
- }, [ctx, value, isItemDisabled, isSelected]);
193
+ });
190
194
 
191
195
  const iconElement = icon ? (
192
196
  <span {...stylex.props(styles.icon, iconSizeStyles[size])}>{icon}</span>
@@ -195,6 +199,7 @@ export function SegmentedControlItem({
195
199
  return (
196
200
  <button
197
201
  ref={ref}
202
+ {...rest}
198
203
  type="button"
199
204
  role="radio"
200
205
  aria-checked={isSelected}
@@ -34,7 +34,7 @@ export const docs = {
34
34
  ],
35
35
  theming: {
36
36
  container: true,
37
- targets: [{className: 'astryx-selectable-card', visualProps: ['selected']}],
37
+ targets: [{className: 'astryx-selectable-card', visualProps: ['selected', 'variant']}],
38
38
  },
39
39
  playground: {
40
40
  defaults: {
@@ -186,7 +186,33 @@ describe('Selector', () => {
186
186
  .getByRole('listbox', {hidden: true})
187
187
  .closest('[popover]');
188
188
  expect(popover?.getAttribute('style')).toContain(
189
- 'position-area: top span-right',
189
+ 'position-area: self-block-start span-self-inline-end',
190
+ );
191
+ });
192
+
193
+ it('emits the direction-independent logical mapping under an RTL ancestor (#3389)', async () => {
194
+ // The self-* position-area keywords resolve against the popover's own
195
+ // inherited direction in the browser, so RTL emits the same string as
196
+ // LTR and the mirroring is pure CSS — jsdom can only assert the string.
197
+ const user = userEvent.setup();
198
+ render(
199
+ <div style={{direction: 'rtl'}}>
200
+ <Selector
201
+ label="Fruit"
202
+ options={OPTIONS}
203
+ value="Banana"
204
+ onChange={() => {}}
205
+ />
206
+ </div>,
207
+ );
208
+
209
+ await user.click(screen.getByRole('combobox'));
210
+
211
+ const popover = screen
212
+ .getByRole('listbox', {hidden: true})
213
+ .closest('[popover]');
214
+ expect(popover?.getAttribute('style')).toContain(
215
+ 'position-area: self-block-end span-self-inline-end',
190
216
  );
191
217
  });
192
218