@astryxdesign/core 0.1.1 → 0.1.2-canary.04e71b2

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 (631) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/README.md +131 -13
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +11 -5
  5. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  6. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  7. package/dist/AvatarGroup/AvatarGroupOverflow.js +4 -1
  8. package/dist/Banner/Banner.d.ts +7 -0
  9. package/dist/Banner/Banner.d.ts.map +1 -1
  10. package/dist/Banner/Banner.js +9 -2
  11. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
  12. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  13. package/dist/Breadcrumbs/BreadcrumbItem.js +24 -5
  14. package/dist/Button/Button.d.ts +12 -2
  15. package/dist/Button/Button.d.ts.map +1 -1
  16. package/dist/Button/Button.js +53 -17
  17. package/dist/Calendar/Calendar.d.ts +5 -4
  18. package/dist/Calendar/Calendar.d.ts.map +1 -1
  19. package/dist/Calendar/Calendar.js +82 -43
  20. package/dist/Calendar/hooks/index.d.ts +0 -2
  21. package/dist/Calendar/hooks/index.d.ts.map +1 -1
  22. package/dist/Calendar/hooks/index.js +1 -2
  23. package/dist/Calendar/index.d.ts +3 -3
  24. package/dist/Calendar/index.d.ts.map +1 -1
  25. package/dist/Calendar/index.js +1 -1
  26. package/dist/Calendar/styles.d.ts +3 -9
  27. package/dist/Calendar/styles.d.ts.map +1 -1
  28. package/dist/Calendar/styles.js +3 -11
  29. package/dist/Carousel/Carousel.d.ts.map +1 -1
  30. package/dist/Carousel/Carousel.js +17 -3
  31. package/dist/Center/Center.d.ts +11 -1
  32. package/dist/Center/Center.d.ts.map +1 -1
  33. package/dist/Center/Center.js +9 -3
  34. package/dist/Chat/ChatMessageList.d.ts +14 -1
  35. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  36. package/dist/Chat/ChatMessageList.js +2 -0
  37. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  38. package/dist/Chat/useTriggerMenu.js +4 -1
  39. package/dist/CheckboxInput/CheckboxInput.d.ts +23 -2
  40. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  41. package/dist/CheckboxInput/CheckboxInput.js +51 -9
  42. package/dist/CheckboxList/CheckboxList.d.ts +13 -1
  43. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  44. package/dist/CheckboxList/CheckboxList.js +39 -9
  45. package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
  46. package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
  47. package/dist/Citation/Citation.d.ts.map +1 -1
  48. package/dist/Citation/Citation.js +3 -3
  49. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  50. package/dist/CodeBlock/CodeBlock.js +49 -37
  51. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  52. package/dist/CommandPalette/CommandPalette.js +5 -5
  53. package/dist/ContextMenu/ContextMenu.d.ts +4 -5
  54. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  55. package/dist/ContextMenu/ContextMenu.js +93 -11
  56. package/dist/DateInput/DateInput.d.ts +23 -1
  57. package/dist/DateInput/DateInput.d.ts.map +1 -1
  58. package/dist/DateInput/DateInput.js +59 -8
  59. package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
  60. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  61. package/dist/DateRangeInput/DateRangeInput.js +42 -9
  62. package/dist/DateTimeInput/DateTimeInput.d.ts +35 -2
  63. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  64. package/dist/DateTimeInput/DateTimeInput.js +78 -15
  65. package/dist/Dialog/Dialog.d.ts.map +1 -1
  66. package/dist/Dialog/Dialog.js +12 -0
  67. package/dist/DropdownMenu/DropdownMenu.d.ts +1 -8
  68. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  69. package/dist/DropdownMenu/DropdownMenu.js +42 -14
  70. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  71. package/dist/EmptyState/EmptyState.js +7 -1
  72. package/dist/Field/Field.d.ts +19 -2
  73. package/dist/Field/Field.d.ts.map +1 -1
  74. package/dist/Field/Field.js +4 -0
  75. package/dist/Field/FieldLabel.d.ts +21 -2
  76. package/dist/Field/FieldLabel.d.ts.map +1 -1
  77. package/dist/Field/FieldLabel.js +41 -26
  78. package/dist/FileInput/FileInput.d.ts +22 -1
  79. package/dist/FileInput/FileInput.d.ts.map +1 -1
  80. package/dist/FileInput/FileInput.js +56 -10
  81. package/dist/Grid/Grid.d.ts +11 -1
  82. package/dist/Grid/Grid.d.ts.map +1 -1
  83. package/dist/Grid/Grid.js +8 -0
  84. package/dist/HoverCard/HoverCard.d.ts +2 -2
  85. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  86. package/dist/HoverCard/HoverCard.js +18 -6
  87. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  88. package/dist/HoverCard/useHoverCard.js +7 -3
  89. package/dist/InputGroup/InputGroup.d.ts +2 -2
  90. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  91. package/dist/InputGroup/InputGroup.js +14 -5
  92. package/dist/InputGroup/InputGroupContext.d.ts +4 -0
  93. package/dist/InputGroup/InputGroupContext.d.ts.map +1 -1
  94. package/dist/InputGroup/InputGroupContext.js +2 -2
  95. package/dist/InputGroup/index.d.ts +1 -0
  96. package/dist/InputGroup/index.d.ts.map +1 -1
  97. package/dist/Kbd/Kbd.d.ts.map +1 -1
  98. package/dist/Kbd/Kbd.js +34 -2
  99. package/dist/Layer/anchorName.d.ts +20 -0
  100. package/dist/Layer/anchorName.d.ts.map +1 -0
  101. package/dist/Layer/anchorName.js +36 -0
  102. package/dist/Layer/layerAnimations.stylex.d.ts +4 -0
  103. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  104. package/dist/Layer/layerAnimations.stylex.js +8 -4
  105. package/dist/Layer/useLayer.d.ts +29 -0
  106. package/dist/Layer/useLayer.d.ts.map +1 -1
  107. package/dist/Layer/useLayer.js +55 -11
  108. package/dist/Layout/Layout.d.ts +4 -11
  109. package/dist/Layout/Layout.d.ts.map +1 -1
  110. package/dist/Layout/Layout.js +10 -11
  111. package/dist/Layout/LayoutFooter.d.ts +2 -2
  112. package/dist/Layout/LayoutFooter.d.ts.map +1 -1
  113. package/dist/Layout/LayoutHeader.d.ts +2 -2
  114. package/dist/Layout/LayoutHeader.d.ts.map +1 -1
  115. package/dist/Layout/LayoutPanel.d.ts +2 -2
  116. package/dist/Layout/LayoutPanel.d.ts.map +1 -1
  117. package/dist/Layout/padding.stylex.d.ts +51 -0
  118. package/dist/Layout/padding.stylex.d.ts.map +1 -1
  119. package/dist/Layout/padding.stylex.js +63 -0
  120. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  121. package/dist/Lightbox/Lightbox.js +4 -2
  122. package/dist/Link/Link.d.ts +17 -2
  123. package/dist/Link/Link.d.ts.map +1 -1
  124. package/dist/Link/Link.js +20 -9
  125. package/dist/Link/LinkProvider.d.ts +1 -0
  126. package/dist/Link/LinkProvider.d.ts.map +1 -1
  127. package/dist/Link/LinkProvider.js +1 -0
  128. package/dist/Markdown/Markdown.d.ts.map +1 -1
  129. package/dist/Markdown/Markdown.js +18 -3
  130. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  131. package/dist/MobileNav/MobileNav.js +13 -0
  132. package/dist/MoreMenu/MoreMenu.d.ts +1 -7
  133. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  134. package/dist/MoreMenu/MoreMenu.js +0 -2
  135. package/dist/MultiSelector/MultiSelector.d.ts +25 -2
  136. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  137. package/dist/MultiSelector/MultiSelector.js +103 -22
  138. package/dist/MultiSelector/hooks.d.ts +12 -1
  139. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  140. package/dist/MultiSelector/hooks.js +14 -1
  141. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  142. package/dist/NavMenu/NavHeadingMenu.js +34 -3
  143. package/dist/NumberInput/NumberInput.d.ts +23 -2
  144. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  145. package/dist/NumberInput/NumberInput.js +62 -12
  146. package/dist/Pagination/Pagination.d.ts +1 -1
  147. package/dist/Pagination/Pagination.d.ts.map +1 -1
  148. package/dist/Pagination/Pagination.js +46 -28
  149. package/dist/Popover/usePopover.d.ts +25 -2
  150. package/dist/Popover/usePopover.d.ts.map +1 -1
  151. package/dist/Popover/usePopover.js +18 -6
  152. package/dist/PowerSearch/PowerSearch.d.ts +11 -1
  153. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  154. package/dist/PowerSearch/PowerSearch.js +6 -1
  155. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  156. package/dist/ProgressBar/ProgressBar.js +3 -5
  157. package/dist/RadioList/RadioList.d.ts +20 -2
  158. package/dist/RadioList/RadioList.d.ts.map +1 -1
  159. package/dist/RadioList/RadioList.js +105 -9
  160. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  161. package/dist/RadioList/RadioListItem.js +13 -2
  162. package/dist/SegmentedControl/SegmentedControl.d.ts +13 -2
  163. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  164. package/dist/SegmentedControl/SegmentedControl.js +78 -44
  165. package/dist/SegmentedControl/SegmentedControlContext.d.ts +7 -0
  166. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  167. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  168. package/dist/SegmentedControl/SegmentedControlItem.js +13 -2
  169. package/dist/Selector/Selector.d.ts +22 -1
  170. package/dist/Selector/Selector.d.ts.map +1 -1
  171. package/dist/Selector/Selector.js +84 -23
  172. package/dist/Selector/hooks.d.ts +8 -1
  173. package/dist/Selector/hooks.d.ts.map +1 -1
  174. package/dist/Selector/hooks.js +14 -1
  175. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  176. package/dist/SideNav/SideNavItem.js +1 -1
  177. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  178. package/dist/Skeleton/Skeleton.js +8 -2
  179. package/dist/Slider/Slider.d.ts +21 -0
  180. package/dist/Slider/Slider.d.ts.map +1 -1
  181. package/dist/Slider/Slider.js +38 -11
  182. package/dist/Spinner/Spinner.d.ts.map +1 -1
  183. package/dist/Spinner/Spinner.js +1 -1
  184. package/dist/Stack/Stack.d.ts +38 -23
  185. package/dist/Stack/Stack.d.ts.map +1 -1
  186. package/dist/Stack/Stack.js +25 -1
  187. package/dist/Stack/StackItem.d.ts +12 -23
  188. package/dist/Stack/StackItem.d.ts.map +1 -1
  189. package/dist/Stack/StackItem.js +8 -1
  190. package/dist/Switch/Switch.d.ts +23 -2
  191. package/dist/Switch/Switch.d.ts.map +1 -1
  192. package/dist/Switch/Switch.js +41 -11
  193. package/dist/TabList/Tab.d.ts.map +1 -1
  194. package/dist/TabList/Tab.js +6 -0
  195. package/dist/TabList/TabList.d.ts +16 -4
  196. package/dist/TabList/TabList.d.ts.map +1 -1
  197. package/dist/TabList/TabList.js +86 -10
  198. package/dist/TabList/TabListContext.d.ts +5 -0
  199. package/dist/TabList/TabListContext.d.ts.map +1 -1
  200. package/dist/TabList/TabListContext.js +5 -0
  201. package/dist/TabList/TabMenu.d.ts.map +1 -1
  202. package/dist/TabList/TabMenu.js +6 -1
  203. package/dist/Table/BaseTable.d.ts.map +1 -1
  204. package/dist/Table/BaseTable.js +38 -16
  205. package/dist/Table/Table.d.ts.map +1 -1
  206. package/dist/Table/Table.js +36 -7
  207. package/dist/Table/TableCell.d.ts +8 -1
  208. package/dist/Table/TableCell.d.ts.map +1 -1
  209. package/dist/Table/TableCell.js +10 -10
  210. package/dist/Table/TableHeaderCell.d.ts +8 -1
  211. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  212. package/dist/Table/TableHeaderCell.js +16 -16
  213. package/dist/Table/TableRow.d.ts +6 -1
  214. package/dist/Table/TableRow.d.ts.map +1 -1
  215. package/dist/Table/TableRow.js +15 -7
  216. package/dist/Table/index.d.ts +4 -1
  217. package/dist/Table/index.d.ts.map +1 -1
  218. package/dist/Table/index.js +3 -2
  219. package/dist/Table/plugins/pagination/paginateData.d.ts +2 -1
  220. package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
  221. package/dist/Table/plugins/pagination/paginateData.js +8 -3
  222. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  223. package/dist/Table/plugins/pagination/useTablePagination.js +6 -1
  224. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  225. package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
  226. package/dist/Table/plugins/stickyColumns/index.d.ts +3 -0
  227. package/dist/Table/plugins/stickyColumns/index.d.ts.map +1 -0
  228. package/dist/Table/plugins/stickyColumns/index.js +3 -0
  229. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts +25 -0
  230. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -0
  231. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +369 -0
  232. package/dist/Table/tableContextMenu.d.ts +33 -0
  233. package/dist/Table/tableContextMenu.d.ts.map +1 -0
  234. package/dist/Table/tableContextMenu.js +133 -0
  235. package/dist/Table/types.d.ts +161 -5
  236. package/dist/Table/types.d.ts.map +1 -1
  237. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  238. package/dist/Table/useBaseTablePlugins.js +1 -1
  239. package/dist/Text/text.stylex.d.ts +2 -2
  240. package/dist/Text/text.stylex.js +2 -2
  241. package/dist/TextArea/TextArea.d.ts +22 -1
  242. package/dist/TextArea/TextArea.d.ts.map +1 -1
  243. package/dist/TextArea/TextArea.js +41 -9
  244. package/dist/TextInput/TextInput.d.ts +23 -2
  245. package/dist/TextInput/TextInput.d.ts.map +1 -1
  246. package/dist/TextInput/TextInput.js +55 -10
  247. package/dist/TimeInput/TimeInput.d.ts +23 -1
  248. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  249. package/dist/TimeInput/TimeInput.js +53 -10
  250. package/dist/Timestamp/Timestamp.d.ts +1 -1
  251. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  252. package/dist/Timestamp/Timestamp.js +28 -3
  253. package/dist/Toast/Toast.d.ts.map +1 -1
  254. package/dist/Toast/Toast.js +14 -0
  255. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  256. package/dist/Toast/ToastViewport.js +132 -3
  257. package/dist/ToggleButton/ToggleButton.d.ts +7 -9
  258. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  259. package/dist/ToggleButton/ToggleButton.js +34 -57
  260. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  261. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  262. package/dist/Tokenizer/Tokenizer.js +27 -5
  263. package/dist/Toolbar/Toolbar.d.ts +3 -3
  264. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  265. package/dist/Toolbar/Toolbar.js +51 -7
  266. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  267. package/dist/Tooltip/useTooltip.js +57 -9
  268. package/dist/TreeList/TreeList.d.ts +1 -1
  269. package/dist/TreeList/TreeList.d.ts.map +1 -1
  270. package/dist/TreeList/TreeList.js +72 -2
  271. package/dist/TreeList/TreeListItem.d.ts +11 -1
  272. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  273. package/dist/TreeList/TreeListItem.js +51 -12
  274. package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
  275. package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
  276. package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
  277. package/dist/Typeahead/BaseTypeahead.d.ts +9 -0
  278. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  279. package/dist/Typeahead/BaseTypeahead.js +67 -6
  280. package/dist/Typeahead/Typeahead.d.ts +24 -1
  281. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  282. package/dist/Typeahead/Typeahead.js +29 -5
  283. package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
  284. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
  285. package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
  286. package/dist/VisuallyHidden/index.d.ts +11 -0
  287. package/dist/VisuallyHidden/index.d.ts.map +1 -0
  288. package/dist/VisuallyHidden/index.js +13 -0
  289. package/dist/astryx.css +40 -1
  290. package/dist/astryx.umd.js +147 -0
  291. package/dist/astryx.umd.js.map +7 -0
  292. package/dist/hooks/focusableSelector.d.ts +22 -0
  293. package/dist/hooks/focusableSelector.d.ts.map +1 -0
  294. package/dist/hooks/focusableSelector.js +24 -0
  295. package/dist/hooks/index.d.ts +12 -2
  296. package/dist/hooks/index.d.ts.map +1 -1
  297. package/dist/hooks/index.js +7 -2
  298. package/dist/hooks/useAnnounce.d.ts +40 -0
  299. package/dist/hooks/useAnnounce.d.ts.map +1 -0
  300. package/dist/hooks/useAnnounce.js +142 -0
  301. package/dist/hooks/useClickableContainer.d.ts +16 -1
  302. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  303. package/dist/hooks/useClickableContainer.js +16 -4
  304. package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
  305. package/dist/hooks/useEntryAnimation.js +4 -4
  306. package/dist/hooks/useFocusTrap.d.ts +18 -0
  307. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  308. package/dist/hooks/useFocusTrap.js +87 -3
  309. package/dist/hooks/useGridFocus.d.ts +88 -1
  310. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  311. package/dist/hooks/useGridFocus.js +261 -62
  312. package/dist/hooks/useKeyboardHint.d.ts +82 -0
  313. package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
  314. package/dist/hooks/useKeyboardHint.js +220 -0
  315. package/dist/hooks/useListFocus.d.ts +78 -7
  316. package/dist/hooks/useListFocus.d.ts.map +1 -1
  317. package/dist/hooks/useListFocus.js +305 -52
  318. package/dist/hooks/useLongPress.d.ts +21 -0
  319. package/dist/hooks/useLongPress.d.ts.map +1 -0
  320. package/dist/hooks/useLongPress.js +89 -0
  321. package/dist/hooks/useTreeFocus.d.ts +157 -0
  322. package/dist/hooks/useTreeFocus.d.ts.map +1 -0
  323. package/dist/hooks/useTreeFocus.js +337 -0
  324. package/dist/hooks/useTypeahead.d.ts +63 -0
  325. package/dist/hooks/useTypeahead.d.ts.map +1 -0
  326. package/dist/hooks/useTypeahead.js +117 -0
  327. package/dist/index.d.ts +1 -0
  328. package/dist/index.d.ts.map +1 -1
  329. package/dist/index.js +1 -0
  330. package/dist/theme/generateThemeRules.js +1 -1
  331. package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
  332. package/dist/theme/syntax/SyntaxTheme.js +1 -1
  333. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  334. package/dist/theme/syntax/defineSyntaxTheme.js +2 -2
  335. package/dist/theme/syntax/presets.d.ts +1 -1
  336. package/dist/theme/syntax/presets.d.ts.map +1 -1
  337. package/dist/theme/syntax/presets.js +1 -1
  338. package/dist/theme/syntax/tokens.d.ts +1 -1
  339. package/dist/theme/syntax/tokens.js +1 -1
  340. package/dist/theme/types.d.ts +1 -1
  341. package/dist/utils/dateTypes.d.ts +12 -0
  342. package/dist/utils/dateTypes.d.ts.map +1 -1
  343. package/dist/utils/dateTypes.js +41 -1
  344. package/dist/utils/index.d.ts +4 -0
  345. package/dist/utils/index.d.ts.map +1 -1
  346. package/dist/utils/index.js +3 -1
  347. package/dist/utils/inputAria.d.ts +29 -0
  348. package/dist/utils/inputAria.d.ts.map +1 -0
  349. package/dist/utils/inputAria.js +30 -0
  350. package/dist/utils/timeParser.d.ts.map +1 -1
  351. package/dist/utils/timeParser.js +5 -2
  352. package/package.json +15 -5
  353. package/src/Avatar/Avatar.test.tsx +37 -0
  354. package/src/Avatar/Avatar.tsx +10 -5
  355. package/src/AvatarGroup/AvatarGroupOverflow.tsx +3 -0
  356. package/src/Banner/Banner.doc.mjs +8 -0
  357. package/src/Banner/Banner.test.tsx +16 -7
  358. package/src/Banner/Banner.tsx +9 -2
  359. package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
  360. package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
  361. package/src/Button/Button.doc.mjs +6 -0
  362. package/src/Button/Button.test.tsx +105 -11
  363. package/src/Button/Button.tsx +76 -21
  364. package/src/Calendar/Calendar.doc.mjs +4 -4
  365. package/src/Calendar/Calendar.test.tsx +168 -30
  366. package/src/Calendar/Calendar.tsx +121 -66
  367. package/src/Calendar/hooks/index.ts +0 -6
  368. package/src/Calendar/index.ts +1 -3
  369. package/src/Calendar/styles.ts +4 -9
  370. package/src/Carousel/Carousel.doc.mjs +7 -1
  371. package/src/Carousel/Carousel.test.tsx +20 -0
  372. package/src/Carousel/Carousel.tsx +16 -1
  373. package/src/Center/Center.doc.mjs +12 -2
  374. package/src/Center/Center.tsx +28 -3
  375. package/src/Chat/ChatComposer.doc.mjs +3 -0
  376. package/src/Chat/ChatComposerDrawer.doc.mjs +12 -0
  377. package/src/Chat/ChatMessageList.doc.mjs +8 -0
  378. package/src/Chat/ChatMessageList.test.tsx +18 -0
  379. package/src/Chat/ChatMessageList.tsx +16 -0
  380. package/src/Chat/useTriggerMenu.tsx +3 -0
  381. package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -0
  382. package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
  383. package/src/CheckboxInput/CheckboxInput.tsx +78 -6
  384. package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
  385. package/src/CheckboxList/CheckboxList.test.tsx +169 -16
  386. package/src/CheckboxList/CheckboxList.tsx +56 -3
  387. package/src/CheckboxList/CheckboxListContext.tsx +7 -0
  388. package/src/Citation/Citation.doc.mjs +10 -0
  389. package/src/Citation/Citation.test.tsx +117 -0
  390. package/src/Citation/Citation.tsx +9 -1
  391. package/src/ClickableCard/ClickableCard.doc.mjs +15 -0
  392. package/src/CodeBlock/CodeBlock.test.tsx +115 -0
  393. package/src/CodeBlock/CodeBlock.tsx +61 -33
  394. package/src/CommandPalette/CommandPalette.test.tsx +47 -1
  395. package/src/CommandPalette/CommandPalette.tsx +9 -21
  396. package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
  397. package/src/ContextMenu/ContextMenu.test.tsx +155 -1
  398. package/src/ContextMenu/ContextMenu.tsx +113 -16
  399. package/src/DateInput/DateInput.doc.mjs +281 -56
  400. package/src/DateInput/DateInput.test.tsx +188 -2
  401. package/src/DateInput/DateInput.tsx +89 -10
  402. package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
  403. package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
  404. package/src/DateRangeInput/DateRangeInput.tsx +63 -5
  405. package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
  406. package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
  407. package/src/DateTimeInput/DateTimeInput.tsx +125 -17
  408. package/src/Dialog/Dialog.doc.mjs +2 -2
  409. package/src/Dialog/Dialog.tsx +12 -0
  410. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
  411. package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
  412. package/src/DropdownMenu/DropdownMenu.tsx +52 -18
  413. package/src/EmptyState/EmptyState.test.tsx +4 -2
  414. package/src/EmptyState/EmptyState.tsx +6 -2
  415. package/src/Field/Field.test.tsx +32 -0
  416. package/src/Field/Field.tsx +23 -5
  417. package/src/Field/FieldLabel.tsx +55 -17
  418. package/src/FileInput/FileInput.doc.mjs +17 -0
  419. package/src/FileInput/FileInput.test.tsx +283 -49
  420. package/src/FileInput/FileInput.tsx +76 -4
  421. package/src/Grid/Grid.doc.mjs +14 -4
  422. package/src/Grid/Grid.tsx +20 -0
  423. package/src/HoverCard/HoverCard.doc.mjs +3 -0
  424. package/src/HoverCard/HoverCard.test.tsx +189 -2
  425. package/src/HoverCard/HoverCard.tsx +20 -16
  426. package/src/HoverCard/useHoverCard.tsx +13 -10
  427. package/src/Icon/Icon.doc.mjs +8 -0
  428. package/src/InputGroup/InputGroup.doc.mjs +2 -2
  429. package/src/InputGroup/InputGroup.test.tsx +98 -60
  430. package/src/InputGroup/InputGroup.tsx +21 -4
  431. package/src/InputGroup/InputGroupContext.ts +9 -4
  432. package/src/InputGroup/index.ts +1 -0
  433. package/src/Kbd/Kbd.test.tsx +22 -4
  434. package/src/Kbd/Kbd.tsx +37 -12
  435. package/src/Layer/anchorName.test.ts +146 -0
  436. package/src/Layer/anchorName.ts +46 -0
  437. package/src/Layer/layerAnimations.stylex.ts +20 -4
  438. package/src/Layer/useLayer.doc.mjs +12 -2
  439. package/src/Layer/useLayer.tsx +100 -15
  440. package/src/Layout/Layout.doc.mjs +1 -1
  441. package/src/Layout/Layout.tsx +8 -16
  442. package/src/Layout/LayoutFooter.doc.mjs +4 -4
  443. package/src/Layout/LayoutFooter.tsx +3 -3
  444. package/src/Layout/LayoutHeader.doc.mjs +4 -4
  445. package/src/Layout/LayoutHeader.tsx +3 -3
  446. package/src/Layout/LayoutPanel.tsx +3 -3
  447. package/src/Layout/padding.stylex.ts +52 -0
  448. package/src/Lightbox/Lightbox.doc.mjs +9 -2
  449. package/src/Lightbox/Lightbox.test.tsx +53 -5
  450. package/src/Lightbox/Lightbox.tsx +9 -4
  451. package/src/Link/Link.doc.mjs +14 -0
  452. package/src/Link/Link.test.tsx +52 -2
  453. package/src/Link/Link.tsx +42 -7
  454. package/src/Link/LinkProvider.tsx +1 -0
  455. package/src/List/List.doc.mjs +7 -0
  456. package/src/Markdown/Markdown.doc.mjs +2 -0
  457. package/src/Markdown/Markdown.test.tsx +28 -26
  458. package/src/Markdown/Markdown.tsx +21 -6
  459. package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
  460. package/src/MobileNav/MobileNav.doc.mjs +8 -8
  461. package/src/MobileNav/MobileNav.tsx +13 -0
  462. package/src/MobileNav/MobileNavReopen.test.tsx +118 -0
  463. package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
  464. package/src/MoreMenu/MoreMenu.tsx +0 -9
  465. package/src/MultiSelector/MultiSelector.doc.mjs +25 -0
  466. package/src/MultiSelector/MultiSelector.test.tsx +375 -8
  467. package/src/MultiSelector/MultiSelector.tsx +145 -21
  468. package/src/MultiSelector/hooks.ts +27 -0
  469. package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
  470. package/src/NavMenu/NavHeadingMenu.tsx +50 -3
  471. package/src/NumberInput/NumberInput.doc.mjs +17 -0
  472. package/src/NumberInput/NumberInput.test.tsx +242 -40
  473. package/src/NumberInput/NumberInput.tsx +89 -11
  474. package/src/OverflowList/OverflowList.doc.mjs +17 -0
  475. package/src/Pagination/Pagination.doc.mjs +3 -3
  476. package/src/Pagination/Pagination.test.tsx +250 -14
  477. package/src/Pagination/Pagination.tsx +54 -29
  478. package/src/Popover/usePopover.doc.mjs +7 -3
  479. package/src/Popover/usePopover.tsx +49 -6
  480. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  481. package/src/PowerSearch/PowerSearch.test.tsx +97 -1
  482. package/src/PowerSearch/PowerSearch.tsx +16 -3
  483. package/src/ProgressBar/ProgressBar.test.tsx +45 -27
  484. package/src/ProgressBar/ProgressBar.tsx +3 -4
  485. package/src/RadioList/RadioList.doc.mjs +9 -0
  486. package/src/RadioList/RadioList.test.tsx +252 -16
  487. package/src/RadioList/RadioList.tsx +166 -10
  488. package/src/RadioList/RadioListItem.tsx +14 -2
  489. package/src/Resizable/Resizable.doc.mjs +1 -1
  490. package/src/Section/Section.doc.mjs +11 -0
  491. package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
  492. package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
  493. package/src/SegmentedControl/SegmentedControl.tsx +102 -54
  494. package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
  495. package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
  496. package/src/SelectableCard/SelectableCard.doc.mjs +15 -0
  497. package/src/Selector/Selector.doc.mjs +25 -0
  498. package/src/Selector/Selector.test.tsx +322 -15
  499. package/src/Selector/Selector.tsx +126 -40
  500. package/src/Selector/hooks.ts +23 -0
  501. package/src/SideNav/SideNav.test.tsx +16 -0
  502. package/src/SideNav/SideNavItem.tsx +2 -4
  503. package/src/Skeleton/Skeleton.doc.mjs +11 -1
  504. package/src/Skeleton/Skeleton.test.tsx +25 -0
  505. package/src/Skeleton/Skeleton.tsx +11 -1
  506. package/src/Slider/Slider.doc.mjs +19 -0
  507. package/src/Slider/Slider.test.tsx +158 -18
  508. package/src/Slider/Slider.tsx +54 -6
  509. package/src/Spinner/Spinner.tsx +7 -1
  510. package/src/Stack/Stack.doc.mjs +77 -0
  511. package/src/Stack/Stack.test.tsx +55 -5
  512. package/src/Stack/Stack.tsx +73 -24
  513. package/src/Stack/StackItem.test.tsx +23 -0
  514. package/src/Stack/StackItem.tsx +20 -23
  515. package/src/Switch/Switch.doc.mjs +15 -0
  516. package/src/Switch/Switch.test.tsx +162 -27
  517. package/src/Switch/Switch.tsx +61 -21
  518. package/src/TabList/Tab.tsx +6 -0
  519. package/src/TabList/TabList.doc.mjs +12 -0
  520. package/src/TabList/TabList.test.tsx +208 -0
  521. package/src/TabList/TabList.tsx +102 -12
  522. package/src/TabList/TabListContext.ts +7 -3
  523. package/src/TabList/TabMenu.tsx +6 -3
  524. package/src/Table/BaseTable.tsx +72 -41
  525. package/src/Table/Table.doc.mjs +14 -0
  526. package/src/Table/Table.test.tsx +39 -30
  527. package/src/Table/Table.tsx +27 -1
  528. package/src/Table/TableCell.tsx +25 -23
  529. package/src/Table/TableHeaderCell.tsx +28 -29
  530. package/src/Table/TableRow.tsx +37 -7
  531. package/src/Table/index.ts +6 -2
  532. package/src/Table/plugins/pagination/paginateData.ts +10 -3
  533. package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
  534. package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
  535. package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
  536. package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
  537. package/src/Table/plugins/stickyColumns/index.ts +4 -0
  538. package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +163 -0
  539. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +407 -0
  540. package/src/Table/tableContextMenu.test.tsx +157 -0
  541. package/src/Table/tableContextMenu.tsx +142 -0
  542. package/src/Table/types.ts +175 -4
  543. package/src/Table/useBaseTablePlugins.ts +1 -0
  544. package/src/Table/useTableColumnResize.doc.mjs +96 -0
  545. package/src/Table/useTableStickyColumns.doc.mjs +59 -0
  546. package/src/Text/Heading.doc.mjs +15 -2
  547. package/src/Text/Text.doc.mjs +7 -1
  548. package/src/Text/text.stylex.ts +2 -2
  549. package/src/TextArea/TextArea.doc.mjs +17 -0
  550. package/src/TextArea/TextArea.test.tsx +167 -35
  551. package/src/TextArea/TextArea.tsx +62 -15
  552. package/src/TextInput/TextInput.doc.mjs +17 -0
  553. package/src/TextInput/TextInput.test.tsx +168 -34
  554. package/src/TextInput/TextInput.tsx +77 -9
  555. package/src/TimeInput/TimeInput.doc.mjs +335 -60
  556. package/src/TimeInput/TimeInput.test.tsx +144 -7
  557. package/src/TimeInput/TimeInput.tsx +74 -5
  558. package/src/Timestamp/Timestamp.doc.mjs +9 -0
  559. package/src/Timestamp/Timestamp.test.tsx +44 -18
  560. package/src/Timestamp/Timestamp.tsx +30 -10
  561. package/src/Toast/Toast.tsx +14 -0
  562. package/src/Toast/ToastViewport.test.tsx +204 -0
  563. package/src/Toast/ToastViewport.tsx +167 -21
  564. package/src/ToggleButton/ToggleButton.doc.mjs +9 -3
  565. package/src/ToggleButton/ToggleButton.test.tsx +39 -18
  566. package/src/ToggleButton/ToggleButton.tsx +46 -83
  567. package/src/Tokenizer/Tokenizer.doc.mjs +15 -0
  568. package/src/Tokenizer/Tokenizer.test.tsx +105 -1
  569. package/src/Tokenizer/Tokenizer.tsx +41 -2
  570. package/src/Toolbar/Toolbar.doc.mjs +65 -5
  571. package/src/Toolbar/Toolbar.test.tsx +109 -6
  572. package/src/Toolbar/Toolbar.tsx +59 -5
  573. package/src/Tooltip/Tooltip.test.tsx +81 -0
  574. package/src/Tooltip/useTooltip.tsx +57 -11
  575. package/src/TreeList/TreeList.test.tsx +295 -6
  576. package/src/TreeList/TreeList.tsx +73 -1
  577. package/src/TreeList/TreeListItem.tsx +51 -5
  578. package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
  579. package/src/Typeahead/BaseTypeahead.tsx +86 -9
  580. package/src/Typeahead/Typeahead.doc.mjs +136 -30
  581. package/src/Typeahead/Typeahead.test.tsx +331 -1
  582. package/src/Typeahead/Typeahead.tsx +52 -1
  583. package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
  584. package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
  585. package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
  586. package/src/VisuallyHidden/index.ts +15 -0
  587. package/src/hooks/focusableSelector.ts +25 -0
  588. package/src/hooks/index.ts +28 -2
  589. package/src/hooks/useAnnounce.test.tsx +101 -0
  590. package/src/hooks/useAnnounce.ts +168 -0
  591. package/src/hooks/useClickableContainer.ts +16 -4
  592. package/src/hooks/useEntryAnimation.ts +16 -4
  593. package/src/hooks/useFocusTrap.test.tsx +132 -0
  594. package/src/hooks/useFocusTrap.ts +98 -4
  595. package/src/hooks/useGridFocus.doc.mjs +40 -2
  596. package/src/hooks/useGridFocus.test.tsx +132 -0
  597. package/src/hooks/useGridFocus.ts +343 -67
  598. package/src/hooks/useImageMode.test.ts +133 -0
  599. package/src/hooks/useKeyboardHint.doc.mjs +101 -0
  600. package/src/hooks/useKeyboardHint.test.tsx +70 -0
  601. package/src/hooks/useKeyboardHint.tsx +332 -0
  602. package/src/hooks/useListFocus.doc.mjs +50 -10
  603. package/src/hooks/useListFocus.test.tsx +375 -0
  604. package/src/hooks/useListFocus.ts +395 -57
  605. package/src/hooks/useLongPress.test.tsx +134 -0
  606. package/src/hooks/useLongPress.ts +119 -0
  607. package/src/hooks/useTreeFocus.doc.mjs +140 -0
  608. package/src/hooks/useTreeFocus.test.tsx +214 -0
  609. package/src/hooks/useTreeFocus.ts +559 -0
  610. package/src/hooks/useTypeahead.test.tsx +109 -0
  611. package/src/hooks/useTypeahead.ts +183 -0
  612. package/src/index.ts +1 -0
  613. package/src/theme/derivedVarRegistry.test.ts +4 -0
  614. package/src/theme/generateThemeRules.test.ts +7 -8
  615. package/src/theme/generateThemeRules.ts +1 -1
  616. package/src/theme/syntax/SyntaxTheme.tsx +1 -1
  617. package/src/theme/syntax/defineSyntaxTheme.ts +20 -11
  618. package/src/theme/syntax/presets.ts +5 -2
  619. package/src/theme/syntax/tokens.ts +1 -1
  620. package/src/theme/types.ts +1 -1
  621. package/src/utils/dateTypes.test.ts +40 -0
  622. package/src/utils/dateTypes.ts +40 -0
  623. package/src/utils/index.ts +9 -0
  624. package/src/utils/inputAria.test.ts +39 -0
  625. package/src/utils/inputAria.ts +58 -0
  626. package/src/utils/timeParser.test.ts +10 -0
  627. package/src/utils/timeParser.ts +5 -2
  628. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
  629. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
  630. package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
  631. package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
@@ -29,6 +29,7 @@ import {mergeProps} from '../utils';
29
29
  import {useLinkComponent} from '../Link/useLinkComponent';
30
30
  import {TreeListBranches} from './TreeListBranches';
31
31
  import type {TreeListDensity} from './TreeListTypes';
32
+ import {treeItemScope} from './treeListItem.markers.stylex';
32
33
  import {themeProps} from '../utils/themeProps';
33
34
 
34
35
  // =============================================================================
@@ -42,6 +43,9 @@ const styles = stylex.create({
42
43
  padding: 0,
43
44
  position: 'relative',
44
45
  width: '100%',
46
+ // The treeitem row is the roving-tabindex focus owner; suppress the
47
+ // native focus ring in favor of the row's :focus-visible outline below.
48
+ outline: 'none',
45
49
  },
46
50
  childGroup: {
47
51
  margin: 0,
@@ -82,10 +86,16 @@ const styles = stylex.create({
82
86
  focusVisibleOutline: {
83
87
  outline: {
84
88
  default: 'none',
89
+ // Focus lives on the treeitem row (the <li>) via roving tabindex.
90
+ // Scoped to the row's OWN treeitem so focusing a parent does not leak
91
+ // the ring onto descendant rows. Also support inner focusable actions.
92
+ [stylex.when.ancestor(':focus-visible', treeItemScope)]:
93
+ `2px solid ${colorVars['--color-accent']}`,
85
94
  ':has(:focus-visible)': `2px solid ${colorVars['--color-accent']}`,
86
95
  },
87
96
  outlineOffset: {
88
97
  default: '0',
98
+ [stylex.when.ancestor(':focus-visible', treeItemScope)]: '2px',
89
99
  ':has(:focus-visible)': '2px',
90
100
  },
91
101
  },
@@ -250,6 +260,16 @@ export interface TreeListItemInternalProps {
250
260
  density: TreeListDensity;
251
261
  /** Pre-rendered children subtree (rendered by the parent recursion) */
252
262
  renderedChildren?: ReactNode;
263
+ /** 1-based position of this item among its siblings (aria-posinset). */
264
+ posInSet: number;
265
+ /** Number of siblings at this level (aria-setsize). */
266
+ setSize: number;
267
+ /**
268
+ * Whether this treeitem is the initial roving-tabindex seed. Exactly one
269
+ * treeitem is seeded tabbable at mount; useTreeFocus (hasRovingTabIndex)
270
+ * then owns the tab stop dynamically.
271
+ */
272
+ isTabbable: boolean;
253
273
  }
254
274
 
255
275
  // =============================================================================
@@ -275,6 +295,9 @@ export function TreeListItem({
275
295
  onToggle,
276
296
  density,
277
297
  renderedChildren,
298
+ posInSet,
299
+ setSize,
300
+ isTabbable,
278
301
  }: TreeListItemInternalProps) {
279
302
  const labelId = useId();
280
303
  const descriptionId = useId();
@@ -342,18 +365,26 @@ export function TreeListItem({
342
365
  );
343
366
 
344
367
  const chevron = hasChildren ? (
345
- handleClick != null && onClick != null ? (
346
- // Separate toggle button when item has its own onClick
368
+ handleToggle != null ? (
369
+ // Real toggle button whenever expand/collapse is supported, so the row
370
+ // can be expanded from the keyboard even when the item has no onClick/href
371
+ // (row-level onClick is the only click path in that case, but there is no
372
+ // focusable element to receive Enter/Space). The row's handleClick ignores
373
+ // clicks originating inside a <button>, so this never double-toggles.
347
374
  <button
348
375
  type="button"
349
376
  aria-expanded={isExpanded}
350
377
  aria-label="Toggle children"
378
+ disabled={isDisabled}
379
+ // Roving tabindex lives on the treeitem row; the chevron toggle is not
380
+ // a separate tab stop. Row-level Enter/Space forwards to this button.
381
+ tabIndex={-1}
351
382
  onClick={handleToggle}
352
383
  {...stylex.props(styles.chevronButton)}>
353
384
  {chevronIcon}
354
385
  </button>
355
386
  ) : (
356
- // Non-interactive chevron when clicking the row toggles
387
+ // Non-interactive chevron only when toggling is not wired up at all
357
388
  <span {...stylex.props(styles.chevronContainer)}>{chevronIcon}</span>
358
389
  )
359
390
  ) : null;
@@ -371,7 +402,9 @@ export function TreeListItem({
371
402
  aria-disabled={isDisabled || undefined}
372
403
  aria-labelledby={labelId}
373
404
  aria-describedby={description != null ? descriptionId : undefined}
374
- tabIndex={isDisabled ? -1 : undefined}
405
+ // Roving tabindex lives on the treeitem row; inner action is not a
406
+ // separate tab stop. Activation is forwarded from the row.
407
+ tabIndex={-1}
375
408
  {...stylex.props(styles.invisibleAnchor)}>
376
409
  {labelAndDescription}
377
410
  </LinkComponent>
@@ -382,6 +415,9 @@ export function TreeListItem({
382
415
  disabled={isDisabled}
383
416
  aria-labelledby={labelId}
384
417
  aria-describedby={description != null ? descriptionId : undefined}
418
+ // Roving tabindex lives on the treeitem row; inner action is not a
419
+ // separate tab stop. Activation is forwarded from the row.
420
+ tabIndex={-1}
385
421
  {...stylex.props(styles.invisibleButton)}>
386
422
  {labelAndDescription}
387
423
  </button>
@@ -400,7 +436,17 @@ export function TreeListItem({
400
436
  aria-expanded={hasChildren ? isExpanded : undefined}
401
437
  aria-selected={isSelected || undefined}
402
438
  aria-disabled={isDisabled || undefined}
403
- {...stylex.props(styles.wrapper)}>
439
+ aria-level={nestedLevel + 1}
440
+ aria-posinset={posInSet}
441
+ aria-setsize={setSize}
442
+ // Roving tabindex: exactly one visible treeitem is tabbable at a time.
443
+ // Disabled items are skipped by the tree keyboard handler but remain
444
+ // in the accessibility tree.
445
+ tabIndex={isDisabled ? -1 : isTabbable ? 0 : -1}
446
+ data-tree-id={id}
447
+ data-tree-level={nestedLevel + 1}
448
+ data-tree-disabled={isDisabled || undefined}
449
+ {...stylex.props(styles.wrapper, treeItemScope)}>
404
450
  <div {...stylex.props(styles.treeBranches)}>
405
451
  <TreeListBranches
406
452
  ancestorsIsLast={ancestorsIsLast}
@@ -0,0 +1,20 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file treeListItem.markers.stylex.ts
5
+ * @input Uses StyleX defineMarker
6
+ * @output Exports treeItemScope marker
7
+ * @position Scoped marker; consumed by TreeListItem.tsx
8
+ *
9
+ * SYNC: When modified, update /packages/core/src/TreeList/TreeListItem.tsx
10
+ */
11
+
12
+ import * as stylex from '@stylexjs/stylex';
13
+
14
+ /**
15
+ * Scoped marker placed on each treeitem row (`<li role="treeitem">`).
16
+ * Binds the row's `:focus-visible` outline to its OWN treeitem, so focusing
17
+ * a parent treeitem does not leak the focus ring onto descendant rows.
18
+ */
19
+ export const treeItemScope: ReturnType<typeof stylex.defineMarker> =
20
+ stylex.defineMarker();
@@ -29,6 +29,7 @@ import React, {
29
29
  import * as stylex from '@stylexjs/stylex';
30
30
  import type {StyleXStyles} from '@stylexjs/stylex';
31
31
  import {usePopover} from '../Popover/usePopover';
32
+ import {useAnnounce} from '../hooks/useAnnounce';
32
33
  import {TypeaheadItem} from './TypeaheadItem';
33
34
  import {Icon} from '../Icon';
34
35
  import {
@@ -48,9 +49,10 @@ import {themeProps} from '../utils/themeProps';
48
49
  // Types
49
50
  // =============================================================================
50
51
 
51
- export interface BaseTypeaheadProps<
52
- T extends SearchableItem,
53
- > extends Omit<BaseProps<HTMLElement>, 'onChange'> {
52
+ export interface BaseTypeaheadProps<T extends SearchableItem> extends Omit<
53
+ BaseProps<HTMLElement>,
54
+ 'onChange'
55
+ > {
54
56
  ref?: React.Ref<HTMLInputElement>;
55
57
  /**
56
58
  * Search source providing items.
@@ -101,6 +103,16 @@ export interface BaseTypeaheadProps<
101
103
  */
102
104
  isDisabled?: boolean;
103
105
 
106
+ /**
107
+ * When disabled with a reason, keeps the input focusable via `aria-disabled`
108
+ * (instead of the native `disabled` attribute) and `readOnly` so an
109
+ * associated disabled-reason tooltip stays discoverable by keyboard and
110
+ * assistive technology. Value mutation is still blocked by the `isDisabled`
111
+ * guards. Consumers (Typeahead) own the tooltip and wrapper.
112
+ * @default false
113
+ */
114
+ isFocusableDisabled?: boolean;
115
+
104
116
  /**
105
117
  * Auto-focus on mount.
106
118
  * @default false
@@ -280,9 +292,7 @@ const itemSizeStyles = stylex.create({
280
292
  * />
281
293
  * ```
282
294
  */
283
- export const BaseTypeahead = function BaseTypeahead<
284
- T extends SearchableItem,
285
- >({
295
+ export const BaseTypeahead = function BaseTypeahead<T extends SearchableItem>({
286
296
  searchSource,
287
297
  value,
288
298
  onChange,
@@ -292,6 +302,7 @@ export const BaseTypeahead = function BaseTypeahead<
292
302
  maxMenuItems = 10,
293
303
  emptySearchResultsText = 'No results found',
294
304
  isDisabled = false,
305
+ isFocusableDisabled = false,
295
306
  hasAutoFocus = false,
296
307
  onChangeQuery,
297
308
  onOpenChange,
@@ -311,6 +322,11 @@ export const BaseTypeahead = function BaseTypeahead<
311
322
  const inputRef = useRef<HTMLInputElement>(null);
312
323
  const fallbackAnchorRef = useRef<HTMLInputElement>(null);
313
324
 
325
+ // Announce result counts / "no results" to screen readers via a persistent
326
+ // live region (comboboxes-6). The combobox's own popup carries no working
327
+ // live region, so highlight/result changes were previously silent.
328
+ const announce = useAnnounce();
329
+
314
330
  const [query, setQuery] = useState('');
315
331
  const [results, setResults] = useState<T[]>([]);
316
332
  const [highlightedIndex, setHighlightedIndex] = useState(-1);
@@ -353,6 +369,9 @@ export const BaseTypeahead = function BaseTypeahead<
353
369
  hasLightDismiss: true,
354
370
  hasCloseButton: false,
355
371
  hasAutoFocus: false,
372
+ // The popup's own role="listbox" is the exposed semantics; the input keeps
373
+ // DOM focus, so wrapping it in a modal dialog would misrepresent it.
374
+ role: 'none',
356
375
  });
357
376
 
358
377
  // Show the layer, deferring past the active click if a pointer is down.
@@ -394,11 +413,21 @@ export const BaseTypeahead = function BaseTypeahead<
394
413
  return;
395
414
  }
396
415
  resultsGenRef.current = gen;
397
- setResults(searchResults.slice(0, maxMenuItems));
416
+ const shown = searchResults.slice(0, maxMenuItems);
417
+ setResults(shown);
398
418
  setHighlightedIndex(searchResults.length > 0 ? 0 : -1);
399
419
  if (searchResults.length > 0 || searchQuery.length > 0) {
400
420
  showLayer();
401
421
  }
422
+ // Announce the outcome only for an active query (not the initial
423
+ // focus-open), so screen-reader users hear result counts / no-results.
424
+ if (searchQuery.length > 0) {
425
+ announce(
426
+ shown.length === 0
427
+ ? emptySearchResultsText
428
+ : `${shown.length} ${shown.length === 1 ? 'result' : 'results'}`,
429
+ );
430
+ }
402
431
  } catch {
403
432
  if (searchGenRef.current !== gen) {
404
433
  return;
@@ -411,7 +440,7 @@ export const BaseTypeahead = function BaseTypeahead<
411
440
  }
412
441
  }
413
442
  },
414
- [searchSource, maxMenuItems, showLayer],
443
+ [searchSource, maxMenuItems, showLayer, announce, emptySearchResultsText],
415
444
  );
416
445
 
417
446
  // Perform bootstrap
@@ -456,6 +485,8 @@ export const BaseTypeahead = function BaseTypeahead<
456
485
  searchSource.cancel?.();
457
486
  setResults([]);
458
487
  setHasSearched(false);
488
+ // Clear any lingering result-count / no-results announcement.
489
+ announce('');
459
490
  popover.hide();
460
491
  return;
461
492
  }
@@ -482,6 +513,7 @@ export const BaseTypeahead = function BaseTypeahead<
482
513
  popover,
483
514
  debounceMs,
484
515
  searchSource,
516
+ announce,
485
517
  ],
486
518
  );
487
519
 
@@ -539,6 +571,32 @@ export const BaseTypeahead = function BaseTypeahead<
539
571
  showLayer,
540
572
  ]);
541
573
 
574
+ // Handle blur — close the dropdown when focus leaves the input for an
575
+ // element that is neither inside the field wrapper (anchor) nor inside the
576
+ // dropdown popover. The native popover="auto" light-dismiss only fires on
577
+ // outside pointer clicks and Escape; it does not close when focus moves away
578
+ // via the keyboard (Tab) or programmatically, which would otherwise leave an
579
+ // orphaned open menu. Clicking a result moves focus onto the option (it is
580
+ // tabIndex={-1}, so it lives inside the popover) and selection re-focuses the
581
+ // input, so this only closes on a genuine focus-out of the whole field.
582
+ const handleBlur = useCallback(
583
+ (e: React.FocusEvent<HTMLInputElement>) => {
584
+ if (!popover.isOpen) {
585
+ return;
586
+ }
587
+ const next = e.relatedTarget as Node | null;
588
+ if (next) {
589
+ const anchorEl = anchorRef?.current ?? fallbackAnchorRef.current;
590
+ const popoverEl = document.getElementById(popover.id);
591
+ if (anchorEl?.contains(next) || popoverEl?.contains(next)) {
592
+ return;
593
+ }
594
+ }
595
+ popover.hide();
596
+ },
597
+ [popover, anchorRef],
598
+ );
599
+
542
600
  // Keyboard navigation
543
601
  const handleKeyDown = useCallback(
544
602
  (e: React.KeyboardEvent<HTMLInputElement>) => {
@@ -615,6 +673,19 @@ export const BaseTypeahead = function BaseTypeahead<
615
673
  [listboxId],
616
674
  );
617
675
 
676
+ // Keep the highlighted option visible during keyboard navigation. The
677
+ // listbox is a fixed-height scroll container, so without this the virtual
678
+ // cursor walks off-screen once navigation passes the visible window. Mirrors
679
+ // CommandPaletteItem's scrollIntoView({block: 'nearest'}) behavior.
680
+ useEffect(() => {
681
+ if (!popover.isOpen || highlightedIndex < 0) {
682
+ return;
683
+ }
684
+ document
685
+ .getElementById(getItemId(highlightedIndex))
686
+ ?.scrollIntoView?.({block: 'nearest'});
687
+ }, [popover.isOpen, highlightedIndex, getItemId]);
688
+
618
689
  const selectedKey =
619
690
  value == null ? null : getKey(value.id, () => results.indexOf(value));
620
691
 
@@ -644,6 +715,7 @@ export const BaseTypeahead = function BaseTypeahead<
644
715
  }
645
716
  aria-autocomplete="list"
646
717
  aria-describedby={ariaDescribedBy}
718
+ aria-disabled={isFocusableDisabled ? 'true' : undefined}
647
719
  value={query}
648
720
  onChange={handleInputChange}
649
721
  onPointerDown={() => {
@@ -657,9 +729,14 @@ export const BaseTypeahead = function BaseTypeahead<
657
729
  );
658
730
  }}
659
731
  onFocus={handleFocus}
732
+ onBlur={handleBlur}
660
733
  onKeyDown={handleKeyDown}
661
734
  placeholder={placeholder}
662
- disabled={isDisabled}
735
+ // When a disabled-reason tooltip is shown the input keeps focusability
736
+ // via aria-disabled + readOnly instead of the native disabled
737
+ // attribute; value mutation stays blocked by the isDisabled guards.
738
+ disabled={isDisabled && !isFocusableDisabled}
739
+ readOnly={isFocusableDisabled || undefined}
663
740
  autoFocus={hasAutoFocus}
664
741
  data-autofocus={hasAutoFocus || undefined}
665
742
  autoComplete="off"
@@ -7,8 +7,21 @@ export const docs = {
7
7
  displayName: 'Typeahead',
8
8
  group: 'Typeahead',
9
9
  category: 'Data Input',
10
- keywords: ["typeahead","autocomplete","combobox","searchbox","autosuggest","select","dropdown","lookup","searchable","suggestion","picker"],
11
- description: 'Styled typeahead with label, description, validation, and all field features. Wraps BaseTypeahead with Field for the primary use case.',
10
+ keywords: [
11
+ 'typeahead',
12
+ 'autocomplete',
13
+ 'combobox',
14
+ 'searchbox',
15
+ 'autosuggest',
16
+ 'select',
17
+ 'dropdown',
18
+ 'lookup',
19
+ 'searchable',
20
+ 'suggestion',
21
+ 'picker',
22
+ ],
23
+ description:
24
+ 'Styled typeahead with label, description, validation, and all field features. Wraps BaseTypeahead with Field for the primary use case.',
12
25
  props: [
13
26
  {
14
27
  name: 'label',
@@ -19,7 +32,8 @@ export const docs = {
19
32
  {
20
33
  name: 'searchSource',
21
34
  type: 'SearchSource<T>',
22
- description: 'Data source providing search and bootstrap methods for populating the dropdown.',
35
+ description:
36
+ 'Data source providing search and bootstrap methods for populating the dropdown.',
23
37
  required: true,
24
38
  },
25
39
  {
@@ -57,6 +71,12 @@ export const docs = {
57
71
  description: 'Disables the input.',
58
72
  default: 'false',
59
73
  },
74
+ {
75
+ name: 'disabledMessage',
76
+ type: 'string',
77
+ description:
78
+ 'Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the field focusable via aria-disabled (activation stays blocked). Use this instead of wrapping a disabled Typeahead in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
79
+ },
60
80
  {
61
81
  name: 'maxMenuItems',
62
82
  type: 'number',
@@ -66,12 +86,14 @@ export const docs = {
66
86
  {
67
87
  name: 'status',
68
88
  type: 'InputStatus',
69
- description: 'Validation status object with type and message for error/warning/success states.',
89
+ description:
90
+ 'Validation status object with type and message for error/warning/success states.',
70
91
  },
71
92
  {
72
93
  name: 'renderItem',
73
94
  type: '(item: T) => ReactNode',
74
- description: 'Custom render function for dropdown items. Default renders TypeaheadItem.',
95
+ description:
96
+ 'Custom render function for dropdown items. Default renders TypeaheadItem.',
75
97
  },
76
98
  {
77
99
  name: 'isLabelHidden',
@@ -122,7 +144,8 @@ export const docs = {
122
144
  {
123
145
  name: 'debounceMs',
124
146
  type: 'number',
125
- description: 'Debounce delay in ms before triggering search. Set to 0 for synchronous sources.',
147
+ description:
148
+ 'Debounce delay in ms before triggering search. Set to 0 for synchronous sources.',
126
149
  default: '150',
127
150
  },
128
151
  {
@@ -138,13 +161,11 @@ export const docs = {
138
161
  {
139
162
  name: 'xstyle',
140
163
  type: 'StyleXStyles',
141
- description: 'StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}.',
164
+ description:
165
+ 'StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}.',
142
166
  },
143
167
  ],
144
- components: [
145
- {name: 'BaseTypeahead'},
146
- {name: 'TypeaheadItem'},
147
- ],
168
+ components: [{name: 'BaseTypeahead'}, {name: 'TypeaheadItem'}],
148
169
  theming: {
149
170
  targets: [
150
171
  {className: 'astryx-typeahead', visualProps: ['status']},
@@ -156,12 +177,40 @@ export const docs = {
156
177
  description:
157
178
  'A searchable input for selecting a single item from a large or dynamic dataset. Results appear as the user types, with support for async data sources, debounced search, and custom item rendering. Use it when the option list is too large for a Selector dropdown.',
158
179
  bestPractices: [
159
- {guidance: true, description: 'Provide descriptive placeholder text that hints at what users can search for.'},
160
- {guidance: true, description: 'Show suggestions on focus when users benefit from seeing popular or recent options before typing.'},
161
- {guidance: true, description: 'Add a search delay for remote data sources to avoid excessive network requests.'},
162
- {guidance: false, description: 'Use for short, static option lists; use Selector for better discoverability.'},
163
- {guidance: false, description: 'Use for multi-selection; use Tokenizer instead.'},
164
- {guidance: false, description: 'Place multiple Typeaheads adjacent to each other without clear labels differentiating them.'},
180
+ {
181
+ guidance: true,
182
+ description:
183
+ 'Provide descriptive placeholder text that hints at what users can search for.',
184
+ },
185
+ {
186
+ guidance: true,
187
+ description:
188
+ 'Show suggestions on focus when users benefit from seeing popular or recent options before typing.',
189
+ },
190
+ {
191
+ guidance: true,
192
+ description:
193
+ 'Add a search delay for remote data sources to avoid excessive network requests.',
194
+ },
195
+ {
196
+ guidance: false,
197
+ description:
198
+ 'Use for short, static option lists; use Selector for better discoverability.',
199
+ },
200
+ {
201
+ guidance: false,
202
+ description: 'Use for multi-selection; use Tokenizer instead.',
203
+ },
204
+ {
205
+ guidance: false,
206
+ description:
207
+ 'Place multiple Typeaheads adjacent to each other without clear labels differentiating them.',
208
+ },
209
+ {
210
+ guidance: false,
211
+ description:
212
+ 'Wrap a disabled Typeahead in Tooltip to explain why it is disabled; disabled triggers swallow the hover events the wrapper needs. Use the disabledMessage prop instead.',
213
+ },
165
214
  ],
166
215
  },
167
216
  };
@@ -172,29 +221,86 @@ export const docsZh = {
172
221
  description:
173
222
  'A searchable input for selecting a single item from a large or dynamic dataset. Results appear as the user types, with support for async data sources, debounced search, and custom item rendering. Use it when the option list is too large for a Selector dropdown.',
174
223
  bestPractices: [
175
- {guidance: true, description: 'Provide descriptive placeholder text that hints at what users can search for.'},
176
- {guidance: true, description: 'Show suggestions on focus when users benefit from seeing popular or recent options before typing.'},
177
- {guidance: true, description: 'Add a search delay for remote data sources to avoid excessive network requests.'},
178
- {guidance: false, description: 'Use for short, static option lists; use Selector for better discoverability.'},
179
- {guidance: false, description: 'Use for multi-selection; use Tokenizer instead.'},
180
- {guidance: false, description: 'Place multiple Typeaheads adjacent to each other without clear labels differentiating them.'},
224
+ {
225
+ guidance: true,
226
+ description:
227
+ 'Provide descriptive placeholder text that hints at what users can search for.',
228
+ },
229
+ {
230
+ guidance: true,
231
+ description:
232
+ 'Show suggestions on focus when users benefit from seeing popular or recent options before typing.',
233
+ },
234
+ {
235
+ guidance: true,
236
+ description:
237
+ 'Add a search delay for remote data sources to avoid excessive network requests.',
238
+ },
239
+ {
240
+ guidance: false,
241
+ description:
242
+ 'Use for short, static option lists; use Selector for better discoverability.',
243
+ },
244
+ {
245
+ guidance: false,
246
+ description: 'Use for multi-selection; use Tokenizer instead.',
247
+ },
248
+ {
249
+ guidance: false,
250
+ description:
251
+ 'Place multiple Typeaheads adjacent to each other without clear labels differentiating them.',
252
+ },
253
+ {
254
+ guidance: false,
255
+ description:
256
+ 'Wrap a disabled Typeahead in Tooltip to explain why it is disabled; disabled triggers swallow the hover events the wrapper needs. Use the disabledMessage prop instead.',
257
+ },
181
258
  ],
182
259
  },
183
260
  };
184
261
 
185
262
  /** @type {import('../docs-types').TranslationDoc} */
186
263
  export const docsDense = {
187
- description: 'Searchable dropdown for single-item selection w/ keyboard navigation. Supports async+sync search via searchSource interface.',
264
+ description:
265
+ 'Searchable dropdown for single-item selection w/ keyboard navigation. Supports async+sync search via searchSource interface.',
188
266
  usage: {
189
267
  description:
190
268
  'A searchable input for selecting a single item from a large or dynamic dataset. Results appear as the user types, with support for async data sources, debounced search, and custom item rendering. Use it when the option list is too large for a Selector dropdown.',
191
269
  bestPractices: [
192
- {guidance: true, description: 'Provide descriptive placeholder text that hints at what users can search for.'},
193
- {guidance: true, description: 'Show suggestions on focus when users benefit from seeing popular or recent options before typing.'},
194
- {guidance: true, description: 'Add a search delay for remote data sources to avoid excessive network requests.'},
195
- {guidance: false, description: 'Use for short, static option lists; use Selector for better discoverability.'},
196
- {guidance: false, description: 'Use for multi-selection; use Tokenizer instead.'},
197
- {guidance: false, description: 'Place multiple Typeaheads adjacent to each other without clear labels differentiating them.'},
270
+ {
271
+ guidance: true,
272
+ description:
273
+ 'Provide descriptive placeholder text that hints at what users can search for.',
274
+ },
275
+ {
276
+ guidance: true,
277
+ description:
278
+ 'Show suggestions on focus when users benefit from seeing popular or recent options before typing.',
279
+ },
280
+ {
281
+ guidance: true,
282
+ description:
283
+ 'Add a search delay for remote data sources to avoid excessive network requests.',
284
+ },
285
+ {
286
+ guidance: false,
287
+ description:
288
+ 'Use for short, static option lists; use Selector for better discoverability.',
289
+ },
290
+ {
291
+ guidance: false,
292
+ description: 'Use for multi-selection; use Tokenizer instead.',
293
+ },
294
+ {
295
+ guidance: false,
296
+ description:
297
+ 'Place multiple Typeaheads adjacent to each other without clear labels differentiating them.',
298
+ },
299
+ {
300
+ guidance: false,
301
+ description:
302
+ 'Wrap a disabled Typeahead in Tooltip to explain why it is disabled; disabled triggers swallow the hover events the wrapper needs. Use the disabledMessage prop instead.',
303
+ },
198
304
  ],
199
305
  },
200
306
  };