@astryxdesign/core 0.4.7 → 0.5.0-canary.1f8525f

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 (566) hide show
  1. package/CHANGELOG.md +161 -1
  2. package/dist/AppShell/AppShell.d.ts.map +1 -1
  3. package/dist/AppShell/AppShell.js +3 -2
  4. package/dist/AspectRatio/AspectRatio.d.ts +24 -0
  5. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  6. package/dist/AspectRatio/AspectRatio.js +23 -4
  7. package/dist/Avatar/Avatar.d.ts +25 -1
  8. package/dist/Avatar/Avatar.d.ts.map +1 -1
  9. package/dist/Avatar/Avatar.js +58 -19
  10. package/dist/Avatar/index.d.ts +2 -2
  11. package/dist/Avatar/index.d.ts.map +1 -1
  12. package/dist/Avatar/index.js +1 -1
  13. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  14. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  15. package/dist/AvatarGroup/AvatarGroup.js +8 -4
  16. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  17. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  19. package/dist/AvatarGroup/AvatarGroupOverflow.js +10 -6
  20. package/dist/Banner/Banner.d.ts +40 -15
  21. package/dist/Banner/Banner.d.ts.map +1 -1
  22. package/dist/Banner/Banner.js +51 -18
  23. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  24. package/dist/BottomSheet/BottomSheet.js +17 -4
  25. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  26. package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
  27. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  28. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
  29. package/dist/Button/Button.d.ts.map +1 -1
  30. package/dist/Button/Button.js +5 -4
  31. package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
  32. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  33. package/dist/ButtonGroup/ButtonGroup.js +26 -7
  34. package/dist/Calendar/Calendar.d.ts +3 -1
  35. package/dist/Calendar/Calendar.d.ts.map +1 -1
  36. package/dist/Calendar/Calendar.js +14 -15
  37. package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
  38. package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
  39. package/dist/Calendar/getInitialFocusDate.js +62 -0
  40. package/dist/Calendar/styles.d.ts +5 -14
  41. package/dist/Calendar/styles.d.ts.map +1 -1
  42. package/dist/Calendar/styles.js +15 -15
  43. package/dist/Carousel/Carousel.d.ts.map +1 -1
  44. package/dist/Carousel/Carousel.js +3 -3
  45. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  46. package/dist/Chat/ChatComposerInput.js +2 -3
  47. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  48. package/dist/Chat/ChatLayout.js +3 -3
  49. package/dist/Chat/ChatMessageList.d.ts +22 -3
  50. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  51. package/dist/Chat/ChatMessageList.js +6 -3
  52. package/dist/Chat/ChatTokenizedText.d.ts +2 -0
  53. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  54. package/dist/Chat/ChatTokenizedText.js +11 -6
  55. package/dist/Chat/useChatComposerTokens.js +1 -1
  56. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  57. package/dist/CheckboxInput/CheckboxInput.js +10 -3
  58. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  59. package/dist/ClickableCard/ClickableCard.js +3 -3
  60. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  61. package/dist/CodeBlock/CodeBlock.js +15 -4
  62. package/dist/CodeBlock/highlightRanges.js +1 -1
  63. package/dist/CodeBlock/highlightStyles.js +13 -13
  64. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  65. package/dist/CommandPalette/CommandPaletteInput.js +3 -2
  66. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  67. package/dist/CommandPalette/CommandPaletteItem.js +3 -2
  68. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  69. package/dist/ContextMenu/ContextMenu.js +4 -3
  70. package/dist/DateInput/DateInput.d.ts +43 -0
  71. package/dist/DateInput/DateInput.d.ts.map +1 -1
  72. package/dist/DateInput/DateInput.js +22 -2
  73. package/dist/DateInput/NativeDateField.d.ts +10 -0
  74. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  75. package/dist/DateInput/NativeDateField.js +494 -0
  76. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  77. package/dist/DateInput/TouchDateField.js +38 -4
  78. package/dist/DateInput/index.d.ts +1 -1
  79. package/dist/DateInput/index.d.ts.map +1 -1
  80. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  81. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  82. package/dist/DateInput/nativeDateSegments.js +111 -0
  83. package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
  84. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  85. package/dist/DateTimeInput/DateTimeInput.js +406 -12
  86. package/dist/DateTimeInput/index.d.ts +1 -1
  87. package/dist/DateTimeInput/index.d.ts.map +1 -1
  88. package/dist/Dialog/Dialog.d.ts +7 -1
  89. package/dist/Dialog/Dialog.d.ts.map +1 -1
  90. package/dist/Dialog/Dialog.js +89 -58
  91. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  92. package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
  93. package/dist/Field/FieldLabel.d.ts.map +1 -1
  94. package/dist/Field/FieldLabel.js +9 -1
  95. package/dist/FileInput/FileInput.d.ts.map +1 -1
  96. package/dist/FileInput/FileInput.js +3 -2
  97. package/dist/Heading/Heading.d.ts.map +1 -1
  98. package/dist/Heading/Heading.js +6 -2
  99. package/dist/HoverCard/HoverCard.d.ts +6 -0
  100. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  101. package/dist/HoverCard/HoverCard.js +52 -3
  102. package/dist/HoverCard/useHoverCard.d.ts +16 -2
  103. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  104. package/dist/HoverCard/useHoverCard.js +74 -26
  105. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  106. package/dist/Indicator/CheckboxIndicator.js +6 -2
  107. package/dist/Item/Item.d.ts.map +1 -1
  108. package/dist/Item/Item.js +4 -2
  109. package/dist/Kbd/Kbd.d.ts.map +1 -1
  110. package/dist/Kbd/Kbd.js +2 -19
  111. package/dist/Layer/LayerDepthContext.d.ts +52 -0
  112. package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
  113. package/dist/Layer/LayerDepthContext.js +66 -0
  114. package/dist/Layer/index.d.ts +3 -0
  115. package/dist/Layer/index.d.ts.map +1 -1
  116. package/dist/Layer/index.js +4 -0
  117. package/dist/Layer/layerStack.d.ts +98 -0
  118. package/dist/Layer/layerStack.d.ts.map +1 -0
  119. package/dist/Layer/layerStack.js +306 -0
  120. package/dist/Layer/useLayerDismissal.d.ts +93 -0
  121. package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
  122. package/dist/Layer/useLayerDismissal.js +91 -0
  123. package/dist/Lightbox/Lightbox.d.ts +1 -0
  124. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  125. package/dist/Lightbox/Lightbox.js +103 -81
  126. package/dist/Markdown/index.d.ts +1 -1
  127. package/dist/Markdown/index.d.ts.map +1 -1
  128. package/dist/Markdown/parser.d.ts +38 -1
  129. package/dist/Markdown/parser.d.ts.map +1 -1
  130. package/dist/Markdown/parser.js +177 -29
  131. package/dist/MobileNav/MobileNav.d.ts +6 -1
  132. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  133. package/dist/MobileNav/MobileNav.js +61 -36
  134. package/dist/MultiSelector/MultiSelector.d.ts +15 -1
  135. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  136. package/dist/MultiSelector/MultiSelector.js +17 -6
  137. package/dist/MultiSelector/index.d.ts +1 -1
  138. package/dist/MultiSelector/index.d.ts.map +1 -1
  139. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  140. package/dist/NavIcon/NavIcon.js +5 -1
  141. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  142. package/dist/NavMenu/NavHeadingMenu.js +3 -2
  143. package/dist/NumberInput/NumberInput.d.ts +1 -0
  144. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  145. package/dist/NumberInput/NumberInput.js +27 -37
  146. package/dist/NumberInput/numberParser.d.ts +51 -0
  147. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  148. package/dist/NumberInput/numberParser.js +333 -0
  149. package/dist/Outline/Outline.d.ts.map +1 -1
  150. package/dist/Outline/Outline.js +3 -2
  151. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  152. package/dist/OverflowList/OverflowList.js +3 -2
  153. package/dist/Overlay/Overlay.d.ts.map +1 -1
  154. package/dist/Overlay/Overlay.js +3 -2
  155. package/dist/Popover/usePopover.d.ts.map +1 -1
  156. package/dist/Popover/usePopover.js +20 -17
  157. package/dist/PowerSearch/PowerSearch.d.ts +8 -2
  158. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  159. package/dist/PowerSearch/PowerSearch.js +19 -6
  160. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
  161. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  162. package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
  163. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
  164. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  165. package/dist/PowerSearch/PowerSearchValueEditor.js +19 -9
  166. package/dist/PowerSearch/types.d.ts +2 -0
  167. package/dist/PowerSearch/types.d.ts.map +1 -1
  168. package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
  169. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  170. package/dist/PowerSearch/usePowerSearchSource.js +14 -5
  171. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  172. package/dist/ProgressBar/ProgressBar.js +18 -5
  173. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  174. package/dist/Resizable/ResizeHandle.js +3 -2
  175. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  176. package/dist/SegmentedControl/SegmentedControl.js +3 -2
  177. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  178. package/dist/SelectableCard/SelectableCard.js +3 -3
  179. package/dist/Selector/Selector.d.ts.map +1 -1
  180. package/dist/Selector/Selector.js +5 -0
  181. package/dist/SideNav/SideNav.d.ts.map +1 -1
  182. package/dist/SideNav/SideNav.js +4 -3
  183. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  184. package/dist/SideNav/SideNavHeading.js +8 -7
  185. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  186. package/dist/SideNav/SideNavItem.js +4 -3
  187. package/dist/Slider/Slider.d.ts.map +1 -1
  188. package/dist/Slider/Slider.js +37 -5
  189. package/dist/Spinner/Spinner.d.ts +3 -3
  190. package/dist/Spinner/Spinner.d.ts.map +1 -1
  191. package/dist/Spinner/Spinner.js +130 -78
  192. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  193. package/dist/StatusDot/StatusDot.js +6 -1
  194. package/dist/Stepper/Step.d.ts +140 -0
  195. package/dist/Stepper/Step.d.ts.map +1 -0
  196. package/dist/Stepper/Step.js +1045 -0
  197. package/dist/Stepper/StepStatus.d.ts +24 -0
  198. package/dist/Stepper/StepStatus.d.ts.map +1 -0
  199. package/dist/Stepper/StepStatus.js +1 -0
  200. package/dist/Stepper/Stepper.d.ts +93 -0
  201. package/dist/Stepper/Stepper.d.ts.map +1 -0
  202. package/dist/Stepper/Stepper.js +184 -0
  203. package/dist/Stepper/StepperContext.d.ts +41 -0
  204. package/dist/Stepper/StepperContext.d.ts.map +1 -0
  205. package/dist/Stepper/StepperContext.js +34 -0
  206. package/dist/Stepper/index.d.ts +8 -0
  207. package/dist/Stepper/index.d.ts.map +1 -0
  208. package/dist/Stepper/index.js +7 -0
  209. package/dist/Stepper/stepper.stylex.d.ts +15 -0
  210. package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
  211. package/dist/Stepper/stepper.stylex.js +20 -0
  212. package/dist/Switch/Switch.d.ts.map +1 -1
  213. package/dist/Switch/Switch.js +8 -3
  214. package/dist/TabList/Tab.d.ts +15 -2
  215. package/dist/TabList/Tab.d.ts.map +1 -1
  216. package/dist/TabList/Tab.js +32 -7
  217. package/dist/TabList/TabList.d.ts +46 -7
  218. package/dist/TabList/TabList.d.ts.map +1 -1
  219. package/dist/TabList/TabList.js +353 -23
  220. package/dist/TabList/TabListContext.d.ts +11 -1
  221. package/dist/TabList/TabListContext.d.ts.map +1 -1
  222. package/dist/TabList/TabListContext.js +11 -2
  223. package/dist/TabList/TabMenu.d.ts.map +1 -1
  224. package/dist/TabList/TabMenu.js +3 -2
  225. package/dist/TabList/index.d.ts +2 -2
  226. package/dist/TabList/index.d.ts.map +1 -1
  227. package/dist/Table/BaseTable.d.ts.map +1 -1
  228. package/dist/Table/BaseTable.js +10 -2
  229. package/dist/Table/Table.d.ts.map +1 -1
  230. package/dist/Table/Table.js +3 -6
  231. package/dist/Table/TableRow.d.ts +16 -5
  232. package/dist/Table/TableRow.d.ts.map +1 -1
  233. package/dist/Table/TableRow.js +16 -5
  234. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  235. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +20 -8
  236. package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
  237. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  238. package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
  239. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  240. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  241. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  242. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
  243. package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
  244. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  245. package/dist/Table/plugins/selection/useTableSelection.js +19 -5
  246. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  247. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  248. package/dist/Table/types.d.ts +22 -4
  249. package/dist/Table/types.d.ts.map +1 -1
  250. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  251. package/dist/Table/useBaseTablePlugins.js +5 -0
  252. package/dist/Text/Text.d.ts.map +1 -1
  253. package/dist/Text/Text.js +6 -2
  254. package/dist/TextArea/TextArea.d.ts.map +1 -1
  255. package/dist/TextArea/TextArea.js +9 -3
  256. package/dist/TextInput/TextInput.d.ts.map +1 -1
  257. package/dist/TextInput/TextInput.js +3 -2
  258. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  259. package/dist/TimeInput/TimeInput.js +3 -2
  260. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  261. package/dist/Timestamp/Timestamp.js +5 -3
  262. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  263. package/dist/Toast/ToastViewport.js +27 -8
  264. package/dist/Token/TokenLink.d.ts.map +1 -1
  265. package/dist/Token/TokenLink.js +2 -2
  266. package/dist/Tokenizer/Tokenizer.d.ts +3 -1
  267. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  268. package/dist/Tokenizer/Tokenizer.js +2 -0
  269. package/dist/Tooltip/Tooltip.d.ts +5 -0
  270. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  271. package/dist/Tooltip/useTooltip.d.ts +5 -0
  272. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  273. package/dist/Tooltip/useTooltip.js +39 -24
  274. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  275. package/dist/TopNav/TopNavHeading.js +5 -4
  276. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  277. package/dist/TopNav/TopNavMegaMenu.js +3 -3
  278. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  279. package/dist/TopNav/TopNavMenu.js +4 -3
  280. package/dist/Typeahead/BaseTypeahead.d.ts +2 -0
  281. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  282. package/dist/Typeahead/BaseTypeahead.js +68 -29
  283. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  284. package/dist/Typeahead/Typeahead.js +3 -2
  285. package/dist/astryx.css +96 -7
  286. package/dist/hooks/index.d.ts +1 -0
  287. package/dist/hooks/index.d.ts.map +1 -1
  288. package/dist/hooks/index.js +1 -0
  289. package/dist/hooks/useFocusTrap.d.ts +7 -4
  290. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  291. package/dist/hooks/useFocusTrap.js +60 -95
  292. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  293. package/dist/hooks/useHotkeys.js +3 -18
  294. package/dist/hooks/useMergedRefs.d.ts +18 -0
  295. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  296. package/dist/hooks/useMergedRefs.js +25 -0
  297. package/dist/index.d.ts +1 -0
  298. package/dist/index.d.ts.map +1 -1
  299. package/dist/index.js +1 -0
  300. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  301. package/dist/theme/derivedVarRegistry.js +24 -4
  302. package/dist/theme/syntax/tokens.d.ts +1 -1
  303. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  304. package/dist/theme/syntax/tokens.js +5 -2
  305. package/dist/utils/groupItems.d.ts +5 -1
  306. package/dist/utils/groupItems.d.ts.map +1 -1
  307. package/dist/utils/groupItems.js +9 -9
  308. package/dist/utils/index.d.ts +1 -1
  309. package/dist/utils/index.d.ts.map +1 -1
  310. package/dist/utils/isApplePlatform.d.ts +18 -0
  311. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  312. package/dist/utils/isApplePlatform.js +37 -0
  313. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  314. package/dist/utils/sharedResizeObserver.js +10 -1
  315. package/dist/utils/timeParser.d.ts +1 -1
  316. package/dist/utils/timeParser.d.ts.map +1 -1
  317. package/dist/utils/timeParser.js +26 -12
  318. package/locales/en.json +31 -7
  319. package/locales/pseudo.json +18 -0
  320. package/package.json +8 -3
  321. package/src/AppShell/AppShell.tsx +3 -2
  322. package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
  323. package/src/AspectRatio/AspectRatio.test.tsx +57 -10
  324. package/src/AspectRatio/AspectRatio.tsx +40 -1
  325. package/src/Avatar/Avatar.doc.mjs +14 -3
  326. package/src/Avatar/Avatar.test.tsx +97 -0
  327. package/src/Avatar/Avatar.tsx +125 -52
  328. package/src/Avatar/index.ts +2 -2
  329. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  330. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  331. package/src/AvatarGroup/AvatarGroup.tsx +15 -6
  332. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  333. package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
  334. package/src/Banner/Banner.doc.mjs +13 -11
  335. package/src/Banner/Banner.test.tsx +102 -15
  336. package/src/Banner/Banner.tsx +72 -25
  337. package/src/BottomSheet/BottomSheet.test.tsx +123 -0
  338. package/src/BottomSheet/BottomSheet.tsx +17 -4
  339. package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
  340. package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
  341. package/src/Button/Button.doc.mjs +22 -0
  342. package/src/Button/Button.test.tsx +13 -0
  343. package/src/Button/Button.tsx +5 -4
  344. package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
  345. package/src/ButtonGroup/ButtonGroup.test.tsx +391 -1
  346. package/src/ButtonGroup/ButtonGroup.tsx +23 -5
  347. package/src/Calendar/Calendar.doc.mjs +4 -3
  348. package/src/Calendar/Calendar.test.tsx +103 -0
  349. package/src/Calendar/Calendar.tsx +19 -16
  350. package/src/Calendar/getInitialFocusDate.test.ts +94 -0
  351. package/src/Calendar/getInitialFocusDate.ts +93 -0
  352. package/src/Calendar/styles.ts +49 -31
  353. package/src/Carousel/Carousel.tsx +3 -2
  354. package/src/Chat/ChatComposerInput.tsx +5 -1
  355. package/src/Chat/ChatLayout.tsx +3 -2
  356. package/src/Chat/ChatMessageList.doc.mjs +9 -1
  357. package/src/Chat/ChatMessageList.test.tsx +46 -0
  358. package/src/Chat/ChatMessageList.tsx +28 -4
  359. package/src/Chat/ChatTokenizedText.tsx +17 -10
  360. package/src/Chat/useChatComposerTokens.ts +1 -1
  361. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  362. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  363. package/src/CheckboxInput/CheckboxInput.tsx +8 -2
  364. package/src/ClickableCard/ClickableCard.tsx +3 -2
  365. package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
  366. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  367. package/src/CodeBlock/CodeBlock.tsx +20 -4
  368. package/src/CodeBlock/highlightRanges.ts +1 -1
  369. package/src/CodeBlock/highlightStyles.ts +13 -13
  370. package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
  371. package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
  372. package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
  373. package/src/ContextMenu/ContextMenu.tsx +4 -3
  374. package/src/DateInput/DateInput.doc.mjs +16 -0
  375. package/src/DateInput/DateInput.tsx +55 -2
  376. package/src/DateInput/DateInputTouch.test.tsx +68 -9
  377. package/src/DateInput/NativeDateField.test.tsx +635 -0
  378. package/src/DateInput/NativeDateField.tsx +641 -0
  379. package/src/DateInput/TouchDateField.tsx +38 -4
  380. package/src/DateInput/index.ts +1 -0
  381. package/src/DateInput/nativeDateSegments.ts +127 -0
  382. package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
  383. package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
  384. package/src/DateTimeInput/DateTimeInput.tsx +556 -24
  385. package/src/DateTimeInput/index.ts +1 -0
  386. package/src/Dialog/Dialog.doc.mjs +8 -3
  387. package/src/Dialog/Dialog.test.tsx +261 -1
  388. package/src/Dialog/Dialog.tsx +109 -58
  389. package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
  390. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
  391. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
  392. package/src/Field/Field.doc.mjs +13 -2
  393. package/src/Field/FieldLabel.test.tsx +29 -0
  394. package/src/Field/FieldLabel.tsx +7 -0
  395. package/src/FileInput/FileInput.tsx +3 -2
  396. package/src/Heading/Heading.test.tsx +23 -1
  397. package/src/Heading/Heading.tsx +6 -2
  398. package/src/HoverCard/HoverCard.doc.mjs +13 -2
  399. package/src/HoverCard/HoverCard.test.tsx +101 -4
  400. package/src/HoverCard/HoverCard.tsx +71 -3
  401. package/src/HoverCard/useHoverCard.tsx +101 -33
  402. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  403. package/src/Indicator/Indicator.doc.mjs +2 -0
  404. package/src/Item/Item.tsx +5 -4
  405. package/src/Kbd/Kbd.tsx +2 -19
  406. package/src/Layer/LayerDepthContext.tsx +62 -0
  407. package/src/Layer/index.ts +9 -0
  408. package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
  409. package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
  410. package/src/Layer/layerStack.ts +362 -0
  411. package/src/Layer/useLayerDismissal.test.tsx +469 -0
  412. package/src/Layer/useLayerDismissal.ts +173 -0
  413. package/src/Layout/Layout.doc.mjs +2 -2
  414. package/src/Lightbox/Lightbox.doc.mjs +12 -0
  415. package/src/Lightbox/Lightbox.tsx +124 -102
  416. package/src/Link/Link.doc.mjs +39 -0
  417. package/src/Markdown/Markdown.doc.mjs +5 -0
  418. package/src/Markdown/incremental.test.ts +16 -2
  419. package/src/Markdown/index.ts +1 -0
  420. package/src/Markdown/parser.perf.test.ts +96 -1
  421. package/src/Markdown/parser.test.ts +145 -2
  422. package/src/Markdown/parser.ts +244 -29
  423. package/src/MobileNav/MobileNav.tsx +62 -36
  424. package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
  425. package/src/MultiSelector/MultiSelector.doc.mjs +27 -0
  426. package/src/MultiSelector/MultiSelector.test.tsx +106 -0
  427. package/src/MultiSelector/MultiSelector.tsx +50 -6
  428. package/src/MultiSelector/index.ts +1 -0
  429. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  430. package/src/NavIcon/NavIcon.test.tsx +9 -0
  431. package/src/NavIcon/NavIcon.tsx +5 -1
  432. package/src/NavMenu/NavHeadingMenu.tsx +3 -2
  433. package/src/NumberInput/NumberInput.doc.mjs +20 -0
  434. package/src/NumberInput/NumberInput.tsx +28 -29
  435. package/src/NumberInput/numberParser.test.ts +210 -0
  436. package/src/NumberInput/numberParser.ts +386 -0
  437. package/src/Outline/Outline.tsx +3 -2
  438. package/src/OverflowList/OverflowList.tsx +3 -2
  439. package/src/Overlay/Overlay.tsx +3 -2
  440. package/src/Popover/usePopover.tsx +31 -28
  441. package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
  442. package/src/PowerSearch/PowerSearch.test.tsx +240 -1
  443. package/src/PowerSearch/PowerSearch.tsx +34 -5
  444. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +201 -0
  445. package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
  446. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +47 -1
  447. package/src/PowerSearch/PowerSearchValueEditor.tsx +15 -0
  448. package/src/PowerSearch/types.ts +2 -0
  449. package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
  450. package/src/PowerSearch/usePowerSearchSource.ts +13 -3
  451. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  452. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  453. package/src/ProgressBar/ProgressBar.tsx +28 -8
  454. package/src/Resizable/ResizeHandle.tsx +3 -2
  455. package/src/SegmentedControl/SegmentedControl.tsx +3 -2
  456. package/src/SelectableCard/SelectableCard.tsx +3 -2
  457. package/src/Selector/Selector.doc.mjs +12 -1
  458. package/src/Selector/Selector.test.tsx +45 -1
  459. package/src/Selector/Selector.tsx +11 -1
  460. package/src/SideNav/SideNav.doc.mjs +6 -6
  461. package/src/SideNav/SideNav.tsx +4 -2
  462. package/src/SideNav/SideNavHeading.tsx +12 -12
  463. package/src/SideNav/SideNavItem.tsx +4 -2
  464. package/src/Slider/Slider.test.tsx +106 -1
  465. package/src/Slider/Slider.tsx +55 -3
  466. package/src/Spinner/Spinner.test.tsx +147 -1
  467. package/src/Spinner/Spinner.tsx +120 -101
  468. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  469. package/src/StatusDot/StatusDot.test.tsx +9 -0
  470. package/src/StatusDot/StatusDot.tsx +7 -1
  471. package/src/Stepper/Step.doc.mjs +98 -0
  472. package/src/Stepper/Step.tsx +1638 -0
  473. package/src/Stepper/StepStatus.ts +26 -0
  474. package/src/Stepper/Stepper.doc.mjs +370 -0
  475. package/src/Stepper/Stepper.test.tsx +1024 -0
  476. package/src/Stepper/Stepper.tsx +258 -0
  477. package/src/Stepper/StepperContext.ts +71 -0
  478. package/src/Stepper/index.ts +18 -0
  479. package/src/Stepper/stepper.stylex.ts +19 -0
  480. package/src/Switch/Switch.doc.mjs +2 -0
  481. package/src/Switch/Switch.test.tsx +10 -0
  482. package/src/Switch/Switch.tsx +6 -2
  483. package/src/TabList/Tab.doc.mjs +13 -1
  484. package/src/TabList/Tab.tsx +67 -7
  485. package/src/TabList/TabList.doc.mjs +22 -6
  486. package/src/TabList/TabList.test.tsx +559 -0
  487. package/src/TabList/TabList.tsx +490 -22
  488. package/src/TabList/TabListContext.ts +13 -2
  489. package/src/TabList/TabMenu.tsx +3 -2
  490. package/src/TabList/index.ts +6 -2
  491. package/src/Table/BaseTable.tsx +12 -4
  492. package/src/Table/Table.doc.mjs +9 -2
  493. package/src/Table/Table.test.tsx +132 -14
  494. package/src/Table/Table.tsx +3 -8
  495. package/src/Table/TableBody.doc.mjs +40 -0
  496. package/src/Table/TableFooter.doc.mjs +40 -0
  497. package/src/Table/TableHeader.doc.mjs +40 -0
  498. package/src/Table/TableRow.tsx +16 -5
  499. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
  500. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
  501. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +17 -8
  502. package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
  503. package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
  504. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
  505. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
  506. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
  507. package/src/Table/plugins/selection/useTableSelection.test.tsx +76 -0
  508. package/src/Table/plugins/selection/useTableSelection.tsx +40 -7
  509. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  510. package/src/Table/types.ts +22 -4
  511. package/src/Table/useBaseTablePlugins.ts +5 -0
  512. package/src/Table/useTableGroupedRows.doc.mjs +5 -4
  513. package/src/Table/useTablePagination.doc.mjs +7 -0
  514. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  515. package/src/Table/useTableSelection.doc.mjs +31 -0
  516. package/src/Text/Text.test.tsx +23 -1
  517. package/src/Text/Text.tsx +6 -2
  518. package/src/TextArea/TextArea.doc.mjs +8 -2
  519. package/src/TextArea/TextArea.test.tsx +11 -0
  520. package/src/TextArea/TextArea.tsx +15 -8
  521. package/src/TextInput/TextInput.doc.mjs +10 -0
  522. package/src/TextInput/TextInput.tsx +3 -2
  523. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  524. package/src/TimeInput/TimeInput.tsx +2 -2
  525. package/src/Timestamp/Timestamp.tsx +4 -2
  526. package/src/Toast/Toast.doc.mjs +6 -0
  527. package/src/Toast/ToastViewport.tsx +17 -1
  528. package/src/Token/TokenLink.tsx +2 -2
  529. package/src/Tokenizer/Tokenizer.doc.mjs +27 -0
  530. package/src/Tokenizer/Tokenizer.tsx +4 -0
  531. package/src/Toolbar/Toolbar.doc.mjs +5 -0
  532. package/src/Tooltip/Tooltip.doc.mjs +5 -0
  533. package/src/Tooltip/Tooltip.test.tsx +32 -0
  534. package/src/Tooltip/Tooltip.tsx +5 -0
  535. package/src/Tooltip/useTooltip.tsx +47 -24
  536. package/src/TopNav/TopNavHeading.tsx +5 -4
  537. package/src/TopNav/TopNavMegaMenu.tsx +3 -2
  538. package/src/TopNav/TopNavMenu.tsx +4 -3
  539. package/src/Typeahead/BaseTypeahead.doc.mjs +11 -0
  540. package/src/Typeahead/BaseTypeahead.tsx +85 -33
  541. package/src/Typeahead/Typeahead.doc.mjs +5 -0
  542. package/src/Typeahead/Typeahead.test.tsx +49 -0
  543. package/src/Typeahead/Typeahead.tsx +3 -2
  544. package/src/hooks/index.ts +2 -0
  545. package/src/hooks/useContainerReveal.doc.mjs +2 -2
  546. package/src/hooks/useFocusTrap.test.tsx +14 -0
  547. package/src/hooks/useFocusTrap.ts +62 -111
  548. package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
  549. package/src/hooks/useHotkeys.ts +3 -18
  550. package/src/hooks/useMergedRefs.doc.mjs +79 -0
  551. package/src/hooks/useMergedRefs.test.tsx +62 -0
  552. package/src/hooks/useMergedRefs.ts +36 -0
  553. package/src/index.ts +1 -0
  554. package/src/theme/MediaTheme.doc.mjs +5 -5
  555. package/src/theme/derivedVarRegistry.test.ts +19 -3
  556. package/src/theme/derivedVarRegistry.ts +23 -4
  557. package/src/theme/generateThemeRules.test.ts +37 -0
  558. package/src/theme/syntax/tokens.ts +5 -2
  559. package/src/utils/groupItems.ts +12 -6
  560. package/src/utils/index.ts +1 -1
  561. package/src/utils/isApplePlatform.test.ts +61 -0
  562. package/src/utils/isApplePlatform.ts +37 -0
  563. package/src/utils/sharedResizeObserver.ts +10 -2
  564. package/src/utils/timeParser.test.ts +6 -1
  565. package/src/utils/timeParser.ts +35 -13
  566. package/src/__tests__/inputWidthContract.test.tsx +0 -69
@@ -213,6 +213,7 @@ function discoverComponents(): ComponentInfo[] {
213
213
  // ---------------------------------------------------------------------------
214
214
 
215
215
  const DIR_TO_REGISTRY_KEY: Record<string, string> = {
216
+ Avatar: 'avatar',
216
217
  Banner: 'banner',
217
218
  Button: 'button',
218
219
  Card: 'card',
@@ -221,13 +222,13 @@ const DIR_TO_REGISTRY_KEY: Record<string, string> = {
221
222
  Dialog: 'dialog',
222
223
  DropdownMenu: 'dropdown-menu',
223
224
  Field: 'field',
224
- HoverCard: 'hovercard',
225
+ HoverCard: 'hover-card',
225
226
  NumberInput: 'number-input',
226
227
  Popover: 'popover',
227
- ProgressBar: 'progressbar-mark',
228
+ ProgressBar: 'progress-bar-mark',
228
229
  Section: 'section',
229
230
  SegmentedControl: 'segmented-control',
230
- TextArea: 'textarea',
231
+ TextArea: 'text-area',
231
232
  };
232
233
 
233
234
  /**
@@ -418,6 +419,21 @@ describe('getDerivedVars', () => {
418
419
  expect(getDerivedVars('unknown', 'borderRadius')).toEqual([]);
419
420
  });
420
421
 
422
+ it('resolves a deprecated key to the entries of the key that replaced it', () => {
423
+ // A theme written against the old spelling still selects the element (the
424
+ // component emits both classes), so its derived vars must still expand —
425
+ // otherwise the rule lands and the var half of it silently does nothing.
426
+ expect(getDerivedVars('hovercard', 'borderRadius')).toEqual(
427
+ getDerivedVars('hover-card', 'borderRadius'),
428
+ );
429
+ expect(getDerivedVars('textarea', 'paddingInline')).toEqual(
430
+ getDerivedVars('text-area', 'paddingInline'),
431
+ );
432
+ expect(getDerivedVars('progressbar-mark', 'width')).toEqual(
433
+ getDerivedVars('progress-bar-mark', 'width'),
434
+ );
435
+ });
436
+
421
437
  it('returns empty for unregistered property', () => {
422
438
  expect(getDerivedVars('card', 'color')).toEqual([]);
423
439
  });
@@ -43,6 +43,7 @@ export interface DerivedVarEntry {
43
43
  * entries share the same property.
44
44
  */
45
45
  export const derivedVarRegistry: Record<string, DerivedVarEntry[]> = {
46
+ avatar: [{property: 'borderRadius', vars: ['--_avatar-radius']}],
46
47
  banner: [{property: 'borderRadius', vars: ['--_banner-radius']}],
47
48
  button: [{property: 'borderRadius', vars: ['--_button-radius']}],
48
49
  card: [
@@ -66,13 +67,13 @@ export const derivedVarRegistry: Record<string, DerivedVarEntry[]> = {
66
67
  {property: 'padding', vars: ['--_dropdown-menu-padding']},
67
68
  ],
68
69
  field: [{property: 'borderRadius', vars: ['--_field-radius']}],
69
- hovercard: [{property: 'borderRadius', vars: ['--_hovercard-radius']}],
70
+ 'hover-card': [{property: 'borderRadius', vars: ['--_hovercard-radius']}],
70
71
  'number-input': [
71
72
  {property: 'padding', expand: 'container'},
72
73
  {property: 'borderRadius', vars: ['--_field-radius']},
73
74
  ],
74
75
  popover: [{property: 'borderRadius', vars: ['--_popover-radius']}],
75
- 'progressbar-mark': [
76
+ 'progress-bar-mark': [
76
77
  {property: 'width', vars: ['--_progressbar-mark-width'], replaces: true},
77
78
  {property: 'height', vars: ['--_progressbar-mark-height'], replaces: true},
78
79
  ],
@@ -81,7 +82,7 @@ export const derivedVarRegistry: Record<string, DerivedVarEntry[]> = {
81
82
  {property: 'borderRadius', vars: ['--_segmented-control-radius']},
82
83
  {property: 'padding', vars: ['--_segmented-control-padding']},
83
84
  ],
84
- textarea: [
85
+ 'text-area': [
85
86
  {
86
87
  property: 'paddingInline',
87
88
  vars: ['--_textarea-inline-padding'],
@@ -90,6 +91,21 @@ export const derivedVarRegistry: Record<string, DerivedVarEntry[]> = {
90
91
  ],
91
92
  };
92
93
 
94
+ /**
95
+ * Deprecated component keys → the key that superseded them.
96
+ *
97
+ * A renamed target keeps emitting its old class, so a theme written against
98
+ * the old key still selects the element. Without this the rule would land but
99
+ * its derived vars would not expand, and the half that travels through a var
100
+ * (a hover card's radius, a text area's inline padding) would silently do
101
+ * nothing. Drop these with the classes, in the next major.
102
+ */
103
+ const DEPRECATED_REGISTRY_KEYS: Record<string, string> = {
104
+ hovercard: 'hover-card',
105
+ 'progressbar-mark': 'progress-bar-mark',
106
+ textarea: 'text-area',
107
+ };
108
+
93
109
  /**
94
110
  * Look up derived var entries for a component + CSS property.
95
111
  * Returns matching entries in priority order, or empty array if none.
@@ -98,7 +114,10 @@ export function getDerivedVars(
98
114
  component: string,
99
115
  property: string,
100
116
  ): DerivedVarEntry[] {
101
- const entries = derivedVarRegistry[component];
117
+ const renamedTo = DEPRECATED_REGISTRY_KEYS[component];
118
+ const entries =
119
+ derivedVarRegistry[component] ??
120
+ (renamedTo ? derivedVarRegistry[renamedTo] : undefined);
102
121
  if (!entries) {
103
122
  return [];
104
123
  }
@@ -702,3 +702,40 @@ describe('physical padding longhands', () => {
702
702
  expect(rule).not.toContain('--_dropdown-menu-padding');
703
703
  });
704
704
  });
705
+
706
+ describe('renamed theme targets', () => {
707
+ // The renamed targets emit both classes, so a rule written against either
708
+ // key selects the element. What is easy to miss is the derived-var half: a
709
+ // key the registry does not know still emits a rule, minus every var the
710
+ // component actually reads — the same silent nothing a misspelled key gives.
711
+ it('expands derived vars for a renamed key and its deprecated spelling', () => {
712
+ const rules = (component: string, styles: Record<string, string>) =>
713
+ generateThemeRules(
714
+ defineTheme({
715
+ name: `test-renamed-${component}`,
716
+ components: {[component]: {base: styles}},
717
+ }),
718
+ ).join('\n');
719
+
720
+ const hoverCard = rules('hover-card', {borderRadius: '9px'});
721
+ expect(hoverCard).toContain('.astryx-hover-card');
722
+ expect(hoverCard).toContain('--_hovercard-radius: 9px');
723
+ expect(rules('hovercard', {borderRadius: '9px'})).toContain(
724
+ '--_hovercard-radius: 9px',
725
+ );
726
+
727
+ const textArea = rules('text-area', {paddingInline: '11px'});
728
+ expect(textArea).toContain('.astryx-text-area');
729
+ expect(textArea).toContain('--_textarea-inline-padding: 11px');
730
+ expect(rules('textarea', {paddingInline: '11px'})).toContain(
731
+ '--_textarea-inline-padding: 11px',
732
+ );
733
+
734
+ const mark = rules('progress-bar-mark', {width: '3px'});
735
+ expect(mark).toContain('.astryx-progress-bar-mark');
736
+ expect(mark).toContain('--_progressbar-mark-width: 3px');
737
+ expect(rules('progressbar-mark', {width: '3px'})).toContain(
738
+ '--_progressbar-mark-width: 3px',
739
+ );
740
+ });
741
+ });
@@ -44,8 +44,11 @@ export const syntaxTokenDefaults = {
44
44
  '--color-syntax-attribute': 'var(--color-text-teal)',
45
45
  // property -> cyan text (object properties)
46
46
  '--color-syntax-property': 'var(--color-text-cyan)',
47
- // punctuation -> disabled text (brackets, semicolons)
48
- '--color-syntax-punctuation': 'var(--color-text-disabled)',
47
+ // punctuation -> secondary text (brackets, semicolons). Not disabled text:
48
+ // disabled grey is calibrated to fail AA on purpose (WCAG exempts inactive
49
+ // controls), and punctuation in a code sample is normal, always-active
50
+ // text — see #5386.
51
+ '--color-syntax-punctuation': 'var(--color-text-secondary)',
49
52
  // background -> muted surface
50
53
  '--color-syntax-background': 'var(--color-background-muted)',
51
54
  } as const;
@@ -19,6 +19,11 @@ export interface ItemGroup<T extends SearchableItem = SearchableItem> {
19
19
  items: T[];
20
20
  }
21
21
 
22
+ export interface GroupItemsOptions {
23
+ /** Place ungrouped items before named groups instead of after them. */
24
+ ungroupedFirst?: boolean;
25
+ }
26
+
22
27
  /**
23
28
  * Extract the group string from an item's auxiliaryData.
24
29
  */
@@ -52,6 +57,7 @@ export function getItemGroup(item: SearchableItem): string | undefined {
52
57
  */
53
58
  export function groupItems<T extends SearchableItem>(
54
59
  items: T[],
60
+ {ungroupedFirst = false}: GroupItemsOptions = {},
55
61
  ): ItemGroup<T>[] {
56
62
  const hasGroups = items.some(item => getItemGroup(item) != null);
57
63
 
@@ -76,14 +82,14 @@ export function groupItems<T extends SearchableItem>(
76
82
  }
77
83
  }
78
84
 
79
- const result: ItemGroup<T>[] = groupOrder.map(heading => ({
85
+ const namedGroups: ItemGroup<T>[] = groupOrder.map(heading => ({
80
86
  heading,
81
87
  items: groups.get(heading) ?? [],
82
88
  }));
89
+ const ungroupedGroup: ItemGroup<T>[] =
90
+ ungrouped.length > 0 ? [{heading: null, items: ungrouped}] : [];
83
91
 
84
- if (ungrouped.length > 0) {
85
- result.push({heading: null, items: ungrouped});
86
- }
87
-
88
- return result;
92
+ return ungroupedFirst
93
+ ? [...ungroupedGroup, ...namedGroups]
94
+ : [...namedGroups, ...ungroupedGroup];
89
95
  }
@@ -86,7 +86,7 @@ export type {
86
86
  ThemeProps,
87
87
  } from './themeProps';
88
88
  export {groupItems, getItemGroup} from './groupItems';
89
- export type {ItemGroup} from './groupItems';
89
+ export type {ItemGroup, GroupItemsOptions} from './groupItems';
90
90
  export {observeResize, unobserveResize} from './sharedResizeObserver';
91
91
  export {isRenderable} from './isRenderable';
92
92
  export {getInputARIA} from './inputAria';
@@ -0,0 +1,61 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file isApplePlatform.test.ts
5
+ * @input Uses vitest, isApplePlatform
6
+ * @output Unit tests for isApplePlatform
7
+ * @position Testing; validates isApplePlatform.ts implementation
8
+ */
9
+
10
+ import {describe, it, expect, vi, afterEach} from 'vitest';
11
+ import {isApplePlatform} from './isApplePlatform';
12
+
13
+ afterEach(() => {
14
+ vi.unstubAllGlobals();
15
+ });
16
+
17
+ describe('isApplePlatform', () => {
18
+ it('trusts a client-hints platform that names one', () => {
19
+ vi.stubGlobal('navigator', {
20
+ userAgentData: {platform: 'macOS'},
21
+ platform: 'Win32',
22
+ });
23
+ expect(isApplePlatform()).toBe(true);
24
+
25
+ vi.stubGlobal('navigator', {
26
+ userAgentData: {platform: 'Windows'},
27
+ platform: 'MacIntel',
28
+ });
29
+ expect(isApplePlatform()).toBe(false);
30
+ });
31
+
32
+ it.each([
33
+ ['blank', ''],
34
+ ['whitespace', ' '],
35
+ ['the spec Unknown sentinel', 'Unknown'],
36
+ ['unknown in any case', 'UNKNOWN'],
37
+ ['a non-string', null],
38
+ ])('falls through to navigator.platform on %s', (_label, platform) => {
39
+ vi.stubGlobal('navigator', {
40
+ userAgentData: {platform},
41
+ platform: 'MacIntel',
42
+ });
43
+ expect(isApplePlatform()).toBe(true);
44
+
45
+ vi.stubGlobal('navigator', {userAgentData: {platform}, platform: 'Win32'});
46
+ expect(isApplePlatform()).toBe(false);
47
+ });
48
+
49
+ it('falls back to navigator.platform when client hints are absent', () => {
50
+ vi.stubGlobal('navigator', {platform: 'iPhone'});
51
+ expect(isApplePlatform()).toBe(true);
52
+
53
+ vi.stubGlobal('navigator', {platform: 'Linux x86_64'});
54
+ expect(isApplePlatform()).toBe(false);
55
+ });
56
+
57
+ it('answers false when there is no navigator at all', () => {
58
+ vi.stubGlobal('navigator', undefined);
59
+ expect(isApplePlatform()).toBe(false);
60
+ });
61
+ });
@@ -0,0 +1,37 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file isApplePlatform.ts
5
+ * @input Reads navigator.userAgentData.platform and navigator.platform
6
+ * @output Exports isApplePlatform
7
+ * @position Internal util; the single platform detection behind useHotkeys and Kbd
8
+ *
9
+ * Deliberately absent from utils/index.ts: packages/core/src/index.ts does
10
+ * `export * from './utils'`, so naming it there would publish it as API.
11
+ * Import it by path, as interactionModality is imported.
12
+ */
13
+
14
+ /**
15
+ * Detects whether the current platform is macOS/iOS.
16
+ * Prefers the User-Agent Client Hints API when it names a platform (modern
17
+ * Chrome/Edge), falls back to navigator.platform (deprecated but universally
18
+ * supported) when it names none.
19
+ */
20
+ export function isApplePlatform(): boolean {
21
+ if (typeof navigator === 'undefined') {
22
+ return false;
23
+ }
24
+ const uaData = 'userAgentData' in navigator ? navigator.userAgentData : null;
25
+ if (uaData && typeof uaData === 'object' && 'platform' in uaData) {
26
+ const uaPlatform = (uaData as {platform?: unknown}).platform;
27
+ const named = typeof uaPlatform === 'string' ? uaPlatform.trim() : '';
28
+ // A value that names nothing is no answer, not a negative one: builds that
29
+ // rewrite their client-hints identity ship '', and 'Unknown' is the spec's
30
+ // own sentinel for "cannot say". Both fall through rather than reading as
31
+ // "not Apple".
32
+ if (named !== '' && named.toLowerCase() !== 'unknown') {
33
+ return /mac/i.test(named);
34
+ }
35
+ }
36
+ return /Mac|iPhone|iPad|iPod/.test(navigator.platform ?? '');
37
+ }
@@ -24,7 +24,15 @@ type ResizeCallback = (entry: ResizeObserverEntry) => void;
24
24
  let observer: ResizeObserver | null = null;
25
25
  const callbacks = new Map<Element, ResizeCallback>();
26
26
 
27
- function getObserver(): ResizeObserver {
27
+ /**
28
+ * The shared observer, or null where the API does not exist (jsdom, an old
29
+ * browser). Callers still get the one-shot measurement `observeResize` fires
30
+ * on registration; live resize updates are the part that needs the API.
31
+ */
32
+ function getObserver(): ResizeObserver | null {
33
+ if (typeof ResizeObserver === 'undefined') {
34
+ return null;
35
+ }
28
36
  if (!observer) {
29
37
  observer = new ResizeObserver(entries => {
30
38
  for (const entry of entries) {
@@ -64,7 +72,7 @@ export function observeResize(
64
72
  callback: ResizeCallback,
65
73
  ): void {
66
74
  callbacks.set(element, callback);
67
- getObserver().observe(element);
75
+ getObserver()?.observe(element);
68
76
 
69
77
  // Fire once immediately so callers get an initial measurement
70
78
  // without duplicating their logic outside the observer path.
@@ -135,6 +135,9 @@ describe('parseTimeInput', () => {
135
135
  it('parses compact formats', () => {
136
136
  expect(parseTimeInput('1430')).toBe('14:30');
137
137
  expect(parseTimeInput('0000')).toBe('00:00');
138
+ expect(parseTimeInput('0230pm')).toBe('14:30');
139
+ expect(parseTimeInput('1230am')).toBe('00:30');
140
+ expect(parseTimeInput('023045pm', true)).toBe('14:30:45');
138
141
  });
139
142
 
140
143
  it('parses hour-only with meridiem', () => {
@@ -259,7 +262,9 @@ describe('adjustTime', () => {
259
262
 
260
263
  it('wraps large negative deltas in constant time', () => {
261
264
  expect(adjustTime('10:00' as ISOTimeString, -1440 * 1e7)).toBe('10:00');
262
- expect(adjustTime('10:00' as ISOTimeString, -1440 * 1e7 - 30)).toBe('09:30');
265
+ expect(adjustTime('10:00' as ISOTimeString, -1440 * 1e7 - 30)).toBe(
266
+ '09:30',
267
+ );
263
268
  });
264
269
 
265
270
  it('adds minutes', () => {
@@ -4,7 +4,7 @@
4
4
  * @file timeParser.ts
5
5
  * @input Uses string parsing
6
6
  * @output Exports time parsing and formatting utilities
7
- * @position Shared utility; used by TimePicker
7
+ * @position Shared utility; used by TimeInput and DateTimeInput
8
8
  *
9
9
  * SYNC: When modified, update this header
10
10
  */
@@ -175,16 +175,29 @@ export function parseTimeInput(
175
175
  // Remove AM/PM suffix
176
176
  const timeStr = trimmed.replace(/\s*[ap]\.?m?\.?\s*$/i, '').trim();
177
177
 
178
+ const convertHourTo24Hour = (hour: number): number | null => {
179
+ if (!hasMeridiem) {
180
+ return hour;
181
+ }
182
+ if (hour < 1 || hour > 12) {
183
+ return null;
184
+ }
185
+ if (isPM && hour !== 12) {
186
+ return hour + 12;
187
+ }
188
+ if (isAM && hour === 12) {
189
+ return 0;
190
+ }
191
+ return hour;
192
+ };
193
+
178
194
  // Handle formats like "2pm" -> "2"
179
195
  if (/^\d{1,2}$/.test(timeStr)) {
180
196
  const hour = parseInt(timeStr, 10);
181
- if (hour >= 1 && hour <= 12 && hasMeridiem) {
182
- let hour24 = hour;
183
- if (isPM && hour !== 12) {
184
- hour24 = hour + 12;
185
- }
186
- if (isAM && hour === 12) {
187
- hour24 = 0;
197
+ if (hasMeridiem) {
198
+ const hour24 = convertHourTo24Hour(hour);
199
+ if (hour24 === null) {
200
+ return null;
188
201
  }
189
202
  return formatISOTime(
190
203
  {hour: hour24, minute: 0, second: 0},
@@ -201,8 +214,15 @@ export function parseTimeInput(
201
214
  if (/^\d{4}$/.test(timeStr)) {
202
215
  const hour = parseInt(timeStr.slice(0, 2), 10);
203
216
  const minute = parseInt(timeStr.slice(2, 4), 10);
204
- if (hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59) {
205
- return formatISOTime({hour, minute, second: 0}, includeSeconds);
217
+ const hour24 = convertHourTo24Hour(hour);
218
+ if (
219
+ hour24 !== null &&
220
+ hour24 >= 0 &&
221
+ hour24 <= 23 &&
222
+ minute >= 0 &&
223
+ minute <= 59
224
+ ) {
225
+ return formatISOTime({hour: hour24, minute, second: 0}, includeSeconds);
206
226
  }
207
227
  return null;
208
228
  }
@@ -212,15 +232,17 @@ export function parseTimeInput(
212
232
  const hour = parseInt(timeStr.slice(0, 2), 10);
213
233
  const minute = parseInt(timeStr.slice(2, 4), 10);
214
234
  const second = parseInt(timeStr.slice(4, 6), 10);
235
+ const hour24 = convertHourTo24Hour(hour);
215
236
  if (
216
- hour >= 0 &&
217
- hour <= 23 &&
237
+ hour24 !== null &&
238
+ hour24 >= 0 &&
239
+ hour24 <= 23 &&
218
240
  minute >= 0 &&
219
241
  minute <= 59 &&
220
242
  second >= 0 &&
221
243
  second <= 59
222
244
  ) {
223
- return formatISOTime({hour, minute, second}, includeSeconds);
245
+ return formatISOTime({hour: hour24, minute, second}, includeSeconds);
224
246
  }
225
247
  return null;
226
248
  }
@@ -1,69 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- import {describe, it, expect} from 'vitest';
4
-
5
- import {docs as CheckboxInputDocs} from '../CheckboxInput/CheckboxInput.doc.mjs';
6
- import {docs as CheckboxListDocs} from '../CheckboxList/CheckboxList.doc.mjs';
7
- import {docs as DateInputDocs} from '../DateInput/DateInput.doc.mjs';
8
- import {docs as DateRangeInputDocs} from '../DateRangeInput/DateRangeInput.doc.mjs';
9
- import {docs as DateTimeInputDocs} from '../DateTimeInput/DateTimeInput.doc.mjs';
10
- import {docs as FileInputDocs} from '../FileInput/FileInput.doc.mjs';
11
- import {docs as MultiSelectorDocs} from '../MultiSelector/MultiSelector.doc.mjs';
12
- import {docs as NumberInputDocs} from '../NumberInput/NumberInput.doc.mjs';
13
- import {docs as RadioListDocs} from '../RadioList/RadioList.doc.mjs';
14
- import {docs as SelectorDocs} from '../Selector/Selector.doc.mjs';
15
- import {docs as SliderDocs} from '../Slider/Slider.doc.mjs';
16
- import {docs as SwitchDocs} from '../Switch/Switch.doc.mjs';
17
- import {docs as TextAreaDocs} from '../TextArea/TextArea.doc.mjs';
18
- import {docs as TextInputDocs} from '../TextInput/TextInput.doc.mjs';
19
- import {docs as TimeInputDocs} from '../TimeInput/TimeInput.doc.mjs';
20
- import {docs as TokenizerDocs} from '../Tokenizer/Tokenizer.doc.mjs';
21
- import {docs as TypeaheadDocs} from '../Typeahead/Typeahead.doc.mjs';
22
-
23
- const inputDocsSuite = [
24
- {name: 'CheckboxInput', docs: CheckboxInputDocs},
25
- {name: 'CheckboxList', docs: CheckboxListDocs},
26
- {name: 'DateInput', docs: DateInputDocs},
27
- {name: 'DateRangeInput', docs: DateRangeInputDocs},
28
- {name: 'DateTimeInput', docs: DateTimeInputDocs},
29
- {name: 'FileInput', docs: FileInputDocs},
30
- {name: 'MultiSelector', docs: MultiSelectorDocs},
31
- {name: 'NumberInput', docs: NumberInputDocs},
32
- {name: 'RadioList', docs: RadioListDocs},
33
- {name: 'Selector', docs: SelectorDocs},
34
- {name: 'Slider', docs: SliderDocs},
35
- {name: 'Switch', docs: SwitchDocs},
36
- {name: 'TextArea', docs: TextAreaDocs},
37
- {name: 'TextInput', docs: TextInputDocs},
38
- {name: 'TimeInput', docs: TimeInputDocs},
39
- {name: 'Tokenizer', docs: TokenizerDocs},
40
- {name: 'Typeahead', docs: TypeaheadDocs},
41
- ];
42
-
43
- describe('Input Family width Prop Contract (#4163)', () => {
44
- inputDocsSuite.forEach(({name, docs}) => {
45
- it(`documents the width prop for ${name}`, () => {
46
- // `docs` is the ComponentDoc union (single vs multi component); narrow it
47
- // for structural access to either the top-level props or the first
48
- // sub-component's props.
49
- const doc = docs as {
50
- props?: {name: string; type: string}[];
51
- components?: {props?: {name: string; type: string}[]}[];
52
- };
53
- const propsList = (doc.props || doc.components?.[0]?.props) as {
54
- name: string;
55
- type: string;
56
- }[];
57
- expect(
58
- propsList,
59
- `${name}.doc.mjs must expose a props array`,
60
- ).toBeDefined();
61
- const widthProp = propsList.find(p => p.name === 'width');
62
- expect(
63
- widthProp,
64
- `${name}.doc.mjs must document the width prop`,
65
- ).toBeDefined();
66
- expect(widthProp?.type).toBe('SizeValue');
67
- });
68
- });
69
- });