@astryxdesign/core 0.1.2 → 0.1.3

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 (567) 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 +2 -4
  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 +4 -5
  54. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  55. package/dist/ContextMenu/ContextMenu.js +93 -11
  56. package/dist/DateInput/DateInput.d.ts +23 -1
  57. package/dist/DateInput/DateInput.d.ts.map +1 -1
  58. package/dist/DateInput/DateInput.js +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 +11 -8
  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 +10 -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 +2 -1
  207. package/dist/Table/index.d.ts.map +1 -1
  208. package/dist/Table/index.js +2 -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/sortable/useTableSortable.d.ts.map +1 -1
  215. package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
  216. package/dist/Table/tableContextMenu.d.ts +33 -0
  217. package/dist/Table/tableContextMenu.d.ts.map +1 -0
  218. package/dist/Table/tableContextMenu.js +133 -0
  219. package/dist/Table/types.d.ts +66 -0
  220. package/dist/Table/types.d.ts.map +1 -1
  221. package/dist/TextArea/TextArea.d.ts +22 -1
  222. package/dist/TextArea/TextArea.d.ts.map +1 -1
  223. package/dist/TextArea/TextArea.js +41 -9
  224. package/dist/TextInput/TextInput.d.ts +23 -2
  225. package/dist/TextInput/TextInput.d.ts.map +1 -1
  226. package/dist/TextInput/TextInput.js +55 -10
  227. package/dist/TimeInput/TimeInput.d.ts +23 -1
  228. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  229. package/dist/TimeInput/TimeInput.js +147 -76
  230. package/dist/Toast/Toast.d.ts.map +1 -1
  231. package/dist/Toast/Toast.js +14 -0
  232. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  233. package/dist/Toast/ToastViewport.js +131 -3
  234. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  235. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  236. package/dist/Tokenizer/Tokenizer.js +26 -4
  237. package/dist/Toolbar/Toolbar.d.ts +3 -3
  238. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  239. package/dist/Toolbar/Toolbar.js +51 -7
  240. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  241. package/dist/Tooltip/useTooltip.js +56 -9
  242. package/dist/TopNav/TopNavHeading.d.ts +7 -1
  243. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  244. package/dist/TopNav/TopNavHeading.js +8 -0
  245. package/dist/TreeList/TreeList.d.ts +1 -1
  246. package/dist/TreeList/TreeList.d.ts.map +1 -1
  247. package/dist/TreeList/TreeList.js +72 -2
  248. package/dist/TreeList/TreeListItem.d.ts +11 -1
  249. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  250. package/dist/TreeList/TreeListItem.js +51 -12
  251. package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
  252. package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
  253. package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
  254. package/dist/Typeahead/BaseTypeahead.d.ts +13 -0
  255. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  256. package/dist/Typeahead/BaseTypeahead.js +69 -6
  257. package/dist/Typeahead/Typeahead.d.ts +26 -3
  258. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  259. package/dist/Typeahead/Typeahead.js +65 -29
  260. package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
  261. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
  262. package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
  263. package/dist/VisuallyHidden/index.d.ts +11 -0
  264. package/dist/VisuallyHidden/index.d.ts.map +1 -0
  265. package/dist/VisuallyHidden/index.js +13 -0
  266. package/dist/astryx.css +18 -0
  267. package/dist/astryx.umd.js +55 -55
  268. package/dist/astryx.umd.js.map +4 -4
  269. package/dist/hooks/focusableSelector.d.ts +22 -0
  270. package/dist/hooks/focusableSelector.d.ts.map +1 -0
  271. package/dist/hooks/focusableSelector.js +24 -0
  272. package/dist/hooks/index.d.ts +12 -2
  273. package/dist/hooks/index.d.ts.map +1 -1
  274. package/dist/hooks/index.js +7 -2
  275. package/dist/hooks/useAnnounce.d.ts +40 -0
  276. package/dist/hooks/useAnnounce.d.ts.map +1 -0
  277. package/dist/hooks/useAnnounce.js +142 -0
  278. package/dist/hooks/useClickableContainer.d.ts +16 -1
  279. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  280. package/dist/hooks/useClickableContainer.js +16 -4
  281. package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
  282. package/dist/hooks/useEntryAnimation.js +4 -4
  283. package/dist/hooks/useFocusTrap.d.ts +18 -0
  284. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  285. package/dist/hooks/useFocusTrap.js +87 -3
  286. package/dist/hooks/useGridFocus.d.ts +88 -1
  287. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  288. package/dist/hooks/useGridFocus.js +261 -62
  289. package/dist/hooks/useKeyboardHint.d.ts +82 -0
  290. package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
  291. package/dist/hooks/useKeyboardHint.js +220 -0
  292. package/dist/hooks/useListFocus.d.ts +78 -7
  293. package/dist/hooks/useListFocus.d.ts.map +1 -1
  294. package/dist/hooks/useListFocus.js +305 -52
  295. package/dist/hooks/useLongPress.d.ts +21 -0
  296. package/dist/hooks/useLongPress.d.ts.map +1 -0
  297. package/dist/hooks/useLongPress.js +89 -0
  298. package/dist/hooks/useTreeFocus.d.ts +157 -0
  299. package/dist/hooks/useTreeFocus.d.ts.map +1 -0
  300. package/dist/hooks/useTreeFocus.js +337 -0
  301. package/dist/hooks/useTypeahead.d.ts +63 -0
  302. package/dist/hooks/useTypeahead.d.ts.map +1 -0
  303. package/dist/hooks/useTypeahead.js +117 -0
  304. package/dist/index.d.ts +1 -0
  305. package/dist/index.d.ts.map +1 -1
  306. package/dist/index.js +1 -0
  307. package/dist/utils/dateTypes.d.ts +12 -0
  308. package/dist/utils/dateTypes.d.ts.map +1 -1
  309. package/dist/utils/dateTypes.js +41 -1
  310. package/dist/utils/index.d.ts +4 -0
  311. package/dist/utils/index.d.ts.map +1 -1
  312. package/dist/utils/index.js +3 -1
  313. package/dist/utils/inputAria.d.ts +29 -0
  314. package/dist/utils/inputAria.d.ts.map +1 -0
  315. package/dist/utils/inputAria.js +30 -0
  316. package/dist/utils/timeParser.d.ts.map +1 -1
  317. package/dist/utils/timeParser.js +5 -2
  318. package/docs.mjs +2 -2
  319. package/package.json +12 -8
  320. package/src/Avatar/Avatar.test.tsx +37 -0
  321. package/src/Avatar/Avatar.tsx +10 -5
  322. package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
  323. package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
  324. package/src/Button/Button.tsx +3 -16
  325. package/src/ButtonGroup/ButtonGroup.test.tsx +9 -9
  326. package/src/ButtonGroup/ButtonGroup.tsx +0 -1
  327. package/src/Calendar/Calendar.doc.mjs +4 -4
  328. package/src/Calendar/Calendar.test.tsx +168 -30
  329. package/src/Calendar/Calendar.tsx +121 -66
  330. package/src/Calendar/hooks/index.ts +0 -6
  331. package/src/Calendar/index.ts +1 -3
  332. package/src/Calendar/styles.ts +4 -9
  333. package/src/Carousel/Carousel.doc.mjs +7 -1
  334. package/src/Carousel/Carousel.test.tsx +20 -0
  335. package/src/Carousel/Carousel.tsx +16 -1
  336. package/src/Center/Center.doc.mjs +12 -2
  337. package/src/Center/Center.tsx +28 -3
  338. package/src/Chat/ChatComposerInput.test.tsx +26 -7
  339. package/src/Chat/ChatComposerInput.tsx +0 -1
  340. package/src/Chat/ChatDictationButton.doc.mjs +1 -1
  341. package/src/Chat/ChatMessageList.doc.mjs +8 -0
  342. package/src/Chat/ChatMessageList.test.tsx +18 -0
  343. package/src/Chat/ChatMessageList.tsx +16 -0
  344. package/src/Chat/useTriggerMenu.tsx +22 -4
  345. package/src/CheckboxInput/CheckboxInput.doc.mjs +10 -0
  346. package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
  347. package/src/CheckboxInput/CheckboxInput.tsx +78 -6
  348. package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
  349. package/src/CheckboxList/CheckboxList.test.tsx +192 -26
  350. package/src/CheckboxList/CheckboxList.tsx +56 -3
  351. package/src/CheckboxList/CheckboxListContext.tsx +7 -0
  352. package/src/CheckboxList/CheckboxListItem.tsx +0 -3
  353. package/src/Citation/Citation.doc.mjs +10 -0
  354. package/src/Citation/Citation.test.tsx +121 -0
  355. package/src/Citation/Citation.tsx +15 -3
  356. package/src/CodeBlock/CodeBlock.test.tsx +115 -0
  357. package/src/CodeBlock/CodeBlock.tsx +63 -33
  358. package/src/CommandPalette/CommandPalette.test.tsx +47 -1
  359. package/src/CommandPalette/CommandPalette.tsx +9 -21
  360. package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
  361. package/src/ContextMenu/ContextMenu.test.tsx +155 -1
  362. package/src/ContextMenu/ContextMenu.tsx +113 -16
  363. package/src/DateInput/DateInput.doc.mjs +286 -56
  364. package/src/DateInput/DateInput.test.tsx +248 -2
  365. package/src/DateInput/DateInput.tsx +196 -100
  366. package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
  367. package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
  368. package/src/DateRangeInput/DateRangeInput.tsx +63 -5
  369. package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
  370. package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
  371. package/src/DateTimeInput/DateTimeInput.tsx +125 -17
  372. package/src/Dialog/Dialog.doc.mjs +2 -2
  373. package/src/Dialog/Dialog.tsx +12 -0
  374. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
  375. package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
  376. package/src/DropdownMenu/DropdownMenu.tsx +52 -18
  377. package/src/Field/Field.doc.mjs +59 -18
  378. package/src/Field/Field.test.tsx +32 -0
  379. package/src/Field/Field.tsx +23 -5
  380. package/src/Field/FieldLabel.tsx +55 -17
  381. package/src/FileInput/FileInput.doc.mjs +17 -0
  382. package/src/FileInput/FileInput.test.tsx +283 -49
  383. package/src/FileInput/FileInput.tsx +76 -4
  384. package/src/Grid/Grid.doc.mjs +17 -4
  385. package/src/Grid/Grid.test.tsx +43 -30
  386. package/src/Grid/Grid.tsx +38 -3
  387. package/src/Icon/Icon.doc.mjs +3 -3
  388. package/src/InputGroup/InputGroup.doc.mjs +111 -23
  389. package/src/InputGroup/InputGroup.test.tsx +257 -60
  390. package/src/InputGroup/InputGroup.tsx +23 -5
  391. package/src/InputGroup/InputGroupContext.ts +9 -4
  392. package/src/InputGroup/groupStyles.ts +7 -1
  393. package/src/InputGroup/index.ts +1 -0
  394. package/src/Kbd/Kbd.test.tsx +22 -4
  395. package/src/Kbd/Kbd.tsx +35 -3
  396. package/src/Layer/layerAnimations.stylex.ts +20 -4
  397. package/src/Layer/useLayer.doc.mjs +5 -0
  398. package/src/Layer/useLayer.test.tsx +111 -0
  399. package/src/Layer/useLayer.tsx +90 -9
  400. package/src/Layout/Layout.tsx +8 -16
  401. package/src/Layout/LayoutFooter.doc.mjs +4 -4
  402. package/src/Layout/LayoutFooter.tsx +3 -3
  403. package/src/Layout/LayoutHeader.doc.mjs +4 -4
  404. package/src/Layout/LayoutHeader.tsx +3 -3
  405. package/src/Layout/LayoutPanel.tsx +3 -3
  406. package/src/Layout/padding.stylex.ts +52 -0
  407. package/src/Lightbox/Lightbox.doc.mjs +9 -0
  408. package/src/Lightbox/Lightbox.test.tsx +53 -5
  409. package/src/Lightbox/Lightbox.tsx +9 -4
  410. package/src/Link/Link.doc.mjs +14 -0
  411. package/src/Link/Link.test.tsx +50 -0
  412. package/src/Link/Link.tsx +39 -4
  413. package/src/Markdown/Markdown.test.tsx +11 -0
  414. package/src/Markdown/Markdown.tsx +7 -0
  415. package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
  416. package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
  417. package/src/MoreMenu/MoreMenu.tsx +0 -9
  418. package/src/MultiSelector/MultiSelector.doc.mjs +30 -0
  419. package/src/MultiSelector/MultiSelector.test.tsx +375 -8
  420. package/src/MultiSelector/MultiSelector.tsx +194 -48
  421. package/src/MultiSelector/hooks.ts +27 -0
  422. package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
  423. package/src/NavMenu/NavHeadingMenu.tsx +50 -3
  424. package/src/NumberInput/NumberInput.doc.mjs +17 -0
  425. package/src/NumberInput/NumberInput.test.tsx +242 -40
  426. package/src/NumberInput/NumberInput.tsx +89 -11
  427. package/src/Pagination/Pagination.doc.mjs +3 -3
  428. package/src/Pagination/Pagination.test.tsx +117 -5
  429. package/src/Pagination/Pagination.tsx +21 -1
  430. package/src/Popover/Popover.doc.mjs +26 -0
  431. package/src/Popover/Popover.test.tsx +121 -0
  432. package/src/Popover/Popover.tsx +23 -2
  433. package/src/Popover/usePopover.doc.mjs +9 -3
  434. package/src/Popover/usePopover.tsx +70 -12
  435. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  436. package/src/PowerSearch/PowerSearch.test.tsx +97 -1
  437. package/src/PowerSearch/PowerSearch.tsx +16 -3
  438. package/src/ProgressBar/ProgressBar.test.tsx +34 -26
  439. package/src/ProgressBar/ProgressBar.tsx +3 -4
  440. package/src/RadioList/RadioList.doc.mjs +9 -0
  441. package/src/RadioList/RadioList.test.tsx +252 -16
  442. package/src/RadioList/RadioList.tsx +166 -10
  443. package/src/RadioList/RadioListItem.tsx +14 -2
  444. package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
  445. package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
  446. package/src/SegmentedControl/SegmentedControl.tsx +102 -54
  447. package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
  448. package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
  449. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  450. package/src/Selector/Selector.doc.mjs +26 -0
  451. package/src/Selector/Selector.test.tsx +387 -15
  452. package/src/Selector/Selector.tsx +175 -67
  453. package/src/Selector/hooks.ts +23 -0
  454. package/src/SideNav/SideNav.test.tsx +48 -0
  455. package/src/SideNav/SideNavHeading.tsx +8 -2
  456. package/src/SideNav/SideNavItem.tsx +2 -4
  457. package/src/Skeleton/Skeleton.test.tsx +25 -0
  458. package/src/Skeleton/Skeleton.tsx +11 -1
  459. package/src/Slider/Slider.doc.mjs +15 -0
  460. package/src/Slider/Slider.test.tsx +155 -2
  461. package/src/Slider/Slider.tsx +53 -5
  462. package/src/Spinner/Spinner.tsx +7 -1
  463. package/src/Stack/Stack.doc.mjs +77 -0
  464. package/src/Stack/Stack.test.tsx +55 -5
  465. package/src/Stack/Stack.tsx +73 -24
  466. package/src/Stack/StackItem.test.tsx +23 -0
  467. package/src/Stack/StackItem.tsx +20 -23
  468. package/src/Switch/Switch.doc.mjs +15 -0
  469. package/src/Switch/Switch.test.tsx +162 -27
  470. package/src/Switch/Switch.tsx +61 -21
  471. package/src/TabList/Tab.tsx +6 -0
  472. package/src/TabList/TabList.doc.mjs +6 -0
  473. package/src/TabList/TabList.test.tsx +251 -0
  474. package/src/TabList/TabList.tsx +103 -12
  475. package/src/TabList/TabListContext.ts +7 -3
  476. package/src/TabList/TabMenu.tsx +6 -3
  477. package/src/Table/BaseTable.tsx +21 -17
  478. package/src/Table/Table.doc.mjs +2 -0
  479. package/src/Table/Table.test.tsx +10 -0
  480. package/src/Table/Table.tsx +8 -0
  481. package/src/Table/TableCell.tsx +25 -23
  482. package/src/Table/TableHeaderCell.tsx +28 -29
  483. package/src/Table/index.ts +3 -2
  484. package/src/Table/plugins/pagination/paginateData.ts +10 -3
  485. package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
  486. package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
  487. package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
  488. package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
  489. package/src/Table/tableContextMenu.test.tsx +157 -0
  490. package/src/Table/tableContextMenu.tsx +142 -0
  491. package/src/Table/types.ts +74 -0
  492. package/src/Table/useTableColumnResize.doc.mjs +3 -3
  493. package/src/Table/useTableStickyColumns.doc.mjs +2 -2
  494. package/src/Text/Text.doc.mjs +18 -18
  495. package/src/TextArea/TextArea.doc.mjs +17 -0
  496. package/src/TextArea/TextArea.test.tsx +167 -35
  497. package/src/TextArea/TextArea.tsx +62 -15
  498. package/src/TextInput/TextInput.doc.mjs +17 -0
  499. package/src/TextInput/TextInput.test.tsx +168 -34
  500. package/src/TextInput/TextInput.tsx +77 -9
  501. package/src/Thumbnail/Thumbnail.doc.mjs +4 -4
  502. package/src/TimeInput/TimeInput.doc.mjs +340 -60
  503. package/src/TimeInput/TimeInput.test.tsx +255 -7
  504. package/src/TimeInput/TimeInput.tsx +176 -70
  505. package/src/Timestamp/Timestamp.doc.mjs +19 -19
  506. package/src/Toast/Toast.tsx +14 -0
  507. package/src/Toast/ToastViewport.test.tsx +214 -0
  508. package/src/Toast/ToastViewport.tsx +167 -21
  509. package/src/Tokenizer/Tokenizer.doc.mjs +29 -14
  510. package/src/Tokenizer/Tokenizer.test.tsx +105 -1
  511. package/src/Tokenizer/Tokenizer.tsx +37 -1
  512. package/src/Toolbar/Toolbar.test.tsx +109 -6
  513. package/src/Toolbar/Toolbar.tsx +59 -5
  514. package/src/Tooltip/Tooltip.test.tsx +68 -0
  515. package/src/Tooltip/useTooltip.tsx +55 -8
  516. package/src/TopNav/TopNav.test.tsx +50 -0
  517. package/src/TopNav/TopNavHeading.tsx +17 -1
  518. package/src/TreeList/TreeList.test.tsx +295 -6
  519. package/src/TreeList/TreeList.tsx +73 -1
  520. package/src/TreeList/TreeListItem.tsx +51 -5
  521. package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
  522. package/src/Typeahead/BaseTypeahead.tsx +93 -9
  523. package/src/Typeahead/Typeahead.doc.mjs +141 -30
  524. package/src/Typeahead/Typeahead.test.tsx +331 -1
  525. package/src/Typeahead/Typeahead.tsx +105 -33
  526. package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
  527. package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
  528. package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
  529. package/src/VisuallyHidden/index.ts +15 -0
  530. package/src/docs-script.test.mjs +50 -0
  531. package/src/hooks/focusableSelector.ts +25 -0
  532. package/src/hooks/index.ts +28 -2
  533. package/src/hooks/useAnnounce.test.tsx +101 -0
  534. package/src/hooks/useAnnounce.ts +168 -0
  535. package/src/hooks/useClickableContainer.ts +16 -4
  536. package/src/hooks/useEntryAnimation.ts +16 -4
  537. package/src/hooks/useFocusTrap.test.tsx +132 -0
  538. package/src/hooks/useFocusTrap.ts +98 -4
  539. package/src/hooks/useGridFocus.doc.mjs +40 -2
  540. package/src/hooks/useGridFocus.test.tsx +132 -0
  541. package/src/hooks/useGridFocus.ts +343 -67
  542. package/src/hooks/useKeyboardHint.doc.mjs +101 -0
  543. package/src/hooks/useKeyboardHint.test.tsx +70 -0
  544. package/src/hooks/useKeyboardHint.tsx +332 -0
  545. package/src/hooks/useListFocus.doc.mjs +50 -10
  546. package/src/hooks/useListFocus.test.tsx +375 -0
  547. package/src/hooks/useListFocus.ts +395 -57
  548. package/src/hooks/useLongPress.test.tsx +134 -0
  549. package/src/hooks/useLongPress.ts +119 -0
  550. package/src/hooks/useTreeFocus.doc.mjs +140 -0
  551. package/src/hooks/useTreeFocus.test.tsx +214 -0
  552. package/src/hooks/useTreeFocus.ts +559 -0
  553. package/src/hooks/useTypeahead.test.tsx +109 -0
  554. package/src/hooks/useTypeahead.ts +183 -0
  555. package/src/index.ts +1 -0
  556. package/src/theme/derivedVarRegistry.test.ts +10 -5
  557. package/src/utils/dateTypes.test.ts +40 -0
  558. package/src/utils/dateTypes.ts +40 -0
  559. package/src/utils/index.ts +9 -0
  560. package/src/utils/inputAria.test.ts +39 -0
  561. package/src/utils/inputAria.ts +58 -0
  562. package/src/utils/timeParser.test.ts +10 -0
  563. package/src/utils/timeParser.ts +5 -2
  564. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
  565. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
  566. package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
  567. package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
@@ -0,0 +1,183 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file useTypeahead.ts
7
+ * @input Uses React useCallback/useRef
8
+ * @output Exports useTypeahead hook for first-character (type-to-focus) search
9
+ * @position Core hook; adds APG typeahead to menus, listboxes, and other
10
+ * collections. Composes with useListFocus/useGridFocus (or any collection)
11
+ * via a caller-supplied getItemLabels + onMatch.
12
+ *
13
+ * SYNC: When modified, update:
14
+ * - /packages/core/src/hooks/index.ts
15
+ */
16
+
17
+ import {useCallback, useRef} from 'react';
18
+
19
+ export interface UseTypeaheadOptions {
20
+ /**
21
+ * Returns the current, in-DOM-order list of item labels to match against.
22
+ * An entry may be `null`/empty to mark a non-matchable slot (its index is
23
+ * preserved so it maps 1:1 to the caller's items).
24
+ */
25
+ getItemLabels: () => ReadonlyArray<string | null | undefined>;
26
+
27
+ /**
28
+ * Called with the index of the matched item so the caller can focus/select
29
+ * it (e.g. `useListFocus`'s `focusItem`).
30
+ */
31
+ onMatch: (index: number) => void;
32
+
33
+ /**
34
+ * The index to start searching from — typically the currently focused item,
35
+ * so repeated presses of the same letter cycle through matches. Defaults to
36
+ * -1 (search from the top).
37
+ */
38
+ getCurrentIndex?: () => number;
39
+
40
+ /**
41
+ * Milliseconds of inactivity after which the typed buffer resets.
42
+ * @default 750
43
+ */
44
+ resetMs?: number;
45
+
46
+ /**
47
+ * Whether an index should be skipped (e.g. disabled items).
48
+ */
49
+ isDisabled?: (index: number) => boolean;
50
+ }
51
+
52
+ export interface UseTypeaheadReturn {
53
+ /**
54
+ * Keydown handler. Call it (or let it fall through) from the collection's
55
+ * own key handler. Returns `true` when it handled a printable character (so
56
+ * the caller can `preventDefault`/stop further handling), `false` otherwise.
57
+ */
58
+ onKeyDown: (e: React.KeyboardEvent | KeyboardEvent) => boolean;
59
+ /** Clear the pending buffer (e.g. on close). */
60
+ reset: () => void;
61
+ }
62
+
63
+ /**
64
+ * Whether a key event represents a single printable character (a type-to-focus
65
+ * candidate) rather than a control/navigation key or a shortcut chord.
66
+ */
67
+ function isPrintableCharacter(e: React.KeyboardEvent | KeyboardEvent): boolean {
68
+ return (
69
+ e.key.length === 1 &&
70
+ !e.ctrlKey &&
71
+ !e.metaKey &&
72
+ !e.altKey &&
73
+ // A lone space is used for activation in menus, not typeahead-from-empty.
74
+ e.key !== ' '
75
+ );
76
+ }
77
+
78
+ /**
79
+ * First-character ("type-ahead") search for a collection.
80
+ *
81
+ * Buffers printable keystrokes (resetting after `resetMs` of inactivity),
82
+ * matches items whose label starts with the buffer, and cycles from the
83
+ * current index — so pressing "s" repeatedly walks through the "s" items
84
+ * instead of sticking on the first. Space is reserved for activation and is
85
+ * only treated as typeahead while a buffer is already active.
86
+ *
87
+ * Additive and collection-agnostic: it does not move focus itself; the caller
88
+ * wires `onMatch` to its own focus/selection (e.g. `useListFocus.focusItem`).
89
+ *
90
+ * @example
91
+ * ```
92
+ * const {listRef, handleKeyDown, focusItem, getItems} = useListFocus(...);
93
+ * const typeahead = useTypeahead({
94
+ * getItemLabels: () => getItems().map(el => el.textContent),
95
+ * onMatch: focusItem,
96
+ * getCurrentIndex: () => getItems().findIndex(el => el === document.activeElement),
97
+ * });
98
+ * const onKeyDown = (e) => { if (!typeahead.onKeyDown(e)) handleKeyDown(e); };
99
+ * ```
100
+ */
101
+ export function useTypeahead(options: UseTypeaheadOptions): UseTypeaheadReturn {
102
+ const {
103
+ getItemLabels,
104
+ onMatch,
105
+ getCurrentIndex,
106
+ resetMs = 750,
107
+ isDisabled,
108
+ } = options;
109
+
110
+ const bufferRef = useRef('');
111
+ const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(
112
+ undefined,
113
+ );
114
+
115
+ const reset = useCallback(() => {
116
+ bufferRef.current = '';
117
+ if (timeoutRef.current) {
118
+ clearTimeout(timeoutRef.current);
119
+ timeoutRef.current = undefined;
120
+ }
121
+ }, []);
122
+
123
+ const scheduleReset = useCallback(() => {
124
+ if (timeoutRef.current) {
125
+ clearTimeout(timeoutRef.current);
126
+ }
127
+ timeoutRef.current = setTimeout(() => {
128
+ bufferRef.current = '';
129
+ timeoutRef.current = undefined;
130
+ }, resetMs);
131
+ }, [resetMs]);
132
+
133
+ const onKeyDown = useCallback(
134
+ (e: React.KeyboardEvent | KeyboardEvent): boolean => {
135
+ // A bare Space with no active buffer is not typeahead (menus activate on
136
+ // Space); once the user is mid-typing, Space extends the query.
137
+ const isSpaceMidType = e.key === ' ' && bufferRef.current.length > 0;
138
+ if (!isPrintableCharacter(e) && !isSpaceMidType) {
139
+ return false;
140
+ }
141
+
142
+ const labels = getItemLabels();
143
+ if (labels.length === 0) {
144
+ return false;
145
+ }
146
+
147
+ // Pressing the SAME single character repeatedly cycles to the next match
148
+ // rather than filtering deeper (APG behavior).
149
+ const char = e.key.toLowerCase();
150
+ const isRepeatSameChar =
151
+ bufferRef.current.length > 0 &&
152
+ bufferRef.current.split('').every(c => c === char);
153
+ const nextBuffer = isRepeatSameChar ? char : bufferRef.current + char;
154
+ bufferRef.current = nextBuffer;
155
+ scheduleReset();
156
+
157
+ const start = getCurrentIndex?.() ?? -1;
158
+ const count = labels.length;
159
+ // When repeating a single char, start the search AFTER the current item
160
+ // so we advance; otherwise include the current item.
161
+ const offset = isRepeatSameChar ? 1 : 0;
162
+
163
+ for (let i = 0; i < count; i++) {
164
+ const index = (start + offset + i + count) % count;
165
+ if (isDisabled?.(index)) {
166
+ continue;
167
+ }
168
+ const label = labels[index];
169
+ if (
170
+ label != null &&
171
+ label.trim().toLowerCase().startsWith(nextBuffer)
172
+ ) {
173
+ onMatch(index);
174
+ return true;
175
+ }
176
+ }
177
+ return true;
178
+ },
179
+ [getItemLabels, onMatch, getCurrentIndex, scheduleReset, isDisabled],
180
+ );
181
+
182
+ return {onKeyDown, reset};
183
+ }
package/src/index.ts CHANGED
@@ -42,6 +42,7 @@ export * from './Collapsible';
42
42
  export * from './RadioList';
43
43
  export * from './Resizable';
44
44
  export * from './Divider';
45
+ export * from './VisuallyHidden';
45
46
  export * from './EmptyState';
46
47
  export * from './Lightbox';
47
48
  export * from './Link';
@@ -14,7 +14,7 @@
14
14
 
15
15
  import {describe, it, expect} from 'vitest';
16
16
  import {derivedVarRegistry, getDerivedVars} from './derivedVarRegistry';
17
- import {readdirSync, readFileSync, existsSync} from 'fs';
17
+ import {readdirSync, readFileSync} from 'fs';
18
18
  import {join} from 'path';
19
19
 
20
20
  const SRC_DIR = join(__dirname, '..');
@@ -129,8 +129,9 @@ function discoverComponents(): ComponentInfo[] {
129
129
 
130
130
  for (const dir of dirs) {
131
131
  const dirPath = join(SRC_DIR, dir);
132
+ const dirEntries = readdirSync(dirPath);
132
133
  // Find source files with component vars (.tsx and .ts, excluding tests/docs)
133
- const sourceFiles = readdirSync(dirPath)
134
+ const sourceFiles = dirEntries
134
135
  .filter(
135
136
  f =>
136
137
  (f.endsWith('.tsx') || f.endsWith('.ts')) &&
@@ -150,11 +151,15 @@ function discoverComponents(): ComponentInfo[] {
150
151
  continue;
151
152
  }
152
153
 
153
- // Only check component directories (those with a doc file)
154
- const docPath = join(dirPath, `${dir}.doc.mjs`);
155
- if (!existsSync(docPath)) {
154
+ // Only check component directories (those with a doc file named after the
155
+ // directory). Match against the on-disk listing rather than existsSync so
156
+ // the comparison is case-exact everywhere — on case-insensitive
157
+ // filesystems (macOS, Windows) existsSync('theme/theme.doc.mjs') matches
158
+ // theme/Theme.doc.mjs and pulls in a directory that CI never checks.
159
+ if (!dirEntries.includes(`${dir}.doc.mjs`)) {
156
160
  continue;
157
161
  }
162
+ const docPath = join(dirPath, `${dir}.doc.mjs`);
158
163
 
159
164
  let docVars: string[] = [];
160
165
  let docDerived: DerivedDocEntry[] = [];
@@ -0,0 +1,40 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file dateTypes.test.ts
5
+ * @input Uses vitest
6
+ * @output Test suite for date type helpers
7
+ * @position Tests for dateTypes.ts (normalizeDayOfWeek)
8
+ *
9
+ * SYNC: When dateTypes.ts changes, update tests accordingly
10
+ */
11
+
12
+ import {describe, it, expect} from 'vitest';
13
+ import {normalizeDayOfWeek} from './dateTypes';
14
+
15
+ describe('normalizeDayOfWeek', () => {
16
+ it('passes numeric days through unchanged', () => {
17
+ expect(normalizeDayOfWeek(0)).toBe(0);
18
+ expect(normalizeDayOfWeek(1)).toBe(1);
19
+ expect(normalizeDayOfWeek(6)).toBe(6);
20
+ });
21
+
22
+ it('maps three-letter day names to their index', () => {
23
+ expect(normalizeDayOfWeek('sun')).toBe(0);
24
+ expect(normalizeDayOfWeek('mon')).toBe(1);
25
+ expect(normalizeDayOfWeek('tue')).toBe(2);
26
+ expect(normalizeDayOfWeek('wed')).toBe(3);
27
+ expect(normalizeDayOfWeek('thu')).toBe(4);
28
+ expect(normalizeDayOfWeek('fri')).toBe(5);
29
+ expect(normalizeDayOfWeek('sat')).toBe(6);
30
+ });
31
+
32
+ it('is case-insensitive for day names', () => {
33
+ expect(normalizeDayOfWeek('MON' as 'mon')).toBe(1);
34
+ expect(normalizeDayOfWeek('Sat' as 'sat')).toBe(6);
35
+ });
36
+
37
+ it('falls back to 0 (Sunday) for an unrecognized name', () => {
38
+ expect(normalizeDayOfWeek('xyz' as 'mon')).toBe(0);
39
+ });
40
+ });
@@ -17,6 +17,46 @@ export type ISODateString =
17
17
  /** Day of week: 0 = Sunday through 6 = Saturday */
18
18
  export type DayOfWeek = 0 | 1 | 2 | 3 | 4 | 5 | 6;
19
19
 
20
+ /**
21
+ * Three-letter lowercase weekday name, 'sun' through 'sat'.
22
+ * A more self-documenting alternative to the numeric {@link DayOfWeek}.
23
+ */
24
+ export type DayOfWeekName =
25
+ | 'sun'
26
+ | 'mon'
27
+ | 'tue'
28
+ | 'wed'
29
+ | 'thu'
30
+ | 'fri'
31
+ | 'sat';
32
+
33
+ /** Weekday names indexed by {@link DayOfWeek} (0 = Sunday). */
34
+ const WEEKDAY_NAMES: ReadonlyArray<DayOfWeekName> = [
35
+ 'sun',
36
+ 'mon',
37
+ 'tue',
38
+ 'wed',
39
+ 'thu',
40
+ 'fri',
41
+ 'sat',
42
+ ];
43
+
44
+ /**
45
+ * Normalize a weekday to its numeric {@link DayOfWeek}. Accepts either a
46
+ * number (0–6) or a three-letter day name ('sun'–'sat', case-insensitive),
47
+ * so APIs like `weekStartsOn` can take whichever is more readable at the
48
+ * call site. Unrecognized values fall back to 0 (Sunday).
49
+ */
50
+ export function normalizeDayOfWeek(
51
+ value: DayOfWeek | DayOfWeekName,
52
+ ): DayOfWeek {
53
+ if (typeof value === 'number') {
54
+ return value;
55
+ }
56
+ const index = WEEKDAY_NAMES.indexOf(value.toLowerCase() as DayOfWeekName);
57
+ return index === -1 ? 0 : (index as DayOfWeek);
58
+ }
59
+
20
60
  /** Immutable date record with 1-based month. */
21
61
  export interface PlainDate {
22
62
  readonly year: number;
@@ -68,7 +68,16 @@ export {getKey, type Key, type KeyFallback} from './getKey';
68
68
 
69
69
  export {mergeProps} from './mergeProps';
70
70
  export {mergeRefs} from './mergeRefs';
71
+ export {themeProps, themeDataAttributes} from './themeProps';
72
+ export type {
73
+ ClassValue,
74
+ ClassProps,
75
+ ThemeDataAttributes,
76
+ ThemeProps,
77
+ } from './themeProps';
71
78
  export {groupItems, getItemGroup} from './groupItems';
72
79
  export type {ItemGroup} from './groupItems';
73
80
  export {observeResize, unobserveResize} from './sharedResizeObserver';
74
81
  export {isRenderable} from './isRenderable';
82
+ export {getInputARIA} from './inputAria';
83
+ export type {InputARIA, InputARIAInputGroup} from './inputAria';
@@ -0,0 +1,39 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import {describe, expect, it} from 'vitest';
4
+ import {getInputARIA} from './inputAria';
5
+
6
+ describe('getInputARIA', () => {
7
+ it('keeps standalone input labeling native while composing descriptions', () => {
8
+ expect(
9
+ getInputARIA('input-label', ['input-help', undefined, 'input-error']),
10
+ ).toEqual({
11
+ ariaLabelledBy: undefined,
12
+ ariaDescribedBy: 'input-help input-error',
13
+ });
14
+ });
15
+
16
+ it('composes InputGroup context before input labels and descriptions', () => {
17
+ expect(
18
+ getInputARIA('input-label', ['input-help'], {
19
+ labelID: 'group-label',
20
+ describedByIDs: 'group-help group-error',
21
+ }),
22
+ ).toEqual({
23
+ ariaLabelledBy: 'group-label input-label',
24
+ ariaDescribedBy: 'group-help group-error input-help',
25
+ });
26
+ });
27
+
28
+ it('deduplicates repeated IDs', () => {
29
+ expect(
30
+ getInputARIA('group-label', ['shared', 'input-help'], {
31
+ labelID: 'group-label',
32
+ describedByIDs: 'shared group-error',
33
+ }),
34
+ ).toEqual({
35
+ ariaLabelledBy: 'group-label',
36
+ ariaDescribedBy: 'shared group-error input-help',
37
+ });
38
+ });
39
+ });
@@ -0,0 +1,58 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file inputAria.ts
5
+ * @input Receives input label/description IDs and optional InputGroup context
6
+ * @output Exports helpers for consistent input ARIA composition
7
+ * @position Internal utility; used by inputs that compose labels/descriptions
8
+ */
9
+
10
+ export interface InputARIAInputGroup {
11
+ /** ID of the visible InputGroup label. */
12
+ labelID: string;
13
+ /** Space-separated IDs for InputGroup description/status text. */
14
+ describedByIDs?: string;
15
+ }
16
+
17
+ export interface InputARIA {
18
+ /** Value for aria-labelledby on the input. */
19
+ ariaLabelledBy?: string;
20
+ /** Value for aria-describedby on the input. */
21
+ ariaDescribedBy?: string;
22
+ }
23
+
24
+ type AriaID = string | null | undefined | false;
25
+
26
+ function joinAriaIDs(...values: AriaID[]): string | undefined {
27
+ const ids = values
28
+ .flatMap(value =>
29
+ typeof value === 'string' ? value.trim().split(/\s+/) : [],
30
+ )
31
+ .filter(Boolean);
32
+
33
+ if (ids.length === 0) {
34
+ return undefined;
35
+ }
36
+
37
+ return Array.from(new Set(ids)).join(' ');
38
+ }
39
+
40
+ /**
41
+ * Builds ARIA label/description wiring for an input.
42
+ *
43
+ * Standalone inputs keep their normal native label association. Grouped inputs
44
+ * are named by the visible InputGroup label plus their own input label, and
45
+ * inherit group description/status text in addition to input-local text.
46
+ */
47
+ export function getInputARIA(
48
+ labelID: string,
49
+ describedByIDs: AriaID[] = [],
50
+ inputGroup?: InputARIAInputGroup | null,
51
+ ): InputARIA {
52
+ return {
53
+ ariaLabelledBy: inputGroup
54
+ ? joinAriaIDs(inputGroup.labelID, labelID)
55
+ : undefined,
56
+ ariaDescribedBy: joinAriaIDs(inputGroup?.describedByIDs, ...describedByIDs),
57
+ };
58
+ }
@@ -144,11 +144,21 @@ describe('parseTimeInput', () => {
144
144
  expect(parseTimeInput('12pm')).toBe('12:00');
145
145
  });
146
146
 
147
+ it('parses dotted meridiems (a.m./p.m.)', () => {
148
+ expect(parseTimeInput('2:30 p.m.')).toBe('14:30');
149
+ expect(parseTimeInput('2:30 P.M.')).toBe('14:30');
150
+ expect(parseTimeInput('2:30 p.m')).toBe('14:30');
151
+ expect(parseTimeInput('12 a.m.')).toBe('00:00');
152
+ expect(parseTimeInput('12 p.m.')).toBe('12:00');
153
+ expect(parseTimeInput('2 p.m.')).toBe('14:00');
154
+ });
155
+
147
156
  it('returns null for invalid input', () => {
148
157
  expect(parseTimeInput('')).toBeNull();
149
158
  expect(parseTimeInput('abc')).toBeNull();
150
159
  expect(parseTimeInput('25:00')).toBeNull();
151
160
  expect(parseTimeInput('13:00 PM')).toBeNull(); // 13 is invalid in 12h format
161
+ expect(parseTimeInput('13:00 p.m.')).toBeNull(); // dotted variant rejected too
152
162
  });
153
163
  });
154
164
 
@@ -164,10 +164,13 @@ export function parseTimeInput(
164
164
 
165
165
  const trimmed = input.trim().toLowerCase();
166
166
 
167
- // Check for AM/PM
168
- const hasMeridiem = /[ap]m?\s*$/i.test(trimmed);
167
+ // Check for AM/PM. hasMeridiem is derived from isPM/isAM so the detection
168
+ // can never drift from them: it previously used its own regex without the
169
+ // optional dots, so dotted meridiems ("2:30 p.m.") skipped the 12h -> 24h
170
+ // conversion and parsed 12 hours off.
169
171
  const isPM = /p\.?m?\.?\s*$/i.test(trimmed);
170
172
  const isAM = /a\.?m?\.?\s*$/i.test(trimmed);
173
+ const hasMeridiem = isPM || isAM;
171
174
 
172
175
  // Remove AM/PM suffix
173
176
  const timeStr = trimmed.replace(/\s*[ap]\.?m?\.?\s*$/i, '').trim();
@@ -1,57 +0,0 @@
1
- import type { ISODateString } from '../../utils/dateTypes';
2
- import { type PlainDate } from '../../utils/plainDate';
3
- import type { CalendarDay } from './useCalendarDays';
4
- /**
5
- * Configuration for calendar roving tabindex
6
- */
7
- export interface UseCalendarRovingTabindexOptions {
8
- /** All days in the grid */
9
- days: CalendarDay[];
10
- /** Today's date as a PlainDate */
11
- today: PlainDate;
12
- /** The year being displayed */
13
- year: number;
14
- /** The month being displayed (1-based: 1 = January, 12 = December) */
15
- month: number;
16
- /** Function to check if a date is disabled */
17
- isDateDisabled: (date: PlainDate) => boolean;
18
- /** Currently selected date (if any) */
19
- selectedDate?: PlainDate | null;
20
- }
21
- /**
22
- * Return type for useCalendarRovingTabindex hook
23
- */
24
- export interface UseCalendarRovingTabindexReturn {
25
- /** The ISO date string of the tabbable element, or null */
26
- tabbableDate: ISODateString | null;
27
- /** Check if a specific date is the tabbable one */
28
- isTabbable: (iso: ISODateString) => boolean;
29
- }
30
- /**
31
- * Hook for managing roving tabindex in calendar grids.
32
- *
33
- * Implements the WAI-ARIA roving tabindex pattern where only one element
34
- * in a group has tabindex="0" while others have tabindex="-1".
35
- *
36
- * Priority for tabbable element:
37
- * 1. Today if visible in the current month and enabled
38
- * 2. First enabled day in the month
39
- *
40
- * @example
41
- * ```
42
- * const {tabbableDate, isTabbable} = useCalendarRovingTabindex({
43
- * days,
44
- * today: {year: 2026, month: 1, day: 20},
45
- * year: 2026,
46
- * month: 1, // January (1-based)
47
- * isDateDisabled,
48
- * });
49
- *
50
- * // In day rendering:
51
- * <button tabIndex={isTabbable(day.iso) ? 0 : -1}>
52
- * {day.dayNumber}
53
- * </button>
54
- * ```
55
- */
56
- export declare function useCalendarRovingTabindex(options: UseCalendarRovingTabindexOptions): UseCalendarRovingTabindexReturn;
57
- //# sourceMappingURL=useCalendarRovingTabindex.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useCalendarRovingTabindex.d.ts","sourceRoot":"","sources":["../../../src/Calendar/hooks/useCalendarRovingTabindex.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAC,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,2BAA2B;IAC3B,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,kCAAkC;IAClC,KAAK,EAAE,SAAS,CAAC;IACjB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,cAAc,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IAC7C,uCAAuC;IACvC,YAAY,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C,2DAA2D;IAC3D,YAAY,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,mDAAmD;IACnD,UAAU,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,+BAA+B,CA0CjC"}
@@ -1,96 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- 'use client';
4
-
5
- /**
6
- * @file useCalendarRovingTabindex.ts
7
- * @input Uses React useMemo, PlainDate utilities
8
- * @output Exports useCalendarRovingTabindex hook for accessible grid navigation
9
- * @position Calendar-specific hook; used by Calendar
10
- *
11
- * SYNC: When modified, update:
12
- * - /packages/core/src/Calendar/hooks/index.ts
13
- */
14
- import { useMemo } from 'react';
15
- import { plainDateToISO } from "../../utils/plainDate.js";
16
-
17
- /**
18
- * Configuration for calendar roving tabindex
19
- */
20
-
21
- /**
22
- * Return type for useCalendarRovingTabindex hook
23
- */
24
-
25
- /**
26
- * Hook for managing roving tabindex in calendar grids.
27
- *
28
- * Implements the WAI-ARIA roving tabindex pattern where only one element
29
- * in a group has tabindex="0" while others have tabindex="-1".
30
- *
31
- * Priority for tabbable element:
32
- * 1. Today if visible in the current month and enabled
33
- * 2. First enabled day in the month
34
- *
35
- * @example
36
- * ```
37
- * const {tabbableDate, isTabbable} = useCalendarRovingTabindex({
38
- * days,
39
- * today: {year: 2026, month: 1, day: 20},
40
- * year: 2026,
41
- * month: 1, // January (1-based)
42
- * isDateDisabled,
43
- * });
44
- *
45
- * // In day rendering:
46
- * <button tabIndex={isTabbable(day.iso) ? 0 : -1}>
47
- * {day.dayNumber}
48
- * </button>
49
- * ```
50
- */
51
- export function useCalendarRovingTabindex(options) {
52
- const {
53
- days,
54
- today,
55
- year,
56
- month,
57
- isDateDisabled,
58
- selectedDate
59
- } = options;
60
-
61
- // Determine which day should be tabbable
62
- const tabbableDate = useMemo(() => {
63
- // Priority 1: Selected date if visible in this month and enabled
64
- if (selectedDate) {
65
- const isSelectedInMonth = selectedDate.year === year && selectedDate.month === month;
66
- if (isSelectedInMonth && !isDateDisabled(selectedDate)) {
67
- return plainDateToISO(selectedDate);
68
- }
69
- }
70
-
71
- // Priority 2: Today if visible in this month and enabled
72
- const isTodayInMonth = today.year === year && today.month === month;
73
- if (isTodayInMonth && !isDateDisabled(today)) {
74
- return plainDateToISO(today);
75
- }
76
-
77
- // Priority 3: First enabled day in this month
78
- for (const day of days) {
79
- if (!day.isOutside && !isDateDisabled(day.date)) {
80
- return day.iso;
81
- }
82
- }
83
- return null;
84
- }, [days, today, year, month, isDateDisabled, selectedDate]);
85
-
86
- // Check if a specific date is tabbable
87
- const isTabbable = useMemo(() => {
88
- return iso => {
89
- return tabbableDate !== null && iso === tabbableDate;
90
- };
91
- }, [tabbableDate]);
92
- return {
93
- tabbableDate,
94
- isTabbable
95
- };
96
- }