@astryxdesign/core 0.4.7 → 0.5.0-canary.009bcb3

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 (730) hide show
  1. package/CHANGELOG.md +161 -1
  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 +45 -20
  5. package/dist/AppShell/AppShell.d.ts.map +1 -1
  6. package/dist/AppShell/AppShell.js +3 -2
  7. package/dist/AspectRatio/AspectRatio.d.ts +24 -0
  8. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  9. package/dist/AspectRatio/AspectRatio.js +23 -4
  10. package/dist/Avatar/Avatar.d.ts +25 -1
  11. package/dist/Avatar/Avatar.d.ts.map +1 -1
  12. package/dist/Avatar/Avatar.js +58 -19
  13. package/dist/Avatar/index.d.ts +2 -2
  14. package/dist/Avatar/index.d.ts.map +1 -1
  15. package/dist/Avatar/index.js +1 -1
  16. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  17. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroup.js +8 -4
  19. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  20. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  21. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  22. package/dist/AvatarGroup/AvatarGroupOverflow.js +10 -6
  23. package/dist/Banner/Banner.d.ts +49 -15
  24. package/dist/Banner/Banner.d.ts.map +1 -1
  25. package/dist/Banner/Banner.js +62 -20
  26. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  27. package/dist/BottomSheet/BottomSheet.js +17 -4
  28. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  29. package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
  30. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  31. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
  32. package/dist/Button/Button.d.ts.map +1 -1
  33. package/dist/Button/Button.js +11 -6
  34. package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
  35. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  36. package/dist/ButtonGroup/ButtonGroup.js +26 -7
  37. package/dist/Calendar/Calendar.d.ts +7 -3
  38. package/dist/Calendar/Calendar.d.ts.map +1 -1
  39. package/dist/Calendar/Calendar.js +21 -23
  40. package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
  41. package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
  42. package/dist/Calendar/getInitialFocusDate.js +62 -0
  43. package/dist/Calendar/styles.d.ts +5 -14
  44. package/dist/Calendar/styles.d.ts.map +1 -1
  45. package/dist/Calendar/styles.js +15 -15
  46. package/dist/Card/Card.d.ts +12 -12
  47. package/dist/Card/Card.d.ts.map +1 -1
  48. package/dist/Card/Card.js +17 -9
  49. package/dist/Card/index.d.ts +35 -1
  50. package/dist/Card/index.d.ts.map +1 -1
  51. package/dist/Card/index.js +21 -1
  52. package/dist/Carousel/Carousel.d.ts.map +1 -1
  53. package/dist/Carousel/Carousel.js +3 -3
  54. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  55. package/dist/Chat/ChatComposerInput.js +2 -3
  56. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  57. package/dist/Chat/ChatLayout.js +3 -3
  58. package/dist/Chat/ChatMessageList.d.ts +22 -3
  59. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  60. package/dist/Chat/ChatMessageList.js +6 -3
  61. package/dist/Chat/ChatTokenizedText.d.ts +2 -0
  62. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  63. package/dist/Chat/ChatTokenizedText.js +11 -6
  64. package/dist/Chat/useChatComposerTokens.js +1 -1
  65. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  66. package/dist/CheckboxInput/CheckboxInput.js +10 -3
  67. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  68. package/dist/ClickableCard/ClickableCard.js +3 -3
  69. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  70. package/dist/CodeBlock/CodeBlock.js +15 -4
  71. package/dist/CodeBlock/highlightRanges.js +1 -1
  72. package/dist/CodeBlock/highlightStyles.js +13 -13
  73. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  74. package/dist/CommandPalette/CommandPaletteInput.js +3 -2
  75. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  76. package/dist/CommandPalette/CommandPaletteItem.js +3 -2
  77. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  78. package/dist/ComplexSelector/ComplexSelector.js +1 -3
  79. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  80. package/dist/ContextMenu/ContextMenu.js +4 -3
  81. package/dist/DateInput/DateInput.d.ts +43 -0
  82. package/dist/DateInput/DateInput.d.ts.map +1 -1
  83. package/dist/DateInput/DateInput.js +22 -2
  84. package/dist/DateInput/NativeDateField.d.ts +10 -0
  85. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  86. package/dist/DateInput/NativeDateField.js +494 -0
  87. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  88. package/dist/DateInput/TouchDateField.js +82 -23
  89. package/dist/DateInput/index.d.ts +1 -1
  90. package/dist/DateInput/index.d.ts.map +1 -1
  91. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  92. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  93. package/dist/DateInput/nativeDateSegments.js +111 -0
  94. package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
  95. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  96. package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
  97. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  98. package/dist/DateTimeInput/DateTimeInput.js +406 -12
  99. package/dist/DateTimeInput/index.d.ts +1 -1
  100. package/dist/DateTimeInput/index.d.ts.map +1 -1
  101. package/dist/Dialog/Dialog.d.ts +21 -1
  102. package/dist/Dialog/Dialog.d.ts.map +1 -1
  103. package/dist/Dialog/Dialog.js +110 -58
  104. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  105. package/dist/DropdownMenu/DropdownMenu.js +4 -13
  106. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  107. package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
  108. package/dist/Field/FieldLabel.d.ts.map +1 -1
  109. package/dist/Field/FieldLabel.js +9 -1
  110. package/dist/Field/InputClearButton.d.ts +9 -3
  111. package/dist/Field/InputClearButton.d.ts.map +1 -1
  112. package/dist/Field/InputClearButton.js +14 -3
  113. package/dist/FileInput/FileInput.d.ts.map +1 -1
  114. package/dist/FileInput/FileInput.js +3 -2
  115. package/dist/Heading/Heading.d.ts.map +1 -1
  116. package/dist/Heading/Heading.js +6 -3
  117. package/dist/HoverCard/HoverCard.d.ts +6 -0
  118. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  119. package/dist/HoverCard/HoverCard.js +104 -3
  120. package/dist/HoverCard/useHoverCard.d.ts +19 -2
  121. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  122. package/dist/HoverCard/useHoverCard.js +74 -26
  123. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  124. package/dist/Indicator/CheckboxIndicator.js +6 -2
  125. package/dist/Item/Item.d.ts.map +1 -1
  126. package/dist/Item/Item.js +4 -2
  127. package/dist/Kbd/Kbd.d.ts.map +1 -1
  128. package/dist/Kbd/Kbd.js +2 -19
  129. package/dist/Layer/LayerDepthContext.d.ts +52 -0
  130. package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
  131. package/dist/Layer/LayerDepthContext.js +66 -0
  132. package/dist/Layer/gestureCounter.d.ts +8 -0
  133. package/dist/Layer/gestureCounter.d.ts.map +1 -0
  134. package/dist/Layer/gestureCounter.js +53 -0
  135. package/dist/Layer/index.d.ts +3 -0
  136. package/dist/Layer/index.d.ts.map +1 -1
  137. package/dist/Layer/index.js +4 -0
  138. package/dist/Layer/layerStack.d.ts +98 -0
  139. package/dist/Layer/layerStack.d.ts.map +1 -0
  140. package/dist/Layer/layerStack.js +306 -0
  141. package/dist/Layer/useLayer.d.ts +23 -13
  142. package/dist/Layer/useLayer.d.ts.map +1 -1
  143. package/dist/Layer/useLayer.js +128 -8
  144. package/dist/Layer/useLayerDismissal.d.ts +93 -0
  145. package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
  146. package/dist/Layer/useLayerDismissal.js +91 -0
  147. package/dist/Lightbox/Lightbox.d.ts +1 -0
  148. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  149. package/dist/Lightbox/Lightbox.js +103 -81
  150. package/dist/List/List.d.ts +1 -1
  151. package/dist/List/List.d.ts.map +1 -1
  152. package/dist/List/List.js +15 -4
  153. package/dist/Markdown/Markdown.d.ts +1 -1
  154. package/dist/Markdown/Markdown.d.ts.map +1 -1
  155. package/dist/Markdown/Markdown.js +20 -7
  156. package/dist/Markdown/index.d.ts +1 -1
  157. package/dist/Markdown/index.d.ts.map +1 -1
  158. package/dist/Markdown/parser.d.ts +38 -1
  159. package/dist/Markdown/parser.d.ts.map +1 -1
  160. package/dist/Markdown/parser.js +182 -32
  161. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  162. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  163. package/dist/MetadataList/MetadataListItem.js +4 -1
  164. package/dist/MobileNav/MobileNav.d.ts +6 -1
  165. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  166. package/dist/MobileNav/MobileNav.js +61 -36
  167. package/dist/MultiSelector/MultiSelector.d.ts +32 -1
  168. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  169. package/dist/MultiSelector/MultiSelector.js +73 -15
  170. package/dist/MultiSelector/hooks.d.ts +7 -1
  171. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  172. package/dist/MultiSelector/hooks.js +3 -2
  173. package/dist/MultiSelector/index.d.ts +1 -1
  174. package/dist/MultiSelector/index.d.ts.map +1 -1
  175. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  176. package/dist/NavIcon/NavIcon.js +5 -1
  177. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  178. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  179. package/dist/NavMenu/NavHeadingMenu.js +9 -5
  180. package/dist/NumberInput/NumberInput.d.ts +6 -1
  181. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  182. package/dist/NumberInput/NumberInput.js +54 -104
  183. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  184. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  185. package/dist/NumberInput/numberInputCommit.js +71 -0
  186. package/dist/NumberInput/numberParser.d.ts +64 -0
  187. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  188. package/dist/NumberInput/numberParser.js +350 -0
  189. package/dist/Outline/Outline.d.ts.map +1 -1
  190. package/dist/Outline/Outline.js +3 -2
  191. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  192. package/dist/OverflowList/OverflowList.js +3 -2
  193. package/dist/Overlay/Overlay.d.ts.map +1 -1
  194. package/dist/Overlay/Overlay.js +3 -2
  195. package/dist/Popover/Popover.d.ts.map +1 -1
  196. package/dist/Popover/Popover.js +1 -9
  197. package/dist/Popover/usePopover.d.ts +7 -41
  198. package/dist/Popover/usePopover.d.ts.map +1 -1
  199. package/dist/Popover/usePopover.js +40 -21
  200. package/dist/PowerSearch/PowerSearch.d.ts +8 -2
  201. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  202. package/dist/PowerSearch/PowerSearch.js +19 -6
  203. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
  204. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  205. package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
  206. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
  207. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  208. package/dist/PowerSearch/PowerSearchValueEditor.js +110 -27
  209. package/dist/PowerSearch/types.d.ts +2 -0
  210. package/dist/PowerSearch/types.d.ts.map +1 -1
  211. package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
  212. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  213. package/dist/PowerSearch/usePowerSearchSource.js +14 -5
  214. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  215. package/dist/ProgressBar/ProgressBar.js +18 -5
  216. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  217. package/dist/Resizable/ResizeHandle.js +3 -2
  218. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  219. package/dist/SegmentedControl/SegmentedControl.js +3 -2
  220. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  221. package/dist/SelectableCard/SelectableCard.js +12 -3
  222. package/dist/Selector/Selector.d.ts +18 -1
  223. package/dist/Selector/Selector.d.ts.map +1 -1
  224. package/dist/Selector/Selector.js +91 -18
  225. package/dist/Selector/hooks.d.ts +7 -1
  226. package/dist/Selector/hooks.d.ts.map +1 -1
  227. package/dist/Selector/hooks.js +3 -2
  228. package/dist/SideNav/SideNav.d.ts.map +1 -1
  229. package/dist/SideNav/SideNav.js +4 -3
  230. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  231. package/dist/SideNav/SideNavHeading.js +8 -7
  232. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  233. package/dist/SideNav/SideNavItem.js +4 -3
  234. package/dist/Slider/Slider.d.ts.map +1 -1
  235. package/dist/Slider/Slider.js +37 -5
  236. package/dist/Spinner/Spinner.d.ts +3 -3
  237. package/dist/Spinner/Spinner.d.ts.map +1 -1
  238. package/dist/Spinner/Spinner.js +130 -78
  239. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  240. package/dist/StatusDot/StatusDot.js +6 -1
  241. package/dist/Stepper/Step.d.ts +140 -0
  242. package/dist/Stepper/Step.d.ts.map +1 -0
  243. package/dist/Stepper/Step.js +1045 -0
  244. package/dist/Stepper/StepStatus.d.ts +24 -0
  245. package/dist/Stepper/StepStatus.d.ts.map +1 -0
  246. package/dist/Stepper/StepStatus.js +1 -0
  247. package/dist/Stepper/Stepper.d.ts +93 -0
  248. package/dist/Stepper/Stepper.d.ts.map +1 -0
  249. package/dist/Stepper/Stepper.js +184 -0
  250. package/dist/Stepper/StepperContext.d.ts +41 -0
  251. package/dist/Stepper/StepperContext.d.ts.map +1 -0
  252. package/dist/Stepper/StepperContext.js +34 -0
  253. package/dist/Stepper/index.d.ts +8 -0
  254. package/dist/Stepper/index.d.ts.map +1 -0
  255. package/dist/Stepper/index.js +7 -0
  256. package/dist/Stepper/stepper.stylex.d.ts +15 -0
  257. package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
  258. package/dist/Stepper/stepper.stylex.js +20 -0
  259. package/dist/Switch/Switch.d.ts.map +1 -1
  260. package/dist/Switch/Switch.js +8 -3
  261. package/dist/TabList/Tab.d.ts +15 -2
  262. package/dist/TabList/Tab.d.ts.map +1 -1
  263. package/dist/TabList/Tab.js +32 -7
  264. package/dist/TabList/TabList.d.ts +46 -7
  265. package/dist/TabList/TabList.d.ts.map +1 -1
  266. package/dist/TabList/TabList.js +353 -23
  267. package/dist/TabList/TabListContext.d.ts +11 -1
  268. package/dist/TabList/TabListContext.d.ts.map +1 -1
  269. package/dist/TabList/TabListContext.js +11 -2
  270. package/dist/TabList/TabMenu.d.ts.map +1 -1
  271. package/dist/TabList/TabMenu.js +3 -2
  272. package/dist/TabList/index.d.ts +2 -2
  273. package/dist/TabList/index.d.ts.map +1 -1
  274. package/dist/Table/BaseTable.d.ts.map +1 -1
  275. package/dist/Table/BaseTable.js +10 -2
  276. package/dist/Table/Table.d.ts.map +1 -1
  277. package/dist/Table/Table.js +3 -6
  278. package/dist/Table/TableRow.d.ts +16 -5
  279. package/dist/Table/TableRow.d.ts.map +1 -1
  280. package/dist/Table/TableRow.js +16 -5
  281. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  282. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  283. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
  284. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  285. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +54 -11
  286. package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
  287. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  288. package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
  289. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  290. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  291. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  292. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
  293. package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
  294. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  295. package/dist/Table/plugins/selection/useTableSelection.js +43 -5
  296. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  297. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  298. package/dist/Table/types.d.ts +22 -4
  299. package/dist/Table/types.d.ts.map +1 -1
  300. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  301. package/dist/Table/useBaseTablePlugins.js +5 -0
  302. package/dist/Text/Text.d.ts.map +1 -1
  303. package/dist/Text/Text.js +6 -3
  304. package/dist/TextArea/TextArea.d.ts.map +1 -1
  305. package/dist/TextArea/TextArea.js +16 -10
  306. package/dist/TextInput/TextInput.d.ts.map +1 -1
  307. package/dist/TextInput/TextInput.js +3 -2
  308. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  309. package/dist/TimeInput/TimeInput.js +3 -2
  310. package/dist/Timestamp/Timestamp.d.ts +1 -1
  311. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  312. package/dist/Timestamp/Timestamp.js +15 -21
  313. package/dist/Toast/Toast.d.ts.map +1 -1
  314. package/dist/Toast/Toast.js +22 -7
  315. package/dist/Toast/ToastViewport.d.ts +1 -0
  316. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  317. package/dist/Toast/ToastViewport.js +71 -18
  318. package/dist/Token/Token.d.ts +1 -1
  319. package/dist/Token/Token.d.ts.map +1 -1
  320. package/dist/Token/Token.js +20 -9
  321. package/dist/Token/TokenLink.d.ts +1 -1
  322. package/dist/Token/TokenLink.d.ts.map +1 -1
  323. package/dist/Token/TokenLink.js +7 -4
  324. package/dist/Tokenizer/Tokenizer.d.ts +14 -1
  325. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  326. package/dist/Tokenizer/Tokenizer.js +33 -21
  327. package/dist/Tooltip/Tooltip.d.ts +5 -0
  328. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  329. package/dist/Tooltip/useTooltip.d.ts +5 -0
  330. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  331. package/dist/Tooltip/useTooltip.js +39 -24
  332. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  333. package/dist/TopNav/TopNavHeading.js +5 -4
  334. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  335. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  336. package/dist/TopNav/TopNavMegaMenu.js +31 -11
  337. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  338. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  339. package/dist/TopNav/TopNavMenu.js +22 -7
  340. package/dist/TreeList/TreeList.d.ts +1 -1
  341. package/dist/TreeList/TreeList.d.ts.map +1 -1
  342. package/dist/TreeList/TreeList.js +7 -2
  343. package/dist/Typeahead/BaseTypeahead.d.ts +35 -0
  344. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  345. package/dist/Typeahead/BaseTypeahead.js +119 -37
  346. package/dist/Typeahead/Typeahead.d.ts +8 -1
  347. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  348. package/dist/Typeahead/Typeahead.js +5 -2
  349. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  350. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  351. package/dist/Typeahead/TypeaheadItem.js +7 -2
  352. package/dist/astryx.css +113 -11
  353. package/dist/hooks/index.d.ts +1 -0
  354. package/dist/hooks/index.d.ts.map +1 -1
  355. package/dist/hooks/index.js +1 -0
  356. package/dist/hooks/useFocusTrap.d.ts +7 -4
  357. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  358. package/dist/hooks/useFocusTrap.js +60 -95
  359. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  360. package/dist/hooks/useHotkeys.js +3 -18
  361. package/dist/hooks/useMergedRefs.d.ts +18 -0
  362. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  363. package/dist/hooks/useMergedRefs.js +25 -0
  364. package/dist/index.d.ts +1 -0
  365. package/dist/index.d.ts.map +1 -1
  366. package/dist/index.js +1 -0
  367. package/dist/theme/Theme.d.ts.map +1 -1
  368. package/dist/theme/Theme.js +46 -10
  369. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  370. package/dist/theme/derivedVarRegistry.js +24 -4
  371. package/dist/theme/generateThemeRules.d.ts +21 -0
  372. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  373. package/dist/theme/generateThemeRules.js +26 -0
  374. package/dist/theme/syntax/tokens.d.ts +1 -1
  375. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  376. package/dist/theme/syntax/tokens.js +5 -2
  377. package/dist/utils/groupItems.d.ts +5 -1
  378. package/dist/utils/groupItems.d.ts.map +1 -1
  379. package/dist/utils/groupItems.js +9 -9
  380. package/dist/utils/index.d.ts +1 -1
  381. package/dist/utils/index.d.ts.map +1 -1
  382. package/dist/utils/isApplePlatform.d.ts +18 -0
  383. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  384. package/dist/utils/isApplePlatform.js +37 -0
  385. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  386. package/dist/utils/sharedResizeObserver.js +10 -1
  387. package/dist/utils/timeParser.d.ts +1 -1
  388. package/dist/utils/timeParser.d.ts.map +1 -1
  389. package/dist/utils/timeParser.js +26 -12
  390. package/locales/af-ZA.json +6 -6
  391. package/locales/ar-SA.json +6 -6
  392. package/locales/ca-ES.json +5 -5
  393. package/locales/cs-CZ.json +6 -6
  394. package/locales/da-DK.json +6 -6
  395. package/locales/de-DE.json +6 -6
  396. package/locales/el-GR.json +6 -6
  397. package/locales/en.json +163 -11
  398. package/locales/es-ES.json +5 -5
  399. package/locales/fi-FI.json +6 -6
  400. package/locales/fr-FR.json +6 -6
  401. package/locales/he-IL.json +6 -6
  402. package/locales/hu-HU.json +6 -6
  403. package/locales/it-IT.json +6 -6
  404. package/locales/ja-JP.json +6 -6
  405. package/locales/ko-KR.json +6 -6
  406. package/locales/nl-NL.json +6 -6
  407. package/locales/no-NO.json +6 -6
  408. package/locales/pl-PL.json +6 -6
  409. package/locales/pseudo.json +114 -0
  410. package/locales/pt-BR.json +6 -6
  411. package/locales/pt-PT.json +6 -6
  412. package/locales/ro-RO.json +6 -6
  413. package/locales/ru-RU.json +6 -6
  414. package/locales/sr-SP.json +6 -6
  415. package/locales/sv-SE.json +6 -6
  416. package/locales/tr-TR.json +6 -6
  417. package/locales/uk-UA.json +6 -6
  418. package/locales/vi-VN.json +6 -6
  419. package/locales/zh-CN.json +6 -6
  420. package/locales/zh-TW.json +6 -6
  421. package/package.json +8 -3
  422. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  423. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  424. package/src/AlertDialog/AlertDialog.tsx +62 -20
  425. package/src/AppShell/AppShell.tsx +3 -2
  426. package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
  427. package/src/AspectRatio/AspectRatio.test.tsx +57 -10
  428. package/src/AspectRatio/AspectRatio.tsx +40 -1
  429. package/src/Avatar/Avatar.doc.mjs +14 -3
  430. package/src/Avatar/Avatar.test.tsx +97 -0
  431. package/src/Avatar/Avatar.tsx +125 -52
  432. package/src/Avatar/index.ts +2 -2
  433. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  434. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  435. package/src/AvatarGroup/AvatarGroup.tsx +15 -6
  436. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  437. package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
  438. package/src/Banner/Banner.doc.mjs +22 -11
  439. package/src/Banner/Banner.test.tsx +177 -25
  440. package/src/Banner/Banner.tsx +93 -27
  441. package/src/BottomSheet/BottomSheet.test.tsx +123 -0
  442. package/src/BottomSheet/BottomSheet.tsx +17 -4
  443. package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
  444. package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
  445. package/src/Button/Button.doc.mjs +24 -1
  446. package/src/Button/Button.test.tsx +32 -4
  447. package/src/Button/Button.tsx +12 -5
  448. package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
  449. package/src/ButtonGroup/ButtonGroup.test.tsx +404 -1
  450. package/src/ButtonGroup/ButtonGroup.tsx +23 -5
  451. package/src/Calendar/Calendar.doc.mjs +7 -6
  452. package/src/Calendar/Calendar.test.tsx +143 -0
  453. package/src/Calendar/Calendar.tsx +30 -26
  454. package/src/Calendar/getInitialFocusDate.test.ts +94 -0
  455. package/src/Calendar/getInitialFocusDate.ts +93 -0
  456. package/src/Calendar/styles.ts +49 -31
  457. package/src/Card/Card.doc.mjs +10 -7
  458. package/src/Card/Card.test.tsx +113 -19
  459. package/src/Card/Card.tsx +67 -89
  460. package/src/Card/index.ts +36 -1
  461. package/src/Carousel/Carousel.tsx +3 -2
  462. package/src/Chat/ChatComposerInput.tsx +5 -1
  463. package/src/Chat/ChatLayout.tsx +3 -2
  464. package/src/Chat/ChatMessageList.doc.mjs +9 -1
  465. package/src/Chat/ChatMessageList.test.tsx +46 -0
  466. package/src/Chat/ChatMessageList.tsx +28 -4
  467. package/src/Chat/ChatTokenizedText.tsx +17 -10
  468. package/src/Chat/useChatComposerTokens.ts +1 -1
  469. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  470. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  471. package/src/CheckboxInput/CheckboxInput.tsx +8 -2
  472. package/src/ClickableCard/ClickableCard.tsx +3 -2
  473. package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
  474. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  475. package/src/CodeBlock/CodeBlock.tsx +20 -4
  476. package/src/CodeBlock/highlightRanges.ts +1 -1
  477. package/src/CodeBlock/highlightStyles.ts +13 -13
  478. package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
  479. package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
  480. package/src/ComplexSelector/ComplexSelector.test.tsx +32 -0
  481. package/src/ComplexSelector/ComplexSelector.tsx +1 -3
  482. package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
  483. package/src/ContextMenu/ContextMenu.tsx +4 -3
  484. package/src/DateInput/DateInput.doc.mjs +16 -0
  485. package/src/DateInput/DateInput.tsx +55 -2
  486. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  487. package/src/DateInput/NativeDateField.test.tsx +635 -0
  488. package/src/DateInput/NativeDateField.tsx +641 -0
  489. package/src/DateInput/TouchDateField.tsx +108 -24
  490. package/src/DateInput/index.ts +1 -0
  491. package/src/DateInput/nativeDateSegments.ts +127 -0
  492. package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
  493. package/src/DateRangeInput/DateRangeInput.test.tsx +22 -0
  494. package/src/DateRangeInput/DateRangeInput.tsx +4 -2
  495. package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
  496. package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
  497. package/src/DateTimeInput/DateTimeInput.tsx +556 -24
  498. package/src/DateTimeInput/index.ts +1 -0
  499. package/src/Dialog/Dialog.doc.mjs +8 -3
  500. package/src/Dialog/Dialog.test.tsx +429 -2
  501. package/src/Dialog/Dialog.tsx +133 -58
  502. package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
  503. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  504. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  505. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
  506. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
  507. package/src/Field/Field.doc.mjs +13 -2
  508. package/src/Field/FieldLabel.test.tsx +29 -0
  509. package/src/Field/FieldLabel.tsx +7 -0
  510. package/src/Field/InputClearButton.test.tsx +15 -1
  511. package/src/Field/InputClearButton.tsx +28 -4
  512. package/src/FileInput/FileInput.tsx +3 -2
  513. package/src/Heading/Heading.test.tsx +23 -1
  514. package/src/Heading/Heading.tsx +6 -3
  515. package/src/HoverCard/HoverCard.doc.mjs +13 -2
  516. package/src/HoverCard/HoverCard.test.tsx +154 -4
  517. package/src/HoverCard/HoverCard.tsx +143 -3
  518. package/src/HoverCard/useHoverCard.tsx +104 -33
  519. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  520. package/src/Indicator/Indicator.doc.mjs +2 -0
  521. package/src/Item/Item.tsx +5 -4
  522. package/src/Kbd/Kbd.tsx +2 -19
  523. package/src/Layer/LayerDepthContext.tsx +62 -0
  524. package/src/Layer/gestureCounter.ts +57 -0
  525. package/src/Layer/index.ts +9 -0
  526. package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
  527. package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
  528. package/src/Layer/layerStack.ts +362 -0
  529. package/src/Layer/useLayer.test.tsx +324 -15
  530. package/src/Layer/useLayer.tsx +164 -8
  531. package/src/Layer/useLayerDismissal.test.tsx +469 -0
  532. package/src/Layer/useLayerDismissal.ts +173 -0
  533. package/src/Layout/Layout.doc.mjs +2 -2
  534. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  535. package/src/Lightbox/Lightbox.doc.mjs +12 -0
  536. package/src/Lightbox/Lightbox.tsx +124 -102
  537. package/src/Link/Link.doc.mjs +39 -0
  538. package/src/List/List.test.tsx +38 -0
  539. package/src/List/List.tsx +8 -1
  540. package/src/Markdown/Markdown.doc.mjs +5 -0
  541. package/src/Markdown/Markdown.test.tsx +37 -0
  542. package/src/Markdown/Markdown.tsx +16 -5
  543. package/src/Markdown/incremental.test.ts +16 -2
  544. package/src/Markdown/index.ts +1 -0
  545. package/src/Markdown/parser.perf.test.ts +96 -1
  546. package/src/Markdown/parser.test.ts +178 -2
  547. package/src/Markdown/parser.ts +253 -32
  548. package/src/MetadataList/MetadataList.test.tsx +75 -2
  549. package/src/MetadataList/MetadataListItem.tsx +5 -2
  550. package/src/MobileNav/MobileNav.tsx +62 -36
  551. package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
  552. package/src/MultiSelector/MultiSelector.doc.mjs +49 -1
  553. package/src/MultiSelector/MultiSelector.test.tsx +311 -0
  554. package/src/MultiSelector/MultiSelector.tsx +151 -15
  555. package/src/MultiSelector/hooks.ts +9 -2
  556. package/src/MultiSelector/index.ts +1 -0
  557. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  558. package/src/NavIcon/NavIcon.test.tsx +9 -0
  559. package/src/NavIcon/NavIcon.tsx +5 -1
  560. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  561. package/src/NavMenu/NavHeadingMenu.tsx +9 -5
  562. package/src/NumberInput/NumberInput.doc.mjs +31 -7
  563. package/src/NumberInput/NumberInput.test.tsx +436 -8
  564. package/src/NumberInput/NumberInput.tsx +62 -114
  565. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  566. package/src/NumberInput/numberInputCommit.ts +103 -0
  567. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  568. package/src/NumberInput/numberParser.test.ts +222 -0
  569. package/src/NumberInput/numberParser.ts +403 -0
  570. package/src/Outline/Outline.tsx +3 -2
  571. package/src/OverflowList/OverflowList.tsx +3 -2
  572. package/src/Overlay/Overlay.tsx +3 -2
  573. package/src/Pagination/Pagination.test.tsx +3 -2
  574. package/src/Popover/Popover.test.tsx +14 -0
  575. package/src/Popover/Popover.tsx +1 -9
  576. package/src/Popover/usePopover.tsx +57 -32
  577. package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
  578. package/src/PowerSearch/PowerSearch.test.tsx +240 -1
  579. package/src/PowerSearch/PowerSearch.tsx +34 -5
  580. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +288 -0
  581. package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
  582. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +111 -1
  583. package/src/PowerSearch/PowerSearchValueEditor.tsx +124 -10
  584. package/src/PowerSearch/types.ts +2 -0
  585. package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
  586. package/src/PowerSearch/usePowerSearchSource.ts +13 -3
  587. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  588. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  589. package/src/ProgressBar/ProgressBar.tsx +28 -8
  590. package/src/Resizable/ResizeHandle.tsx +3 -2
  591. package/src/SegmentedControl/SegmentedControl.tsx +3 -2
  592. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  593. package/src/SelectableCard/SelectableCard.tsx +19 -2
  594. package/src/Selector/Selector.doc.mjs +26 -1
  595. package/src/Selector/Selector.test.tsx +346 -1
  596. package/src/Selector/Selector.tsx +148 -21
  597. package/src/Selector/hooks.ts +17 -2
  598. package/src/SideNav/SideNav.doc.mjs +6 -6
  599. package/src/SideNav/SideNav.tsx +4 -2
  600. package/src/SideNav/SideNavHeading.tsx +12 -12
  601. package/src/SideNav/SideNavItem.tsx +4 -2
  602. package/src/Slider/Slider.test.tsx +106 -1
  603. package/src/Slider/Slider.tsx +55 -3
  604. package/src/Spinner/Spinner.test.tsx +147 -1
  605. package/src/Spinner/Spinner.tsx +120 -101
  606. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  607. package/src/StatusDot/StatusDot.test.tsx +9 -0
  608. package/src/StatusDot/StatusDot.tsx +7 -1
  609. package/src/Stepper/Step.doc.mjs +98 -0
  610. package/src/Stepper/Step.tsx +1638 -0
  611. package/src/Stepper/StepStatus.ts +26 -0
  612. package/src/Stepper/Stepper.doc.mjs +370 -0
  613. package/src/Stepper/Stepper.test.tsx +1024 -0
  614. package/src/Stepper/Stepper.tsx +258 -0
  615. package/src/Stepper/StepperContext.ts +71 -0
  616. package/src/Stepper/index.ts +18 -0
  617. package/src/Stepper/stepper.stylex.ts +19 -0
  618. package/src/Switch/Switch.doc.mjs +2 -0
  619. package/src/Switch/Switch.test.tsx +10 -0
  620. package/src/Switch/Switch.tsx +6 -2
  621. package/src/TabList/Tab.doc.mjs +13 -1
  622. package/src/TabList/Tab.tsx +67 -7
  623. package/src/TabList/TabList.doc.mjs +22 -6
  624. package/src/TabList/TabList.test.tsx +559 -0
  625. package/src/TabList/TabList.tsx +490 -22
  626. package/src/TabList/TabListContext.ts +13 -2
  627. package/src/TabList/TabMenu.tsx +3 -2
  628. package/src/TabList/index.ts +6 -2
  629. package/src/Table/BaseTable.tsx +12 -4
  630. package/src/Table/Table.doc.mjs +9 -2
  631. package/src/Table/Table.test.tsx +132 -14
  632. package/src/Table/Table.tsx +3 -8
  633. package/src/Table/TableBody.doc.mjs +40 -0
  634. package/src/Table/TableFooter.doc.mjs +40 -0
  635. package/src/Table/TableHeader.doc.mjs +40 -0
  636. package/src/Table/TableRow.tsx +16 -5
  637. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  638. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  639. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
  640. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
  641. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +67 -12
  642. package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
  643. package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
  644. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
  645. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
  646. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
  647. package/src/Table/plugins/selection/useTableSelection.test.tsx +138 -0
  648. package/src/Table/plugins/selection/useTableSelection.tsx +63 -7
  649. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  650. package/src/Table/types.ts +22 -4
  651. package/src/Table/useBaseTablePlugins.ts +5 -0
  652. package/src/Table/useTableGroupedRows.doc.mjs +5 -4
  653. package/src/Table/useTablePagination.doc.mjs +7 -0
  654. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  655. package/src/Table/useTableSelection.doc.mjs +31 -0
  656. package/src/Text/Text.test.tsx +67 -1
  657. package/src/Text/Text.tsx +6 -3
  658. package/src/TextArea/TextArea.doc.mjs +12 -2
  659. package/src/TextArea/TextArea.test.tsx +11 -0
  660. package/src/TextArea/TextArea.tsx +37 -24
  661. package/src/TextInput/TextInput.doc.mjs +10 -0
  662. package/src/TextInput/TextInput.tsx +3 -2
  663. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  664. package/src/TimeInput/TimeInput.tsx +2 -2
  665. package/src/Timestamp/Timestamp.test.tsx +58 -0
  666. package/src/Timestamp/Timestamp.tsx +12 -10
  667. package/src/Toast/Toast.doc.mjs +26 -12
  668. package/src/Toast/Toast.tsx +28 -4
  669. package/src/Toast/ToastViewport.test.tsx +536 -8
  670. package/src/Toast/ToastViewport.tsx +81 -12
  671. package/src/Token/Token.test.tsx +95 -0
  672. package/src/Token/Token.tsx +15 -10
  673. package/src/Token/TokenLink.tsx +14 -5
  674. package/src/Tokenizer/Tokenizer.doc.mjs +43 -3
  675. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  676. package/src/Tokenizer/Tokenizer.tsx +53 -24
  677. package/src/Toolbar/Toolbar.doc.mjs +5 -0
  678. package/src/Tooltip/Tooltip.doc.mjs +5 -0
  679. package/src/Tooltip/Tooltip.test.tsx +32 -0
  680. package/src/Tooltip/Tooltip.tsx +5 -0
  681. package/src/Tooltip/useTooltip.tsx +47 -24
  682. package/src/TopNav/TopNavHeading.tsx +5 -4
  683. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  684. package/src/TopNav/TopNavMegaMenu.tsx +47 -5
  685. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  686. package/src/TopNav/TopNavMenu.tsx +38 -7
  687. package/src/TreeList/TreeList.test.tsx +49 -0
  688. package/src/TreeList/TreeList.tsx +7 -2
  689. package/src/Typeahead/BaseTypeahead.doc.mjs +24 -0
  690. package/src/Typeahead/BaseTypeahead.tsx +181 -39
  691. package/src/Typeahead/Typeahead.doc.mjs +11 -0
  692. package/src/Typeahead/Typeahead.test.tsx +203 -0
  693. package/src/Typeahead/Typeahead.tsx +12 -2
  694. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  695. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  696. package/src/hooks/index.ts +2 -0
  697. package/src/hooks/useAnnounce.doc.mjs +96 -0
  698. package/src/hooks/useContainerReveal.doc.mjs +2 -2
  699. package/src/hooks/useDevWarning.doc.mjs +96 -0
  700. package/src/hooks/useFocusTrap.test.tsx +14 -0
  701. package/src/hooks/useFocusTrap.ts +62 -111
  702. package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
  703. package/src/hooks/useHotkeys.ts +3 -18
  704. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  705. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  706. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  707. package/src/hooks/useLongPress.doc.mjs +123 -0
  708. package/src/hooks/useMergedRefs.doc.mjs +79 -0
  709. package/src/hooks/useMergedRefs.test.tsx +62 -0
  710. package/src/hooks/useMergedRefs.ts +36 -0
  711. package/src/hooks/useTypeahead.doc.mjs +153 -0
  712. package/src/index.ts +1 -0
  713. package/src/raw-import.d.ts +14 -0
  714. package/src/theme/MediaTheme.doc.mjs +5 -5
  715. package/src/theme/Theme.test.tsx +104 -2
  716. package/src/theme/Theme.tsx +49 -14
  717. package/src/theme/defineTheme.test.ts +23 -0
  718. package/src/theme/derivedVarRegistry.test.ts +26 -3
  719. package/src/theme/derivedVarRegistry.ts +23 -4
  720. package/src/theme/generateThemeRules.test.ts +99 -1
  721. package/src/theme/generateThemeRules.ts +28 -0
  722. package/src/theme/syntax/tokens.ts +5 -2
  723. package/src/utils/groupItems.ts +12 -6
  724. package/src/utils/index.ts +1 -1
  725. package/src/utils/isApplePlatform.test.ts +61 -0
  726. package/src/utils/isApplePlatform.ts +37 -0
  727. package/src/utils/sharedResizeObserver.ts +10 -2
  728. package/src/utils/timeParser.test.ts +6 -1
  729. package/src/utils/timeParser.ts +35 -13
  730. package/src/__tests__/inputWidthContract.test.tsx +0 -69
@@ -4,11 +4,15 @@
4
4
 
5
5
  /**
6
6
  * @file TabList.tsx
7
- * @input Uses React, StyleX, TabListContext, useListFocus, useKeyboardHint
8
- * @output Exports TabList component and TabListProps type
9
- * @position Nav wrapper; provides TabListContext to Tab and TabMenu children.
10
- * Owns roving-tabindex keyboard navigation (Arrow/Home/End) across the tab
11
- * strip via the shared useListFocus hook so it is a single Tab stop.
7
+ * @input Uses React, StyleX, TabListContext, useListFocus, useKeyboardHint,
8
+ * useScrollOverflow, Icon
9
+ * @output Exports TabList component, TabListProps and TabListOverflow types
10
+ * @position Tab strip wrapper; provides TabListContext to Tab and TabMenu
11
+ * children. A `<nav>` landmark by default; speaks the WAI-ARIA tabs pattern
12
+ * where the caller asks for it with `role="tablist"`. Owns
13
+ * roving-tabindex keyboard navigation (Arrow/Home/End) across the tab
14
+ * strip via the shared useListFocus hook so it is a single Tab stop, and
15
+ * owns horizontal scrolling when the tabs are wider than the strip.
12
16
  *
13
17
  * SYNC: When modified, update:
14
18
  * - /packages/core/src/TabList/TabList.doc.mjs
@@ -17,20 +21,44 @@
17
21
  * - /packages/cli/assets/templates/blocks/components/TabList/ (showcase blocks)
18
22
  */
19
23
 
20
- import React, {useCallback, useMemo, type ReactNode} from 'react';
24
+ import React, {
25
+ useCallback,
26
+ useEffect,
27
+ useMemo,
28
+ useRef,
29
+ type AriaRole,
30
+ type ReactNode,
31
+ } from 'react';
21
32
  import * as stylex from '@stylexjs/stylex';
22
- import {borderVars, colorVars, spacingVars} from '../theme/tokens.stylex';
33
+ import {
34
+ borderVars,
35
+ colorVars,
36
+ durationVars,
37
+ easeVars,
38
+ focusVars,
39
+ radiusVars,
40
+ shadowVars,
41
+ sizeVars,
42
+ spacingVars,
43
+ } from '../theme/tokens.stylex';
23
44
  import type {BaseProps} from '../BaseProps';
24
45
  import {TabListContext} from './TabListContext';
25
46
  import type {TabListSize} from './TabListContext';
26
47
  import {useSize} from '../SizeContext/SizeContext';
27
- import {mergeProps, mergeRefs} from '../utils';
48
+ import {mergeProps, rtlStyles} from '../utils';
28
49
  import {useListFocus} from '../hooks/useListFocus';
29
50
  import {useKeyboardHint} from '../hooks/useKeyboardHint';
51
+ import {useScrollOverflow} from '../hooks/useScrollOverflow';
52
+ import {isRtlElement} from '../hooks/isRtlElement';
53
+ import {Icon} from '../Icon';
30
54
  import {EDGE_COMP_ATTR} from '../Layout/edgeCompensation.stylex';
31
55
  import {themeProps} from '../utils/themeProps';
56
+ import {observeResize, unobserveResize} from '../utils/sharedResizeObserver';
57
+ import {devWarn} from '../utils/devWarning';
58
+ import {focusOutlineProps} from '../utils/focusOutline.stylex';
32
59
  import {useTranslator} from '../i18n';
33
60
 
61
+ import {useMergedRefs} from '../hooks/useMergedRefs';
34
62
  /**
35
63
  * Selector matching the focusable stops in the tab strip: every Tab
36
64
  * (`[data-tab-value]`) and every TabMenu trigger (`[data-tab-menu]`),
@@ -38,6 +66,24 @@ import {useTranslator} from '../i18n';
38
66
  */
39
67
  const TAB_STOP_SELECTOR = '[data-tab-value],[data-tab-menu]';
40
68
 
69
+ function preventFocus(e: React.MouseEvent) {
70
+ e.preventDefault();
71
+ }
72
+
73
+ /** Fraction of the visible strip an arrow press scrolls. */
74
+ const SCROLL_PAGE_RATIO = 0.8;
75
+
76
+ /**
77
+ * How a strip narrower than its tabs behaves.
78
+ *
79
+ * - `'auto'` — the component picks the strategy. Today that is always
80
+ * `'scroll'`.
81
+ * - `'scroll'` — the tabs scroll horizontally. Every tab stays a tab.
82
+ * - `'visible'` — no overflow handling: tabs keep their intrinsic widths and
83
+ * spill out of the strip, as they did before overflow existed.
84
+ */
85
+ export type TabListOverflow = 'auto' | 'scroll' | 'visible';
86
+
41
87
  export interface TabListProps extends Omit<BaseProps<HTMLElement>, 'onChange'> {
42
88
  ref?: React.Ref<HTMLElement>;
43
89
  /**
@@ -66,12 +112,85 @@ export interface TabListProps extends Omit<BaseProps<HTMLElement>, 'onChange'> {
66
112
  * @default false
67
113
  */
68
114
  hasDivider?: boolean;
115
+ /**
116
+ * ARIA role for the strip.
117
+ *
118
+ * `"tablist"` asks for the WAI-ARIA tabs pattern: `role="tablist"` /
119
+ * `role="tab"` and `aria-selected`, with each tab pointing at the panel it
120
+ * controls via its `panelId`. Only tabs may live in a tablist strip, and a
121
+ * tab does not navigate — an `href` is ignored there.
122
+ *
123
+ * Left unset, the strip is a `<nav>` landmark marking the current tab with
124
+ * `aria-current`. Any other value is passed through to the element
125
+ * unchanged.
126
+ */
127
+ role?: AriaRole;
128
+ /**
129
+ * What happens when the tabs are wider than the strip.
130
+ *
131
+ * `'auto'` lets the component choose; today it always scrolls. `'scroll'`
132
+ * scrolls the tabs horizontally, with edge fades and — for pointers that
133
+ * can hover — arrow affordances. `'visible'` turns overflow handling off and
134
+ * lets the tabs spill out of the strip.
135
+ *
136
+ * The selected tab is always scrolled back into view.
137
+ * @default 'auto'
138
+ */
139
+ overflow?: TabListOverflow;
69
140
  /**
70
141
  * Tab and TabMenu children.
71
142
  */
72
143
  children: ReactNode;
73
144
  }
74
145
 
146
+ /**
147
+ * A scroll container clips at its padding box, and two things a tab paints sit
148
+ * outside its own box: the focus ring (offset + width) and the selected
149
+ * indicator, which `--_tab-indicator-bottom` pushes further down when a
150
+ * divider rail is reserved. The strip pads by that much and takes the padding
151
+ * straight back off with a negative margin, so nothing is clipped and the tabs
152
+ * stay exactly where they were.
153
+ *
154
+ * A bleed is not free, though. The padding is real geometry: the strip's
155
+ * border box sticks out of the TabList's, and any ancestor that scrolls counts
156
+ * that as something to scroll to. So the ring's share of the bleed is taken
157
+ * only while a ring is actually drawn inside the strip -- the same
158
+ * `:has(:focus-visible)` condition that draws it -- and at rest the strip is
159
+ * exactly as wide and as tall as the TabList, as it was before the strip could
160
+ * scroll. The indicator's share is always taken, because the indicator is
161
+ * always drawn.
162
+ *
163
+ * Turning the bleed on moves nothing: padding and negative margin cancel, so
164
+ * the border box grows outwards and the content stays put.
165
+ */
166
+ const RING_BLEED = `calc(${focusVars['--focus-outline-width']} + ${focusVars['--focus-outline-offset']})`;
167
+ const BLEED_VAR = '--_tab-strip-bleed';
168
+ const BLEED = `var(${BLEED_VAR})`;
169
+ const INDICATOR_BLEED = 'calc(-1 * var(--_tab-indicator-bottom, -1px))';
170
+ const BLOCK_END_BLEED = `max(${BLEED}, ${INDICATOR_BLEED})`;
171
+
172
+ /** How far the edge fade runs; wide enough to sit under an arrow. */
173
+ const FADE_WIDTH = spacingVars['--spacing-8'];
174
+
175
+ /**
176
+ * Where the fade turns fully opaque, and — the same distance, for the same
177
+ * reason — how far a revealed stop is kept clear of the edge. Declared as
178
+ * scroll-padding so the browser's own focus scrolling uses it too, and read
179
+ * back from the computed style so the arithmetic below has one source of
180
+ * truth with the CSS.
181
+ */
182
+ const SCROLL_EDGE_INSET = `calc(${BLEED} + ${FADE_WIDTH})`;
183
+
184
+ /**
185
+ * The fade reaches transparent at the strip's *own* edge, not at the bleed
186
+ * edge — otherwise the scroll container paints tabs past the TabList's box,
187
+ * past a divider rail, and past the scroll arrow that caps that edge. Masking
188
+ * the bleed costs nothing: only a faded edge is masked, and a stop at a faded
189
+ * edge never holds focus, so the bleed is still there when the ring needs it.
190
+ */
191
+ const FADE_FROM_START = `linear-gradient(to right, transparent ${BLEED}, black ${SCROLL_EDGE_INSET})`;
192
+ const FADE_FROM_END = `linear-gradient(to left, transparent ${BLEED}, black ${SCROLL_EDGE_INSET})`;
193
+
75
194
  const styles = stylex.create({
76
195
  nav: {
77
196
  display: 'flex',
@@ -79,6 +198,7 @@ const styles = stylex.create({
79
198
  gap: spacingVars['--spacing-0-5'],
80
199
  maxWidth: '100%',
81
200
  minWidth: 0,
201
+ position: 'relative',
82
202
  },
83
203
  fill: {
84
204
  width: '100%',
@@ -96,6 +216,114 @@ const styles = stylex.create({
96
216
  paddingBlockEnd: spacingVars['--spacing-1'],
97
217
  '--_tab-indicator-bottom': `calc(-1 * (${spacingVars['--spacing-1']} + ${borderVars['--border-width']}))`,
98
218
  },
219
+ strip: {
220
+ display: 'flex',
221
+ alignItems: 'stretch',
222
+ // Inherited rather than restated so an `xstyle` gap override on the
223
+ // TabList still reaches the tabs.
224
+ gap: 'inherit',
225
+ flexGrow: 1,
226
+ flexShrink: 1,
227
+ minWidth: 0,
228
+ // Content-height, not stretched: the bleed padding below is inside the
229
+ // strip's own height, and a stretched height would push the tabs out of
230
+ // the scrollport.
231
+ alignSelf: 'flex-start',
232
+ },
233
+ stripScroll: {
234
+ overflowX: 'auto',
235
+ overflowY: 'hidden',
236
+ overscrollBehaviorX: 'contain',
237
+ scrollPaddingInline: SCROLL_EDGE_INSET,
238
+ scrollbarWidth: 'none',
239
+ scrollBehavior: {
240
+ default: 'smooth',
241
+ '@media (prefers-reduced-motion: reduce)': 'auto',
242
+ },
243
+ [BLEED_VAR]: {
244
+ default: '0px',
245
+ ':has(:focus-visible)': RING_BLEED,
246
+ },
247
+ paddingBlockStart: BLEED,
248
+ marginBlockStart: `calc(-1 * (${BLEED}))`,
249
+ paddingBlockEnd: BLOCK_END_BLEED,
250
+ marginBlockEnd: `calc(-1 * (${BLOCK_END_BLEED}))`,
251
+ paddingInline: BLEED,
252
+ marginInline: `calc(-1 * (${BLEED}))`,
253
+ maskImage: 'none',
254
+ transitionProperty: 'mask-image',
255
+ transitionDuration: {
256
+ default: durationVars['--duration-medium'],
257
+ '@media (prefers-reduced-motion: reduce)': '0ms',
258
+ },
259
+ transitionTimingFunction: easeVars['--ease-standard'],
260
+ },
261
+ fadeStart: {
262
+ maskImage: {
263
+ default: FADE_FROM_START,
264
+ ':is([dir="rtl"] *)': FADE_FROM_END,
265
+ },
266
+ },
267
+ fadeEnd: {
268
+ maskImage: {
269
+ default: FADE_FROM_END,
270
+ ':is([dir="rtl"] *)': FADE_FROM_START,
271
+ },
272
+ },
273
+ fadeBoth: {
274
+ maskImage: `linear-gradient(to right, transparent ${BLEED}, black ${SCROLL_EDGE_INSET}, black calc(100% - ${SCROLL_EDGE_INSET}), transparent calc(100% - ${BLEED}))`,
275
+ },
276
+ arrow: {
277
+ position: 'absolute',
278
+ insetBlockStart: 0,
279
+ // A pointer-only affordance: keyboard and assistive-technology users move
280
+ // through the strip with the arrow keys, which scrolls the focused tab
281
+ // into view on its own.
282
+ display: {
283
+ default: 'none',
284
+ '@media (hover: hover)': 'flex',
285
+ },
286
+ alignItems: 'center',
287
+ justifyContent: 'center',
288
+ padding: 0,
289
+ borderWidth: 0,
290
+ borderStyle: 'none',
291
+ borderRadius: radiusVars['--radius-full'],
292
+ // Opaque, because it sits over the tabs it scrolls: the strip's edge fade
293
+ // thins the content underneath but does not clear it.
294
+ backgroundColor: colorVars['--color-background-popover'],
295
+ boxShadow: shadowVars['--shadow-low'],
296
+ color: {
297
+ default: colorVars['--color-text-secondary'],
298
+ ':hover:where(:not(:disabled,[aria-disabled="true"]))':
299
+ colorVars['--color-text-primary'],
300
+ },
301
+ cursor: {
302
+ default: 'pointer',
303
+ ':is(:disabled,[aria-disabled="true"])': 'default',
304
+ },
305
+ },
306
+ arrowStart: {
307
+ insetInlineStart: 0,
308
+ },
309
+ arrowEnd: {
310
+ insetInlineEnd: 0,
311
+ },
312
+ });
313
+
314
+ const arrowSizeStyles = stylex.create({
315
+ sm: {
316
+ width: sizeVars['--size-element-sm'],
317
+ height: sizeVars['--size-element-sm'],
318
+ },
319
+ md: {
320
+ width: sizeVars['--size-element-md'],
321
+ height: sizeVars['--size-element-md'],
322
+ },
323
+ lg: {
324
+ width: sizeVars['--size-element-lg'],
325
+ height: sizeVars['--size-element-lg'],
326
+ },
99
327
  });
100
328
 
101
329
  /**
@@ -121,6 +349,8 @@ export function TabList({
121
349
  size: sizeProp,
122
350
  layout = 'hug',
123
351
  hasDivider = false,
352
+ role,
353
+ overflow = 'auto',
124
354
  xstyle,
125
355
  className,
126
356
  style,
@@ -129,6 +359,7 @@ export function TabList({
129
359
  onFocus: onFocusProp,
130
360
  onBlur: onBlurProp,
131
361
  'aria-label': ariaLabelFromProps,
362
+ 'aria-labelledby': ariaLabelledBy,
132
363
  'aria-orientation': _ariaOrientation,
133
364
  [EDGE_COMP_ATTR]: _edgeCompAttr,
134
365
  ...restProps
@@ -136,13 +367,22 @@ export function TabList({
136
367
  const t = useTranslator();
137
368
  const ariaLabel = ariaLabelFromProps ?? t('@astryx.tabList.label');
138
369
  const size = useSize(sizeProp, 'md');
370
+ const hasScroll = overflow !== 'visible';
371
+
372
+ const stripRef = useRef<HTMLDivElement | null>(null);
373
+ // Only an asserted `role="tablist"` switches the pattern. Left unset the
374
+ // strip is the `<nav>` it has always been, and every other role passes
375
+ // through to the element untouched.
376
+ const isTabList = role === 'tablist';
139
377
 
140
378
  // Roving-tabindex keyboard navigation across the tab strip via the shared
141
- // hook. `orientation: 'both'` accepts both arrow axes per the WAI-ARIA APG
142
- // allowance for tab strips (ArrowRight/ArrowDown advance, ArrowLeft/ArrowUp
143
- // retreat). We do not set `aria-orientation` on the `<nav>`: that attribute
144
- // is invalid on the navigation role and triggers an axe `aria-allowed-attr`
145
- // violation.
379
+ // hook. Under the navigation pattern `orientation: 'both'` accepts both
380
+ // arrow axes per the WAI-ARIA APG allowance for tab strips
381
+ // (ArrowRight/ArrowDown advance, ArrowLeft/ArrowUp retreat). A tablist
382
+ // reports itself as horizontal, so there the strip takes only the
383
+ // horizontal arrows and leaves ArrowUp and ArrowDown to scroll the page. We
384
+ // do not set `aria-orientation` on the `<nav>`: that attribute is invalid on
385
+ // the navigation role and triggers an axe `aria-allowed-attr` violation.
146
386
  //
147
387
  // `hasRovingTabIndex` makes the hook own the single tab stop: it stamps
148
388
  // tabindex 0/-1, repairs the stop on mount and as stops mount/unmount or
@@ -153,7 +393,7 @@ export function TabList({
153
393
  // the first enabled stop when none is tabbable.
154
394
  const {listRef, handleKeyDown, handleFocus} = useListFocus<HTMLElement>({
155
395
  itemSelector: TAB_STOP_SELECTOR,
156
- orientation: 'both',
396
+ orientation: isTabList ? 'horizontal' : 'both',
157
397
  hasRovingTabIndex: true,
158
398
  });
159
399
 
@@ -164,9 +404,124 @@ export function TabList({
164
404
  onBlur: onHintBlur,
165
405
  } = useKeyboardHint();
166
406
 
407
+ const {scrollRef, overflowStart, overflowEnd} = useScrollOverflow();
408
+
409
+ const attachStrip = useCallback(
410
+ (el: HTMLDivElement | null) => {
411
+ stripRef.current = el;
412
+ scrollRef(hasScroll ? el : null);
413
+ },
414
+ [hasScroll, scrollRef],
415
+ );
416
+
417
+ const revealStop = useCallback(
418
+ (stop: HTMLElement | null) => {
419
+ const strip = stripRef.current;
420
+ if (!hasScroll || !strip || !stop) {
421
+ return;
422
+ }
423
+ const stripBox = strip.getBoundingClientRect();
424
+ const stopBox = stop.getBoundingClientRect();
425
+ const inset = parseFloat(getComputedStyle(strip).scrollPaddingLeft) || 0;
426
+ const pastEnd = stopBox.right - (stripBox.right - inset);
427
+ const pastStart = stopBox.left - (stripBox.left + inset);
428
+ // A stop wider than the space kept clear cannot be shown whole, so show
429
+ // its reading start, the way `scrollIntoView({inline: 'nearest'})` does.
430
+ const tooWide = stopBox.width > stripBox.width - 2 * inset;
431
+ const delta = tooWide
432
+ ? isRtlElement(strip)
433
+ ? pastEnd
434
+ : pastStart
435
+ : pastEnd > 0
436
+ ? pastEnd
437
+ : pastStart < 0
438
+ ? pastStart
439
+ : 0;
440
+ if (delta !== 0) {
441
+ // Not an animation: the strip has to arrive already showing the right
442
+ // tab, so this overrides the CSS smooth behaviour arrow presses use.
443
+ strip.scrollBy({left: delta, behavior: 'instant'});
444
+ }
445
+ },
446
+ [hasScroll],
447
+ );
448
+
449
+ const revealSelectedTab = useCallback(() => {
450
+ const strip = stripRef.current;
451
+ if (!strip) {
452
+ return;
453
+ }
454
+ revealStop(
455
+ Array.from(strip.querySelectorAll<HTMLElement>('[data-tab-value]')).find(
456
+ el => el.dataset.tabValue === value,
457
+ ) ?? null,
458
+ );
459
+ }, [revealStop, value]);
460
+
461
+ // Both reveals below reach the callback through a ref instead of depending
462
+ // on it: its identity also changes with `overflow`, and that is not a reason
463
+ // to scroll anything.
464
+ const revealSelectedTabRef = useRef(revealSelectedTab);
465
+ useEffect(() => {
466
+ revealSelectedTabRef.current = revealSelectedTab;
467
+ }, [revealSelectedTab]);
468
+
469
+ // The tab you are on has to be visible. Selection can move without focus —
470
+ // on mount, or when the host sets `value` itself — and neither scrolls the
471
+ // strip the way clicking or arrowing to a tab does. The check is what makes
472
+ // a selection change the trigger, rather than the effect happening to run.
473
+ const revealedValueRef = useRef<string | null>(null);
474
+ useEffect(() => {
475
+ if (revealedValueRef.current === value) {
476
+ return;
477
+ }
478
+ revealedValueRef.current = value;
479
+ revealSelectedTabRef.current();
480
+ }, [value]);
481
+
482
+ // ...and it has to stay visible when the strip is what moved. A strip that
483
+ // fitted at one width can hide the selected tab at a narrower one, and no
484
+ // prop changes when that happens. This one re-reveals the same selection by
485
+ // design, which is why the check above sits in the effect rather than in
486
+ // `revealSelectedTab`.
487
+ //
488
+ // The wrapper is observed rather than the strip because the shared observer
489
+ // keeps one callback per element and `useScrollOverflow` already holds the
490
+ // strip's.
491
+ useEffect(() => {
492
+ const root = listRef.current;
493
+ if (!hasScroll || !root) {
494
+ return;
495
+ }
496
+ const onResize = () => revealSelectedTabRef.current();
497
+ observeResize(root, onResize);
498
+ return () => unobserveResize(root);
499
+ }, [hasScroll, listRef]);
500
+
501
+ const scrollByPage = useCallback((direction: -1 | 1) => {
502
+ const strip = stripRef.current;
503
+ if (!strip) {
504
+ return;
505
+ }
506
+ // Under RTL the scroll axis is inverted, so flip the physical delta.
507
+ const rtlSign = isRtlElement(strip) ? -1 : 1;
508
+ strip.scrollBy({
509
+ left: rtlSign * direction * strip.clientWidth * SCROLL_PAGE_RATIO,
510
+ });
511
+ }, []);
512
+
513
+ const scrollToStart = useCallback(() => scrollByPage(-1), [scrollByPage]);
514
+ const scrollToEnd = useCallback(() => scrollByPage(1), [scrollByPage]);
515
+
167
516
  const contextValue = useMemo(
168
- () => ({value, onChange, size, layout}),
169
- [value, onChange, size, layout],
517
+ () => ({
518
+ value,
519
+ onChange,
520
+ size,
521
+ layout,
522
+ pattern: isTabList ? ('tabs' as const) : ('nav' as const),
523
+ }),
524
+ [value, onChange, size, layout, isTabList],
170
525
  );
171
526
 
172
527
  const handleRootKeyDown = useCallback(
@@ -189,8 +544,12 @@ export function TabList({
189
544
  }
190
545
  onHintFocus(e);
191
546
  handleFocus(e);
547
+ // The browser scrolls a focused element into view only when it is
548
+ // entirely outside the scrollport, so arrowing onto a half-visible stop
549
+ // leaves it cut off under the fade. Finish the job it started.
550
+ revealStop(e.target.closest(TAB_STOP_SELECTOR));
192
551
  },
193
- [onFocusProp, onHintFocus, handleFocus],
552
+ [onFocusProp, onHintFocus, handleFocus, revealStop],
194
553
  );
195
554
 
196
555
  const handleRootBlur = useCallback(
@@ -204,12 +563,58 @@ export function TabList({
204
563
  [onBlurProp, onHintBlur],
205
564
  );
206
565
 
566
+ // `role="tablist"` owns only tabs, so anything else in the strip is invalid
567
+ // markup. Dev-only, and only under the asserted role — nothing else in the
568
+ // component reads the rendered DOM.
569
+ const hasWarnedContentRef = useRef(false);
570
+ useEffect(() => {
571
+ const strip = stripRef.current;
572
+ if (
573
+ process.env.NODE_ENV === 'production' ||
574
+ !isTabList ||
575
+ !strip ||
576
+ hasWarnedContentRef.current
577
+ ) {
578
+ return;
579
+ }
580
+ const stranger = Array.from(strip.children).find(
581
+ child => child.getAttribute('role') !== 'tab',
582
+ );
583
+ if (stranger) {
584
+ hasWarnedContentRef.current = true;
585
+ devWarn(
586
+ 'TabList',
587
+ `role="tablist" owns only tabs, but the strip contains a <${stranger.tagName.toLowerCase()}> that is not one. ` +
588
+ 'Render menus and other controls outside the strip, or drop the role for the navigation pattern.',
589
+ );
590
+ }
591
+ // No dependency list: the check is on rendered DOM, which can change
592
+ // without any prop this component could watch.
593
+ });
594
+
595
+ const fadeStyle = !hasScroll
596
+ ? null
597
+ : overflowStart && overflowEnd
598
+ ? styles.fadeBoth
599
+ : overflowStart
600
+ ? styles.fadeStart
601
+ : overflowEnd
602
+ ? styles.fadeEnd
603
+ : null;
604
+
605
+ // A tablist is not navigation, so the landmark element is only right under
606
+ // the navigation pattern. The role is fixed by a prop rather than by what
607
+ // the strip happens to hold, so this is settled once at the callsite.
608
+ const Wrapper = isTabList ? 'div' : 'nav';
609
+
207
610
  return (
208
611
  <TabListContext value={contextValue}>
209
- <nav
210
- ref={mergeRefs(ref, listRef)}
612
+ <Wrapper
613
+ ref={useMergedRefs(ref, listRef)}
211
614
  {...restProps}
212
- aria-label={ariaLabel}
615
+ role={isTabList ? undefined : role}
616
+ aria-label={isTabList ? undefined : ariaLabel}
617
+ aria-labelledby={isTabList ? undefined : ariaLabelledBy}
213
618
  onKeyDown={handleRootKeyDown}
214
619
  onFocus={handleRootFocus}
215
620
  onBlur={handleRootBlur}
@@ -225,9 +630,72 @@ export function TabList({
225
630
  className,
226
631
  style,
227
632
  )}>
228
- {children}
633
+ <div
634
+ ref={attachStrip}
635
+ role={isTabList ? 'tablist' : undefined}
636
+ aria-label={isTabList ? ariaLabel : undefined}
637
+ // The name belongs to whichever element carries the widget role.
638
+ aria-labelledby={isTabList ? ariaLabelledBy : undefined}
639
+ {...mergeProps(
640
+ themeProps('tab-strip'),
641
+ stylex.props(
642
+ styles.strip,
643
+ hasScroll && styles.stripScroll,
644
+ fadeStyle,
645
+ ),
646
+ )}>
647
+ {children}
648
+ </div>
649
+ {hasScroll && overflowStart && (
650
+ <button
651
+ type="button"
652
+ aria-hidden="true"
653
+ tabIndex={-1}
654
+ // Nothing hidden from assistive technology should end up holding
655
+ // focus, and a click would put it here.
656
+ onMouseDown={preventFocus}
657
+ onClick={scrollToStart}
658
+ {...mergeProps(
659
+ themeProps('tab-scroll-button'),
660
+ focusOutlineProps.focusVisible(
661
+ styles.arrow,
662
+ styles.arrowStart,
663
+ arrowSizeStyles[size],
664
+ ),
665
+ )}>
666
+ <Icon
667
+ icon="chevronLeft"
668
+ size="sm"
669
+ color="inherit"
670
+ xstyle={rtlStyles.mirror}
671
+ />
672
+ </button>
673
+ )}
674
+ {hasScroll && overflowEnd && (
675
+ <button
676
+ type="button"
677
+ aria-hidden="true"
678
+ tabIndex={-1}
679
+ onMouseDown={preventFocus}
680
+ onClick={scrollToEnd}
681
+ {...mergeProps(
682
+ themeProps('tab-scroll-button'),
683
+ focusOutlineProps.focusVisible(
684
+ styles.arrow,
685
+ styles.arrowEnd,
686
+ arrowSizeStyles[size],
687
+ ),
688
+ )}>
689
+ <Icon
690
+ icon="chevronRight"
691
+ size="sm"
692
+ color="inherit"
693
+ xstyle={rtlStyles.mirror}
694
+ />
695
+ </button>
696
+ )}
229
697
  {hintElement}
230
- </nav>
698
+ </Wrapper>
231
699
  </TabListContext>
232
700
  );
233
701
  }
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @file TabListContext.ts
7
7
  * @input React createContext, use
8
- * @output Exports TabListContext, useTabListContext
8
+ * @output Exports TabListContext, useTabListContext, TabListPattern
9
9
  * @position Context provider; consumed by Tab.tsx, TabMenu.tsx
10
10
  *
11
11
  * SYNC: When modified, update /packages/core/src/TabList/TabList.doc.mjs
@@ -27,13 +27,24 @@ export type TabListSize = 'sm' | 'md' | 'lg';
27
27
  export type TabListLayout = 'hug' | 'fill';
28
28
 
29
29
  /**
30
- * Context for communicating value/onChange/size/layout from TabList to children.
30
+ * ARIA pattern the strip resolved to.
31
+ * - `'nav'`: a `<nav>` of links or buttons, current item marked with
32
+ * `aria-current`.
33
+ * - `'tabs'`: the WAI-ARIA tabs pattern — `role="tablist"` / `role="tab"`,
34
+ * `aria-selected`, and `aria-controls` for the panel each tab owns.
35
+ */
36
+ export type TabListPattern = 'nav' | 'tabs';
37
+
38
+ /**
39
+ * Context for communicating value/onChange/size/layout and the resolved ARIA
40
+ * pattern from TabList to children.
31
41
  */
32
42
  export interface TabListContextValue {
33
43
  value: string;
34
44
  onChange: (value: string) => void;
35
45
  size: TabListSize;
36
46
  layout: TabListLayout;
47
+ pattern: TabListPattern;
37
48
  }
38
49
 
39
50
  export const TabListContext = createContext<TabListContextValue | null>(null);
@@ -37,7 +37,8 @@ import {useListFocus} from '../hooks/useListFocus';
37
37
  import {useTabListContext} from './TabListContext';
38
38
  import type {TabListSize} from './TabListContext';
39
39
  import {tabScope} from './tab.markers.stylex';
40
- import {mergeProps, mergeRefs} from '../utils';
40
+ import {mergeProps} from '../utils';
41
+ import {useMergedRefs} from '../hooks/useMergedRefs';
41
42
  import type {BaseProps} from '../BaseProps';
42
43
  import {themeProps} from '../utils/themeProps';
43
44
 
@@ -336,7 +337,7 @@ export function TabMenu({
336
337
  [tabListCtx, popover],
337
338
  );
338
339
 
339
- const setButtonRef = mergeRefs<HTMLButtonElement>(
340
+ const setButtonRef = useMergedRefs<HTMLButtonElement>(
340
341
  popover.triggerRef,
341
342
  buttonRef,
342
343
  ref,