@astryxdesign/core 0.4.7 → 0.5.0-canary.055e75f

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 (597) 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 +40 -15
  24. package/dist/Banner/Banner.d.ts.map +1 -1
  25. package/dist/Banner/Banner.js +51 -18
  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 +3 -1
  38. package/dist/Calendar/Calendar.d.ts.map +1 -1
  39. package/dist/Calendar/Calendar.js +14 -15
  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 +6 -9
  47. package/dist/Card/Card.d.ts.map +1 -1
  48. package/dist/Card/Card.js +6 -6
  49. package/dist/Carousel/Carousel.d.ts.map +1 -1
  50. package/dist/Carousel/Carousel.js +3 -3
  51. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  52. package/dist/Chat/ChatComposerInput.js +2 -3
  53. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  54. package/dist/Chat/ChatLayout.js +3 -3
  55. package/dist/Chat/ChatMessageList.d.ts +22 -3
  56. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  57. package/dist/Chat/ChatMessageList.js +6 -3
  58. package/dist/Chat/ChatTokenizedText.d.ts +2 -0
  59. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  60. package/dist/Chat/ChatTokenizedText.js +11 -6
  61. package/dist/Chat/useChatComposerTokens.js +1 -1
  62. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  63. package/dist/CheckboxInput/CheckboxInput.js +10 -3
  64. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  65. package/dist/ClickableCard/ClickableCard.js +3 -3
  66. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  67. package/dist/CodeBlock/CodeBlock.js +15 -4
  68. package/dist/CodeBlock/highlightRanges.js +1 -1
  69. package/dist/CodeBlock/highlightStyles.js +13 -13
  70. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  71. package/dist/CommandPalette/CommandPaletteInput.js +3 -2
  72. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  73. package/dist/CommandPalette/CommandPaletteItem.js +3 -2
  74. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  75. package/dist/ContextMenu/ContextMenu.js +4 -3
  76. package/dist/DateInput/DateInput.d.ts +43 -0
  77. package/dist/DateInput/DateInput.d.ts.map +1 -1
  78. package/dist/DateInput/DateInput.js +22 -2
  79. package/dist/DateInput/NativeDateField.d.ts +10 -0
  80. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  81. package/dist/DateInput/NativeDateField.js +494 -0
  82. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  83. package/dist/DateInput/TouchDateField.js +82 -23
  84. package/dist/DateInput/index.d.ts +1 -1
  85. package/dist/DateInput/index.d.ts.map +1 -1
  86. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  87. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  88. package/dist/DateInput/nativeDateSegments.js +111 -0
  89. package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
  90. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  91. package/dist/DateTimeInput/DateTimeInput.js +406 -12
  92. package/dist/DateTimeInput/index.d.ts +1 -1
  93. package/dist/DateTimeInput/index.d.ts.map +1 -1
  94. package/dist/Dialog/Dialog.d.ts +21 -1
  95. package/dist/Dialog/Dialog.d.ts.map +1 -1
  96. package/dist/Dialog/Dialog.js +110 -58
  97. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  98. package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
  99. package/dist/Field/FieldLabel.d.ts.map +1 -1
  100. package/dist/Field/FieldLabel.js +9 -1
  101. package/dist/FileInput/FileInput.d.ts.map +1 -1
  102. package/dist/FileInput/FileInput.js +3 -2
  103. package/dist/Heading/Heading.d.ts.map +1 -1
  104. package/dist/Heading/Heading.js +6 -2
  105. package/dist/HoverCard/HoverCard.d.ts +6 -0
  106. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  107. package/dist/HoverCard/HoverCard.js +104 -3
  108. package/dist/HoverCard/useHoverCard.d.ts +19 -2
  109. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  110. package/dist/HoverCard/useHoverCard.js +74 -26
  111. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  112. package/dist/Indicator/CheckboxIndicator.js +6 -2
  113. package/dist/Item/Item.d.ts.map +1 -1
  114. package/dist/Item/Item.js +4 -2
  115. package/dist/Kbd/Kbd.d.ts.map +1 -1
  116. package/dist/Kbd/Kbd.js +2 -19
  117. package/dist/Layer/LayerDepthContext.d.ts +52 -0
  118. package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
  119. package/dist/Layer/LayerDepthContext.js +66 -0
  120. package/dist/Layer/index.d.ts +3 -0
  121. package/dist/Layer/index.d.ts.map +1 -1
  122. package/dist/Layer/index.js +4 -0
  123. package/dist/Layer/layerStack.d.ts +98 -0
  124. package/dist/Layer/layerStack.d.ts.map +1 -0
  125. package/dist/Layer/layerStack.js +306 -0
  126. package/dist/Layer/useLayerDismissal.d.ts +93 -0
  127. package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
  128. package/dist/Layer/useLayerDismissal.js +91 -0
  129. package/dist/Lightbox/Lightbox.d.ts +1 -0
  130. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  131. package/dist/Lightbox/Lightbox.js +103 -81
  132. package/dist/Markdown/Markdown.d.ts.map +1 -1
  133. package/dist/Markdown/Markdown.js +9 -4
  134. package/dist/Markdown/index.d.ts +1 -1
  135. package/dist/Markdown/index.d.ts.map +1 -1
  136. package/dist/Markdown/parser.d.ts +38 -1
  137. package/dist/Markdown/parser.d.ts.map +1 -1
  138. package/dist/Markdown/parser.js +182 -32
  139. package/dist/MobileNav/MobileNav.d.ts +6 -1
  140. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  141. package/dist/MobileNav/MobileNav.js +61 -36
  142. package/dist/MultiSelector/MultiSelector.d.ts +32 -1
  143. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  144. package/dist/MultiSelector/MultiSelector.js +63 -11
  145. package/dist/MultiSelector/index.d.ts +1 -1
  146. package/dist/MultiSelector/index.d.ts.map +1 -1
  147. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  148. package/dist/NavIcon/NavIcon.js +5 -1
  149. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  150. package/dist/NavMenu/NavHeadingMenu.js +3 -2
  151. package/dist/NumberInput/NumberInput.d.ts +6 -1
  152. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  153. package/dist/NumberInput/NumberInput.js +54 -104
  154. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  155. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  156. package/dist/NumberInput/numberInputCommit.js +71 -0
  157. package/dist/NumberInput/numberParser.d.ts +64 -0
  158. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  159. package/dist/NumberInput/numberParser.js +350 -0
  160. package/dist/Outline/Outline.d.ts.map +1 -1
  161. package/dist/Outline/Outline.js +3 -2
  162. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  163. package/dist/OverflowList/OverflowList.js +3 -2
  164. package/dist/Overlay/Overlay.d.ts.map +1 -1
  165. package/dist/Overlay/Overlay.js +3 -2
  166. package/dist/Popover/usePopover.d.ts.map +1 -1
  167. package/dist/Popover/usePopover.js +20 -17
  168. package/dist/PowerSearch/PowerSearch.d.ts +8 -2
  169. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  170. package/dist/PowerSearch/PowerSearch.js +19 -6
  171. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
  172. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  173. package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
  174. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
  175. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  176. package/dist/PowerSearch/PowerSearchValueEditor.js +110 -27
  177. package/dist/PowerSearch/types.d.ts +2 -0
  178. package/dist/PowerSearch/types.d.ts.map +1 -1
  179. package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
  180. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  181. package/dist/PowerSearch/usePowerSearchSource.js +14 -5
  182. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  183. package/dist/ProgressBar/ProgressBar.js +18 -5
  184. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  185. package/dist/Resizable/ResizeHandle.js +3 -2
  186. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  187. package/dist/SegmentedControl/SegmentedControl.js +3 -2
  188. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  189. package/dist/SelectableCard/SelectableCard.js +3 -3
  190. package/dist/Selector/Selector.d.ts +17 -0
  191. package/dist/Selector/Selector.d.ts.map +1 -1
  192. package/dist/Selector/Selector.js +81 -14
  193. package/dist/SideNav/SideNav.d.ts.map +1 -1
  194. package/dist/SideNav/SideNav.js +4 -3
  195. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  196. package/dist/SideNav/SideNavHeading.js +8 -7
  197. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  198. package/dist/SideNav/SideNavItem.js +4 -3
  199. package/dist/Slider/Slider.d.ts.map +1 -1
  200. package/dist/Slider/Slider.js +37 -5
  201. package/dist/Spinner/Spinner.d.ts +3 -3
  202. package/dist/Spinner/Spinner.d.ts.map +1 -1
  203. package/dist/Spinner/Spinner.js +130 -78
  204. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  205. package/dist/StatusDot/StatusDot.js +6 -1
  206. package/dist/Stepper/Step.d.ts +140 -0
  207. package/dist/Stepper/Step.d.ts.map +1 -0
  208. package/dist/Stepper/Step.js +1045 -0
  209. package/dist/Stepper/StepStatus.d.ts +24 -0
  210. package/dist/Stepper/StepStatus.d.ts.map +1 -0
  211. package/dist/Stepper/StepStatus.js +1 -0
  212. package/dist/Stepper/Stepper.d.ts +93 -0
  213. package/dist/Stepper/Stepper.d.ts.map +1 -0
  214. package/dist/Stepper/Stepper.js +184 -0
  215. package/dist/Stepper/StepperContext.d.ts +41 -0
  216. package/dist/Stepper/StepperContext.d.ts.map +1 -0
  217. package/dist/Stepper/StepperContext.js +34 -0
  218. package/dist/Stepper/index.d.ts +8 -0
  219. package/dist/Stepper/index.d.ts.map +1 -0
  220. package/dist/Stepper/index.js +7 -0
  221. package/dist/Stepper/stepper.stylex.d.ts +15 -0
  222. package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
  223. package/dist/Stepper/stepper.stylex.js +20 -0
  224. package/dist/Switch/Switch.d.ts.map +1 -1
  225. package/dist/Switch/Switch.js +8 -3
  226. package/dist/TabList/Tab.d.ts +15 -2
  227. package/dist/TabList/Tab.d.ts.map +1 -1
  228. package/dist/TabList/Tab.js +32 -7
  229. package/dist/TabList/TabList.d.ts +46 -7
  230. package/dist/TabList/TabList.d.ts.map +1 -1
  231. package/dist/TabList/TabList.js +353 -23
  232. package/dist/TabList/TabListContext.d.ts +11 -1
  233. package/dist/TabList/TabListContext.d.ts.map +1 -1
  234. package/dist/TabList/TabListContext.js +11 -2
  235. package/dist/TabList/TabMenu.d.ts.map +1 -1
  236. package/dist/TabList/TabMenu.js +3 -2
  237. package/dist/TabList/index.d.ts +2 -2
  238. package/dist/TabList/index.d.ts.map +1 -1
  239. package/dist/Table/BaseTable.d.ts.map +1 -1
  240. package/dist/Table/BaseTable.js +10 -2
  241. package/dist/Table/Table.d.ts.map +1 -1
  242. package/dist/Table/Table.js +3 -6
  243. package/dist/Table/TableRow.d.ts +16 -5
  244. package/dist/Table/TableRow.d.ts.map +1 -1
  245. package/dist/Table/TableRow.js +16 -5
  246. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  247. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  248. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  249. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +20 -8
  250. package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
  251. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  252. package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
  253. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  254. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  255. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  256. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
  257. package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
  258. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  259. package/dist/Table/plugins/selection/useTableSelection.js +19 -5
  260. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  261. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  262. package/dist/Table/types.d.ts +22 -4
  263. package/dist/Table/types.d.ts.map +1 -1
  264. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  265. package/dist/Table/useBaseTablePlugins.js +5 -0
  266. package/dist/Text/Text.d.ts.map +1 -1
  267. package/dist/Text/Text.js +6 -2
  268. package/dist/TextArea/TextArea.d.ts.map +1 -1
  269. package/dist/TextArea/TextArea.js +9 -3
  270. package/dist/TextInput/TextInput.d.ts.map +1 -1
  271. package/dist/TextInput/TextInput.js +3 -2
  272. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  273. package/dist/TimeInput/TimeInput.js +3 -2
  274. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  275. package/dist/Timestamp/Timestamp.js +5 -3
  276. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  277. package/dist/Toast/ToastViewport.js +27 -8
  278. package/dist/Token/TokenLink.d.ts.map +1 -1
  279. package/dist/Token/TokenLink.js +2 -2
  280. package/dist/Tokenizer/Tokenizer.d.ts +3 -1
  281. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  282. package/dist/Tokenizer/Tokenizer.js +2 -0
  283. package/dist/Tooltip/Tooltip.d.ts +5 -0
  284. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  285. package/dist/Tooltip/useTooltip.d.ts +5 -0
  286. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  287. package/dist/Tooltip/useTooltip.js +39 -24
  288. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  289. package/dist/TopNav/TopNavHeading.js +5 -4
  290. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  291. package/dist/TopNav/TopNavMegaMenu.js +3 -3
  292. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  293. package/dist/TopNav/TopNavMenu.js +4 -3
  294. package/dist/Typeahead/BaseTypeahead.d.ts +2 -0
  295. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  296. package/dist/Typeahead/BaseTypeahead.js +68 -29
  297. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  298. package/dist/Typeahead/Typeahead.js +3 -2
  299. package/dist/astryx.css +98 -7
  300. package/dist/hooks/index.d.ts +1 -0
  301. package/dist/hooks/index.d.ts.map +1 -1
  302. package/dist/hooks/index.js +1 -0
  303. package/dist/hooks/useFocusTrap.d.ts +7 -4
  304. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  305. package/dist/hooks/useFocusTrap.js +60 -95
  306. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  307. package/dist/hooks/useHotkeys.js +3 -18
  308. package/dist/hooks/useMergedRefs.d.ts +18 -0
  309. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  310. package/dist/hooks/useMergedRefs.js +25 -0
  311. package/dist/index.d.ts +1 -0
  312. package/dist/index.d.ts.map +1 -1
  313. package/dist/index.js +1 -0
  314. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  315. package/dist/theme/derivedVarRegistry.js +24 -4
  316. package/dist/theme/syntax/tokens.d.ts +1 -1
  317. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  318. package/dist/theme/syntax/tokens.js +5 -2
  319. package/dist/utils/groupItems.d.ts +5 -1
  320. package/dist/utils/groupItems.d.ts.map +1 -1
  321. package/dist/utils/groupItems.js +9 -9
  322. package/dist/utils/index.d.ts +1 -1
  323. package/dist/utils/index.d.ts.map +1 -1
  324. package/dist/utils/isApplePlatform.d.ts +18 -0
  325. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  326. package/dist/utils/isApplePlatform.js +37 -0
  327. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  328. package/dist/utils/sharedResizeObserver.js +10 -1
  329. package/dist/utils/timeParser.d.ts +1 -1
  330. package/dist/utils/timeParser.d.ts.map +1 -1
  331. package/dist/utils/timeParser.js +26 -12
  332. package/locales/en.json +154 -10
  333. package/locales/pseudo.json +108 -0
  334. package/package.json +8 -3
  335. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  336. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  337. package/src/AlertDialog/AlertDialog.tsx +62 -20
  338. package/src/AppShell/AppShell.tsx +3 -2
  339. package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
  340. package/src/AspectRatio/AspectRatio.test.tsx +57 -10
  341. package/src/AspectRatio/AspectRatio.tsx +40 -1
  342. package/src/Avatar/Avatar.doc.mjs +14 -3
  343. package/src/Avatar/Avatar.test.tsx +97 -0
  344. package/src/Avatar/Avatar.tsx +125 -52
  345. package/src/Avatar/index.ts +2 -2
  346. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  347. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  348. package/src/AvatarGroup/AvatarGroup.tsx +15 -6
  349. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  350. package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
  351. package/src/Banner/Banner.doc.mjs +13 -11
  352. package/src/Banner/Banner.test.tsx +102 -15
  353. package/src/Banner/Banner.tsx +72 -25
  354. package/src/BottomSheet/BottomSheet.test.tsx +123 -0
  355. package/src/BottomSheet/BottomSheet.tsx +17 -4
  356. package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
  357. package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
  358. package/src/Button/Button.doc.mjs +24 -1
  359. package/src/Button/Button.test.tsx +32 -4
  360. package/src/Button/Button.tsx +12 -5
  361. package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
  362. package/src/ButtonGroup/ButtonGroup.test.tsx +404 -1
  363. package/src/ButtonGroup/ButtonGroup.tsx +23 -5
  364. package/src/Calendar/Calendar.doc.mjs +4 -3
  365. package/src/Calendar/Calendar.test.tsx +103 -0
  366. package/src/Calendar/Calendar.tsx +19 -16
  367. package/src/Calendar/getInitialFocusDate.test.ts +94 -0
  368. package/src/Calendar/getInitialFocusDate.ts +93 -0
  369. package/src/Calendar/styles.ts +49 -31
  370. package/src/Card/Card.doc.mjs +10 -7
  371. package/src/Card/Card.test.tsx +44 -19
  372. package/src/Card/Card.tsx +12 -32
  373. package/src/Carousel/Carousel.tsx +3 -2
  374. package/src/Chat/ChatComposerInput.tsx +5 -1
  375. package/src/Chat/ChatLayout.tsx +3 -2
  376. package/src/Chat/ChatMessageList.doc.mjs +9 -1
  377. package/src/Chat/ChatMessageList.test.tsx +46 -0
  378. package/src/Chat/ChatMessageList.tsx +28 -4
  379. package/src/Chat/ChatTokenizedText.tsx +17 -10
  380. package/src/Chat/useChatComposerTokens.ts +1 -1
  381. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  382. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  383. package/src/CheckboxInput/CheckboxInput.tsx +8 -2
  384. package/src/ClickableCard/ClickableCard.tsx +3 -2
  385. package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
  386. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  387. package/src/CodeBlock/CodeBlock.tsx +20 -4
  388. package/src/CodeBlock/highlightRanges.ts +1 -1
  389. package/src/CodeBlock/highlightStyles.ts +13 -13
  390. package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
  391. package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
  392. package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
  393. package/src/ContextMenu/ContextMenu.tsx +4 -3
  394. package/src/DateInput/DateInput.doc.mjs +16 -0
  395. package/src/DateInput/DateInput.tsx +55 -2
  396. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  397. package/src/DateInput/NativeDateField.test.tsx +635 -0
  398. package/src/DateInput/NativeDateField.tsx +641 -0
  399. package/src/DateInput/TouchDateField.tsx +108 -24
  400. package/src/DateInput/index.ts +1 -0
  401. package/src/DateInput/nativeDateSegments.ts +127 -0
  402. package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
  403. package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
  404. package/src/DateTimeInput/DateTimeInput.tsx +556 -24
  405. package/src/DateTimeInput/index.ts +1 -0
  406. package/src/Dialog/Dialog.doc.mjs +8 -3
  407. package/src/Dialog/Dialog.test.tsx +429 -2
  408. package/src/Dialog/Dialog.tsx +133 -58
  409. package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
  410. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
  411. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
  412. package/src/Field/Field.doc.mjs +13 -2
  413. package/src/Field/FieldLabel.test.tsx +29 -0
  414. package/src/Field/FieldLabel.tsx +7 -0
  415. package/src/FileInput/FileInput.tsx +3 -2
  416. package/src/Heading/Heading.test.tsx +23 -1
  417. package/src/Heading/Heading.tsx +6 -2
  418. package/src/HoverCard/HoverCard.doc.mjs +13 -2
  419. package/src/HoverCard/HoverCard.test.tsx +154 -4
  420. package/src/HoverCard/HoverCard.tsx +143 -3
  421. package/src/HoverCard/useHoverCard.tsx +104 -33
  422. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  423. package/src/Indicator/Indicator.doc.mjs +2 -0
  424. package/src/Item/Item.tsx +5 -4
  425. package/src/Kbd/Kbd.tsx +2 -19
  426. package/src/Layer/LayerDepthContext.tsx +62 -0
  427. package/src/Layer/index.ts +9 -0
  428. package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
  429. package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
  430. package/src/Layer/layerStack.ts +362 -0
  431. package/src/Layer/useLayer.test.tsx +62 -14
  432. package/src/Layer/useLayerDismissal.test.tsx +469 -0
  433. package/src/Layer/useLayerDismissal.ts +173 -0
  434. package/src/Layout/Layout.doc.mjs +2 -2
  435. package/src/Lightbox/Lightbox.doc.mjs +12 -0
  436. package/src/Lightbox/Lightbox.tsx +124 -102
  437. package/src/Link/Link.doc.mjs +39 -0
  438. package/src/Markdown/Markdown.doc.mjs +5 -0
  439. package/src/Markdown/Markdown.tsx +9 -4
  440. package/src/Markdown/incremental.test.ts +16 -2
  441. package/src/Markdown/index.ts +1 -0
  442. package/src/Markdown/parser.perf.test.ts +96 -1
  443. package/src/Markdown/parser.test.ts +178 -2
  444. package/src/Markdown/parser.ts +253 -32
  445. package/src/MobileNav/MobileNav.tsx +62 -36
  446. package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
  447. package/src/MultiSelector/MultiSelector.doc.mjs +49 -1
  448. package/src/MultiSelector/MultiSelector.test.tsx +277 -0
  449. package/src/MultiSelector/MultiSelector.tsx +142 -11
  450. package/src/MultiSelector/index.ts +1 -0
  451. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  452. package/src/NavIcon/NavIcon.test.tsx +9 -0
  453. package/src/NavIcon/NavIcon.tsx +5 -1
  454. package/src/NavMenu/NavHeadingMenu.tsx +3 -2
  455. package/src/NumberInput/NumberInput.doc.mjs +31 -7
  456. package/src/NumberInput/NumberInput.test.tsx +436 -8
  457. package/src/NumberInput/NumberInput.tsx +62 -114
  458. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  459. package/src/NumberInput/numberInputCommit.ts +103 -0
  460. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  461. package/src/NumberInput/numberParser.test.ts +222 -0
  462. package/src/NumberInput/numberParser.ts +403 -0
  463. package/src/Outline/Outline.tsx +3 -2
  464. package/src/OverflowList/OverflowList.tsx +3 -2
  465. package/src/Overlay/Overlay.tsx +3 -2
  466. package/src/Pagination/Pagination.test.tsx +3 -2
  467. package/src/Popover/usePopover.tsx +31 -28
  468. package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
  469. package/src/PowerSearch/PowerSearch.test.tsx +240 -1
  470. package/src/PowerSearch/PowerSearch.tsx +34 -5
  471. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +288 -0
  472. package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
  473. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +111 -1
  474. package/src/PowerSearch/PowerSearchValueEditor.tsx +124 -10
  475. package/src/PowerSearch/types.ts +2 -0
  476. package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
  477. package/src/PowerSearch/usePowerSearchSource.ts +13 -3
  478. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  479. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  480. package/src/ProgressBar/ProgressBar.tsx +28 -8
  481. package/src/Resizable/ResizeHandle.tsx +3 -2
  482. package/src/SegmentedControl/SegmentedControl.tsx +3 -2
  483. package/src/SelectableCard/SelectableCard.tsx +3 -2
  484. package/src/Selector/Selector.doc.mjs +26 -1
  485. package/src/Selector/Selector.test.tsx +311 -1
  486. package/src/Selector/Selector.tsx +139 -16
  487. package/src/SideNav/SideNav.doc.mjs +6 -6
  488. package/src/SideNav/SideNav.tsx +4 -2
  489. package/src/SideNav/SideNavHeading.tsx +12 -12
  490. package/src/SideNav/SideNavItem.tsx +4 -2
  491. package/src/Slider/Slider.test.tsx +106 -1
  492. package/src/Slider/Slider.tsx +55 -3
  493. package/src/Spinner/Spinner.test.tsx +147 -1
  494. package/src/Spinner/Spinner.tsx +120 -101
  495. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  496. package/src/StatusDot/StatusDot.test.tsx +9 -0
  497. package/src/StatusDot/StatusDot.tsx +7 -1
  498. package/src/Stepper/Step.doc.mjs +98 -0
  499. package/src/Stepper/Step.tsx +1638 -0
  500. package/src/Stepper/StepStatus.ts +26 -0
  501. package/src/Stepper/Stepper.doc.mjs +370 -0
  502. package/src/Stepper/Stepper.test.tsx +1024 -0
  503. package/src/Stepper/Stepper.tsx +258 -0
  504. package/src/Stepper/StepperContext.ts +71 -0
  505. package/src/Stepper/index.ts +18 -0
  506. package/src/Stepper/stepper.stylex.ts +19 -0
  507. package/src/Switch/Switch.doc.mjs +2 -0
  508. package/src/Switch/Switch.test.tsx +10 -0
  509. package/src/Switch/Switch.tsx +6 -2
  510. package/src/TabList/Tab.doc.mjs +13 -1
  511. package/src/TabList/Tab.tsx +67 -7
  512. package/src/TabList/TabList.doc.mjs +22 -6
  513. package/src/TabList/TabList.test.tsx +559 -0
  514. package/src/TabList/TabList.tsx +490 -22
  515. package/src/TabList/TabListContext.ts +13 -2
  516. package/src/TabList/TabMenu.tsx +3 -2
  517. package/src/TabList/index.ts +6 -2
  518. package/src/Table/BaseTable.tsx +12 -4
  519. package/src/Table/Table.doc.mjs +9 -2
  520. package/src/Table/Table.test.tsx +132 -14
  521. package/src/Table/Table.tsx +3 -8
  522. package/src/Table/TableBody.doc.mjs +40 -0
  523. package/src/Table/TableFooter.doc.mjs +40 -0
  524. package/src/Table/TableHeader.doc.mjs +40 -0
  525. package/src/Table/TableRow.tsx +16 -5
  526. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  527. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  528. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
  529. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
  530. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +17 -8
  531. package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
  532. package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
  533. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
  534. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
  535. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
  536. package/src/Table/plugins/selection/useTableSelection.test.tsx +76 -0
  537. package/src/Table/plugins/selection/useTableSelection.tsx +40 -7
  538. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  539. package/src/Table/types.ts +22 -4
  540. package/src/Table/useBaseTablePlugins.ts +5 -0
  541. package/src/Table/useTableGroupedRows.doc.mjs +5 -4
  542. package/src/Table/useTablePagination.doc.mjs +7 -0
  543. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  544. package/src/Table/useTableSelection.doc.mjs +31 -0
  545. package/src/Text/Text.test.tsx +23 -1
  546. package/src/Text/Text.tsx +6 -2
  547. package/src/TextArea/TextArea.doc.mjs +8 -2
  548. package/src/TextArea/TextArea.test.tsx +11 -0
  549. package/src/TextArea/TextArea.tsx +15 -8
  550. package/src/TextInput/TextInput.doc.mjs +10 -0
  551. package/src/TextInput/TextInput.tsx +3 -2
  552. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  553. package/src/TimeInput/TimeInput.tsx +2 -2
  554. package/src/Timestamp/Timestamp.test.tsx +18 -0
  555. package/src/Timestamp/Timestamp.tsx +4 -2
  556. package/src/Toast/Toast.doc.mjs +6 -0
  557. package/src/Toast/ToastViewport.tsx +17 -1
  558. package/src/Token/TokenLink.tsx +2 -2
  559. package/src/Tokenizer/Tokenizer.doc.mjs +27 -0
  560. package/src/Tokenizer/Tokenizer.tsx +4 -0
  561. package/src/Toolbar/Toolbar.doc.mjs +5 -0
  562. package/src/Tooltip/Tooltip.doc.mjs +5 -0
  563. package/src/Tooltip/Tooltip.test.tsx +32 -0
  564. package/src/Tooltip/Tooltip.tsx +5 -0
  565. package/src/Tooltip/useTooltip.tsx +47 -24
  566. package/src/TopNav/TopNavHeading.tsx +5 -4
  567. package/src/TopNav/TopNavMegaMenu.tsx +3 -2
  568. package/src/TopNav/TopNavMenu.tsx +4 -3
  569. package/src/Typeahead/BaseTypeahead.doc.mjs +11 -0
  570. package/src/Typeahead/BaseTypeahead.tsx +85 -33
  571. package/src/Typeahead/Typeahead.doc.mjs +5 -0
  572. package/src/Typeahead/Typeahead.test.tsx +49 -0
  573. package/src/Typeahead/Typeahead.tsx +3 -2
  574. package/src/hooks/index.ts +2 -0
  575. package/src/hooks/useContainerReveal.doc.mjs +2 -2
  576. package/src/hooks/useFocusTrap.test.tsx +14 -0
  577. package/src/hooks/useFocusTrap.ts +62 -111
  578. package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
  579. package/src/hooks/useHotkeys.ts +3 -18
  580. package/src/hooks/useMergedRefs.doc.mjs +79 -0
  581. package/src/hooks/useMergedRefs.test.tsx +62 -0
  582. package/src/hooks/useMergedRefs.ts +36 -0
  583. package/src/index.ts +1 -0
  584. package/src/raw-import.d.ts +14 -0
  585. package/src/theme/MediaTheme.doc.mjs +5 -5
  586. package/src/theme/derivedVarRegistry.test.ts +19 -3
  587. package/src/theme/derivedVarRegistry.ts +23 -4
  588. package/src/theme/generateThemeRules.test.ts +37 -0
  589. package/src/theme/syntax/tokens.ts +5 -2
  590. package/src/utils/groupItems.ts +12 -6
  591. package/src/utils/index.ts +1 -1
  592. package/src/utils/isApplePlatform.test.ts +61 -0
  593. package/src/utils/isApplePlatform.ts +37 -0
  594. package/src/utils/sharedResizeObserver.ts +10 -2
  595. package/src/utils/timeParser.test.ts +6 -1
  596. package/src/utils/timeParser.ts +35 -13
  597. package/src/__tests__/inputWidthContract.test.tsx +0 -69
@@ -1,10 +1,14 @@
1
1
  /**
2
2
  * @file TabList.tsx
3
- * @input Uses React, StyleX, TabListContext, useListFocus, useKeyboardHint
4
- * @output Exports TabList component and TabListProps type
5
- * @position Nav wrapper; provides TabListContext to Tab and TabMenu children.
6
- * Owns roving-tabindex keyboard navigation (Arrow/Home/End) across the tab
7
- * strip via the shared useListFocus hook so it is a single Tab stop.
3
+ * @input Uses React, StyleX, TabListContext, useListFocus, useKeyboardHint,
4
+ * useScrollOverflow, Icon
5
+ * @output Exports TabList component, TabListProps and TabListOverflow types
6
+ * @position Tab strip wrapper; provides TabListContext to Tab and TabMenu
7
+ * children. A `<nav>` landmark by default; speaks the WAI-ARIA tabs pattern
8
+ * where the caller asks for it with `role="tablist"`. Owns
9
+ * roving-tabindex keyboard navigation (Arrow/Home/End) across the tab
10
+ * strip via the shared useListFocus hook so it is a single Tab stop, and
11
+ * owns horizontal scrolling when the tabs are wider than the strip.
8
12
  *
9
13
  * SYNC: When modified, update:
10
14
  * - /packages/core/src/TabList/TabList.doc.mjs
@@ -12,10 +16,20 @@
12
16
  * - /packages/core/src/TabList/TabList.test.tsx
13
17
  * - /packages/cli/assets/templates/blocks/components/TabList/ (showcase blocks)
14
18
  */
15
- import React, { type ReactNode } from 'react';
19
+ import React, { type AriaRole, type ReactNode } from 'react';
16
20
  import type { BaseProps } from '../BaseProps';
17
21
  import type { TabListSize } from './TabListContext';
18
22
  import { EDGE_COMP_ATTR } from '../Layout/edgeCompensation.stylex';
23
+ /**
24
+ * How a strip narrower than its tabs behaves.
25
+ *
26
+ * - `'auto'` — the component picks the strategy. Today that is always
27
+ * `'scroll'`.
28
+ * - `'scroll'` — the tabs scroll horizontally. Every tab stays a tab.
29
+ * - `'visible'` — no overflow handling: tabs keep their intrinsic widths and
30
+ * spill out of the strip, as they did before overflow existed.
31
+ */
32
+ export type TabListOverflow = 'auto' | 'scroll' | 'visible';
19
33
  export interface TabListProps extends Omit<BaseProps<HTMLElement>, 'onChange'> {
20
34
  ref?: React.Ref<HTMLElement>;
21
35
  /**
@@ -44,6 +58,31 @@ export interface TabListProps extends Omit<BaseProps<HTMLElement>, 'onChange'> {
44
58
  * @default false
45
59
  */
46
60
  hasDivider?: boolean;
61
+ /**
62
+ * ARIA role for the strip.
63
+ *
64
+ * `"tablist"` asks for the WAI-ARIA tabs pattern: `role="tablist"` /
65
+ * `role="tab"` and `aria-selected`, with each tab pointing at the panel it
66
+ * controls via its `panelId`. Only tabs may live in a tablist strip, and a
67
+ * tab does not navigate — an `href` is ignored there.
68
+ *
69
+ * Left unset, the strip is a `<nav>` landmark marking the current tab with
70
+ * `aria-current`. Any other value is passed through to the element
71
+ * unchanged.
72
+ */
73
+ role?: AriaRole;
74
+ /**
75
+ * What happens when the tabs are wider than the strip.
76
+ *
77
+ * `'auto'` lets the component choose; today it always scrolls. `'scroll'`
78
+ * scrolls the tabs horizontally, with edge fades and — for pointers that
79
+ * can hover — arrow affordances. `'visible'` turns overflow handling off and
80
+ * lets the tabs spill out of the strip.
81
+ *
82
+ * The selected tab is always scrolled back into view.
83
+ * @default 'auto'
84
+ */
85
+ overflow?: TabListOverflow;
47
86
  /**
48
87
  * Tab and TabMenu children.
49
88
  */
@@ -65,7 +104,7 @@ export interface TabListProps extends Omit<BaseProps<HTMLElement>, 'onChange'> {
65
104
  * </TabList>
66
105
  * ```
67
106
  */
68
- export declare function TabList({ ref, value, onChange, size: sizeProp, layout, hasDivider, xstyle, className, style, children, onKeyDown: onKeyDownProp, onFocus: onFocusProp, onBlur: onBlurProp, 'aria-label': ariaLabelFromProps, 'aria-orientation': _ariaOrientation, [EDGE_COMP_ATTR]: _edgeCompAttr, ...restProps }: TabListProps): React.JSX.Element;
107
+ export declare function TabList({ ref, value, onChange, size: sizeProp, layout, hasDivider, role, overflow, xstyle, className, style, children, onKeyDown: onKeyDownProp, onFocus: onFocusProp, onBlur: onBlurProp, 'aria-label': ariaLabelFromProps, 'aria-labelledby': ariaLabelledBy, 'aria-orientation': _ariaOrientation, [EDGE_COMP_ATTR]: _edgeCompAttr, ...restProps }: TabListProps): React.JSX.Element;
69
108
  export declare namespace TabList {
70
109
  var displayName: string;
71
110
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TabList.d.ts","sourceRoot":"","sources":["../../src/TabList/TabList.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAAuB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGlE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAKlD,OAAO,EAAC,cAAc,EAAC,MAAM,mCAAmC,CAAC;AAWjE,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IAC5E,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AA4BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,GAAG,EACH,KAAK,EACL,QAAQ,EACR,IAAI,EAAE,QAAQ,EACd,MAAc,EACd,UAAkB,EAClB,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,kBAAkB,EAChC,kBAAkB,EAAE,gBAAgB,EACpC,CAAC,cAAc,CAAC,EAAE,aAAa,EAC/B,GAAG,SAAS,EACb,EAAE,YAAY,qBAkGd;yBApHe,OAAO"}
1
+ {"version":3,"file":"TabList.d.ts","sourceRoot":"","sources":["../../src/TabList/TabList.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,EAKZ,KAAK,QAAQ,EACb,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAaf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAQlD,OAAO,EAAC,cAAc,EAAC,MAAM,mCAAmC,CAAC;AAsBjE;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE5D,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IAC5E,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAyLD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,GAAG,EACH,KAAK,EACL,QAAQ,EACR,IAAI,EAAE,QAAQ,EACd,MAAc,EACd,UAAkB,EAClB,IAAI,EACJ,QAAiB,EACjB,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,kBAAkB,EAChC,iBAAiB,EAAE,cAAc,EACjC,kBAAkB,EAAE,gBAAgB,EACpC,CAAC,cAAc,CAAC,EAAE,aAAa,EAC/B,GAAG,SAAS,EACb,EAAE,YAAY,qBA+Ud;yBApWe,OAAO"}
@@ -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
@@ -16,26 +20,96 @@
16
20
  * - /packages/core/src/TabList/TabList.test.tsx
17
21
  * - /packages/cli/assets/templates/blocks/components/TabList/ (showcase blocks)
18
22
  */
19
- import React, { useCallback, useMemo } from 'react';
23
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
20
24
  import * as stylex from '@stylexjs/stylex';
21
25
  import "../theme/tokens.stylex.js";
22
- import { borderVars, colorVars, spacingVars } from "../theme/tokens.stylex.js";
26
+ import { borderVars, colorVars, durationVars, easeVars, focusVars, radiusVars, shadowVars, sizeVars, spacingVars } from "../theme/tokens.stylex.js";
23
27
  import { TabListContext } from "./TabListContext.js";
24
28
  import { useSize } from "../SizeContext/SizeContext.js";
25
- import { mergeProps, mergeRefs } from "../utils/index.js";
29
+ import { mergeProps, rtlStyles } from "../utils/index.js";
26
30
  import { useListFocus } from "../hooks/useListFocus.js";
27
31
  import { useKeyboardHint } from "../hooks/useKeyboardHint.js";
32
+ import { useScrollOverflow } from "../hooks/useScrollOverflow.js";
33
+ import { isRtlElement } from "../hooks/isRtlElement.js";
34
+ import { Icon } from "../Icon/index.js";
28
35
  import { EDGE_COMP_ATTR } from "../Layout/edgeCompensation.stylex.js";
29
36
  import { themeProps } from "../utils/themeProps.js";
37
+ import { observeResize, unobserveResize } from "../utils/sharedResizeObserver.js";
38
+ import { devWarn } from "../utils/devWarning.js";
39
+ import { focusOutlineProps } from "../utils/focusOutline.stylex.js";
30
40
  import { useTranslator } from "../i18n/index.js";
31
-
41
+ import { useMergedRefs } from "../hooks/useMergedRefs.js";
32
42
  /**
33
43
  * Selector matching the focusable stops in the tab strip: every Tab
34
44
  * (`[data-tab-value]`) and every TabMenu trigger (`[data-tab-menu]`),
35
45
  * in DOM order. Disabled stops are filtered out by the handler.
36
46
  */
37
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
47
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
38
48
  const TAB_STOP_SELECTOR = '[data-tab-value],[data-tab-menu]';
49
+ function preventFocus(e) {
50
+ e.preventDefault();
51
+ }
52
+
53
+ /** Fraction of the visible strip an arrow press scrolls. */
54
+ const SCROLL_PAGE_RATIO = 0.8;
55
+
56
+ /**
57
+ * How a strip narrower than its tabs behaves.
58
+ *
59
+ * - `'auto'` — the component picks the strategy. Today that is always
60
+ * `'scroll'`.
61
+ * - `'scroll'` — the tabs scroll horizontally. Every tab stays a tab.
62
+ * - `'visible'` — no overflow handling: tabs keep their intrinsic widths and
63
+ * spill out of the strip, as they did before overflow existed.
64
+ */
65
+
66
+ /**
67
+ * A scroll container clips at its padding box, and two things a tab paints sit
68
+ * outside its own box: the focus ring (offset + width) and the selected
69
+ * indicator, which `--_tab-indicator-bottom` pushes further down when a
70
+ * divider rail is reserved. The strip pads by that much and takes the padding
71
+ * straight back off with a negative margin, so nothing is clipped and the tabs
72
+ * stay exactly where they were.
73
+ *
74
+ * A bleed is not free, though. The padding is real geometry: the strip's
75
+ * border box sticks out of the TabList's, and any ancestor that scrolls counts
76
+ * that as something to scroll to. So the ring's share of the bleed is taken
77
+ * only while a ring is actually drawn inside the strip -- the same
78
+ * `:has(:focus-visible)` condition that draws it -- and at rest the strip is
79
+ * exactly as wide and as tall as the TabList, as it was before the strip could
80
+ * scroll. The indicator's share is always taken, because the indicator is
81
+ * always drawn.
82
+ *
83
+ * Turning the bleed on moves nothing: padding and negative margin cancel, so
84
+ * the border box grows outwards and the content stays put.
85
+ */
86
+ const RING_BLEED = `calc(${focusVars['--focus-outline-width']} + ${focusVars['--focus-outline-offset']})`;
87
+ const BLEED_VAR = '--_tab-strip-bleed';
88
+ const BLEED = `var(${BLEED_VAR})`;
89
+ const INDICATOR_BLEED = 'calc(-1 * var(--_tab-indicator-bottom, -1px))';
90
+ const BLOCK_END_BLEED = `max(${BLEED}, ${INDICATOR_BLEED})`;
91
+
92
+ /** How far the edge fade runs; wide enough to sit under an arrow. */
93
+ const FADE_WIDTH = spacingVars['--spacing-8'];
94
+
95
+ /**
96
+ * Where the fade turns fully opaque, and — the same distance, for the same
97
+ * reason — how far a revealed stop is kept clear of the edge. Declared as
98
+ * scroll-padding so the browser's own focus scrolling uses it too, and read
99
+ * back from the computed style so the arithmetic below has one source of
100
+ * truth with the CSS.
101
+ */
102
+ const SCROLL_EDGE_INSET = `calc(${BLEED} + ${FADE_WIDTH})`;
103
+
104
+ /**
105
+ * The fade reaches transparent at the strip's *own* edge, not at the bleed
106
+ * edge — otherwise the scroll container paints tabs past the TabList's box,
107
+ * past a divider rail, and past the scroll arrow that caps that edge. Masking
108
+ * the bleed costs nothing: only a faded edge is masked, and a stop at a faded
109
+ * edge never holds focus, so the bleed is still there when the ring needs it.
110
+ */
111
+ const FADE_FROM_START = `linear-gradient(to right, transparent ${BLEED}, black ${SCROLL_EDGE_INSET})`;
112
+ const FADE_FROM_END = `linear-gradient(to left, transparent ${BLEED}, black ${SCROLL_EDGE_INSET})`;
39
113
  const styles = {
40
114
  nav: {
41
115
  k1xSpc: "x78zum5",
@@ -43,6 +117,7 @@ const styles = {
43
117
  kOIVth: "x1lsbc85",
44
118
  ks0D6T: "x193iq5w",
45
119
  k7Eaqz: "xeuugli",
120
+ kVAEAm: "x1n2onr6",
46
121
  $$css: true
47
122
  },
48
123
  fill: {
@@ -56,6 +131,89 @@ const styles = {
56
131
  kGO01o: "xy143xn",
57
132
  "--_tab-indicator-bottom": "xficto1",
58
133
  $$css: true
134
+ },
135
+ strip: {
136
+ k1xSpc: "x78zum5",
137
+ kGNEyG: "x1qjc9v5",
138
+ kOIVth: "x14kbac9",
139
+ kzQI83: "x1iyjqo2",
140
+ kmuXW: "xs83m0k",
141
+ k7Eaqz: "xeuugli",
142
+ kSGwAc: "xqcrz7y",
143
+ $$css: true
144
+ },
145
+ stripScroll: {
146
+ kXHlph: "xw2csxc",
147
+ kORKVm: "x10wlt62",
148
+ kvh3hx: "x7p5m3t",
149
+ katHQp: "x1xif8ns",
150
+ k5wCbM: "x1rohswg",
151
+ khEr5k: "xkcv6ua xg83hb1",
152
+ "--_tab-strip-bleed": "x78b515 x158n88w",
153
+ kLKAdn: "xlr2r7p",
154
+ keoZOQ: "xmqyaqf",
155
+ kGO01o: "xwhchk8",
156
+ k1K539: "xlgak1e",
157
+ kg3NbH: "x1kpkw9v",
158
+ kUOVxO: "xi5l473",
159
+ kX1K2I: "xw4ya9i",
160
+ k1ekBW: "x157bb6t",
161
+ kIyJzY: "x80gvsz x12w9bfk",
162
+ kAMwcw: "xlr8y92",
163
+ $$css: true
164
+ },
165
+ fadeStart: {
166
+ kX1K2I: "x1hua2o0 x1nwey30",
167
+ $$css: true
168
+ },
169
+ fadeEnd: {
170
+ kX1K2I: "xoj6v2h x1rxa4r8",
171
+ $$css: true
172
+ },
173
+ fadeBoth: {
174
+ kX1K2I: "xq05pg6",
175
+ $$css: true
176
+ },
177
+ arrow: {
178
+ kVAEAm: "x10l6tqk",
179
+ k87sOh: "x13vifvy",
180
+ k1xSpc: "x1s85apg xqwu39o",
181
+ kGNEyG: "x6s0dn4",
182
+ kjj79g: "xl56j7k",
183
+ kmVPX3: "x1717udv",
184
+ kMzoRj: "xc342km",
185
+ ksu8eU: "xng3xce",
186
+ kaIpWk: "xjspbzw",
187
+ kWkggS: "x1prclbq",
188
+ kGVxlE: "x1i5ehqx",
189
+ kMwMTN: "xv1l7n4 x9o1np9",
190
+ kkrTdU: "x1ypdohk x16khyan",
191
+ $$css: true
192
+ },
193
+ arrowStart: {
194
+ kLqNvP: "x1o0tod",
195
+ $$css: true
196
+ },
197
+ arrowEnd: {
198
+ kt4wiu: "xtijo5x",
199
+ $$css: true
200
+ }
201
+ };
202
+ const arrowSizeStyles = {
203
+ sm: {
204
+ kzqmXN: "x1fvqzum",
205
+ kZKoxP: "x6k0iem",
206
+ $$css: true
207
+ },
208
+ md: {
209
+ kzqmXN: "x805d0l",
210
+ kZKoxP: "x1ueg155",
211
+ $$css: true
212
+ },
213
+ lg: {
214
+ kzqmXN: "x1m747yf",
215
+ kZKoxP: "xssyfek",
216
+ $$css: true
59
217
  }
60
218
  };
61
219
 
@@ -82,6 +240,8 @@ export function TabList({
82
240
  size: sizeProp,
83
241
  layout = 'hug',
84
242
  hasDivider = false,
243
+ role,
244
+ overflow = 'auto',
85
245
  xstyle,
86
246
  className,
87
247
  style,
@@ -90,6 +250,7 @@ export function TabList({
90
250
  onFocus: onFocusProp,
91
251
  onBlur: onBlurProp,
92
252
  'aria-label': ariaLabelFromProps,
253
+ 'aria-labelledby': ariaLabelledBy,
93
254
  'aria-orientation': _ariaOrientation,
94
255
  [EDGE_COMP_ATTR]: _edgeCompAttr,
95
256
  ...restProps
@@ -97,13 +258,21 @@ export function TabList({
97
258
  const t = useTranslator();
98
259
  const ariaLabel = ariaLabelFromProps ?? t('@astryx.tabList.label');
99
260
  const size = useSize(sizeProp, 'md');
261
+ const hasScroll = overflow !== 'visible';
262
+ const stripRef = useRef(null);
263
+ // Only an asserted `role="tablist"` switches the pattern. Left unset the
264
+ // strip is the `<nav>` it has always been, and every other role passes
265
+ // through to the element untouched.
266
+ const isTabList = role === 'tablist';
100
267
 
101
268
  // Roving-tabindex keyboard navigation across the tab strip via the shared
102
- // hook. `orientation: 'both'` accepts both arrow axes per the WAI-ARIA APG
103
- // allowance for tab strips (ArrowRight/ArrowDown advance, ArrowLeft/ArrowUp
104
- // retreat). We do not set `aria-orientation` on the `<nav>`: that attribute
105
- // is invalid on the navigation role and triggers an axe `aria-allowed-attr`
106
- // violation.
269
+ // hook. Under the navigation pattern `orientation: 'both'` accepts both
270
+ // arrow axes per the WAI-ARIA APG allowance for tab strips
271
+ // (ArrowRight/ArrowDown advance, ArrowLeft/ArrowUp retreat). A tablist
272
+ // reports itself as horizontal, so there the strip takes only the
273
+ // horizontal arrows and leaves ArrowUp and ArrowDown to scroll the page. We
274
+ // do not set `aria-orientation` on the `<nav>`: that attribute is invalid on
275
+ // the navigation role and triggers an axe `aria-allowed-attr` violation.
107
276
  //
108
277
  // `hasRovingTabIndex` makes the hook own the single tab stop: it stamps
109
278
  // tabindex 0/-1, repairs the stop on mount and as stops mount/unmount or
@@ -118,7 +287,7 @@ export function TabList({
118
287
  handleFocus
119
288
  } = useListFocus({
120
289
  itemSelector: TAB_STOP_SELECTOR,
121
- orientation: 'both',
290
+ orientation: isTabList ? 'horizontal' : 'both',
122
291
  hasRovingTabIndex: true
123
292
  });
124
293
  const {
@@ -127,12 +296,105 @@ export function TabList({
127
296
  onFocus: onHintFocus,
128
297
  onBlur: onHintBlur
129
298
  } = useKeyboardHint();
299
+ const {
300
+ scrollRef,
301
+ overflowStart,
302
+ overflowEnd
303
+ } = useScrollOverflow();
304
+ const attachStrip = useCallback(el => {
305
+ stripRef.current = el;
306
+ scrollRef(hasScroll ? el : null);
307
+ }, [hasScroll, scrollRef]);
308
+ const revealStop = useCallback(stop => {
309
+ const strip = stripRef.current;
310
+ if (!hasScroll || !strip || !stop) {
311
+ return;
312
+ }
313
+ const stripBox = strip.getBoundingClientRect();
314
+ const stopBox = stop.getBoundingClientRect();
315
+ const inset = parseFloat(getComputedStyle(strip).scrollPaddingLeft) || 0;
316
+ const pastEnd = stopBox.right - (stripBox.right - inset);
317
+ const pastStart = stopBox.left - (stripBox.left + inset);
318
+ // A stop wider than the space kept clear cannot be shown whole, so show
319
+ // its reading start, the way `scrollIntoView({inline: 'nearest'})` does.
320
+ const tooWide = stopBox.width > stripBox.width - 2 * inset;
321
+ const delta = tooWide ? isRtlElement(strip) ? pastEnd : pastStart : pastEnd > 0 ? pastEnd : pastStart < 0 ? pastStart : 0;
322
+ if (delta !== 0) {
323
+ // Not an animation: the strip has to arrive already showing the right
324
+ // tab, so this overrides the CSS smooth behaviour arrow presses use.
325
+ strip.scrollBy({
326
+ left: delta,
327
+ behavior: 'instant'
328
+ });
329
+ }
330
+ }, [hasScroll]);
331
+ const revealSelectedTab = useCallback(() => {
332
+ const strip = stripRef.current;
333
+ if (!strip) {
334
+ return;
335
+ }
336
+ revealStop(Array.from(strip.querySelectorAll('[data-tab-value]')).find(el => el.dataset.tabValue === value) ?? null);
337
+ }, [revealStop, value]);
338
+
339
+ // Both reveals below reach the callback through a ref instead of depending
340
+ // on it: its identity also changes with `overflow`, and that is not a reason
341
+ // to scroll anything.
342
+ const revealSelectedTabRef = useRef(revealSelectedTab);
343
+ useEffect(() => {
344
+ revealSelectedTabRef.current = revealSelectedTab;
345
+ }, [revealSelectedTab]);
346
+
347
+ // The tab you are on has to be visible. Selection can move without focus —
348
+ // on mount, or when the host sets `value` itself — and neither scrolls the
349
+ // strip the way clicking or arrowing to a tab does. The check is what makes
350
+ // a selection change the trigger, rather than the effect happening to run.
351
+ const revealedValueRef = useRef(null);
352
+ useEffect(() => {
353
+ if (revealedValueRef.current === value) {
354
+ return;
355
+ }
356
+ revealedValueRef.current = value;
357
+ revealSelectedTabRef.current();
358
+ }, [value]);
359
+
360
+ // ...and it has to stay visible when the strip is what moved. A strip that
361
+ // fitted at one width can hide the selected tab at a narrower one, and no
362
+ // prop changes when that happens. This one re-reveals the same selection by
363
+ // design, which is why the check above sits in the effect rather than in
364
+ // `revealSelectedTab`.
365
+ //
366
+ // The wrapper is observed rather than the strip because the shared observer
367
+ // keeps one callback per element and `useScrollOverflow` already holds the
368
+ // strip's.
369
+ useEffect(() => {
370
+ const root = listRef.current;
371
+ if (!hasScroll || !root) {
372
+ return;
373
+ }
374
+ const onResize = () => revealSelectedTabRef.current();
375
+ observeResize(root, onResize);
376
+ return () => unobserveResize(root);
377
+ }, [hasScroll, listRef]);
378
+ const scrollByPage = useCallback(direction => {
379
+ const strip = stripRef.current;
380
+ if (!strip) {
381
+ return;
382
+ }
383
+ // Under RTL the scroll axis is inverted, so flip the physical delta.
384
+ const rtlSign = isRtlElement(strip) ? -1 : 1;
385
+ strip.scrollBy({
386
+ left: rtlSign * direction * strip.clientWidth * SCROLL_PAGE_RATIO
387
+ });
388
+ }, []);
389
+ const scrollToStart = useCallback(() => scrollByPage(-1), [scrollByPage]);
390
+ const scrollToEnd = useCallback(() => scrollByPage(1), [scrollByPage]);
130
391
  const contextValue = useMemo(() => ({
131
392
  value,
132
393
  onChange,
133
394
  size,
134
- layout
135
- }), [value, onChange, size, layout]);
395
+ layout,
396
+ pattern: isTabList ? 'tabs' : 'nav'
397
+ }), [value, onChange, size, layout, isTabList]);
136
398
  const handleRootKeyDown = useCallback(e => {
137
399
  onKeyDownProp?.(e);
138
400
  if (e.defaultPrevented) {
@@ -148,7 +410,11 @@ export function TabList({
148
410
  }
149
411
  onHintFocus(e);
150
412
  handleFocus(e);
151
- }, [onFocusProp, onHintFocus, handleFocus]);
413
+ // The browser scrolls a focused element into view only when it is
414
+ // entirely outside the scrollport, so arrowing onto a half-visible stop
415
+ // leaves it cut off under the fade. Finish the job it started.
416
+ revealStop(e.target.closest(TAB_STOP_SELECTOR));
417
+ }, [onFocusProp, onHintFocus, handleFocus, revealStop]);
152
418
  const handleRootBlur = useCallback(e => {
153
419
  onBlurProp?.(e);
154
420
  if (e.defaultPrevented) {
@@ -156,12 +422,38 @@ export function TabList({
156
422
  }
157
423
  onHintBlur(e);
158
424
  }, [onBlurProp, onHintBlur]);
425
+
426
+ // `role="tablist"` owns only tabs, so anything else in the strip is invalid
427
+ // markup. Dev-only, and only under the asserted role — nothing else in the
428
+ // component reads the rendered DOM.
429
+ const hasWarnedContentRef = useRef(false);
430
+ useEffect(() => {
431
+ const strip = stripRef.current;
432
+ if (process.env.NODE_ENV === 'production' || !isTabList || !strip || hasWarnedContentRef.current) {
433
+ return;
434
+ }
435
+ const stranger = Array.from(strip.children).find(child => child.getAttribute('role') !== 'tab');
436
+ if (stranger) {
437
+ hasWarnedContentRef.current = true;
438
+ devWarn('TabList', `role="tablist" owns only tabs, but the strip contains a <${stranger.tagName.toLowerCase()}> that is not one. ` + 'Render menus and other controls outside the strip, or drop the role for the navigation pattern.');
439
+ }
440
+ // No dependency list: the check is on rendered DOM, which can change
441
+ // without any prop this component could watch.
442
+ });
443
+ const fadeStyle = !hasScroll ? null : overflowStart && overflowEnd ? styles.fadeBoth : overflowStart ? styles.fadeStart : overflowEnd ? styles.fadeEnd : null;
444
+
445
+ // A tablist is not navigation, so the landmark element is only right under
446
+ // the navigation pattern. The role is fixed by a prop rather than by what
447
+ // the strip happens to hold, so this is settled once at the callsite.
448
+ const Wrapper = isTabList ? 'div' : 'nav';
159
449
  return /*#__PURE__*/_jsx(TabListContext, {
160
450
  value: contextValue,
161
- children: /*#__PURE__*/_jsxs("nav", {
162
- ref: mergeRefs(ref, listRef),
451
+ children: /*#__PURE__*/_jsxs(Wrapper, {
452
+ ref: useMergedRefs(ref, listRef),
163
453
  ...restProps,
164
- "aria-label": ariaLabel,
454
+ role: isTabList ? undefined : role,
455
+ "aria-label": isTabList ? undefined : ariaLabel,
456
+ "aria-labelledby": isTabList ? undefined : ariaLabelledBy,
165
457
  onKeyDown: handleRootKeyDown,
166
458
  onFocus: handleRootFocus,
167
459
  onBlur: handleRootBlur,
@@ -169,7 +461,45 @@ export function TabList({
169
461
  ...mergeProps(themeProps('tab-list', {
170
462
  size
171
463
  }), stylex.props(styles.nav, layout === 'fill' && styles.fill, hasDivider && styles.divider, xstyle), className, style),
172
- children: [children, hintElement]
464
+ children: [/*#__PURE__*/_jsx("div", {
465
+ ref: attachStrip,
466
+ role: isTabList ? 'tablist' : undefined,
467
+ "aria-label": isTabList ? ariaLabel : undefined
468
+ // The name belongs to whichever element carries the widget role.
469
+ ,
470
+ "aria-labelledby": isTabList ? ariaLabelledBy : undefined,
471
+ ...mergeProps(themeProps('tab-strip'), stylex.props(styles.strip, hasScroll && styles.stripScroll, fadeStyle)),
472
+ children: children
473
+ }), hasScroll && overflowStart && /*#__PURE__*/_jsx("button", {
474
+ type: "button",
475
+ "aria-hidden": "true",
476
+ tabIndex: -1
477
+ // Nothing hidden from assistive technology should end up holding
478
+ // focus, and a click would put it here.
479
+ ,
480
+ onMouseDown: preventFocus,
481
+ onClick: scrollToStart,
482
+ ...mergeProps(themeProps('tab-scroll-button'), focusOutlineProps.focusVisible(styles.arrow, styles.arrowStart, arrowSizeStyles[size])),
483
+ children: /*#__PURE__*/_jsx(Icon, {
484
+ icon: "chevronLeft",
485
+ size: "sm",
486
+ color: "inherit",
487
+ xstyle: rtlStyles.mirror
488
+ })
489
+ }), hasScroll && overflowEnd && /*#__PURE__*/_jsx("button", {
490
+ type: "button",
491
+ "aria-hidden": "true",
492
+ tabIndex: -1,
493
+ onMouseDown: preventFocus,
494
+ onClick: scrollToEnd,
495
+ ...mergeProps(themeProps('tab-scroll-button'), focusOutlineProps.focusVisible(styles.arrow, styles.arrowEnd, arrowSizeStyles[size])),
496
+ children: /*#__PURE__*/_jsx(Icon, {
497
+ icon: "chevronRight",
498
+ size: "sm",
499
+ color: "inherit",
500
+ xstyle: rtlStyles.mirror
501
+ })
502
+ }), hintElement]
173
503
  })
174
504
  });
175
505
  }
@@ -10,13 +10,23 @@ export type TabListSize = 'sm' | 'md' | 'lg';
10
10
  */
11
11
  export type TabListLayout = 'hug' | 'fill';
12
12
  /**
13
- * Context for communicating value/onChange/size/layout from TabList to children.
13
+ * ARIA pattern the strip resolved to.
14
+ * - `'nav'`: a `<nav>` of links or buttons, current item marked with
15
+ * `aria-current`.
16
+ * - `'tabs'`: the WAI-ARIA tabs pattern — `role="tablist"` / `role="tab"`,
17
+ * `aria-selected`, and `aria-controls` for the panel each tab owns.
18
+ */
19
+ export type TabListPattern = 'nav' | 'tabs';
20
+ /**
21
+ * Context for communicating value/onChange/size/layout and the resolved ARIA
22
+ * pattern from TabList to children.
14
23
  */
15
24
  export interface TabListContextValue {
16
25
  value: string;
17
26
  onChange: (value: string) => void;
18
27
  size: TabListSize;
19
28
  layout: TabListLayout;
29
+ pattern: TabListPattern;
20
30
  }
21
31
  export declare const TabListContext: import("react").Context<TabListContextValue | null>;
22
32
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"TabListContext.d.ts","sourceRoot":"","sources":["../../src/TabList/TabListContext.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,eAAO,MAAM,cAAc,qDAAkD,CAAC;AAG9E;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,CASvD"}
1
+ {"version":3,"file":"TabListContext.d.ts","sourceRoot":"","sources":["../../src/TabList/TabListContext.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE7C;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,eAAO,MAAM,cAAc,qDAAkD,CAAC;AAG9E;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,CASvD"}
@@ -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
@@ -24,7 +24,16 @@ import { createContext, use } from 'react';
24
24
  */
25
25
 
26
26
  /**
27
- * Context for communicating value/onChange/size/layout from TabList to children.
27
+ * ARIA pattern the strip resolved to.
28
+ * - `'nav'`: a `<nav>` of links or buttons, current item marked with
29
+ * `aria-current`.
30
+ * - `'tabs'`: the WAI-ARIA tabs pattern — `role="tablist"` / `role="tab"`,
31
+ * `aria-selected`, and `aria-controls` for the panel each tab owns.
32
+ */
33
+
34
+ /**
35
+ * Context for communicating value/onChange/size/layout and the resolved ARIA
36
+ * pattern from TabList to children.
28
37
  */
29
38
 
30
39
  export const TabListContext = /*#__PURE__*/createContext(null);
@@ -1 +1 @@
1
- {"version":3,"file":"TabMenu.d.ts","sourceRoot":"","sources":["../../src/TabList/TabMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,EAA6B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGxE,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAmBtD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,SAAS,CAAC,iBAAiB,CAAC,EAC5B,QAAQ,GAAG,WAAW,GAAG,OAAO,CACjC;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AA+KD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,GAAG,EACH,KAAK,EACL,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,YAAY,qBA4Ld;yBAnMe,OAAO"}
1
+ {"version":3,"file":"TabMenu.d.ts","sourceRoot":"","sources":["../../src/TabList/TabMenu.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,EAA6B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAGxE,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAoBtD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,SAAS,CAAC,iBAAiB,CAAC,EAC5B,QAAQ,GAAG,WAAW,GAAG,OAAO,CACjC;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AA+KD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,GAAG,EACH,KAAK,EACL,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,YAAY,qBA4Ld;yBAnMe,OAAO"}
@@ -28,7 +28,8 @@ import { useListFocus } from "../hooks/useListFocus.js";
28
28
  import { useTabListContext } from "./TabListContext.js";
29
29
  import "./tab.markers.stylex.js";
30
30
  import { tabScope } from "./tab.markers.stylex.js";
31
- import { mergeProps, mergeRefs } from "../utils/index.js";
31
+ import { mergeProps } from "../utils/index.js";
32
+ import { useMergedRefs } from "../hooks/useMergedRefs.js";
32
33
  import { themeProps } from "../utils/themeProps.js";
33
34
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
34
35
  // =============================================================================
@@ -227,7 +228,7 @@ export function TabMenu({
227
228
  tabListCtx.onChange(value);
228
229
  popover.hide();
229
230
  }, [tabListCtx, popover]);
230
- const setButtonRef = mergeRefs(popover.triggerRef, buttonRef, ref);
231
+ const setButtonRef = useMergedRefs(popover.triggerRef, buttonRef, ref);
231
232
  return /*#__PURE__*/_jsxs(_Fragment, {
232
233
  children: [/*#__PURE__*/_jsxs("button", {
233
234
  ref: setButtonRef,