@astryxdesign/core 0.1.2 → 0.1.3-canary.1e94ba0

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 (581) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/README.md +12 -12
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +11 -5
  5. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
  6. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  7. package/dist/Breadcrumbs/BreadcrumbItem.js +24 -5
  8. package/dist/Button/Button.d.ts.map +1 -1
  9. package/dist/Button/Button.js +31 -12
  10. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  11. package/dist/ButtonGroup/ButtonGroup.js +0 -1
  12. package/dist/Calendar/Calendar.d.ts +5 -4
  13. package/dist/Calendar/Calendar.d.ts.map +1 -1
  14. package/dist/Calendar/Calendar.js +82 -43
  15. package/dist/Calendar/hooks/index.d.ts +0 -2
  16. package/dist/Calendar/hooks/index.d.ts.map +1 -1
  17. package/dist/Calendar/hooks/index.js +1 -2
  18. package/dist/Calendar/index.d.ts +3 -3
  19. package/dist/Calendar/index.d.ts.map +1 -1
  20. package/dist/Calendar/index.js +1 -1
  21. package/dist/Calendar/styles.d.ts +3 -9
  22. package/dist/Calendar/styles.d.ts.map +1 -1
  23. package/dist/Calendar/styles.js +3 -11
  24. package/dist/Carousel/Carousel.d.ts.map +1 -1
  25. package/dist/Carousel/Carousel.js +17 -3
  26. package/dist/Center/Center.d.ts +11 -1
  27. package/dist/Center/Center.d.ts.map +1 -1
  28. package/dist/Center/Center.js +9 -3
  29. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  30. package/dist/Chat/ChatComposerInput.js +0 -1
  31. package/dist/Chat/ChatMessageList.d.ts +14 -1
  32. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  33. package/dist/Chat/ChatMessageList.js +2 -0
  34. package/dist/Chat/useTriggerMenu.d.ts +8 -1
  35. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  36. package/dist/Chat/useTriggerMenu.js +15 -3
  37. package/dist/CheckboxInput/CheckboxInput.d.ts +23 -2
  38. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  39. package/dist/CheckboxInput/CheckboxInput.js +51 -9
  40. package/dist/CheckboxList/CheckboxList.d.ts +13 -1
  41. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  42. package/dist/CheckboxList/CheckboxList.js +39 -9
  43. package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
  44. package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
  45. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  46. package/dist/CheckboxList/CheckboxListItem.js +0 -1
  47. package/dist/Citation/Citation.d.ts.map +1 -1
  48. package/dist/Citation/Citation.js +9 -5
  49. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  50. package/dist/CodeBlock/CodeBlock.js +51 -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 +12 -5
  54. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  55. package/dist/ContextMenu/ContextMenu.js +96 -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 +167 -99
  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/Field/Field.d.ts +19 -2
  71. package/dist/Field/Field.d.ts.map +1 -1
  72. package/dist/Field/Field.js +4 -0
  73. package/dist/Field/FieldLabel.d.ts +21 -2
  74. package/dist/Field/FieldLabel.d.ts.map +1 -1
  75. package/dist/Field/FieldLabel.js +41 -26
  76. package/dist/FileInput/FileInput.d.ts +22 -1
  77. package/dist/FileInput/FileInput.d.ts.map +1 -1
  78. package/dist/FileInput/FileInput.js +56 -10
  79. package/dist/Grid/Grid.d.ts +11 -1
  80. package/dist/Grid/Grid.d.ts.map +1 -1
  81. package/dist/Grid/Grid.js +32 -6
  82. package/dist/InputGroup/InputGroup.d.ts +4 -3
  83. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  84. package/dist/InputGroup/InputGroup.js +16 -6
  85. package/dist/InputGroup/InputGroupContext.d.ts +4 -0
  86. package/dist/InputGroup/InputGroupContext.d.ts.map +1 -1
  87. package/dist/InputGroup/InputGroupContext.js +2 -2
  88. package/dist/InputGroup/groupStyles.d.ts +1 -1
  89. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  90. package/dist/InputGroup/groupStyles.js +3 -3
  91. package/dist/InputGroup/index.d.ts +1 -0
  92. package/dist/InputGroup/index.d.ts.map +1 -1
  93. package/dist/Kbd/Kbd.d.ts.map +1 -1
  94. package/dist/Kbd/Kbd.js +33 -1
  95. package/dist/Layer/layerAnimations.stylex.d.ts +4 -0
  96. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  97. package/dist/Layer/layerAnimations.stylex.js +8 -4
  98. package/dist/Layer/useLayer.d.ts +10 -0
  99. package/dist/Layer/useLayer.d.ts.map +1 -1
  100. package/dist/Layer/useLayer.js +64 -9
  101. package/dist/Layout/Layout.d.ts +4 -11
  102. package/dist/Layout/Layout.d.ts.map +1 -1
  103. package/dist/Layout/Layout.js +10 -11
  104. package/dist/Layout/LayoutFooter.d.ts +2 -2
  105. package/dist/Layout/LayoutFooter.d.ts.map +1 -1
  106. package/dist/Layout/LayoutHeader.d.ts +2 -2
  107. package/dist/Layout/LayoutHeader.d.ts.map +1 -1
  108. package/dist/Layout/LayoutPanel.d.ts +2 -2
  109. package/dist/Layout/LayoutPanel.d.ts.map +1 -1
  110. package/dist/Layout/padding.stylex.d.ts +51 -0
  111. package/dist/Layout/padding.stylex.d.ts.map +1 -1
  112. package/dist/Layout/padding.stylex.js +63 -0
  113. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  114. package/dist/Lightbox/Lightbox.js +4 -2
  115. package/dist/Link/Link.d.ts +16 -1
  116. package/dist/Link/Link.d.ts.map +1 -1
  117. package/dist/Link/Link.js +18 -7
  118. package/dist/Markdown/Markdown.d.ts.map +1 -1
  119. package/dist/Markdown/Markdown.js +7 -0
  120. package/dist/MoreMenu/MoreMenu.d.ts +1 -7
  121. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  122. package/dist/MoreMenu/MoreMenu.js +0 -2
  123. package/dist/MultiSelector/MultiSelector.d.ts +27 -2
  124. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  125. package/dist/MultiSelector/MultiSelector.js +141 -42
  126. package/dist/MultiSelector/hooks.d.ts +12 -1
  127. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  128. package/dist/MultiSelector/hooks.js +14 -1
  129. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  130. package/dist/NavMenu/NavHeadingMenu.js +34 -3
  131. package/dist/NumberInput/NumberInput.d.ts +23 -2
  132. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  133. package/dist/NumberInput/NumberInput.js +62 -12
  134. package/dist/Pagination/Pagination.d.ts +1 -1
  135. package/dist/Pagination/Pagination.d.ts.map +1 -1
  136. package/dist/Pagination/Pagination.js +15 -1
  137. package/dist/Popover/Popover.d.ts +18 -2
  138. package/dist/Popover/Popover.d.ts.map +1 -1
  139. package/dist/Popover/Popover.js +5 -2
  140. package/dist/Popover/usePopover.d.ts +38 -3
  141. package/dist/Popover/usePopover.d.ts.map +1 -1
  142. package/dist/Popover/usePopover.js +24 -9
  143. package/dist/PowerSearch/PowerSearch.d.ts +11 -1
  144. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  145. package/dist/PowerSearch/PowerSearch.js +6 -1
  146. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  147. package/dist/ProgressBar/ProgressBar.js +3 -5
  148. package/dist/RadioList/RadioList.d.ts +20 -2
  149. package/dist/RadioList/RadioList.d.ts.map +1 -1
  150. package/dist/RadioList/RadioList.js +105 -9
  151. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  152. package/dist/RadioList/RadioListItem.js +13 -2
  153. package/dist/SegmentedControl/SegmentedControl.d.ts +13 -2
  154. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  155. package/dist/SegmentedControl/SegmentedControl.js +78 -44
  156. package/dist/SegmentedControl/SegmentedControlContext.d.ts +7 -0
  157. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  158. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  159. package/dist/SegmentedControl/SegmentedControlItem.js +13 -2
  160. package/dist/Selector/Selector.d.ts +24 -1
  161. package/dist/Selector/Selector.d.ts.map +1 -1
  162. package/dist/Selector/Selector.js +122 -43
  163. package/dist/Selector/hooks.d.ts +8 -1
  164. package/dist/Selector/hooks.d.ts.map +1 -1
  165. package/dist/Selector/hooks.js +14 -1
  166. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  167. package/dist/SideNav/SideNavHeading.js +2 -0
  168. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  169. package/dist/SideNav/SideNavItem.js +1 -1
  170. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  171. package/dist/Skeleton/Skeleton.js +8 -2
  172. package/dist/Slider/Slider.d.ts +21 -0
  173. package/dist/Slider/Slider.d.ts.map +1 -1
  174. package/dist/Slider/Slider.js +36 -9
  175. package/dist/Spinner/Spinner.d.ts.map +1 -1
  176. package/dist/Spinner/Spinner.js +1 -1
  177. package/dist/Stack/Stack.d.ts +38 -23
  178. package/dist/Stack/Stack.d.ts.map +1 -1
  179. package/dist/Stack/Stack.js +25 -1
  180. package/dist/Stack/StackItem.d.ts +12 -23
  181. package/dist/Stack/StackItem.d.ts.map +1 -1
  182. package/dist/Stack/StackItem.js +8 -1
  183. package/dist/Switch/Switch.d.ts +23 -2
  184. package/dist/Switch/Switch.d.ts.map +1 -1
  185. package/dist/Switch/Switch.js +41 -11
  186. package/dist/TabList/Tab.d.ts.map +1 -1
  187. package/dist/TabList/Tab.js +6 -0
  188. package/dist/TabList/TabList.d.ts +16 -4
  189. package/dist/TabList/TabList.d.ts.map +1 -1
  190. package/dist/TabList/TabList.js +87 -10
  191. package/dist/TabList/TabListContext.d.ts +5 -0
  192. package/dist/TabList/TabListContext.d.ts.map +1 -1
  193. package/dist/TabList/TabListContext.js +5 -0
  194. package/dist/TabList/TabMenu.d.ts.map +1 -1
  195. package/dist/TabList/TabMenu.js +6 -1
  196. package/dist/Table/BaseTable.d.ts.map +1 -1
  197. package/dist/Table/BaseTable.js +13 -9
  198. package/dist/Table/Table.d.ts.map +1 -1
  199. package/dist/Table/Table.js +10 -1
  200. package/dist/Table/TableCell.d.ts +8 -1
  201. package/dist/Table/TableCell.d.ts.map +1 -1
  202. package/dist/Table/TableCell.js +79 -10
  203. package/dist/Table/TableHeaderCell.d.ts +8 -1
  204. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  205. package/dist/Table/TableHeaderCell.js +16 -16
  206. package/dist/Table/index.d.ts +4 -1
  207. package/dist/Table/index.d.ts.map +1 -1
  208. package/dist/Table/index.js +3 -2
  209. package/dist/Table/plugins/pagination/paginateData.d.ts +2 -1
  210. package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
  211. package/dist/Table/plugins/pagination/paginateData.js +8 -3
  212. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  213. package/dist/Table/plugins/pagination/useTablePagination.js +6 -1
  214. package/dist/Table/plugins/rowExpansion/index.d.ts +3 -0
  215. package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -0
  216. package/dist/Table/plugins/rowExpansion/index.js +3 -0
  217. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +90 -0
  218. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -0
  219. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +398 -0
  220. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  221. package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
  222. package/dist/Table/tableContextMenu.d.ts +37 -0
  223. package/dist/Table/tableContextMenu.d.ts.map +1 -0
  224. package/dist/Table/tableContextMenu.js +140 -0
  225. package/dist/Table/types.d.ts +66 -0
  226. package/dist/Table/types.d.ts.map +1 -1
  227. package/dist/TextArea/TextArea.d.ts +22 -1
  228. package/dist/TextArea/TextArea.d.ts.map +1 -1
  229. package/dist/TextArea/TextArea.js +41 -9
  230. package/dist/TextInput/TextInput.d.ts +23 -2
  231. package/dist/TextInput/TextInput.d.ts.map +1 -1
  232. package/dist/TextInput/TextInput.js +55 -10
  233. package/dist/TimeInput/TimeInput.d.ts +23 -1
  234. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  235. package/dist/TimeInput/TimeInput.js +147 -76
  236. package/dist/Toast/Toast.d.ts.map +1 -1
  237. package/dist/Toast/Toast.js +14 -0
  238. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  239. package/dist/Toast/ToastViewport.js +131 -3
  240. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  241. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  242. package/dist/Tokenizer/Tokenizer.js +26 -4
  243. package/dist/Toolbar/Toolbar.d.ts +3 -3
  244. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  245. package/dist/Toolbar/Toolbar.js +51 -7
  246. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  247. package/dist/Tooltip/useTooltip.js +56 -9
  248. package/dist/TopNav/TopNavHeading.d.ts +7 -1
  249. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  250. package/dist/TopNav/TopNavHeading.js +8 -0
  251. package/dist/TreeList/TreeList.d.ts +1 -1
  252. package/dist/TreeList/TreeList.d.ts.map +1 -1
  253. package/dist/TreeList/TreeList.js +72 -2
  254. package/dist/TreeList/TreeListItem.d.ts +11 -1
  255. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  256. package/dist/TreeList/TreeListItem.js +51 -12
  257. package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
  258. package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
  259. package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
  260. package/dist/Typeahead/BaseTypeahead.d.ts +13 -0
  261. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  262. package/dist/Typeahead/BaseTypeahead.js +69 -6
  263. package/dist/Typeahead/Typeahead.d.ts +26 -3
  264. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  265. package/dist/Typeahead/Typeahead.js +65 -29
  266. package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
  267. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
  268. package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
  269. package/dist/VisuallyHidden/index.d.ts +11 -0
  270. package/dist/VisuallyHidden/index.d.ts.map +1 -0
  271. package/dist/VisuallyHidden/index.js +13 -0
  272. package/dist/astryx.css +22 -0
  273. package/dist/astryx.umd.js +54 -54
  274. package/dist/astryx.umd.js.map +4 -4
  275. package/dist/hooks/focusableSelector.d.ts +22 -0
  276. package/dist/hooks/focusableSelector.d.ts.map +1 -0
  277. package/dist/hooks/focusableSelector.js +24 -0
  278. package/dist/hooks/index.d.ts +12 -2
  279. package/dist/hooks/index.d.ts.map +1 -1
  280. package/dist/hooks/index.js +7 -2
  281. package/dist/hooks/useAnnounce.d.ts +40 -0
  282. package/dist/hooks/useAnnounce.d.ts.map +1 -0
  283. package/dist/hooks/useAnnounce.js +142 -0
  284. package/dist/hooks/useClickableContainer.d.ts +16 -1
  285. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  286. package/dist/hooks/useClickableContainer.js +16 -4
  287. package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
  288. package/dist/hooks/useEntryAnimation.js +4 -4
  289. package/dist/hooks/useFocusTrap.d.ts +18 -0
  290. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  291. package/dist/hooks/useFocusTrap.js +87 -3
  292. package/dist/hooks/useGridFocus.d.ts +88 -1
  293. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  294. package/dist/hooks/useGridFocus.js +261 -62
  295. package/dist/hooks/useKeyboardHint.d.ts +82 -0
  296. package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
  297. package/dist/hooks/useKeyboardHint.js +220 -0
  298. package/dist/hooks/useListFocus.d.ts +78 -7
  299. package/dist/hooks/useListFocus.d.ts.map +1 -1
  300. package/dist/hooks/useListFocus.js +305 -52
  301. package/dist/hooks/useLongPress.d.ts +21 -0
  302. package/dist/hooks/useLongPress.d.ts.map +1 -0
  303. package/dist/hooks/useLongPress.js +89 -0
  304. package/dist/hooks/useTreeFocus.d.ts +157 -0
  305. package/dist/hooks/useTreeFocus.d.ts.map +1 -0
  306. package/dist/hooks/useTreeFocus.js +337 -0
  307. package/dist/hooks/useTypeahead.d.ts +63 -0
  308. package/dist/hooks/useTypeahead.d.ts.map +1 -0
  309. package/dist/hooks/useTypeahead.js +117 -0
  310. package/dist/index.d.ts +1 -0
  311. package/dist/index.d.ts.map +1 -1
  312. package/dist/index.js +1 -0
  313. package/dist/utils/dateTypes.d.ts +12 -0
  314. package/dist/utils/dateTypes.d.ts.map +1 -1
  315. package/dist/utils/dateTypes.js +41 -1
  316. package/dist/utils/index.d.ts +4 -0
  317. package/dist/utils/index.d.ts.map +1 -1
  318. package/dist/utils/index.js +3 -1
  319. package/dist/utils/inputAria.d.ts +29 -0
  320. package/dist/utils/inputAria.d.ts.map +1 -0
  321. package/dist/utils/inputAria.js +30 -0
  322. package/dist/utils/timeParser.d.ts.map +1 -1
  323. package/dist/utils/timeParser.js +5 -2
  324. package/docs.mjs +2 -2
  325. package/package.json +12 -8
  326. package/src/Avatar/Avatar.doc.mjs +2 -2
  327. package/src/Avatar/Avatar.test.tsx +37 -0
  328. package/src/Avatar/Avatar.tsx +10 -5
  329. package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
  330. package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
  331. package/src/Button/Button.tsx +42 -22
  332. package/src/ButtonGroup/ButtonGroup.test.tsx +9 -9
  333. package/src/ButtonGroup/ButtonGroup.tsx +0 -1
  334. package/src/Calendar/Calendar.doc.mjs +4 -4
  335. package/src/Calendar/Calendar.test.tsx +168 -30
  336. package/src/Calendar/Calendar.tsx +121 -66
  337. package/src/Calendar/hooks/index.ts +0 -6
  338. package/src/Calendar/index.ts +1 -3
  339. package/src/Calendar/styles.ts +4 -9
  340. package/src/Carousel/Carousel.doc.mjs +7 -1
  341. package/src/Carousel/Carousel.test.tsx +20 -0
  342. package/src/Carousel/Carousel.tsx +16 -1
  343. package/src/Center/Center.doc.mjs +12 -2
  344. package/src/Center/Center.tsx +28 -3
  345. package/src/Chat/ChatComposerInput.test.tsx +26 -7
  346. package/src/Chat/ChatComposerInput.tsx +0 -1
  347. package/src/Chat/ChatDictationButton.doc.mjs +1 -1
  348. package/src/Chat/ChatMessageList.doc.mjs +8 -0
  349. package/src/Chat/ChatMessageList.test.tsx +18 -0
  350. package/src/Chat/ChatMessageList.tsx +16 -0
  351. package/src/Chat/useTriggerMenu.tsx +22 -4
  352. package/src/CheckboxInput/CheckboxInput.doc.mjs +10 -0
  353. package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
  354. package/src/CheckboxInput/CheckboxInput.tsx +78 -6
  355. package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
  356. package/src/CheckboxList/CheckboxList.test.tsx +192 -26
  357. package/src/CheckboxList/CheckboxList.tsx +56 -3
  358. package/src/CheckboxList/CheckboxListContext.tsx +7 -0
  359. package/src/CheckboxList/CheckboxListItem.tsx +0 -3
  360. package/src/Citation/Citation.doc.mjs +10 -0
  361. package/src/Citation/Citation.test.tsx +121 -0
  362. package/src/Citation/Citation.tsx +15 -3
  363. package/src/CodeBlock/CodeBlock.test.tsx +115 -0
  364. package/src/CodeBlock/CodeBlock.tsx +63 -33
  365. package/src/CommandPalette/CommandPalette.test.tsx +47 -1
  366. package/src/CommandPalette/CommandPalette.tsx +9 -21
  367. package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
  368. package/src/ContextMenu/ContextMenu.test.tsx +155 -1
  369. package/src/ContextMenu/ContextMenu.tsx +129 -16
  370. package/src/DateInput/DateInput.doc.mjs +286 -56
  371. package/src/DateInput/DateInput.test.tsx +248 -2
  372. package/src/DateInput/DateInput.tsx +196 -100
  373. package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
  374. package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
  375. package/src/DateRangeInput/DateRangeInput.tsx +63 -5
  376. package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
  377. package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
  378. package/src/DateTimeInput/DateTimeInput.tsx +125 -17
  379. package/src/Dialog/Dialog.doc.mjs +2 -2
  380. package/src/Dialog/Dialog.tsx +12 -0
  381. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
  382. package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
  383. package/src/DropdownMenu/DropdownMenu.tsx +52 -18
  384. package/src/Field/Field.doc.mjs +59 -18
  385. package/src/Field/Field.test.tsx +32 -0
  386. package/src/Field/Field.tsx +23 -5
  387. package/src/Field/FieldLabel.tsx +55 -17
  388. package/src/FileInput/FileInput.doc.mjs +17 -0
  389. package/src/FileInput/FileInput.test.tsx +283 -49
  390. package/src/FileInput/FileInput.tsx +76 -4
  391. package/src/Grid/Grid.doc.mjs +17 -4
  392. package/src/Grid/Grid.test.tsx +43 -30
  393. package/src/Grid/Grid.tsx +38 -3
  394. package/src/Icon/Icon.doc.mjs +3 -3
  395. package/src/InputGroup/InputGroup.doc.mjs +111 -23
  396. package/src/InputGroup/InputGroup.test.tsx +257 -60
  397. package/src/InputGroup/InputGroup.tsx +23 -5
  398. package/src/InputGroup/InputGroupContext.ts +9 -4
  399. package/src/InputGroup/groupStyles.ts +7 -1
  400. package/src/InputGroup/index.ts +1 -0
  401. package/src/Kbd/Kbd.test.tsx +22 -4
  402. package/src/Kbd/Kbd.tsx +35 -3
  403. package/src/Layer/layerAnimations.stylex.ts +20 -4
  404. package/src/Layer/useLayer.doc.mjs +5 -0
  405. package/src/Layer/useLayer.test.tsx +111 -0
  406. package/src/Layer/useLayer.tsx +90 -9
  407. package/src/Layout/Layout.tsx +8 -16
  408. package/src/Layout/LayoutFooter.doc.mjs +4 -4
  409. package/src/Layout/LayoutFooter.tsx +3 -3
  410. package/src/Layout/LayoutHeader.doc.mjs +4 -4
  411. package/src/Layout/LayoutHeader.tsx +3 -3
  412. package/src/Layout/LayoutPanel.tsx +3 -3
  413. package/src/Layout/__tests__/edgeCompensation.test.tsx +72 -0
  414. package/src/Layout/padding.stylex.ts +52 -0
  415. package/src/Lightbox/Lightbox.doc.mjs +9 -0
  416. package/src/Lightbox/Lightbox.test.tsx +53 -5
  417. package/src/Lightbox/Lightbox.tsx +9 -4
  418. package/src/Link/Link.doc.mjs +14 -0
  419. package/src/Link/Link.test.tsx +50 -0
  420. package/src/Link/Link.tsx +39 -4
  421. package/src/Markdown/Markdown.test.tsx +11 -0
  422. package/src/Markdown/Markdown.tsx +7 -0
  423. package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
  424. package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
  425. package/src/MoreMenu/MoreMenu.tsx +0 -9
  426. package/src/MultiSelector/MultiSelector.doc.mjs +30 -0
  427. package/src/MultiSelector/MultiSelector.test.tsx +375 -8
  428. package/src/MultiSelector/MultiSelector.tsx +194 -48
  429. package/src/MultiSelector/hooks.ts +27 -0
  430. package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
  431. package/src/NavMenu/NavHeadingMenu.tsx +50 -3
  432. package/src/NumberInput/NumberInput.doc.mjs +17 -0
  433. package/src/NumberInput/NumberInput.test.tsx +242 -40
  434. package/src/NumberInput/NumberInput.tsx +89 -11
  435. package/src/Pagination/Pagination.doc.mjs +3 -3
  436. package/src/Pagination/Pagination.test.tsx +117 -5
  437. package/src/Pagination/Pagination.tsx +21 -1
  438. package/src/Popover/Popover.doc.mjs +26 -0
  439. package/src/Popover/Popover.test.tsx +121 -0
  440. package/src/Popover/Popover.tsx +23 -2
  441. package/src/Popover/usePopover.doc.mjs +9 -3
  442. package/src/Popover/usePopover.tsx +70 -12
  443. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  444. package/src/PowerSearch/PowerSearch.test.tsx +97 -1
  445. package/src/PowerSearch/PowerSearch.tsx +16 -3
  446. package/src/ProgressBar/ProgressBar.test.tsx +34 -26
  447. package/src/ProgressBar/ProgressBar.tsx +3 -4
  448. package/src/RadioList/RadioList.doc.mjs +9 -0
  449. package/src/RadioList/RadioList.test.tsx +252 -16
  450. package/src/RadioList/RadioList.tsx +166 -10
  451. package/src/RadioList/RadioListItem.tsx +14 -2
  452. package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
  453. package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
  454. package/src/SegmentedControl/SegmentedControl.tsx +102 -54
  455. package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
  456. package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
  457. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  458. package/src/Selector/Selector.doc.mjs +26 -0
  459. package/src/Selector/Selector.test.tsx +387 -15
  460. package/src/Selector/Selector.tsx +175 -67
  461. package/src/Selector/hooks.ts +23 -0
  462. package/src/SideNav/SideNav.test.tsx +48 -0
  463. package/src/SideNav/SideNavHeading.tsx +8 -2
  464. package/src/SideNav/SideNavItem.tsx +2 -4
  465. package/src/Skeleton/Skeleton.test.tsx +25 -0
  466. package/src/Skeleton/Skeleton.tsx +11 -1
  467. package/src/Slider/Slider.doc.mjs +15 -0
  468. package/src/Slider/Slider.test.tsx +155 -2
  469. package/src/Slider/Slider.tsx +53 -5
  470. package/src/Spinner/Spinner.tsx +7 -1
  471. package/src/Stack/Stack.doc.mjs +77 -0
  472. package/src/Stack/Stack.test.tsx +55 -5
  473. package/src/Stack/Stack.tsx +73 -24
  474. package/src/Stack/StackItem.test.tsx +23 -0
  475. package/src/Stack/StackItem.tsx +20 -23
  476. package/src/Switch/Switch.doc.mjs +15 -0
  477. package/src/Switch/Switch.test.tsx +162 -27
  478. package/src/Switch/Switch.tsx +61 -21
  479. package/src/TabList/Tab.tsx +6 -0
  480. package/src/TabList/TabList.doc.mjs +6 -0
  481. package/src/TabList/TabList.test.tsx +251 -0
  482. package/src/TabList/TabList.tsx +103 -12
  483. package/src/TabList/TabListContext.ts +7 -3
  484. package/src/TabList/TabMenu.tsx +6 -3
  485. package/src/Table/BaseTable.tsx +24 -18
  486. package/src/Table/Table.doc.mjs +2 -0
  487. package/src/Table/Table.test.tsx +10 -0
  488. package/src/Table/Table.tsx +8 -0
  489. package/src/Table/TableCell.tsx +105 -24
  490. package/src/Table/TableHeaderCell.tsx +28 -29
  491. package/src/Table/index.ts +8 -2
  492. package/src/Table/plugins/pagination/paginateData.ts +10 -3
  493. package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
  494. package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
  495. package/src/Table/plugins/rowExpansion/index.ts +7 -0
  496. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +155 -0
  497. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +590 -0
  498. package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
  499. package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
  500. package/src/Table/tableContextMenu.test.tsx +181 -0
  501. package/src/Table/tableContextMenu.tsx +160 -0
  502. package/src/Table/types.ts +74 -0
  503. package/src/Table/useTableColumnResize.doc.mjs +3 -3
  504. package/src/Table/useTablePagination.doc.mjs +4 -1
  505. package/src/Table/useTableRowExpansion.doc.mjs +63 -0
  506. package/src/Table/useTableSortable.doc.mjs +4 -1
  507. package/src/Table/useTableStickyColumns.doc.mjs +2 -2
  508. package/src/Text/Text.doc.mjs +18 -18
  509. package/src/TextArea/TextArea.doc.mjs +17 -0
  510. package/src/TextArea/TextArea.test.tsx +167 -35
  511. package/src/TextArea/TextArea.tsx +62 -15
  512. package/src/TextInput/TextInput.doc.mjs +17 -0
  513. package/src/TextInput/TextInput.test.tsx +168 -34
  514. package/src/TextInput/TextInput.tsx +77 -9
  515. package/src/Thumbnail/Thumbnail.doc.mjs +4 -4
  516. package/src/TimeInput/TimeInput.doc.mjs +345 -60
  517. package/src/TimeInput/TimeInput.test.tsx +255 -7
  518. package/src/TimeInput/TimeInput.tsx +176 -70
  519. package/src/Timestamp/Timestamp.doc.mjs +19 -19
  520. package/src/Toast/Toast.tsx +14 -0
  521. package/src/Toast/ToastViewport.test.tsx +214 -0
  522. package/src/Toast/ToastViewport.tsx +167 -21
  523. package/src/Tokenizer/Tokenizer.doc.mjs +29 -14
  524. package/src/Tokenizer/Tokenizer.test.tsx +105 -1
  525. package/src/Tokenizer/Tokenizer.tsx +37 -1
  526. package/src/Toolbar/Toolbar.test.tsx +109 -6
  527. package/src/Toolbar/Toolbar.tsx +59 -5
  528. package/src/Tooltip/Tooltip.test.tsx +68 -0
  529. package/src/Tooltip/useTooltip.tsx +55 -8
  530. package/src/TopNav/TopNav.test.tsx +50 -0
  531. package/src/TopNav/TopNavHeading.tsx +17 -1
  532. package/src/TreeList/TreeList.test.tsx +295 -6
  533. package/src/TreeList/TreeList.tsx +73 -1
  534. package/src/TreeList/TreeListItem.tsx +51 -5
  535. package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
  536. package/src/Typeahead/BaseTypeahead.tsx +93 -9
  537. package/src/Typeahead/Typeahead.doc.mjs +141 -30
  538. package/src/Typeahead/Typeahead.test.tsx +331 -1
  539. package/src/Typeahead/Typeahead.tsx +105 -33
  540. package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
  541. package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
  542. package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
  543. package/src/VisuallyHidden/index.ts +15 -0
  544. package/src/docs-script.test.mjs +50 -0
  545. package/src/hooks/focusableSelector.ts +25 -0
  546. package/src/hooks/index.ts +28 -2
  547. package/src/hooks/useAnnounce.test.tsx +101 -0
  548. package/src/hooks/useAnnounce.ts +168 -0
  549. package/src/hooks/useClickableContainer.ts +16 -4
  550. package/src/hooks/useEntryAnimation.ts +16 -4
  551. package/src/hooks/useFocusTrap.test.tsx +132 -0
  552. package/src/hooks/useFocusTrap.ts +98 -4
  553. package/src/hooks/useGridFocus.doc.mjs +40 -2
  554. package/src/hooks/useGridFocus.test.tsx +132 -0
  555. package/src/hooks/useGridFocus.ts +343 -67
  556. package/src/hooks/useKeyboardHint.doc.mjs +101 -0
  557. package/src/hooks/useKeyboardHint.test.tsx +70 -0
  558. package/src/hooks/useKeyboardHint.tsx +332 -0
  559. package/src/hooks/useListFocus.doc.mjs +50 -10
  560. package/src/hooks/useListFocus.test.tsx +375 -0
  561. package/src/hooks/useListFocus.ts +395 -57
  562. package/src/hooks/useLongPress.test.tsx +134 -0
  563. package/src/hooks/useLongPress.ts +119 -0
  564. package/src/hooks/useTreeFocus.doc.mjs +140 -0
  565. package/src/hooks/useTreeFocus.test.tsx +214 -0
  566. package/src/hooks/useTreeFocus.ts +559 -0
  567. package/src/hooks/useTypeahead.test.tsx +109 -0
  568. package/src/hooks/useTypeahead.ts +183 -0
  569. package/src/index.ts +1 -0
  570. package/src/theme/derivedVarRegistry.test.ts +10 -5
  571. package/src/utils/dateTypes.test.ts +40 -0
  572. package/src/utils/dateTypes.ts +40 -0
  573. package/src/utils/index.ts +9 -0
  574. package/src/utils/inputAria.test.ts +39 -0
  575. package/src/utils/inputAria.ts +58 -0
  576. package/src/utils/timeParser.test.ts +10 -0
  577. package/src/utils/timeParser.ts +5 -2
  578. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
  579. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
  580. package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
  581. package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
@@ -32,7 +32,6 @@ import {useGridFocus} from '../hooks';
32
32
  import {
33
33
  useCalendarDays,
34
34
  useCalendarConstraints,
35
- useCalendarRovingTabindex,
36
35
  type CalendarDay,
37
36
  } from './hooks';
38
37
  import {
@@ -46,7 +45,6 @@ import {
46
45
  plainDateFromISO,
47
46
  plainDateToISO,
48
47
  plainDateToDate,
49
- plainDateFromDate,
50
48
  plainDateToday,
51
49
  plainDateSetFirstOfMonth,
52
50
  plainDateAddMonths,
@@ -70,8 +68,19 @@ import {
70
68
  // Types
71
69
  // =============================================================================
72
70
 
73
- export type {ISODateString, DayOfWeek, DateRange} from '../utils/dateTypes';
74
- import type {ISODateString, DayOfWeek, DateRange} from '../utils/dateTypes';
71
+ export type {
72
+ ISODateString,
73
+ DayOfWeek,
74
+ DayOfWeekName,
75
+ DateRange,
76
+ } from '../utils/dateTypes';
77
+ import type {
78
+ ISODateString,
79
+ DayOfWeek,
80
+ DayOfWeekName,
81
+ DateRange,
82
+ } from '../utils/dateTypes';
83
+ import {normalizeDayOfWeek} from '../utils/dateTypes';
75
84
  import {themeProps} from '../utils/themeProps';
76
85
 
77
86
  /** Imperative handle for Calendar handleRef */
@@ -134,10 +143,11 @@ interface CalendarBaseProps extends Omit<
134
143
  hasVariableRowCount?: boolean;
135
144
 
136
145
  /**
137
- * First day of week.
146
+ * First day of week. Accepts a number (0 = Sunday … 6 = Saturday) or a
147
+ * three-letter day name ('sun'–'sat', case-insensitive) for readability.
138
148
  * Default: 0 (Sunday)
139
149
  */
140
- weekStartsOn?: DayOfWeek;
150
+ weekStartsOn?: DayOfWeek | DayOfWeekName;
141
151
  }
142
152
 
143
153
  // ─── Mode-specific Props (discriminated union) ────────────────
@@ -200,13 +210,17 @@ export function Calendar({ref, ...props}: CalendarProps) {
200
210
  hasOutsideDays = true,
201
211
  hasWeekNumbers = false,
202
212
  hasVariableRowCount = false,
203
- weekStartsOn = 0,
213
+ weekStartsOn: weekStartsOnProp = 0,
204
214
  xstyle,
205
215
  className,
206
216
  style,
207
217
  ...rest
208
218
  } = props;
209
219
 
220
+ // Normalize `weekStartsOn` (number or three-letter day name) to a numeric
221
+ // DayOfWeek so all downstream date math keeps working with an index.
222
+ const weekStartsOn = normalizeDayOfWeek(weekStartsOnProp);
223
+
210
224
  // Today's date (memoized)
211
225
  const today = useMemo(() => plainDateToday(), []);
212
226
 
@@ -539,33 +553,52 @@ function MonthGrid({
539
553
  return null;
540
554
  }, [mode, value]);
541
555
 
542
- const {isTabbable} = useCalendarRovingTabindex({
543
- days,
544
- today,
545
- year,
546
- month: month.month,
547
- isDateDisabled,
548
- selectedDate: selectedDateForTabindex,
549
- });
556
+ // Seed the initial roving tab stop for this month. useGridFocus owns the
557
+ // live tab stop (see `hasRovingTabIndex` below) — it honors an existing
558
+ // `tabindex="0"` and repairs/moves it thereafter — so this only decides
559
+ // which day button starts tabbable. Priority: selected date (if visible and
560
+ // enabled) > today (if visible and enabled) > first enabled in-month day.
561
+ const seedTabbableIso = useMemo((): ISODateString | null => {
562
+ if (selectedDateForTabindex) {
563
+ const isSelectedInMonth =
564
+ selectedDateForTabindex.year === year &&
565
+ selectedDateForTabindex.month === month.month;
566
+ if (isSelectedInMonth && !isDateDisabled(selectedDateForTabindex)) {
567
+ return plainDateToISO(selectedDateForTabindex);
568
+ }
569
+ }
570
+
571
+ const isTodayInMonth = today.year === year && today.month === month.month;
572
+ if (isTodayInMonth && !isDateDisabled(today)) {
573
+ return plainDateToISO(today);
574
+ }
550
575
 
551
- // Helper to get the focused date from the currently focused element
576
+ for (const day of days) {
577
+ if (!day.isOutside && !isDateDisabled(day.date)) {
578
+ return day.iso;
579
+ }
580
+ }
581
+
582
+ return null;
583
+ }, [days, today, year, month.month, isDateDisabled, selectedDateForTabindex]);
584
+
585
+ // Helper to get the focused date from the currently focused element.
586
+ // Reads the machine-readable `data-date` (ISO) attribute rather than parsing
587
+ // the human-readable `aria-label` with `new Date()`, which is locale/format
588
+ // dependent and returns Invalid Date in non-English locales (e.g. fr-FR,
589
+ // ja-JP), silently swallowing month-boundary arrow navigation (complex-4).
552
590
  const getFocusedDate = useCallback((): ISODateString | null => {
553
591
  const activeElement = document.activeElement as HTMLElement | null;
554
592
  if (!activeElement) {
555
593
  return null;
556
594
  }
557
595
 
558
- const ariaLabel = activeElement.getAttribute('aria-label');
559
- if (!ariaLabel) {
596
+ const iso = activeElement.getAttribute('data-date');
597
+ if (!iso) {
560
598
  return null;
561
599
  }
562
600
 
563
- const parsed = new Date(ariaLabel);
564
- if (isNaN(parsed.getTime())) {
565
- return null;
566
- }
567
-
568
- return plainDateToISO(plainDateFromDate(parsed));
601
+ return iso as ISODateString;
569
602
  }, []);
570
603
 
571
604
  // Handle navigation to previous month
@@ -605,16 +638,31 @@ function MonthGrid({
605
638
  }
606
639
  }, [getFocusedDate, onNavigateNext]);
607
640
 
608
- // Grid focus navigation
609
- const {gridRef, handleKeyDown: handleGridKeyDown} =
610
- useGridFocus<HTMLDivElement>({
611
- columns: 7,
612
- cellSelector: 'button:not([disabled])',
613
- onNavigateBefore: handleNavigatePrevious,
614
- onNavigateAfter: handleNavigateNext,
615
- onPageUp: handlePageUp,
616
- onPageDown: handlePageDown,
617
- });
641
+ // Grid focus navigation.
642
+ //
643
+ // The hook enumerates ALL grid cells (every `role="gridcell"`, including
644
+ // disabled days and empty placeholder cells) so the true 7-column geometry is
645
+ // preserved. `isCellFocusable` / `getFocusTarget` tell the hook which cells
646
+ // can take focus (those containing an enabled day button) and where to send
647
+ // focus (the day button inside the cell). Arrow keys move to the target
648
+ // row/column and, if that cell is disabled, continue in the same direction to
649
+ // the next enabled cell.
650
+ const {
651
+ gridRef,
652
+ handleKeyDown: handleGridKeyDown,
653
+ handleFocus: handleGridFocus,
654
+ } = useGridFocus<HTMLDivElement>({
655
+ columns: 7,
656
+ cellSelector: '[role="gridcell"]',
657
+ isCellFocusable: cell =>
658
+ cell.querySelector('button:not([disabled])') !== null,
659
+ getFocusTarget: cell => cell.querySelector<HTMLElement>('button'),
660
+ hasRovingTabIndex: true,
661
+ onNavigateBefore: handleNavigatePrevious,
662
+ onNavigateAfter: handleNavigateNext,
663
+ onPageUp: handlePageUp,
664
+ onPageDown: handlePageDown,
665
+ });
618
666
 
619
667
  // Handle pending focus after month navigation
620
668
  useEffect(() => {
@@ -627,11 +675,11 @@ function MonthGrid({
627
675
  );
628
676
 
629
677
  const targetPd = plainDateFromISO(pendingFocus);
630
- const targetLabel = plainDateFormat(targetPd, DATE_FORMAT_WITH_WEEKDAY);
678
+ const targetIso = plainDateToISO(targetPd);
631
679
 
632
680
  let targetButton: HTMLElement | null = null;
633
681
  for (const button of buttons) {
634
- if (button.getAttribute('aria-label') === targetLabel) {
682
+ if (button.getAttribute('data-date') === targetIso) {
635
683
  targetButton = button;
636
684
  break;
637
685
  }
@@ -688,40 +736,38 @@ function MonthGrid({
688
736
 
689
737
  return (
690
738
  <div {...stylex.props(monthGridStyles.monthGrid)}>
691
- {/* Day names header */}
692
- <div
693
- {...stylex.props(
694
- monthGridStyles.weekHeader,
695
- hasWeekNumbers && monthGridStyles.weekHeaderWithNumbers,
696
- )}>
697
- {hasWeekNumbers && (
698
- <div
699
- {...stylex.props(
700
- monthGridStyles.dayName,
701
- monthGridStyles.weekNumberHeader,
702
- )}
703
- />
704
- )}
705
- {dayNames.map(name => (
706
- <div
707
- key={name}
708
- role="columnheader"
709
- {...stylex.props(monthGridStyles.dayName)}>
710
- {name}
711
- </div>
712
- ))}
713
- </div>
714
-
715
- {/* Days grid */}
739
+ {/* Days grid (APG grid: header row of columnheaders + week rows) */}
716
740
  <div
717
741
  ref={gridRef}
718
742
  role="grid"
719
743
  aria-label={monthLabel}
720
744
  onKeyDown={handleGridKeyDown}
745
+ onFocus={handleGridFocus}
721
746
  {...stylex.props(
722
747
  monthGridStyles.daysGrid,
723
748
  hasWeekNumbers && monthGridStyles.daysGridWithNumbers,
724
749
  )}>
750
+ {/* Day names header row (columnheaders live inside the grid). Uses the
751
+ same display:contents row so its cells align to the grid columns. */}
752
+ <div role="row" {...stylex.props(monthGridStyles.weekRow)}>
753
+ {hasWeekNumbers && (
754
+ <div
755
+ {...stylex.props(
756
+ monthGridStyles.dayName,
757
+ monthGridStyles.weekNumberHeader,
758
+ )}
759
+ />
760
+ )}
761
+ {dayNames.map(name => (
762
+ <div
763
+ key={name}
764
+ role="columnheader"
765
+ {...stylex.props(monthGridStyles.dayName)}>
766
+ {name}
767
+ </div>
768
+ ))}
769
+ </div>
770
+
725
771
  {weeks.map(week => {
726
772
  const weekDate = week.find(d => !d.isOutside)?.date || week[0].date;
727
773
  const weekNum = plainDateGetWeekNumber(weekDate);
@@ -732,7 +778,9 @@ function MonthGrid({
732
778
  role="row"
733
779
  {...stylex.props(monthGridStyles.weekRow)}>
734
780
  {hasWeekNumbers && (
735
- <div {...stylex.props(monthGridStyles.weekNumber)}>
781
+ <div
782
+ role="rowheader"
783
+ {...stylex.props(monthGridStyles.weekNumber)}>
736
784
  {weekNum}
737
785
  </div>
738
786
  )}
@@ -750,7 +798,7 @@ function MonthGrid({
750
798
  today={today}
751
799
  hasOutsideDays={hasOutsideDays}
752
800
  isDisabled={isDateDisabled(day.date)}
753
- isTabbable={isTabbable(day.iso)}
801
+ isTabbable={day.iso === seedTabbableIso}
754
802
  onDayClick={onDayClick}
755
803
  onDayHover={onDayHover}
756
804
  />
@@ -779,6 +827,11 @@ interface DayCellProps {
779
827
  today: PlainDate;
780
828
  hasOutsideDays: boolean;
781
829
  isDisabled: boolean;
830
+ /**
831
+ * Whether this day seeds the initial roving tab stop. useGridFocus
832
+ * (`hasRovingTabIndex`) owns the live tab stop thereafter — it honors an
833
+ * existing `tabindex="0"` and repairs/moves it on navigation and focus.
834
+ */
782
835
  isTabbable: boolean;
783
836
  onDayClick: (date: PlainDate) => void;
784
837
  onDayHover: (date: PlainDate | null) => void;
@@ -803,7 +856,9 @@ function DayCell({
803
856
  const {date, isOutside, dayNumber} = day;
804
857
 
805
858
  if (isOutside && !hasOutsideDays) {
806
- return <div {...stylex.props(dayCellStyles.cell)} />;
859
+ // Empty placeholder cell — still a gridcell so the grid geometry stays a
860
+ // clean 7-per-row set for keyboard navigation.
861
+ return <div role="gridcell" {...stylex.props(dayCellStyles.cell)} />;
807
862
  }
808
863
 
809
864
  const state = computeDayCellState({
@@ -825,7 +880,7 @@ function DayCell({
825
880
  const previewRounding = computePreviewRounding(state);
826
881
 
827
882
  return (
828
- <div {...stylex.props(dayCellStyles.cell)}>
883
+ <div role="gridcell" {...stylex.props(dayCellStyles.cell)}>
829
884
  {/* Range background */}
830
885
  {state.isInRange && (
831
886
  <div
@@ -863,12 +918,12 @@ function DayCell({
863
918
  {/* Day button */}
864
919
  <button
865
920
  type="button"
866
- role="gridcell"
867
921
  data-date={day.iso}
868
922
  aria-label={plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY)}
869
923
  aria-selected={state.isSelected || state.isInRange || undefined}
870
924
  aria-disabled={state.effectivelyDisabled || undefined}
871
925
  disabled={isDisabled}
926
+ // Initial roving tab-stop seed; useGridFocus owns it after mount.
872
927
  tabIndex={isTabbableDay ? 0 : -1}
873
928
  onClick={() => !state.effectivelyDisabled && onDayClick(date)}
874
929
  onMouseEnter={() => !state.effectivelyDisabled && onDayHover(date)}
@@ -27,9 +27,3 @@ export type {
27
27
  UseCalendarNavigationOptions,
28
28
  UseCalendarNavigationReturn,
29
29
  } from './useCalendarNavigation';
30
-
31
- export {useCalendarRovingTabindex} from './useCalendarRovingTabindex';
32
- export type {
33
- UseCalendarRovingTabindexOptions,
34
- UseCalendarRovingTabindexReturn,
35
- } from './useCalendarRovingTabindex';
@@ -17,6 +17,7 @@ export type {
17
17
  CalendarHandle,
18
18
  ISODateString,
19
19
  DayOfWeek,
20
+ DayOfWeekName,
20
21
  DateRange,
21
22
  } from './Calendar';
22
23
 
@@ -25,7 +26,6 @@ export {
25
26
  useCalendarDays,
26
27
  useCalendarConstraints,
27
28
  useCalendarNavigation,
28
- useCalendarRovingTabindex,
29
29
  } from './hooks';
30
30
  export type {
31
31
  CalendarDay,
@@ -35,8 +35,6 @@ export type {
35
35
  UseCalendarConstraintsReturn,
36
36
  UseCalendarNavigationOptions,
37
37
  UseCalendarNavigationReturn,
38
- UseCalendarRovingTabindexOptions,
39
- UseCalendarRovingTabindexReturn,
40
38
  } from './hooks';
41
39
 
42
40
  // Re-export calendar-specific utilities for advanced usage
@@ -78,17 +78,12 @@ export const monthGridStyles = stylex.create({
78
78
  monthGrid: {
79
79
  flex: '1 1 0',
80
80
  },
81
- weekHeader: {
82
- display: 'grid',
83
- gridTemplateColumns: 'repeat(7, 1fr)',
84
- marginBottom: spacingVars['--spacing-1'],
85
- },
86
- weekHeaderWithNumbers: {
87
- gridTemplateColumns: 'auto repeat(7, 1fr)',
88
- },
89
81
  dayName: {
90
82
  width: sizeVars['--size-element-md'],
91
- height: sizeVars['--size-element-md'],
83
+ // Restores the small gap the standalone header used to have below it.
84
+ height: `calc(${sizeVars['--size-element-md']} + ${spacingVars['--spacing-1']})`,
85
+ paddingBottom: spacingVars['--spacing-1'],
86
+ boxSizing: 'border-box',
92
87
  display: 'flex',
93
88
  alignItems: 'center',
94
89
  justifyContent: 'center',
@@ -21,7 +21,7 @@ export const docs = {
21
21
  anatomy: [
22
22
  {name: 'Scroll container', required: true, description: 'The horizontal overflow area that holds all items.'},
23
23
  {name: 'Items', required: true, description: 'The children rendered in a row. Each item is animated with a scroll-driven scale effect.'},
24
- {name: 'Fade edges', required: true, description: 'Gradient fades on the left and right edges that indicate more content is available.'},
24
+ {name: 'Fade edges', required: false, description: 'Gradient fades on the left and right edges that indicate more content is available. Enabled by default, disable with hasEdgeFade={false}.'},
25
25
  {name: 'Navigation buttons', required: false, description: 'Prev/next buttons that appear on hover. Enabled by default, disable with hasButtons={false}.'},
26
26
  ],
27
27
  },
@@ -29,7 +29,9 @@ export const docs = {
29
29
  {name: 'children', type: 'ReactNode', description: 'Carousel items rendered in a horizontal scroll container.', required: true},
30
30
  {name: 'gap', type: "0 | 0.5 | 1 | 1.5 | 2 | 3 | 4", description: 'Gap between items using the spacing token scale.', default: '1'},
31
31
  {name: 'hasButtons', type: 'boolean', description: 'Show prev/next navigation buttons on hover (desktop only).', default: 'true'},
32
+ {name: 'hasEdgeFade', type: 'boolean', description: 'Show a gradient edge-fade mask when content overflows, signalling that more items exist off-screen.', default: 'true'},
32
33
  {name: 'hasSnap', type: 'boolean', description: 'Enable scroll-snap so each child snaps to the start edge.', default: 'false'},
34
+ {name: 'padding', type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10', description: 'Inline padding inside the scroll container, with matching scroll-padding so snap points align to the content edge.'},
33
35
  {name: 'aria-label', type: 'string', description: 'Accessible label for the carousel region.', default: "\'Carousel\'"},
34
36
  {name: 'ref', type: 'React.Ref<HTMLDivElement>', description: 'Ref forwarded to the root element.'},
35
37
  {name: 'xstyle', type: 'StyleXStyles', description: 'StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value.'},
@@ -71,7 +73,9 @@ export const docsZh = {
71
73
  children: '在水平滚动容器中渲染的轮播项目。',
72
74
  gap: '使用间距令牌比例的项目间距。',
73
75
  hasButtons: '悬停时显示上一个/下一个导航按钮(仅桌面端)。',
76
+ hasEdgeFade: '内容溢出时显示渐变边缘遮罩,提示屏幕外还有更多项目。',
74
77
  hasSnap: '启用滚动吸附,使每个子元素吸附到起始边缘。',
78
+ padding: '滚动容器内的内联内边距,并设置匹配的 scroll-padding,使吸附点与内容边缘对齐。',
75
79
  'aria-label': '轮播区域的无障碍标签。',
76
80
  },
77
81
  };
@@ -95,7 +99,9 @@ export const docsDense = {
95
99
  children: 'carousel items in horizontal scroll',
96
100
  gap: 'item spacing via spacing token scale',
97
101
  hasButtons: 'prev/next buttons on hover (desktop)',
102
+ hasEdgeFade: 'gradient edge-fade mask on overflow',
98
103
  hasSnap: 'scroll-snap; children snap to start edge',
104
+ padding: 'inline padding; scroll-padding keeps snap points on content edge',
99
105
  'aria-label': 'accessible label for carousel region',
100
106
  'data-testid': 'test selector for automated testing frameworks',
101
107
  },
@@ -78,4 +78,24 @@ describe('Carousel', () => {
78
78
  expect(screen.getByLabelText('Scroll left')).toBeInTheDocument();
79
79
  expect(screen.getByLabelText('Scroll right')).toBeInTheDocument();
80
80
  });
81
+
82
+ it('disables edge scroll buttons instead of removing them from the tab order', () => {
83
+ // In jsdom there is no measurable overflow, so both edges are at rest and
84
+ // the scroll buttons are in their hidden/inert state. They must stay
85
+ // mounted but be disabled — a disabled <button> is skipped by the tab
86
+ // order and hidden from the a11y tree, so keyboard users don't focus an
87
+ // invisible control (WCAG 2.4.7).
88
+ render(
89
+ <Carousel aria-label="Edge state">
90
+ <div>Item 1</div>
91
+ <div>Item 2</div>
92
+ </Carousel>,
93
+ );
94
+ const left = screen.getByLabelText('Scroll left');
95
+ const right = screen.getByLabelText('Scroll right');
96
+ expect(left).toBeInTheDocument();
97
+ expect(right).toBeInTheDocument();
98
+ expect(left).toBeDisabled();
99
+ expect(right).toBeDisabled();
100
+ });
81
101
  });
@@ -295,9 +295,16 @@ export function Carousel({
295
295
  const firstChild = el.firstElementChild as HTMLElement | null;
296
296
  const itemWidth = firstChild ? firstChild.offsetWidth : 0;
297
297
  const amount = el.clientWidth - itemWidth * 0.5;
298
+ // Respect the user's reduced-motion preference — mirrors the CSS
299
+ // scroll-behavior override so button-driven scrolling doesn't animate
300
+ // for users who opted out of motion.
301
+ const prefersReducedMotion =
302
+ typeof window !== 'undefined' &&
303
+ typeof window.matchMedia === 'function' &&
304
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
298
305
  el.scrollBy({
299
306
  left: direction * Math.max(amount, itemWidth),
300
- behavior: 'smooth',
307
+ behavior: prefersReducedMotion ? 'auto' : 'smooth',
301
308
  });
302
309
  }, []);
303
310
 
@@ -360,6 +367,11 @@ export function Carousel({
360
367
  variant="ghost"
361
368
  size="sm"
362
369
  isIconOnly
370
+ // Disabled when there's nothing to scroll toward. Keeps the
371
+ // button mounted (stable layout/focus) but removes it from the
372
+ // tab order and a11y tree while it's visually hidden, so
373
+ // keyboard users don't land on an invisible control.
374
+ isDisabled={!overflowStart}
363
375
  onClick={() => scrollBy(-1)}
364
376
  xstyle={styles.buttonRadiusOverride}
365
377
  />
@@ -376,6 +388,9 @@ export function Carousel({
376
388
  variant="ghost"
377
389
  size="sm"
378
390
  isIconOnly
391
+ // See "Scroll left" — disabled while visually hidden so the
392
+ // button stays mounted but out of the tab order / a11y tree.
393
+ isDisabled={!overflowEnd}
379
394
  onClick={() => scrollBy(1)}
380
395
  xstyle={styles.buttonRadiusOverride}
381
396
  />
@@ -18,14 +18,24 @@ export const docs = {
18
18
  },
19
19
  {
20
20
  name: 'width',
21
- type: 'number | string',
21
+ type: 'SizeValue',
22
22
  description: 'Container width (px or CSS value).',
23
23
  },
24
24
  {
25
25
  name: 'height',
26
- type: 'number | string',
26
+ type: 'SizeValue',
27
27
  description: 'Container height (px or CSS value).',
28
28
  },
29
+ {
30
+ name: 'maxWidth',
31
+ type: 'SizeValue',
32
+ description: 'Maximum container width (px or CSS value).',
33
+ },
34
+ {
35
+ name: 'minHeight',
36
+ type: 'SizeValue',
37
+ description: 'Minimum container height (px or CSS value).',
38
+ },
29
39
  {
30
40
  name: 'isInline',
31
41
  type: 'boolean',
@@ -39,15 +39,21 @@ const styles = stylex.create({
39
39
 
40
40
  // Dynamic styles for sizing props
41
41
  const dynamicStyles = stylex.create({
42
- sizing: (width: SizeValue | null, height: SizeValue | null) => ({
42
+ sizing: (
43
+ width: SizeValue | null,
44
+ height: SizeValue | null,
45
+ maxWidth: SizeValue | null,
46
+ minHeight: SizeValue | null,
47
+ ) => ({
43
48
  width,
44
49
  height,
50
+ maxWidth,
51
+ minHeight,
45
52
  }),
46
53
  });
47
54
 
48
55
  export type CenterAxis = 'both' | 'horizontal' | 'vertical';
49
56
 
50
-
51
57
  export interface CenterProps extends BaseProps<HTMLDivElement> {
52
58
  /** Ref forwarded to the root element */
53
59
  ref?: React.Ref<HTMLDivElement>;
@@ -72,6 +78,18 @@ export interface CenterProps extends BaseProps<HTMLDivElement> {
72
78
  */
73
79
  height?: SizeValue;
74
80
 
81
+ /**
82
+ * Maximum width of the container.
83
+ * Numbers are treated as pixels, strings are used as-is (e.g., '100%').
84
+ */
85
+ maxWidth?: SizeValue;
86
+
87
+ /**
88
+ * Minimum height of the container.
89
+ * Numbers are treated as pixels, strings are used as-is (e.g., '100%').
90
+ */
91
+ minHeight?: SizeValue;
92
+
75
93
  /**
76
94
  * Whether to make the container inline-flex (useful for text/icons).
77
95
  * @default false
@@ -101,6 +119,8 @@ export function Center({
101
119
  axis = 'both',
102
120
  width,
103
121
  height,
122
+ maxWidth,
123
+ minHeight,
104
124
  isInline = false,
105
125
  children,
106
126
  xstyle,
@@ -115,7 +135,12 @@ export function Center({
115
135
  isInline ? styles.inline : styles.base,
116
136
  (axis === 'both' || axis === 'vertical') && styles.alignItemsCenter,
117
137
  (axis === 'both' || axis === 'horizontal') && styles.justifyContentCenter,
118
- dynamicStyles.sizing(width ?? null, height ?? null),
138
+ dynamicStyles.sizing(
139
+ width ?? null,
140
+ height ?? null,
141
+ maxWidth ?? null,
142
+ minHeight ?? null,
143
+ ),
119
144
  xstyle,
120
145
  ),
121
146
  className,
@@ -409,18 +409,36 @@ describe('ChatComposerInput', () => {
409
409
  });
410
410
 
411
411
  describe('accessibility', () => {
412
- it('has aria-haspopup on the textbox', () => {
412
+ it('exposes role=combobox when triggers are configured', () => {
413
413
  const triggers = [createMentionTrigger()];
414
414
  render(<ChatComposerInput triggers={triggers} />);
415
- const textbox = screen.getByRole('textbox');
416
- expect(textbox).toHaveAttribute('aria-haspopup', 'listbox');
415
+ // aria-expanded/haspopup/controls/activedescendant are only valid on
416
+ // role="combobox", so the editable element must be a combobox (not a
417
+ // plain textbox) whenever trigger-menu behavior is wired.
418
+ expect(screen.getByRole('combobox')).toBeInTheDocument();
419
+ expect(screen.queryByRole('textbox')).not.toBeInTheDocument();
420
+ });
421
+
422
+ it('has aria-haspopup on the combobox', () => {
423
+ const triggers = [createMentionTrigger()];
424
+ render(<ChatComposerInput triggers={triggers} />);
425
+ const combobox = screen.getByRole('combobox');
426
+ expect(combobox).toHaveAttribute('aria-haspopup', 'listbox');
417
427
  });
418
428
 
419
429
  it('has aria-expanded=false when menu is closed', () => {
420
430
  const triggers = [createMentionTrigger()];
421
431
  render(<ChatComposerInput triggers={triggers} />);
422
- const textbox = screen.getByRole('textbox');
423
- expect(textbox).toHaveAttribute('aria-expanded', 'false');
432
+ const combobox = screen.getByRole('combobox');
433
+ expect(combobox).toHaveAttribute('aria-expanded', 'false');
434
+ });
435
+
436
+ it('stays role=textbox with no combobox attributes when no triggers are configured', () => {
437
+ render(<ChatComposerInput label="Message" />);
438
+ const textbox = screen.getByRole('textbox', {name: 'Message'});
439
+ // A plain textbox must not carry combobox-only ARIA (axe: aria-allowed-attr).
440
+ expect(textbox).not.toHaveAttribute('aria-expanded');
441
+ expect(textbox).not.toHaveAttribute('aria-haspopup');
424
442
  });
425
443
  });
426
444
 
@@ -590,7 +608,8 @@ describe('ChatComposerInput', () => {
590
608
  const result = render(
591
609
  <ChatComposerInput triggers={triggers} onChange={onChange} />,
592
610
  );
593
- const textbox = screen.getByRole('textbox');
611
+ // With triggers configured the editable is a combobox, not a textbox.
612
+ const textbox = screen.getByRole('combobox');
594
613
  textbox.focus();
595
614
  return {...result, textbox, onChange};
596
615
  }
@@ -684,7 +703,7 @@ describe('ChatComposerInput', () => {
684
703
  onChange={onChange}
685
704
  />,
686
705
  );
687
- const textbox = screen.getByRole('textbox');
706
+ const textbox = screen.getByRole('combobox');
688
707
  textbox.focus();
689
708
 
690
709
  setCursorAfterText(textbox, 'hello @');
@@ -632,7 +632,6 @@ export function ChatComposerInput(props: ChatComposerInputProps) {
632
632
  )}
633
633
  <div
634
634
  ref={editableRef}
635
- role="textbox"
636
635
  aria-multiline="true"
637
636
  aria-label={label}
638
637
  contentEditable={!isDisabled}
@@ -34,7 +34,7 @@ export const docs = {
34
34
  name: 'dictation',
35
35
  type: 'UseSpeechRecognitionReturn',
36
36
  description:
37
- 'The return value from useChatDictation or useSpeechRecognition. Controls all button state \u2014 listening, volume, bands, and toggle.',
37
+ 'The return value from useChatDictation or useSpeechRecognition. Controls all button state: listening, volume, bands, and toggle.',
38
38
  required: true,
39
39
  },
40
40
  {