@astryxdesign/core 0.4.5 → 0.4.6-canary.cea9ecd

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 (538) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/dist/Avatar/Avatar.d.ts +10 -5
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +139 -30
  5. package/dist/Avatar/AvatarStatusDot.d.ts +2 -1
  6. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  7. package/dist/Avatar/AvatarStatusDot.js +30 -4
  8. package/dist/Avatar/AvatarStatusLabelContext.d.ts +39 -0
  9. package/dist/Avatar/AvatarStatusLabelContext.d.ts.map +1 -0
  10. package/dist/Avatar/AvatarStatusLabelContext.js +41 -0
  11. package/dist/AvatarGroup/AvatarGroup.d.ts +3 -1
  12. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  13. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroupOverflow.js +15 -9
  15. package/dist/Blockquote/Blockquote.d.ts +4 -3
  16. package/dist/Blockquote/Blockquote.d.ts.map +1 -1
  17. package/dist/Blockquote/Blockquote.js +9 -10
  18. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  19. package/dist/BottomSheet/BottomSheetPanel.js +21 -5
  20. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  21. package/dist/Breadcrumbs/BreadcrumbItem.js +47 -34
  22. package/dist/Button/Button.d.ts.map +1 -1
  23. package/dist/Button/Button.js +7 -7
  24. package/dist/Calendar/Calendar.d.ts.map +1 -1
  25. package/dist/Calendar/Calendar.js +21 -12
  26. package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
  27. package/dist/Calendar/hooks/useCalendarNavigation.js +8 -4
  28. package/dist/Calendar/styles.d.ts +2 -2
  29. package/dist/Calendar/styles.d.ts.map +1 -1
  30. package/dist/Calendar/styles.js +5 -5
  31. package/dist/Center/Center.d.ts +23 -1
  32. package/dist/Center/Center.d.ts.map +1 -1
  33. package/dist/Center/Center.js +12 -6
  34. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  35. package/dist/Chat/ChatComposer.js +3 -3
  36. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  37. package/dist/Chat/ChatComposerDrawer.js +2 -2
  38. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  39. package/dist/Chat/ChatToolCalls.js +2 -2
  40. package/dist/Chat/useChatDictation.d.ts +1 -1
  41. package/dist/Chat/useChatDictation.d.ts.map +1 -1
  42. package/dist/Chat/useSpeechRecognition.d.ts +1 -1
  43. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  44. package/dist/Chat/useSpeechRecognition.js +4 -3
  45. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  46. package/dist/Chat/useTriggerMenu.js +2 -2
  47. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  48. package/dist/CheckboxInput/CheckboxInput.js +2 -2
  49. package/dist/Citation/Citation.d.ts.map +1 -1
  50. package/dist/Citation/Citation.js +5 -5
  51. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  52. package/dist/ClickableCard/ClickableCard.js +4 -4
  53. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  54. package/dist/CodeBlock/CodeBlock.js +1 -1
  55. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  56. package/dist/Collapsible/Collapsible.js +2 -2
  57. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  58. package/dist/CommandPalette/CommandPaletteItem.js +3 -3
  59. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  60. package/dist/ComplexSelector/ComplexSelector.js +6 -6
  61. package/dist/DateInput/DateInput.d.ts +31 -2
  62. package/dist/DateInput/DateInput.d.ts.map +1 -1
  63. package/dist/DateInput/DateInput.js +90 -22
  64. package/dist/DateInput/MonthScroller.d.ts +35 -0
  65. package/dist/DateInput/MonthScroller.d.ts.map +1 -0
  66. package/dist/DateInput/MonthScroller.js +658 -0
  67. package/dist/DateInput/MonthYearWheels.d.ts +24 -0
  68. package/dist/DateInput/MonthYearWheels.d.ts.map +1 -0
  69. package/dist/DateInput/MonthYearWheels.js +114 -0
  70. package/dist/DateInput/TouchDateField.d.ts +10 -0
  71. package/dist/DateInput/TouchDateField.d.ts.map +1 -0
  72. package/dist/DateInput/TouchDateField.js +810 -0
  73. package/dist/DateInput/Wheel.d.ts +41 -0
  74. package/dist/DateInput/Wheel.d.ts.map +1 -0
  75. package/dist/DateInput/Wheel.js +315 -0
  76. package/dist/DateInput/monthGeometry.d.ts +65 -0
  77. package/dist/DateInput/monthGeometry.d.ts.map +1 -0
  78. package/dist/DateInput/monthGeometry.js +98 -0
  79. package/dist/DateInput/tokens.stylex.d.ts +63 -0
  80. package/dist/DateInput/tokens.stylex.d.ts.map +1 -0
  81. package/dist/DateInput/tokens.stylex.js +74 -0
  82. package/dist/DateInput/useOwnScrollGesture.d.ts +41 -0
  83. package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -0
  84. package/dist/DateInput/useOwnScrollGesture.js +202 -0
  85. package/dist/DateInput/usePointerDragScroll.d.ts +15 -0
  86. package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -0
  87. package/dist/DateInput/usePointerDragScroll.js +216 -0
  88. package/dist/DateInput/useScrollSettle.d.ts +26 -0
  89. package/dist/DateInput/useScrollSettle.d.ts.map +1 -0
  90. package/dist/DateInput/useScrollSettle.js +149 -0
  91. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  92. package/dist/DateRangeInput/DateRangeInput.js +17 -14
  93. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  94. package/dist/DateTimeInput/DateTimeInput.js +17 -14
  95. package/dist/Dialog/Dialog.d.ts.map +1 -1
  96. package/dist/Dialog/Dialog.js +3 -3
  97. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  98. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +2 -2
  99. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  100. package/dist/DropdownMenu/DropdownMenuItem.js +2 -2
  101. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  102. package/dist/DropdownMenu/DropdownMenuRadioItem.js +2 -2
  103. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  104. package/dist/DropdownMenu/DropdownMenuSubMenu.js +2 -2
  105. package/dist/Field/FieldLabel.d.ts.map +1 -1
  106. package/dist/Field/FieldLabel.js +4 -4
  107. package/dist/Field/InputClearButton.d.ts.map +1 -1
  108. package/dist/Field/InputClearButton.js +6 -0
  109. package/dist/Field/inputStyles.stylex.d.ts +1 -1
  110. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  111. package/dist/Field/inputStyles.stylex.js +5 -5
  112. package/dist/FileInput/FileInput.d.ts.map +1 -1
  113. package/dist/FileInput/FileInput.js +6 -6
  114. package/dist/HoverCard/HoverCard.d.ts +13 -3
  115. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  116. package/dist/HoverCard/HoverCard.js +2 -0
  117. package/dist/HoverCard/index.d.ts +1 -1
  118. package/dist/HoverCard/index.d.ts.map +1 -1
  119. package/dist/HoverCard/useHoverCard.d.ts +17 -2
  120. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  121. package/dist/HoverCard/useHoverCard.js +78 -9
  122. package/dist/InputGroup/InputGroup.js +1 -1
  123. package/dist/Item/Item.d.ts +9 -1
  124. package/dist/Item/Item.d.ts.map +1 -1
  125. package/dist/Item/Item.js +52 -14
  126. package/dist/Layer/index.d.ts +4 -2
  127. package/dist/Layer/index.d.ts.map +1 -1
  128. package/dist/Layer/index.js +2 -0
  129. package/dist/Layer/useLayer.d.ts.map +1 -1
  130. package/dist/Layer/useLayer.js +3 -2
  131. package/dist/Layer/useTouchTrigger.d.ts +113 -0
  132. package/dist/Layer/useTouchTrigger.d.ts.map +1 -0
  133. package/dist/Layer/useTouchTrigger.js +241 -0
  134. package/dist/Layout/container.stylex.d.ts +4 -2
  135. package/dist/Layout/container.stylex.d.ts.map +1 -1
  136. package/dist/Layout/container.stylex.js +19 -11
  137. package/dist/Layout/index.d.ts +1 -0
  138. package/dist/Layout/index.d.ts.map +1 -1
  139. package/dist/Layout/index.js +4 -0
  140. package/dist/Layout/padding.stylex.d.ts +315 -12
  141. package/dist/Layout/padding.stylex.d.ts.map +1 -1
  142. package/dist/Layout/padding.stylex.js +389 -12
  143. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  144. package/dist/Lightbox/Lightbox.js +5 -4
  145. package/dist/Link/Link.d.ts.map +1 -1
  146. package/dist/Link/Link.js +6 -6
  147. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  148. package/dist/MetadataList/MetadataList.js +1 -1
  149. package/dist/MobileNav/MobileNav.d.ts +1 -0
  150. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  151. package/dist/MobileNav/MobileNav.js +24 -6
  152. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  153. package/dist/MultiSelector/MultiSelector.js +8 -8
  154. package/dist/NavItem/navItemStyles.stylex.d.ts +4 -4
  155. package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
  156. package/dist/NavItem/navItemStyles.stylex.js +4 -4
  157. package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
  158. package/dist/NavMenu/NavHeadingMenuItem.js +3 -3
  159. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  160. package/dist/NumberInput/NumberInput.js +36 -8
  161. package/dist/Outline/Outline.d.ts.map +1 -1
  162. package/dist/Outline/Outline.js +3 -3
  163. package/dist/Pagination/Pagination.d.ts.map +1 -1
  164. package/dist/Pagination/Pagination.js +2 -2
  165. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  166. package/dist/PowerSearch/PowerSearch.js +11 -12
  167. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchToken.js +3 -1
  169. package/dist/PowerSearch/formatFilterValue.d.ts +11 -2
  170. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  171. package/dist/PowerSearch/formatFilterValue.js +23 -8
  172. package/dist/RadioList/RadioListItem.d.ts +2 -2
  173. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  174. package/dist/RadioList/RadioListItem.js +70 -40
  175. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  176. package/dist/Resizable/ResizeHandle.js +7 -7
  177. package/dist/Section/Section.d.ts +36 -1
  178. package/dist/Section/Section.d.ts.map +1 -1
  179. package/dist/Section/Section.js +12 -2
  180. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  181. package/dist/SegmentedControl/SegmentedControlItem.js +7 -2
  182. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  183. package/dist/SelectableCard/SelectableCard.js +3 -3
  184. package/dist/Selector/Selector.d.ts +26 -1
  185. package/dist/Selector/Selector.d.ts.map +1 -1
  186. package/dist/Selector/Selector.js +93 -20
  187. package/dist/Selector/SelectorOption.d.ts +14 -1
  188. package/dist/Selector/SelectorOption.d.ts.map +1 -1
  189. package/dist/Selector/SelectorOption.js +6 -0
  190. package/dist/Selector/SelectorRowLayoutContext.d.ts +8 -0
  191. package/dist/Selector/SelectorRowLayoutContext.d.ts.map +1 -0
  192. package/dist/Selector/SelectorRowLayoutContext.js +27 -0
  193. package/dist/Selector/types.d.ts +1 -0
  194. package/dist/Selector/types.d.ts.map +1 -1
  195. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  196. package/dist/SideNav/SideNavHeading.js +4 -4
  197. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  198. package/dist/SideNav/SideNavItem.js +3 -3
  199. package/dist/Slider/Slider.d.ts.map +1 -1
  200. package/dist/Slider/Slider.js +7 -7
  201. package/dist/Stack/Stack.d.ts +23 -1
  202. package/dist/Stack/Stack.d.ts.map +1 -1
  203. package/dist/Stack/Stack.js +12 -6
  204. package/dist/Switch/Switch.d.ts.map +1 -1
  205. package/dist/Switch/Switch.js +2 -2
  206. package/dist/TabList/Tab.d.ts.map +1 -1
  207. package/dist/TabList/Tab.js +1 -1
  208. package/dist/TabList/TabMenu.d.ts.map +1 -1
  209. package/dist/TabList/TabMenu.js +3 -3
  210. package/dist/Table/TableRow.js +4 -4
  211. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  212. package/dist/Table/plugins/columnResize/useTableColumnResize.js +1 -1
  213. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  214. package/dist/Table/plugins/filtering/useTableFiltering.js +2 -2
  215. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  216. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +2 -2
  217. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  218. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +2 -2
  219. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  220. package/dist/Table/plugins/sortable/useTableSortable.js +1 -1
  221. package/dist/Table/plugins/sortable/useTableSortableState.d.ts +5 -3
  222. package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
  223. package/dist/Table/plugins/sortable/useTableSortableState.js +12 -9
  224. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  225. package/dist/Table/plugins/tree/useTableTreeData.js +3 -3
  226. package/dist/TextArea/TextArea.js +1 -1
  227. package/dist/TextInput/TextInput.js +1 -1
  228. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  229. package/dist/Thumbnail/Thumbnail.js +3 -3
  230. package/dist/TimeInput/TimeInput.js +2 -2
  231. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  232. package/dist/Timestamp/Timestamp.js +6 -4
  233. package/dist/Timestamp/formatInstant.d.ts +3 -2
  234. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  235. package/dist/Timestamp/formatInstant.js +8 -8
  236. package/dist/Timestamp/tooltipEntries.d.ts +2 -1
  237. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -1
  238. package/dist/Timestamp/tooltipEntries.js +5 -3
  239. package/dist/Toast/Toast.d.ts +4 -3
  240. package/dist/Toast/Toast.d.ts.map +1 -1
  241. package/dist/Toast/Toast.js +10 -7
  242. package/dist/Token/Token.d.ts.map +1 -1
  243. package/dist/Token/Token.js +6 -6
  244. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  245. package/dist/Tokenizer/Tokenizer.js +1 -1
  246. package/dist/Tooltip/Tooltip.d.ts +16 -3
  247. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  248. package/dist/Tooltip/Tooltip.js +2 -0
  249. package/dist/Tooltip/index.d.ts +1 -1
  250. package/dist/Tooltip/index.d.ts.map +1 -1
  251. package/dist/Tooltip/useTooltip.d.ts +21 -2
  252. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  253. package/dist/Tooltip/useTooltip.js +71 -13
  254. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  255. package/dist/TopNav/TopNavHeading.js +4 -4
  256. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavItem.js +3 -3
  258. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  259. package/dist/TopNav/TopNavMegaMenu.js +2 -2
  260. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  261. package/dist/TopNav/TopNavMegaMenuItem.js +2 -2
  262. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  263. package/dist/TopNav/TopNavMenu.js +4 -4
  264. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  265. package/dist/TreeList/TreeListItem.js +7 -7
  266. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  267. package/dist/Typeahead/BaseTypeahead.js +2 -2
  268. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  269. package/dist/Typeahead/Typeahead.js +1 -1
  270. package/dist/astryx.css +124 -62
  271. package/dist/hooks/containerReveal.stylex.d.ts.map +1 -1
  272. package/dist/hooks/containerReveal.stylex.js +18 -18
  273. package/dist/hooks/scrollbarGutter.d.ts +28 -0
  274. package/dist/hooks/scrollbarGutter.d.ts.map +1 -0
  275. package/dist/hooks/scrollbarGutter.js +103 -0
  276. package/dist/hooks/useAutoMediaMode.d.ts +31 -0
  277. package/dist/hooks/useAutoMediaMode.d.ts.map +1 -0
  278. package/dist/hooks/useAutoMediaMode.js +201 -0
  279. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  280. package/dist/hooks/useInputStatusIcon.js +1 -1
  281. package/dist/hooks/useListFocus.d.ts +5 -2
  282. package/dist/hooks/useListFocus.d.ts.map +1 -1
  283. package/dist/hooks/useListFocus.js +12 -6
  284. package/dist/hooks/useScrollLock.d.ts +4 -0
  285. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  286. package/dist/hooks/useScrollLock.js +13 -1
  287. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  288. package/dist/i18n/InternationalizationContext.js +2 -0
  289. package/dist/i18n/index.d.ts +6 -0
  290. package/dist/i18n/index.d.ts.map +1 -1
  291. package/dist/i18n/index.js +6 -0
  292. package/dist/i18n/useCollator.d.ts +12 -0
  293. package/dist/i18n/useCollator.d.ts.map +1 -0
  294. package/dist/i18n/useCollator.js +40 -0
  295. package/dist/i18n/useLocale.d.ts +3 -0
  296. package/dist/i18n/useLocale.d.ts.map +1 -0
  297. package/dist/i18n/useLocale.js +31 -0
  298. package/dist/theme/MediaTheme.d.ts +25 -5
  299. package/dist/theme/MediaTheme.d.ts.map +1 -1
  300. package/dist/theme/MediaTheme.js +31 -6
  301. package/dist/theme/defineTheme.d.ts +5 -0
  302. package/dist/theme/defineTheme.d.ts.map +1 -1
  303. package/dist/theme/defineTheme.js +5 -0
  304. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  305. package/dist/theme/derivedVarRegistry.js +7 -0
  306. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  307. package/dist/theme/generateThemeRules.js +66 -5
  308. package/dist/theme/index.d.ts +1 -1
  309. package/dist/theme/index.d.ts.map +1 -1
  310. package/dist/theme/syntax/index.d.ts +6 -0
  311. package/dist/theme/syntax/index.d.ts.map +1 -1
  312. package/dist/theme/syntax/index.js +7 -2
  313. package/dist/utils/dateParser.d.ts +4 -3
  314. package/dist/utils/dateParser.d.ts.map +1 -1
  315. package/dist/utils/dateParser.js +8 -8
  316. package/dist/utils/index.d.ts +1 -1
  317. package/dist/utils/index.d.ts.map +1 -1
  318. package/dist/utils/index.js +1 -1
  319. package/dist/utils/plainDate.d.ts +5 -2
  320. package/dist/utils/plainDate.d.ts.map +1 -1
  321. package/dist/utils/plainDate.js +20 -4
  322. package/locales/en.json +28 -0
  323. package/locales/pseudo.json +21 -0
  324. package/package.json +3 -3
  325. package/src/Avatar/Avatar.doc.mjs +10 -6
  326. package/src/Avatar/Avatar.test.tsx +219 -1
  327. package/src/Avatar/Avatar.tsx +179 -37
  328. package/src/Avatar/AvatarStatusDot.tsx +30 -4
  329. package/src/Avatar/AvatarStatusLabelContext.ts +47 -0
  330. package/src/AvatarGroup/AvatarGroup.doc.mjs +10 -6
  331. package/src/AvatarGroup/AvatarGroup.test.tsx +62 -0
  332. package/src/AvatarGroup/AvatarGroup.tsx +3 -1
  333. package/src/AvatarGroup/AvatarGroupOverflow.tsx +31 -8
  334. package/src/Banner/Banner.doc.mjs +2 -0
  335. package/src/Blockquote/Blockquote.doc.mjs +30 -7
  336. package/src/Blockquote/Blockquote.test.tsx +34 -3
  337. package/src/Blockquote/Blockquote.tsx +11 -9
  338. package/src/BottomSheet/BottomSheet.doc.mjs +3 -3
  339. package/src/BottomSheet/BottomSheet.test.tsx +24 -0
  340. package/src/BottomSheet/BottomSheetPanel.test.tsx +91 -0
  341. package/src/BottomSheet/BottomSheetPanel.tsx +58 -3
  342. package/src/Breadcrumbs/BreadcrumbItem.tsx +36 -23
  343. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +26 -2
  344. package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -0
  345. package/src/Button/Button.tsx +12 -9
  346. package/src/Calendar/Calendar.tsx +15 -9
  347. package/src/Calendar/hooks/useCalendarNavigation.ts +6 -4
  348. package/src/Calendar/styles.ts +8 -5
  349. package/src/Center/Center.doc.mjs +48 -0
  350. package/src/Center/Center.test.tsx +158 -0
  351. package/src/Center/Center.tsx +50 -9
  352. package/src/Chat/ChatComposer.tsx +11 -5
  353. package/src/Chat/ChatComposerDrawer.tsx +4 -1
  354. package/src/Chat/ChatToolCalls.tsx +13 -4
  355. package/src/Chat/{useChatDictation.test.ts → useChatDictation.test.tsx} +29 -14
  356. package/src/Chat/useChatDictation.ts +1 -1
  357. package/src/Chat/useSpeechRecognition.ts +5 -3
  358. package/src/Chat/useTriggerMenu.tsx +4 -1
  359. package/src/CheckboxInput/CheckboxInput.tsx +5 -2
  360. package/src/Citation/Citation.test.tsx +6 -1
  361. package/src/Citation/Citation.tsx +11 -5
  362. package/src/ClickableCard/ClickableCard.tsx +7 -4
  363. package/src/CodeBlock/CodeBlock.tsx +4 -1
  364. package/src/Collapsible/Collapsible.tsx +5 -2
  365. package/src/CommandPalette/CommandPaletteItem.tsx +6 -3
  366. package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -0
  367. package/src/ComplexSelector/ComplexSelector.tsx +14 -7
  368. package/src/DateInput/DateInput.test.tsx +17 -1
  369. package/src/DateInput/DateInput.tsx +93 -21
  370. package/src/DateInput/DateInputTouch.test.tsx +2582 -0
  371. package/src/DateInput/MonthScroller.tsx +878 -0
  372. package/src/DateInput/MonthYearWheels.tsx +147 -0
  373. package/src/DateInput/TouchDateField.tsx +1223 -0
  374. package/src/DateInput/Wheel.tsx +473 -0
  375. package/src/DateInput/monthGeometry.ts +118 -0
  376. package/src/DateInput/tokens.stylex.ts +99 -0
  377. package/src/DateInput/useOwnScrollGesture.ts +227 -0
  378. package/src/DateInput/usePointerDragScroll.ts +220 -0
  379. package/src/DateInput/useScrollSettle.ts +164 -0
  380. package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
  381. package/src/DateRangeInput/DateRangeInput.tsx +31 -13
  382. package/src/DateTimeInput/DateTimeInput.tsx +25 -9
  383. package/src/Dialog/Dialog.test.tsx +24 -0
  384. package/src/Dialog/Dialog.tsx +3 -0
  385. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +5 -2
  386. package/src/DropdownMenu/DropdownMenuItem.tsx +5 -2
  387. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +5 -2
  388. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +5 -2
  389. package/src/Field/Field.doc.mjs +2 -0
  390. package/src/Field/FieldLabel.tsx +9 -3
  391. package/src/Field/InputClearButton.test.tsx +110 -3
  392. package/src/Field/InputClearButton.tsx +38 -0
  393. package/src/Field/inputStyles.stylex.ts +17 -13
  394. package/src/FileInput/FileInput.tsx +15 -8
  395. package/src/FormLayout/FormLayout.doc.mjs +1 -1
  396. package/src/HoverCard/HoverCard.doc.mjs +18 -0
  397. package/src/HoverCard/HoverCard.test.tsx +189 -0
  398. package/src/HoverCard/HoverCard.tsx +22 -2
  399. package/src/HoverCard/index.ts +1 -0
  400. package/src/HoverCard/useHoverCard.doc.mjs +2 -0
  401. package/src/HoverCard/useHoverCard.tsx +103 -7
  402. package/src/InputGroup/InputGroup.tsx +1 -1
  403. package/src/Item/Item.doc.mjs +1 -0
  404. package/src/Item/Item.test.tsx +50 -0
  405. package/src/Item/Item.tsx +54 -6
  406. package/src/Layer/index.ts +10 -0
  407. package/src/Layer/useLayer.tsx +13 -2
  408. package/src/Layer/useTouchTrigger.test.ts +70 -0
  409. package/src/Layer/useTouchTrigger.ts +366 -0
  410. package/src/Layout/Layout.doc.mjs +18 -0
  411. package/src/Layout/container.stylex.ts +11 -3
  412. package/src/Layout/index.ts +4 -0
  413. package/src/Layout/overlayPaddingReset.test.tsx +222 -0
  414. package/src/Layout/padding.stylex.ts +192 -12
  415. package/src/Lightbox/Lightbox.tsx +11 -3
  416. package/src/Link/Link.tsx +9 -6
  417. package/src/MetadataList/MetadataList.tsx +4 -1
  418. package/src/MobileNav/MobileNav.tsx +61 -5
  419. package/src/MobileNav/MobileNavEntryAnimation.test.tsx +212 -0
  420. package/src/MobileNav/MobileNavScrollbarGutter.test.tsx +109 -0
  421. package/src/MultiSelector/MultiSelector.test.tsx +1 -1
  422. package/src/MultiSelector/MultiSelector.tsx +26 -10
  423. package/src/NavItem/navItemStyles.stylex.ts +7 -4
  424. package/src/NavMenu/NavHeadingMenuItem.tsx +6 -3
  425. package/src/NumberInput/NumberInput.doc.mjs +24 -0
  426. package/src/NumberInput/NumberInput.test.tsx +138 -0
  427. package/src/NumberInput/NumberInput.tsx +47 -8
  428. package/src/Outline/Outline.tsx +5 -2
  429. package/src/Pagination/Pagination.tsx +5 -2
  430. package/src/Popover/Popover.test.tsx +27 -1
  431. package/src/PowerSearch/PowerSearch.tsx +17 -8
  432. package/src/PowerSearch/PowerSearchToken.tsx +3 -0
  433. package/src/PowerSearch/formatFilterValue.test.ts +22 -2
  434. package/src/PowerSearch/formatFilterValue.ts +31 -6
  435. package/src/RadioList/RadioList.doc.mjs +1 -1
  436. package/src/RadioList/RadioList.test.tsx +170 -2
  437. package/src/RadioList/RadioListItem.tsx +88 -53
  438. package/src/Resizable/ResizeHandle.test.tsx +22 -0
  439. package/src/Resizable/ResizeHandle.tsx +25 -7
  440. package/src/Section/Section.doc.mjs +55 -0
  441. package/src/Section/Section.test.tsx +201 -4
  442. package/src/Section/Section.tsx +69 -0
  443. package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
  444. package/src/SegmentedControl/SegmentedControlItem.tsx +15 -3
  445. package/src/SelectableCard/SelectableCard.tsx +6 -3
  446. package/src/Selector/Selector.doc.mjs +16 -2
  447. package/src/Selector/Selector.test.tsx +525 -1
  448. package/src/Selector/Selector.tsx +180 -25
  449. package/src/Selector/SelectorOption.doc.mjs +7 -0
  450. package/src/Selector/SelectorOption.tsx +21 -0
  451. package/src/Selector/SelectorRowLayoutContext.ts +32 -0
  452. package/src/Selector/types.ts +4 -4
  453. package/src/SideNav/SideNavHeading.tsx +14 -5
  454. package/src/SideNav/SideNavItem.tsx +9 -3
  455. package/src/Slider/Slider.tsx +25 -6
  456. package/src/Stack/Stack.doc.mjs +72 -0
  457. package/src/Stack/Stack.test.tsx +156 -0
  458. package/src/Stack/Stack.tsx +50 -8
  459. package/src/Switch/Switch.tsx +5 -2
  460. package/src/TabList/Tab.tsx +4 -1
  461. package/src/TabList/TabMenu.tsx +9 -3
  462. package/src/Table/TableRow.tsx +4 -4
  463. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +6 -2
  464. package/src/Table/plugins/filtering/useTableFiltering.tsx +4 -1
  465. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +10 -3
  466. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +6 -3
  467. package/src/Table/plugins/sortable/useTableSortable.tsx +4 -1
  468. package/src/Table/plugins/sortable/useTableSortableState.test.tsx +34 -0
  469. package/src/Table/plugins/sortable/useTableSortableState.tsx +26 -23
  470. package/src/Table/plugins/tree/useTableTreeData.tsx +10 -4
  471. package/src/TextArea/TextArea.doc.mjs +1 -1
  472. package/src/TextArea/TextArea.tsx +1 -1
  473. package/src/TextInput/TextInput.tsx +1 -1
  474. package/src/Thumbnail/Thumbnail.tsx +9 -3
  475. package/src/TimeInput/TimeInput.tsx +1 -1
  476. package/src/Timestamp/Timestamp.test.tsx +27 -7
  477. package/src/Timestamp/Timestamp.tsx +8 -4
  478. package/src/Timestamp/formatInstant.ts +9 -7
  479. package/src/Timestamp/tooltipEntries.test.ts +11 -6
  480. package/src/Timestamp/tooltipEntries.ts +6 -2
  481. package/src/Toast/Toast.tsx +9 -7
  482. package/src/Token/Token.tsx +14 -5
  483. package/src/Tokenizer/Tokenizer.tsx +4 -1
  484. package/src/Tooltip/Tooltip.doc.mjs +18 -0
  485. package/src/Tooltip/Tooltip.test.tsx +254 -1
  486. package/src/Tooltip/Tooltip.tsx +22 -2
  487. package/src/Tooltip/index.ts +1 -0
  488. package/src/Tooltip/useTooltip.doc.mjs +2 -0
  489. package/src/Tooltip/useTooltip.tsx +99 -21
  490. package/src/TopNav/TopNavHeading.tsx +13 -4
  491. package/src/TopNav/TopNavItem.tsx +6 -3
  492. package/src/TopNav/TopNavMegaMenu.tsx +5 -2
  493. package/src/TopNav/TopNavMegaMenuItem.tsx +5 -2
  494. package/src/TopNav/TopNavMenu.tsx +10 -4
  495. package/src/TreeList/TreeListItem.tsx +22 -7
  496. package/src/Typeahead/BaseTypeahead.tsx +5 -2
  497. package/src/Typeahead/Typeahead.tsx +4 -1
  498. package/src/hooks/containerReveal.stylex.ts +54 -18
  499. package/src/hooks/scrollbarGutter.test.ts +167 -0
  500. package/src/hooks/scrollbarGutter.ts +121 -0
  501. package/src/hooks/useAutoMediaMode.test.ts +109 -0
  502. package/src/hooks/useAutoMediaMode.ts +233 -0
  503. package/src/hooks/useInputStatusIcon.tsx +4 -1
  504. package/src/hooks/useListFocus.doc.mjs +2 -2
  505. package/src/hooks/useListFocus.test.tsx +65 -3
  506. package/src/hooks/useListFocus.ts +15 -7
  507. package/src/hooks/useScrollLock.doc.mjs +4 -4
  508. package/src/hooks/useScrollLock.test.ts +73 -0
  509. package/src/hooks/useScrollLock.ts +14 -0
  510. package/src/i18n/InternationalizationContext.ts +2 -0
  511. package/src/i18n/__tests__/e2e-powersearch.test.tsx +37 -1
  512. package/src/i18n/__tests__/useCollator.test.tsx +115 -0
  513. package/src/i18n/__tests__/useLocale.test.tsx +52 -0
  514. package/src/i18n/index.ts +6 -0
  515. package/src/i18n/useCollator.doc.mjs +84 -0
  516. package/src/i18n/useCollator.ts +44 -0
  517. package/src/i18n/useLocale.doc.mjs +70 -0
  518. package/src/i18n/useLocale.ts +34 -0
  519. package/src/i18n/useTranslator.doc.mjs +1 -1
  520. package/src/reset.css +9 -2
  521. package/src/reset.test.ts +22 -0
  522. package/src/theme/MediaTheme.doc.mjs +23 -4
  523. package/src/theme/MediaTheme.dom.test.tsx +97 -0
  524. package/src/theme/MediaTheme.tsx +42 -7
  525. package/src/theme/defineTheme.test.ts +9 -3
  526. package/src/theme/defineTheme.ts +5 -0
  527. package/src/theme/derivedVarRegistry.test.ts +19 -5
  528. package/src/theme/derivedVarRegistry.ts +4 -0
  529. package/src/theme/generateThemeRules.test.ts +118 -0
  530. package/src/theme/generateThemeRules.ts +83 -5
  531. package/src/theme/index.ts +1 -1
  532. package/src/theme/syntax/index.ts +6 -2
  533. package/src/theme/syntax/serverSafeSyntax.test.ts +68 -0
  534. package/src/utils/dateParser.test.ts +20 -0
  535. package/src/utils/dateParser.ts +14 -7
  536. package/src/utils/index.ts +2 -0
  537. package/src/utils/plainDate.test.ts +6 -0
  538. package/src/utils/plainDate.ts +21 -4
@@ -46,12 +46,30 @@ function componentClassSelector(component: string, suffix: string): string {
46
46
  return `.${classPrefix}-${component}${suffix}`;
47
47
  }
48
48
 
49
+ /**
50
+ * Guard appended to a themed `:hover` rule so it cannot match a disabled
51
+ * element.
52
+ *
53
+ * A theme authoring `':hover': {backgroundColor: …}` is describing the
54
+ * enabled control; `:hover` on its own would paint that background on a
55
+ * disabled one too, because browsers suppress a disabled control's events,
56
+ * not its hover styling. `:where()` contributes no specificity, so a themed
57
+ * hover rule still weighs exactly what it weighed before.
58
+ *
59
+ * Mirrors the `@astryx/no-hover-on-disabled` lint rule, which enforces the
60
+ * same guard on the components' own StyleX styles.
61
+ */
62
+ const HOVER_DISABLED_GUARD = ':where(:not(:disabled,[aria-disabled="true"]))';
63
+
49
64
  /**
50
65
  * Append a pseudo-class to every selector in a comma-separated selector list.
51
66
  *
52
67
  * Selector helpers may emit comma-separated lists. CSS does not distribute a
53
68
  * trailing pseudo over selector lists, so `${list}:hover` would only target the
54
69
  * final selector. Rewrite each item so the pseudo applies to all of them.
70
+ *
71
+ * A `:hover` pseudo also picks up the disabled guard. A pseudo-ELEMENT has to
72
+ * end the selector, so the guard is spliced in before it.
55
73
  */
56
74
  function appendPseudoToSelectorList(selector: string, pseudo: string): string {
57
75
  const parts: string[] = [];
@@ -71,7 +89,22 @@ function appendPseudoToSelectorList(selector: string, pseudo: string): string {
71
89
  }
72
90
  parts.push(selector.slice(start).trim());
73
91
 
74
- return parts.map(part => `${part}${pseudo}`).join(', ');
92
+ const guarded = guardHoverPseudo(pseudo);
93
+
94
+ return parts.map(part => `${part}${guarded}`).join(', ');
95
+ }
96
+
97
+ /** Insert the disabled guard into a `:hover` pseudo, keeping any pseudo-element last. */
98
+ function guardHoverPseudo(pseudo: string): string {
99
+ if (!/^:hover(?![-\w])/.test(pseudo) || pseudo.includes('[aria-disabled')) {
100
+ return pseudo;
101
+ }
102
+ const pseudoElement = pseudo.indexOf('::');
103
+ return pseudoElement === -1
104
+ ? pseudo + HOVER_DISABLED_GUARD
105
+ : pseudo.slice(0, pseudoElement) +
106
+ HOVER_DISABLED_GUARD +
107
+ pseudo.slice(pseudoElement);
75
108
  }
76
109
 
77
110
  // =============================================================================
@@ -128,6 +161,34 @@ const PADDING_PROPS = new Set([
128
161
  'paddingInlineEnd',
129
162
  ]);
130
163
 
164
+ /**
165
+ * Physical block-axis longhands, and the logical longhand each one *is* in
166
+ * every horizontal writing mode. Normalizing them costs no direction
167
+ * assumption, which is why they can join the container expansion.
168
+ *
169
+ * `paddingLeft`/`paddingRight` are deliberately absent. They are
170
+ * direction-relative — left is inline-start in LTR and inline-end in RTL — and
171
+ * the expansion's tokens are consumed by logical properties, so mapping them
172
+ * would put the padding on the opposite edge in RTL. They keep their physical
173
+ * meaning and land on the element as `padding-left`/`padding-right`; the cost
174
+ * is that a component's internals cannot see them.
175
+ */
176
+ const PHYSICAL_BLOCK_PADDING_PROPS: Record<string, string> = {
177
+ paddingTop: 'paddingBlockStart',
178
+ paddingBottom: 'paddingBlockEnd',
179
+ };
180
+
181
+ /**
182
+ * Every padding spelling the container expansion consumes. Kept separate from
183
+ * PADDING_PROPS, which also routes longhands to `vars`-style derived entries —
184
+ * those carry one value for the whole box, so a single physical edge must not
185
+ * reach them.
186
+ */
187
+ const CONTAINER_PADDING_PROPS = new Set([
188
+ ...PADDING_PROPS,
189
+ ...Object.keys(PHYSICAL_BLOCK_PADDING_PROPS),
190
+ ]);
191
+
131
192
  interface ParsedPadding {
132
193
  blockStart?: string;
133
194
  blockEnd?: string;
@@ -138,12 +199,14 @@ interface ParsedPadding {
138
199
 
139
200
  /**
140
201
  * Parse CSS padding shorthand/longhand into block/inline values.
141
- * Supports 1-3 value shorthands and logical properties.
202
+ * Supports 1-3 value shorthands, logical properties, and the physical block
203
+ * longhands normalized by PHYSICAL_BLOCK_PADDING_PROPS.
142
204
  */
143
205
  function parsePadding(props: [string, string][]): ParsedPadding {
144
206
  const result: ParsedPadding = {};
145
207
 
146
- for (const [prop, value] of props) {
208
+ for (const [rawProp, value] of props) {
209
+ const prop = PHYSICAL_BLOCK_PADDING_PROPS[rawProp] ?? rawProp;
147
210
  switch (prop) {
148
211
  case 'padding': {
149
212
  const parts = value.trim().split(/\s+/);
@@ -377,13 +440,28 @@ function generateComponentRules(
377
440
  }
378
441
  }
379
442
  }
443
+ // A physical block longhand reaches the container expansion only. It
444
+ // names one edge, so it must not feed a `vars` entry above, which
445
+ // carries the padding for the whole box.
446
+ if (
447
+ prop in PHYSICAL_BLOCK_PADDING_PROPS &&
448
+ getDerivedVars(component, 'padding').some(
449
+ e => e.expand === 'container',
450
+ )
451
+ ) {
452
+ containerExpanded = true;
453
+ }
380
454
  }
381
455
 
382
456
  // Container padding expansion: replace padding props with
383
457
  // component-scoped container tokens for layout integration.
384
458
  if (containerExpanded) {
385
- const paddingProps = props.filter(([p]) => PADDING_PROPS.has(p));
386
- const nonPaddingProps = props.filter(([p]) => !PADDING_PROPS.has(p));
459
+ const paddingProps = props.filter(([p]) =>
460
+ CONTAINER_PADDING_PROPS.has(p),
461
+ );
462
+ const nonPaddingProps = props.filter(
463
+ ([p]) => !CONTAINER_PADDING_PROPS.has(p),
464
+ );
387
465
  const parsed = parsePadding(paddingProps);
388
466
  const containerTokens = expandContainerPadding(component, parsed);
389
467
  finalProps = [...nonPaddingProps, ...containerTokens];
@@ -17,7 +17,7 @@
17
17
 
18
18
  export {Theme} from './Theme';
19
19
  export {MediaTheme} from './MediaTheme';
20
- export type {MediaThemeProps} from './MediaTheme';
20
+ export type {MediaThemeProps, MediaThemeMode} from './MediaTheme';
21
21
  export {
22
22
  defineTheme,
23
23
  generateThemeCSS,
@@ -1,10 +1,14 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
- 'use client';
4
-
5
3
  /**
6
4
  * @file syntax/index.ts
7
5
  * @position Re-exports for the syntax theme subsystem
6
+ *
7
+ * No `'use client'` here on purpose. Most of what this barrel exports is data
8
+ * (presets, token defaults) or pure functions, and a directive on the barrel
9
+ * turns every export into a client reference for a server importer — so
10
+ * `dracula.tokens` reads back `undefined` instead of colors. `SyntaxTheme.tsx`
11
+ * carries its own directive, which is what the provider actually needs.
8
12
  */
9
13
 
10
14
  export {syntaxTokenDefaults} from './tokens';
@@ -0,0 +1,68 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Guards the server-safety of the `./theme/syntax` subpath.
5
+ * @input Reads the source files in this directory
6
+ * @output One invariant per module: only the provider carries `'use client'`
7
+ * @position Narrow sibling of src/serverSafeComponents.test.ts, which only
8
+ * walks `./src/<Name>/index.ts` subpaths and so never sees this directory.
9
+ *
10
+ * `./theme/syntax` is the only export subpath for the syntax module, and it
11
+ * mixes a provider with presets, token defaults and pure functions. A
12
+ * directive on the barrel makes React hand a server importer a client
13
+ * reference for every one of those exports, so `dracula.tokens` reads back
14
+ * `undefined` — a silent failure far from its cause.
15
+ */
16
+
17
+ import {describe, it, expect} from 'vitest';
18
+ import {readdirSync, readFileSync} from 'node:fs';
19
+ import {join} from 'node:path';
20
+
21
+ /**
22
+ * The directives at the top of a module, in order. Comments and blank lines
23
+ * may precede them; the prologue ends at the first statement that is not a
24
+ * bare string literal, so a `'use strict';` cannot hide a later directive.
25
+ */
26
+ function directives(file: string): string[] {
27
+ const source = readFileSync(join(__dirname, file), 'utf-8');
28
+ const found: string[] = [];
29
+ let rest = source;
30
+ for (;;) {
31
+ const trimmed = rest.replace(/^(?:\s+|\/\/[^\n]*|\/\*[\s\S]*?\*\/)+/, '');
32
+ const directive = /^(['"])([^'"]*)\1\s*;?/.exec(trimmed);
33
+ if (!directive) {
34
+ return found;
35
+ }
36
+ found.push(directive[2]);
37
+ rest = trimmed.slice(directive[0].length);
38
+ }
39
+ }
40
+
41
+ /**
42
+ * The modules in this directory that legitimately need a client boundary.
43
+ * Everything else is data or pure functions and must stay directive-free —
44
+ * derived from the directory, so a module added here is covered by default.
45
+ */
46
+ const CLIENT_MODULES = ['SyntaxTheme.tsx'];
47
+
48
+ const serverSafeModules = readdirSync(__dirname)
49
+ .filter(
50
+ name =>
51
+ /\.[jt]sx?$/.test(name) &&
52
+ !/\.(test|stories|doc|perf)\./.test(name) &&
53
+ !name.endsWith('.d.ts') &&
54
+ !CLIENT_MODULES.includes(name),
55
+ )
56
+ .sort();
57
+
58
+ describe('./theme/syntax is importable from a server component', () => {
59
+ it.each(serverSafeModules)('%s carries no "use client"', file => {
60
+ expect(directives(file)).not.toContain('use client');
61
+ });
62
+
63
+ // Also the proof that the reader above is not blind, which would make every
64
+ // assertion in this file pass vacuously.
65
+ it.each(CLIENT_MODULES)('%s keeps the directive it needs', file => {
66
+ expect(directives(file)).toContain('use client');
67
+ });
68
+ });
@@ -277,6 +277,26 @@ describe('parseDateInput', () => {
277
277
  });
278
278
  });
279
279
 
280
+ describe('ambiguous numeric formats follow the passed locale (#5074)', () => {
281
+ // Both numbers are <= 12, so the day/month order is genuinely ambiguous
282
+ // and resolved by isLocaleDayFirst(locale) rather than the host locale.
283
+ it('reads month-first for en-US', () => {
284
+ expect(parseDateInput('3/4/2026', 'en-US')).toEqual({
285
+ year: 2026,
286
+ month: 3,
287
+ day: 4,
288
+ });
289
+ });
290
+
291
+ it('reads day-first for es-ES', () => {
292
+ expect(parseDateInput('3/4/2026', 'es-ES')).toEqual({
293
+ year: 2026,
294
+ month: 4,
295
+ day: 3,
296
+ });
297
+ });
298
+ });
299
+
280
300
  describe('edge cases', () => {
281
301
  it('returns null for empty string', () => {
282
302
  expect(parseDateInput('')).toBeNull();
@@ -12,6 +12,7 @@
12
12
  */
13
13
 
14
14
  import {type PlainDate, plainDateCreate, plainDateFromDate} from './plainDate';
15
+ import type {Locale} from '../i18n/types';
15
16
 
16
17
  export {
17
18
  plainDateFromISO as parseISO,
@@ -19,11 +20,13 @@ export {
19
20
  } from './plainDate';
20
21
 
21
22
  /**
22
- * Detects if the user's locale uses day-first date format (DD/MM/YYYY).
23
+ * Detects if the locale uses day-first date format (DD/MM/YYYY).
23
24
  * US and a few others use month-first (MM/DD/YYYY).
24
25
  */
25
- export function isLocaleDayFirst(): boolean {
26
- const parts = new Intl.DateTimeFormat().formatToParts(new Date(2000, 0, 15));
26
+ export function isLocaleDayFirst(locale?: Locale): boolean {
27
+ const parts = new Intl.DateTimeFormat(locale).formatToParts(
28
+ new Date(2000, 0, 15),
29
+ );
27
30
  const dayIndex = parts.findIndex(p => p.type === 'day');
28
31
  const monthIndex = parts.findIndex(p => p.type === 'month');
29
32
  return dayIndex < monthIndex;
@@ -43,7 +46,10 @@ export function isLocaleDayFirst(): boolean {
43
46
  *
44
47
  * @returns PlainDate if valid, null if unparseable
45
48
  */
46
- export function parseDateInput(input: string): PlainDate | null {
49
+ export function parseDateInput(
50
+ input: string,
51
+ locale?: Locale,
52
+ ): PlainDate | null {
47
53
  const trimmed = input.trim();
48
54
  if (!trimmed) {
49
55
  return null;
@@ -114,14 +120,14 @@ export function parseDateInput(input: string): PlainDate | null {
114
120
  if (sep1 !== sep2) {
115
121
  return null;
116
122
  }
117
- return parseNumericDate(+first, +second, +year);
123
+ return parseNumericDate(+first, +second, +year, locale);
118
124
  }
119
125
 
120
126
  // 5. Try numeric formats WITHOUT year (defaults to current year)
121
127
  const numericNoYearMatch = trimmed.match(/^(\d{1,2})[-/.](\d{1,2})$/);
122
128
  if (numericNoYearMatch) {
123
129
  const [, first, second] = numericNoYearMatch;
124
- return parseNumericDate(+first, +second, currentYear);
130
+ return parseNumericDate(+first, +second, currentYear, locale);
125
131
  }
126
132
 
127
133
  // 6. Fall back to native Date parsing for other formats.
@@ -151,6 +157,7 @@ function parseNumericDate(
151
157
  first: number,
152
158
  second: number,
153
159
  year: number,
160
+ locale?: Locale,
154
161
  ): PlainDate | null {
155
162
  let day: number;
156
163
  let month: number;
@@ -164,7 +171,7 @@ function parseNumericDate(
164
171
  } else if (first > 12 && second > 12) {
165
172
  return null;
166
173
  } else {
167
- if (isLocaleDayFirst()) {
174
+ if (isLocaleDayFirst(locale)) {
168
175
  day = first;
169
176
  month = second;
170
177
  } else {
@@ -47,6 +47,8 @@ export {
47
47
  DATE_FORMAT_SHORT_WITH_WEEKDAY,
48
48
  DATE_FORMAT_LONG,
49
49
  DATE_FORMAT_MONTH_YEAR,
50
+ DATE_FORMAT_MONTH_ONLY,
51
+ DATE_FORMAT_WEEKDAY_ONLY,
50
52
  DATE_FORMAT_SHORT,
51
53
  DATE_FORMAT_SHORT_WITH_YEAR,
52
54
  SHARED_DATE_FORMAT_OPTIONS,
@@ -610,4 +610,10 @@ describe('formatSharedDate', () => {
610
610
  it('formats the ISO "system_date" shape', () => {
611
611
  expect(formatSharedDate(pd, 'system_date')).toBe('2026-01-25');
612
612
  });
613
+
614
+ it('follows the passed locale rather than the host locale (#5074)', () => {
615
+ expect(formatSharedDate(pd, 'date_long', 'es-ES')).toBe(
616
+ '25 de enero de 2026',
617
+ );
618
+ });
613
619
  });
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  import type {ISODateString, PlainDate} from './dateTypes';
11
+ import type {Locale} from '../i18n/types';
11
12
 
12
13
  export type {PlainDate} from './dateTypes';
13
14
 
@@ -277,6 +278,22 @@ export const DATE_FORMAT_MONTH_YEAR: Intl.DateTimeFormatOptions = {
277
278
  month: 'long',
278
279
  };
279
280
 
281
+ // e.g. "Sun" (locale-dependent) — the weekday on its own, abbreviated.
282
+ //
283
+ // This is CLDR's `abbreviated` width, which `Intl` reaches natively. Note
284
+ // that Calendar's 2-letter header ("Su") is CLDR's *short* width, a
285
+ // different thing that `Intl` cannot express at all — which is why that one
286
+ // needs the generated lookup table beside it and this one does not.
287
+ export const DATE_FORMAT_WEEKDAY_ONLY: Intl.DateTimeFormatOptions = {
288
+ weekday: 'short',
289
+ };
290
+
291
+ // e.g. "January" (locale-dependent) — the month on its own, for a control
292
+ // that shows a list of months and carries the year separately.
293
+ export const DATE_FORMAT_MONTH_ONLY: Intl.DateTimeFormatOptions = {
294
+ month: 'long',
295
+ };
296
+
280
297
  // e.g. "Jan 25" (locale-dependent)
281
298
  export const DATE_FORMAT_SHORT: Intl.DateTimeFormatOptions = {
282
299
  month: 'short',
@@ -293,10 +310,9 @@ export const DATE_FORMAT_SHORT_WITH_YEAR: Intl.DateTimeFormatOptions = {
293
310
  export function plainDateFormat(
294
311
  pd: PlainDate,
295
312
  options: Intl.DateTimeFormatOptions,
313
+ locale?: Locale,
296
314
  ): string {
297
- return new Intl.DateTimeFormat(undefined, options).format(
298
- plainDateToDate(pd),
299
- );
315
+ return new Intl.DateTimeFormat(locale, options).format(plainDateToDate(pd));
300
316
  }
301
317
 
302
318
  // =============================================================================
@@ -344,9 +360,10 @@ export const SHARED_DATE_FORMAT_OPTIONS: Record<
344
360
  export function formatSharedDate(
345
361
  pd: PlainDate,
346
362
  format: SharedDateFormat,
363
+ locale?: Locale,
347
364
  ): string {
348
365
  if (format === 'system_date') {
349
366
  return plainDateToISO(pd);
350
367
  }
351
- return plainDateFormat(pd, SHARED_DATE_FORMAT_OPTIONS[format]);
368
+ return plainDateFormat(pd, SHARED_DATE_FORMAT_OPTIONS[format], locale);
352
369
  }