@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
@@ -21,6 +21,7 @@
21
21
  import {useRef, useTransition, type ReactNode} from 'react';
22
22
  import type {BaseProps} from '../BaseProps';
23
23
  import * as stylex from '@stylexjs/stylex';
24
+ import {useTooltip} from '../Tooltip/useTooltip';
24
25
  import {
25
26
  colorVars,
26
27
  sizeVars,
@@ -32,13 +33,13 @@ import {
32
33
  fontWeightVars,
33
34
  typeScaleVars,
34
35
  } from '../theme/tokens.stylex';
35
- import {Tooltip} from '../Tooltip/Tooltip';
36
36
  import {Spinner} from '../Spinner';
37
+ import {VisuallyHidden} from '../VisuallyHidden';
37
38
 
38
39
  import {EDGE_COMP_ATTR} from '../Layout/edgeCompensation.stylex';
39
40
  import {useSize} from '../SizeContext/SizeContext';
40
41
  import {useButtonGroup} from '../ButtonGroup/ButtonGroupContext';
41
- import {mergeProps} from '../utils';
42
+ import {mergeProps, mergeRefs} from '../utils';
42
43
  import {useLinkComponent} from '../Link/useLinkComponent';
43
44
  import type {LinkComponentType} from '../Link/types';
44
45
  import {themeProps} from '../utils/themeProps';
@@ -124,17 +125,6 @@ const styles = stylex.create({
124
125
  textOverflow: 'ellipsis',
125
126
  minWidth: 0,
126
127
  },
127
- visuallyHidden: {
128
- position: 'absolute',
129
- width: '1px',
130
- height: '1px',
131
- padding: 0,
132
- margin: '-1px',
133
- overflow: 'hidden',
134
- clip: 'rect(0, 0, 0, 0)',
135
- whiteSpace: 'nowrap',
136
- borderWidth: 0,
137
- },
138
128
  link: {
139
129
  textDecoration: 'none',
140
130
  },
@@ -590,6 +580,16 @@ export function Button({
590
580
  // for keyboard users to reach the tooltip. Otherwise use native disabled.
591
581
  const useAriaDisabled = tooltip != null && buttonDisabled;
592
582
 
583
+ // Attach tooltip behavior via the hook rather than wrapping the button in a
584
+ // <Tooltip> element. The hook adds hover/focus triggers to the button itself,
585
+ // so no extra DOM node is inserted — the button stays a direct child of its
586
+ // container (no layout shift, and edge-compensation markers remain
587
+ // discoverable through the container's direct-child `:has()` selector).
588
+ const tooltipHook = useTooltip({
589
+ placement: 'above',
590
+ isEnabled: tooltip != null,
591
+ });
592
+
593
593
  const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
594
594
  // The ref guard dedupes fire-once actions. Interruptible callers skip it so
595
595
  // a re-click while pending starts a fresh action that interrupts the prior.
@@ -690,12 +690,9 @@ export function Button({
690
690
  )}
691
691
  </span>
692
692
  {/* Live region for loading state announcements */}
693
- <span
694
- {...stylex.props(styles.visuallyHidden)}
695
- role="status"
696
- aria-live="polite">
693
+ <VisuallyHidden role="status" aria-live="polite">
697
694
  {isLoadingState ? 'Loading' : ''}
698
- </span>
695
+ </VisuallyHidden>
699
696
  </>
700
697
  );
701
698
 
@@ -709,18 +706,39 @@ export function Button({
709
706
  (children != null && children !== label);
710
707
  const ariaLabelProp = needsAriaLabel ? {'aria-label': label} : null;
711
708
 
709
+ // When a tooltip is attached via the hook, point aria-describedby at the
710
+ // tooltip content (composing with any consumer-provided value).
711
+ const describedByProp =
712
+ tooltip != null
713
+ ? {
714
+ 'aria-describedby':
715
+ [props['aria-describedby'], tooltipHook.describedBy]
716
+ .filter(Boolean)
717
+ .join(' ') || undefined,
718
+ }
719
+ : null;
720
+
721
+ // Merge the consumer ref with the tooltip hook's trigger ref so both point at
722
+ // the same element. mergeRefs tolerates undefined, so this is a no-op for the
723
+ // tooltip side when no tooltip is set.
724
+ const mergedButtonRef = mergeRefs(
725
+ ref,
726
+ tooltip != null ? tooltipHook.ref : undefined,
727
+ );
728
+
712
729
  let element: ReactNode;
713
730
 
714
731
  if (renderAsLink) {
715
732
  element = (
716
733
  <LinkComponent
717
- ref={ref as React.Ref<HTMLAnchorElement>}
734
+ ref={mergedButtonRef as React.Ref<HTMLAnchorElement>}
718
735
  href={href}
719
736
  target={target}
720
737
  rel={rel}
721
738
  {...sharedMergedProps}
722
739
  {...props}
723
740
  {...ariaLabelProp}
741
+ {...describedByProp}
724
742
  {...edgeCompAttr}
725
743
  onClick={handleClick}>
726
744
  {buttonContent}
@@ -729,12 +747,13 @@ export function Button({
729
747
  } else {
730
748
  element = (
731
749
  <button
732
- ref={ref}
750
+ ref={mergedButtonRef}
733
751
  type={type}
734
752
  disabled={useAriaDisabled ? undefined : buttonDisabled}
735
753
  {...sharedMergedProps}
736
754
  {...props}
737
755
  {...ariaLabelProp}
756
+ {...describedByProp}
738
757
  {...edgeCompAttr}
739
758
  aria-busy={isLoadingState || undefined}
740
759
  aria-disabled={useAriaDisabled || undefined}
@@ -747,9 +766,10 @@ export function Button({
747
766
 
748
767
  if (tooltip) {
749
768
  return (
750
- <Tooltip content={tooltip} placement="above">
769
+ <>
751
770
  {element}
752
- </Tooltip>
771
+ {tooltipHook.renderTooltip(tooltip)}
772
+ </>
753
773
  );
754
774
  }
755
775
 
@@ -88,17 +88,18 @@ describe('ButtonGroup', () => {
88
88
  expect(refValue).toBe(screen.getByRole('group'));
89
89
  });
90
90
 
91
- it('sets aria-orientation', () => {
91
+ it('reflects orientation via data-orientation, not aria-orientation', () => {
92
+ // aria-orientation is not a valid ARIA attribute on role="group"; the
93
+ // orientation is exposed through data-orientation instead.
92
94
  const {rerender} = render(
93
95
  <ButtonGroup label="Actions">
94
96
  <Button label="Copy" />
95
97
  </ButtonGroup>,
96
98
  );
97
99
 
98
- expect(screen.getByRole('group')).toHaveAttribute(
99
- 'aria-orientation',
100
- 'horizontal',
101
- );
100
+ let group = screen.getByRole('group');
101
+ expect(group).not.toHaveAttribute('aria-orientation');
102
+ expect(group).toHaveAttribute('data-orientation', 'horizontal');
102
103
 
103
104
  rerender(
104
105
  <ButtonGroup label="Actions" orientation="vertical">
@@ -106,10 +107,9 @@ describe('ButtonGroup', () => {
106
107
  </ButtonGroup>,
107
108
  );
108
109
 
109
- expect(screen.getByRole('group')).toHaveAttribute(
110
- 'aria-orientation',
111
- 'vertical',
112
- );
110
+ group = screen.getByRole('group');
111
+ expect(group).not.toHaveAttribute('aria-orientation');
112
+ expect(group).toHaveAttribute('data-orientation', 'vertical');
113
113
  });
114
114
 
115
115
  it('renders with vertical orientation', () => {
@@ -141,7 +141,6 @@ export function ButtonGroup({
141
141
  role="group"
142
142
  aria-label={label}
143
143
  onKeyDown={handleKeyDown}
144
- aria-orientation={orientation}
145
144
  aria-disabled={isDisabled || undefined}
146
145
  data-testid={testId}
147
146
  {...mergeProps(
@@ -103,8 +103,8 @@ export const docs = {
103
103
  },
104
104
  {
105
105
  name: 'weekStartsOn',
106
- type: '0 | 1 | 2 | 3 | 4 | 5 | 6',
107
- description: 'First day of week (0=Sunday).',
106
+ type: "0 | 1 | 2 | 3 | 4 | 5 | 6 | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'",
107
+ description: 'First day of week. Accepts a number (0=Sunday) or a three-letter day name (e.g. "mon").',
108
108
  default: '0',
109
109
  },
110
110
  ],
@@ -147,7 +147,7 @@ export const docsZh = {
147
147
  {name: 'hasOutsideDays', type: 'boolean', description: '显示相邻月份的日期。', default: 'true'},
148
148
  {name: 'hasWeekNumbers', type: 'boolean', description: '显示 ISO 周数。', default: 'false'},
149
149
  {name: 'hasVariableRowCount', type: 'boolean', description: '可变行数与固定 6 行网格。', default: 'false'},
150
- {name: 'weekStartsOn', type: '0 | 1 | 2 | 3 | 4 | 5 | 6', description: '每周起始日(0=周日)。', default: '0'},
150
+ {name: 'weekStartsOn', type: "0 | 1 | 2 | 3 | 4 | 5 | 6 | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'", description: '每周起始日。可为数字(0=周日)或三字母星期缩写(如 "mon")。', default: '0'},
151
151
  ],
152
152
  theming: {
153
153
  targets: [
@@ -200,6 +200,6 @@ export const docsDense = {
200
200
  hasOutsideDays: 'show days from adjacent months',
201
201
  hasWeekNumbers: 'show ISO week numbers',
202
202
  hasVariableRowCount: 'variable vs fixed 6-row grid',
203
- weekStartsOn: 'first day of week (0=Sunday)',
203
+ weekStartsOn: 'first day of week (0=Sunday, or name e.g. "mon")',
204
204
  },
205
205
  };
@@ -10,19 +10,21 @@
10
10
  */
11
11
 
12
12
  import {describe, it, expect, vi} from 'vitest';
13
- import {act, render, screen} from '@testing-library/react';
13
+ import {act, render, screen, within} from '@testing-library/react';
14
14
  import userEvent from '@testing-library/user-event';
15
15
  import {Calendar} from './Calendar';
16
16
  import type {CalendarHandle} from './Calendar';
17
17
 
18
18
  /**
19
19
  * Helper to find a day button by its day number.
20
- * Day buttons have aria-labels like "Thursday, January 15, 2026".
20
+ * Day buttons are native <button> elements with aria-labels like
21
+ * "Thursday, January 15, 2026". Each button is the sole child of a
22
+ * role="gridcell" wrapper.
21
23
  */
22
24
  function getDayButton(day: number, month = 'January', year = 2026) {
23
25
  // Match the full date pattern with the day number
24
26
  const pattern = new RegExp(`${month}\\s+${day},\\s+${year}`);
25
- return screen.getByRole('gridcell', {name: pattern});
27
+ return screen.getByRole('button', {name: pattern});
26
28
  }
27
29
 
28
30
  describe('Calendar', () => {
@@ -146,10 +148,7 @@ describe('Calendar', () => {
146
148
  const handleFocusChange = vi.fn();
147
149
 
148
150
  render(
149
- <Calendar
150
- focusDate="2026-01-01"
151
- onFocusDateChange={handleFocusChange}
152
- />,
151
+ <Calendar focusDate="2026-01-01" onFocusDateChange={handleFocusChange} />,
153
152
  );
154
153
 
155
154
  const nextButton = screen.getByRole('button', {name: 'Next month'});
@@ -189,9 +188,7 @@ describe('Calendar', () => {
189
188
  return day !== 0 && day !== 6;
190
189
  };
191
190
 
192
- render(
193
- <Calendar focusDate="2026-01-01" dateConstraints={[isWeekday]} />,
194
- );
191
+ render(<Calendar focusDate="2026-01-01" dateConstraints={[isWeekday]} />);
195
192
 
196
193
  // January 4, 2026 is a Sunday - should be disabled
197
194
  const sunday = getDayButton(4);
@@ -238,6 +235,21 @@ describe('Calendar', () => {
238
235
  expect(dayNames[0]).toHaveTextContent('Mo');
239
236
  });
240
237
 
238
+ it('accepts a three-letter day name for weekStartsOn', () => {
239
+ render(<Calendar weekStartsOn="mon" />);
240
+
241
+ // "mon" should behave exactly like the numeric 1 (Monday first).
242
+ const dayNames = screen.getAllByText(/^(Mo|Tu|We|Th|Fr|Sa|Su)$/);
243
+ expect(dayNames[0]).toHaveTextContent('Mo');
244
+ });
245
+
246
+ it('treats weekStartsOn day names case-insensitively', () => {
247
+ render(<Calendar weekStartsOn={'WED' as 'wed'} />);
248
+
249
+ const dayNames = screen.getAllByText(/^(Mo|Tu|We|Th|Fr|Sa|Su)$/);
250
+ expect(dayNames[0]).toHaveTextContent('We');
251
+ });
252
+
241
253
  // ─── Range Mode ──────────────────────────────────────────────
242
254
 
243
255
  it('supports range selection mode', async () => {
@@ -245,11 +257,7 @@ describe('Calendar', () => {
245
257
  const handleChange = vi.fn();
246
258
 
247
259
  render(
248
- <Calendar
249
- mode="range"
250
- onChange={handleChange}
251
- focusDate="2026-01-01"
252
- />,
260
+ <Calendar mode="range" onChange={handleChange} focusDate="2026-01-01" />,
253
261
  );
254
262
 
255
263
  // Click start date
@@ -271,11 +279,7 @@ describe('Calendar', () => {
271
279
  const handleChange = vi.fn();
272
280
 
273
281
  render(
274
- <Calendar
275
- mode="range"
276
- onChange={handleChange}
277
- focusDate="2026-01-01"
278
- />,
282
+ <Calendar mode="range" onChange={handleChange} focusDate="2026-01-01" />,
279
283
  );
280
284
 
281
285
  // Click later date first
@@ -321,6 +325,75 @@ describe('Calendar', () => {
321
325
  expect(screen.getAllByRole('gridcell').length).toBeGreaterThan(0);
322
326
  });
323
327
 
328
+ it('renders a valid APG grid: one grid, header row of columnheaders inside it, week rows of gridcells', () => {
329
+ render(<Calendar focusDate="2026-01-01" />);
330
+
331
+ const grids = screen.getAllByRole('grid');
332
+ expect(grids.length).toBe(1);
333
+ const grid = grids[0];
334
+
335
+ // The columnheaders live INSIDE the grid.
336
+ const columnHeaders = screen.getAllByRole('columnheader');
337
+ expect(columnHeaders.length).toBe(7);
338
+ for (const header of columnHeaders) {
339
+ expect(grid.contains(header)).toBe(true);
340
+ }
341
+
342
+ // The grid's rows: first is the header row of columnheaders, the rest are
343
+ // week rows whose direct children are gridcells.
344
+ const rows = within(grid).getAllByRole('row');
345
+ // 1 header row + 6 week rows (fixed 6-row grid).
346
+ expect(rows.length).toBe(7);
347
+
348
+ const [headerRow, ...weekRows] = rows;
349
+
350
+ // Header row's direct children are the 7 columnheaders.
351
+ const headerChildren = Array.from(headerRow.children);
352
+ const headerColHeaders = headerChildren.filter(
353
+ child => child.getAttribute('role') === 'columnheader',
354
+ );
355
+ expect(headerColHeaders.length).toBe(7);
356
+
357
+ // Each week row's direct children are gridcells (7 per row).
358
+ for (const row of weekRows) {
359
+ const gridcellChildren = Array.from(row.children).filter(
360
+ child => child.getAttribute('role') === 'gridcell',
361
+ );
362
+ expect(gridcellChildren.length).toBe(7);
363
+ }
364
+ });
365
+
366
+ it('renders week-number cells as rowheader when hasWeekNumbers is set', () => {
367
+ render(<Calendar hasWeekNumbers focusDate="2026-01-01" />);
368
+
369
+ const grid = screen.getByRole('grid');
370
+ const rowHeaders = within(grid).getAllByRole('rowheader');
371
+ // One rowheader (week number) per week row.
372
+ expect(rowHeaders.length).toBeGreaterThanOrEqual(5);
373
+ // Week numbers are numeric.
374
+ for (const header of rowHeaders) {
375
+ expect(header.textContent).toMatch(/^\d+$/);
376
+ }
377
+ });
378
+
379
+ it('gridcell wrappers are direct children of week rows, and the button is inside the gridcell', () => {
380
+ render(<Calendar focusDate="2026-01-01" />);
381
+
382
+ const grid = screen.getByRole('grid');
383
+ const gridcells = within(grid).getAllByRole('gridcell');
384
+ for (const cell of gridcells) {
385
+ // The gridcell's parent is a role="row".
386
+ const parent = cell.parentElement;
387
+ expect(parent?.getAttribute('role')).toBe('row');
388
+ // The day button (if present) is a descendant of the gridcell.
389
+ const button = cell.querySelector('button');
390
+ if (button) {
391
+ expect(cell.contains(button)).toBe(true);
392
+ expect(button).not.toHaveAttribute('role', 'gridcell');
393
+ }
394
+ }
395
+ });
396
+
324
397
  it('has navigation buttons with accessible labels', () => {
325
398
  render(<Calendar />);
326
399
 
@@ -346,16 +419,13 @@ describe('Calendar', () => {
346
419
  const handleFocusChange = vi.fn();
347
420
 
348
421
  render(
349
- <Calendar
350
- focusDate="2026-01-01"
351
- onFocusDateChange={handleFocusChange}
352
- />,
422
+ <Calendar focusDate="2026-01-01" onFocusDateChange={handleFocusChange} />,
353
423
  );
354
424
 
355
425
  // Focus Jan 28
356
426
  const day28 = getDayButton(28);
357
427
  await user.click(day28);
358
- day28.querySelector('button')?.focus();
428
+ day28.focus();
359
429
 
360
430
  // Press ArrowDown — should move to Feb 4 (+7 days), not Feb 28
361
431
  await user.keyboard('{ArrowDown}');
@@ -365,6 +435,78 @@ describe('Calendar', () => {
365
435
  expect(focusedElement).toHaveAttribute('data-date', '2026-02-04');
366
436
  });
367
437
 
438
+ it('ArrowDown lands on the same weekday +7 days even when earlier days are disabled (complex-2)', async () => {
439
+ const user = userEvent.setup();
440
+
441
+ // min disables Jan 1–4 (HTML-disabled). Jan 8 is a Thursday; ArrowDown must
442
+ // land on Jan 15 (the same weekday, +7 days), not a shifted date caused by
443
+ // the removed enabled cells.
444
+ render(<Calendar focusDate="2026-01-01" min="2026-01-05" />);
445
+
446
+ const day1 = getDayButton(1);
447
+ expect(day1).toBeDisabled();
448
+
449
+ const day8 = getDayButton(8);
450
+ day8.focus();
451
+
452
+ await user.keyboard('{ArrowDown}');
453
+ expect(document.activeElement).toHaveAttribute('data-date', '2026-01-15');
454
+
455
+ await user.keyboard('{ArrowDown}');
456
+ expect(document.activeElement).toHaveAttribute('data-date', '2026-01-22');
457
+ });
458
+
459
+ it('ArrowUp skips a disabled cell in the same column to the next enabled row (complex-2)', async () => {
460
+ const user = userEvent.setup();
461
+
462
+ // max disables Jan 22 onward. Focus Feb 5 handling is out of scope; instead
463
+ // use dateConstraints to disable a single mid-grid day and verify column
464
+ // geometry is preserved (ArrowUp from Jan 15 skips disabled Jan 8 → Jan 1).
465
+ const disableJan8 = (date: Date) =>
466
+ !(
467
+ date.getFullYear() === 2026 &&
468
+ date.getMonth() === 0 &&
469
+ date.getDate() === 8
470
+ );
471
+
472
+ render(<Calendar focusDate="2026-01-01" dateConstraints={[disableJan8]} />);
473
+
474
+ const day8 = getDayButton(8);
475
+ expect(day8).toBeDisabled();
476
+
477
+ const day15 = getDayButton(15);
478
+ day15.focus();
479
+
480
+ // ArrowUp: same column one row up is Jan 8 (disabled) → skip to Jan 1.
481
+ await user.keyboard('{ArrowUp}');
482
+ expect(document.activeElement).toHaveAttribute('data-date', '2026-01-01');
483
+ });
484
+
485
+ it('cross-month arrow nav resolves the focused date from data-date (locale-safe)', async () => {
486
+ // Regression for complex-4: getFocusedDate must read the machine-readable
487
+ // data-date attribute, not parse the human-readable aria-label with
488
+ // new Date() (which is locale-dependent). We prove the resolution path by
489
+ // corrupting the aria-label to something new Date() cannot parse — cross-
490
+ // month navigation must still report the correct ISO date.
491
+ const user = userEvent.setup();
492
+ const handleFocusChange = vi.fn();
493
+
494
+ render(
495
+ <Calendar focusDate="2026-01-01" onFocusDateChange={handleFocusChange} />,
496
+ );
497
+
498
+ const day28 = getDayButton(28);
499
+ await user.click(day28);
500
+ day28.focus();
501
+ // Simulate a non-English/unparseable aria-label while keeping data-date.
502
+ day28.setAttribute('aria-label', '2026年1月28日 水曜日');
503
+
504
+ await user.keyboard('{ArrowDown}');
505
+
506
+ // Feb 4 (+7 days) — resolved via data-date despite the unparseable label.
507
+ expect(document.activeElement).toHaveAttribute('data-date', '2026-02-04');
508
+ });
509
+
368
510
  it('prev button is disabled when focusDate month contains min', () => {
369
511
  render(<Calendar focusDate="2026-01-01" min="2026-01-15" />);
370
512
 
@@ -414,11 +556,7 @@ describe('Calendar', () => {
414
556
  const handleChange = vi.fn();
415
557
 
416
558
  render(
417
- <Calendar
418
- mode="range"
419
- onChange={handleChange}
420
- focusDate="2026-01-01"
421
- />,
559
+ <Calendar mode="range" onChange={handleChange} focusDate="2026-01-01" />,
422
560
  );
423
561
 
424
562
  // Click start date to begin range selection