@astryxdesign/core 0.5.0 → 0.5.1-canary.046f6ea

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 (622) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +45 -20
  5. package/dist/AspectRatio/AspectRatio.d.ts +6 -6
  6. package/dist/Avatar/Avatar.d.ts +25 -1
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +43 -9
  9. package/dist/Avatar/index.d.ts +2 -2
  10. package/dist/Avatar/index.d.ts.map +1 -1
  11. package/dist/Avatar/index.js +1 -1
  12. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  13. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroup.js +5 -2
  15. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  16. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  17. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroupOverflow.js +11 -7
  19. package/dist/Badge/Badge.d.ts.map +1 -1
  20. package/dist/Badge/Badge.js +26 -2
  21. package/dist/Banner/Banner.d.ts +10 -1
  22. package/dist/Banner/Banner.d.ts.map +1 -1
  23. package/dist/Banner/Banner.js +11 -2
  24. package/dist/Button/Button.d.ts.map +1 -1
  25. package/dist/Button/Button.js +8 -7
  26. package/dist/Calendar/Calendar.d.ts +4 -2
  27. package/dist/Calendar/Calendar.d.ts.map +1 -1
  28. package/dist/Calendar/Calendar.js +15 -21
  29. package/dist/Calendar/hooks/useCalendarDays.js +4 -6
  30. package/dist/Calendar/hooks/useCalendarNavigation.js +4 -6
  31. package/dist/Calendar/styles.d.ts +5 -20
  32. package/dist/Calendar/styles.d.ts.map +1 -1
  33. package/dist/Calendar/styles.js +15 -17
  34. package/dist/Card/Card.d.ts +12 -12
  35. package/dist/Card/Card.d.ts.map +1 -1
  36. package/dist/Card/Card.js +17 -9
  37. package/dist/Card/index.d.ts +35 -1
  38. package/dist/Card/index.d.ts.map +1 -1
  39. package/dist/Card/index.js +21 -1
  40. package/dist/Carousel/Carousel.d.ts.map +1 -1
  41. package/dist/Carousel/Carousel.js +108 -7
  42. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  43. package/dist/CheckboxInput/CheckboxInput.js +7 -1
  44. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  45. package/dist/CodeBlock/CodeBlock.js +15 -4
  46. package/dist/CodeBlock/highlightRanges.js +1 -1
  47. package/dist/CodeBlock/highlightStyles.js +13 -13
  48. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  49. package/dist/CommandPalette/CommandPaletteItem.js +2 -7
  50. package/dist/ComplexSelector/ComplexSelector.d.ts +10 -2
  51. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  52. package/dist/ComplexSelector/ComplexSelector.js +14 -7
  53. package/dist/DateInput/DateInput.d.ts +43 -0
  54. package/dist/DateInput/DateInput.d.ts.map +1 -1
  55. package/dist/DateInput/DateInput.js +22 -5
  56. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  57. package/dist/DateInput/MonthScroller.js +5 -3
  58. package/dist/DateInput/MonthYearWheels.d.ts.map +1 -1
  59. package/dist/DateInput/MonthYearWheels.js +6 -4
  60. package/dist/DateInput/NativeDateField.d.ts +10 -0
  61. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  62. package/dist/DateInput/NativeDateField.js +494 -0
  63. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  64. package/dist/DateInput/TouchDateField.js +52 -25
  65. package/dist/DateInput/Wheel.d.ts.map +1 -1
  66. package/dist/DateInput/Wheel.js +1 -0
  67. package/dist/DateInput/index.d.ts +1 -1
  68. package/dist/DateInput/index.d.ts.map +1 -1
  69. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  70. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  71. package/dist/DateInput/nativeDateSegments.js +111 -0
  72. package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
  73. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  74. package/dist/DateRangeInput/DateRangeInput.js +3 -5
  75. package/dist/DateTimeInput/DateTimeInput.d.ts +23 -24
  76. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  77. package/dist/DateTimeInput/DateTimeInput.js +35 -10
  78. package/dist/DateTimeInput/TouchDateTimeField.d.ts +6 -0
  79. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -0
  80. package/dist/DateTimeInput/TouchDateTimeField.js +1021 -0
  81. package/dist/Dialog/Dialog.d.ts +16 -2
  82. package/dist/Dialog/Dialog.d.ts.map +1 -1
  83. package/dist/Dialog/Dialog.js +28 -7
  84. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  85. package/dist/DropdownMenu/DropdownMenu.js +4 -13
  86. package/dist/Field/FieldLabel.d.ts.map +1 -1
  87. package/dist/Field/FieldLabel.js +9 -1
  88. package/dist/Field/InputClearButton.d.ts +9 -3
  89. package/dist/Field/InputClearButton.d.ts.map +1 -1
  90. package/dist/Field/InputClearButton.js +14 -3
  91. package/dist/Heading/Heading.d.ts.map +1 -1
  92. package/dist/Heading/Heading.js +0 -1
  93. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  94. package/dist/HoverCard/HoverCard.js +104 -3
  95. package/dist/HoverCard/useHoverCard.d.ts +14 -2
  96. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  97. package/dist/HoverCard/useHoverCard.js +7 -1
  98. package/dist/Icon/Icon.d.ts +4 -2
  99. package/dist/Icon/Icon.d.ts.map +1 -1
  100. package/dist/Icon/defaultIcons.d.ts +3 -2
  101. package/dist/Icon/defaultIcons.d.ts.map +1 -1
  102. package/dist/Icon/defaultIcons.js +7 -0
  103. package/dist/Icon/globalIconRegistry.d.ts +13 -0
  104. package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
  105. package/dist/Icon/globalIconRegistry.js +34 -6
  106. package/dist/Icon/index.d.ts +1 -1
  107. package/dist/Icon/index.d.ts.map +1 -1
  108. package/dist/Icon/useIcon.d.ts +5 -2
  109. package/dist/Icon/useIcon.d.ts.map +1 -1
  110. package/dist/Icon/useIcon.js +3 -0
  111. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  112. package/dist/Indicator/CheckboxIndicator.js +6 -2
  113. package/dist/Item/Item.d.ts.map +1 -1
  114. package/dist/Item/Item.js +2 -2
  115. package/dist/Kbd/Kbd.d.ts.map +1 -1
  116. package/dist/Kbd/Kbd.js +2 -26
  117. package/dist/Layer/gestureCounter.d.ts +8 -0
  118. package/dist/Layer/gestureCounter.d.ts.map +1 -0
  119. package/dist/Layer/gestureCounter.js +53 -0
  120. package/dist/Layer/useLayer.d.ts +23 -13
  121. package/dist/Layer/useLayer.d.ts.map +1 -1
  122. package/dist/Layer/useLayer.js +146 -24
  123. package/dist/List/List.d.ts +1 -1
  124. package/dist/List/List.d.ts.map +1 -1
  125. package/dist/List/List.js +15 -4
  126. package/dist/Markdown/Markdown.d.ts +1 -1
  127. package/dist/Markdown/Markdown.d.ts.map +1 -1
  128. package/dist/Markdown/Markdown.js +20 -7
  129. package/dist/Markdown/parser.d.ts.map +1 -1
  130. package/dist/Markdown/parser.js +5 -3
  131. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  132. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  133. package/dist/MetadataList/MetadataListItem.js +4 -1
  134. package/dist/MultiSelector/MultiSelector.d.ts +18 -1
  135. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  136. package/dist/MultiSelector/MultiSelector.js +58 -11
  137. package/dist/MultiSelector/hooks.d.ts +7 -1
  138. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  139. package/dist/MultiSelector/hooks.js +3 -2
  140. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  141. package/dist/NavIcon/NavIcon.js +5 -1
  142. package/dist/NavItem/navItemStyles.stylex.d.ts +0 -8
  143. package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
  144. package/dist/NavItem/navItemStyles.stylex.js +0 -2
  145. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  146. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  147. package/dist/NavMenu/NavHeadingMenu.js +7 -4
  148. package/dist/NumberInput/NumberInput.d.ts +6 -1
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +95 -126
  151. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  152. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  153. package/dist/NumberInput/numberInputCommit.js +71 -0
  154. package/dist/NumberInput/numberParser.d.ts +64 -0
  155. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  156. package/dist/NumberInput/numberParser.js +350 -0
  157. package/dist/Outline/Outline.d.ts.map +1 -1
  158. package/dist/Outline/Outline.js +2 -3
  159. package/dist/OverflowList/OverflowList.d.ts +41 -1
  160. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  161. package/dist/OverflowList/OverflowList.js +43 -2
  162. package/dist/Popover/Popover.d.ts.map +1 -1
  163. package/dist/Popover/Popover.js +8 -14
  164. package/dist/Popover/usePopover.d.ts +15 -41
  165. package/dist/Popover/usePopover.d.ts.map +1 -1
  166. package/dist/Popover/usePopover.js +26 -7
  167. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchValueEditor.js +91 -18
  169. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  170. package/dist/PowerSearch/formatFilterValue.js +4 -2
  171. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  172. package/dist/ProgressBar/ProgressBar.js +18 -5
  173. package/dist/Resizable/useResizable.d.ts +19 -1
  174. package/dist/Resizable/useResizable.d.ts.map +1 -1
  175. package/dist/Resizable/useResizable.js +104 -38
  176. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  177. package/dist/SelectableCard/SelectableCard.js +9 -0
  178. package/dist/Selector/Selector.d.ts +18 -1
  179. package/dist/Selector/Selector.d.ts.map +1 -1
  180. package/dist/Selector/Selector.js +92 -21
  181. package/dist/Selector/hooks.d.ts +7 -1
  182. package/dist/Selector/hooks.d.ts.map +1 -1
  183. package/dist/Selector/hooks.js +3 -2
  184. package/dist/SideNav/SideNav.d.ts +6 -1
  185. package/dist/SideNav/SideNav.d.ts.map +1 -1
  186. package/dist/SideNav/SideNav.js +57 -27
  187. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  188. package/dist/SideNav/SideNavHeading.js +5 -4
  189. package/dist/SideNav/SideNavItem.d.ts +29 -4
  190. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  191. package/dist/SideNav/SideNavItem.js +75 -20
  192. package/dist/Slider/Slider.d.ts.map +1 -1
  193. package/dist/Slider/Slider.js +34 -2
  194. package/dist/Spinner/Spinner.d.ts +3 -1
  195. package/dist/Spinner/Spinner.d.ts.map +1 -1
  196. package/dist/Spinner/Spinner.js +199 -20
  197. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  198. package/dist/StatusDot/StatusDot.js +6 -1
  199. package/dist/Stepper/Step.d.ts.map +1 -1
  200. package/dist/Stepper/Step.js +7 -6
  201. package/dist/Switch/Switch.d.ts.map +1 -1
  202. package/dist/Switch/Switch.js +5 -1
  203. package/dist/Table/BaseTable.d.ts.map +1 -1
  204. package/dist/Table/BaseTable.js +6 -1
  205. package/dist/Table/Table.d.ts.map +1 -1
  206. package/dist/Table/Table.js +3 -6
  207. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  208. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  209. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
  210. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  211. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +34 -3
  212. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  213. package/dist/Table/plugins/selection/useTableSelection.js +25 -1
  214. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  215. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  216. package/dist/Text/Text.d.ts.map +1 -1
  217. package/dist/Text/Text.js +0 -1
  218. package/dist/TextArea/TextArea.d.ts.map +1 -1
  219. package/dist/TextArea/TextArea.js +13 -8
  220. package/dist/Timestamp/Timestamp.d.ts +1 -1
  221. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  222. package/dist/Timestamp/Timestamp.js +10 -18
  223. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  224. package/dist/Timestamp/formatInstant.js +10 -5
  225. package/dist/Toast/Toast.d.ts +17 -2
  226. package/dist/Toast/Toast.d.ts.map +1 -1
  227. package/dist/Toast/Toast.js +77 -11
  228. package/dist/Toast/ToastViewport.d.ts +1 -0
  229. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  230. package/dist/Toast/ToastViewport.js +76 -21
  231. package/dist/Toast/index.d.ts +1 -1
  232. package/dist/Toast/index.d.ts.map +1 -1
  233. package/dist/Toast/types.d.ts +38 -0
  234. package/dist/Toast/types.d.ts.map +1 -1
  235. package/dist/Toast/useToastGesture.d.ts +26 -0
  236. package/dist/Toast/useToastGesture.d.ts.map +1 -0
  237. package/dist/Toast/useToastGesture.js +223 -0
  238. package/dist/Token/Token.d.ts +1 -1
  239. package/dist/Token/Token.d.ts.map +1 -1
  240. package/dist/Token/Token.js +23 -12
  241. package/dist/Token/TokenLink.d.ts +1 -1
  242. package/dist/Token/TokenLink.d.ts.map +1 -1
  243. package/dist/Token/TokenLink.js +5 -2
  244. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  245. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  246. package/dist/Tokenizer/Tokenizer.js +31 -21
  247. package/dist/TopNav/TopNavHeading.js +2 -2
  248. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  249. package/dist/TopNav/TopNavItem.js +3 -3
  250. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  251. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  252. package/dist/TopNav/TopNavMegaMenu.js +30 -9
  253. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  254. package/dist/TopNav/TopNavMegaMenuItem.js +3 -3
  255. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  256. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMenu.js +21 -6
  258. package/dist/TreeList/TreeList.d.ts +1 -1
  259. package/dist/TreeList/TreeList.d.ts.map +1 -1
  260. package/dist/TreeList/TreeList.js +7 -2
  261. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  262. package/dist/TreeList/TreeListItem.js +2 -2
  263. package/dist/Typeahead/BaseTypeahead.d.ts +33 -0
  264. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  265. package/dist/Typeahead/BaseTypeahead.js +51 -8
  266. package/dist/Typeahead/Typeahead.d.ts +8 -1
  267. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  268. package/dist/Typeahead/Typeahead.js +2 -0
  269. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  270. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  271. package/dist/Typeahead/TypeaheadItem.js +7 -2
  272. package/dist/astryx.css +87 -22
  273. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  274. package/dist/hooks/useHotkeys.js +3 -25
  275. package/dist/hooks/useOverflow.d.ts.map +1 -1
  276. package/dist/hooks/useOverflow.js +14 -4
  277. package/dist/i18n/InternationalizationContext.d.ts +2 -0
  278. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  279. package/dist/i18n/InternationalizationContext.js +3 -1
  280. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  281. package/dist/i18n/InternationalizationProvider.js +3 -1
  282. package/dist/i18n/resolve.d.ts +1 -1
  283. package/dist/i18n/resolve.d.ts.map +1 -1
  284. package/dist/i18n/resolve.js +37 -38
  285. package/dist/i18n/useTranslator.d.ts.map +1 -1
  286. package/dist/i18n/useTranslator.js +2 -3
  287. package/dist/index.d.ts +1 -1
  288. package/dist/index.d.ts.map +1 -1
  289. package/dist/theme/Theme.d.ts.map +1 -1
  290. package/dist/theme/Theme.js +46 -10
  291. package/dist/theme/defineTheme.d.ts +9 -3
  292. package/dist/theme/defineTheme.d.ts.map +1 -1
  293. package/dist/theme/defineTheme.js +5 -0
  294. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  295. package/dist/theme/derivedVarRegistry.js +24 -4
  296. package/dist/theme/generateThemeRules.d.ts +21 -0
  297. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  298. package/dist/theme/generateThemeRules.js +26 -0
  299. package/dist/theme/syntax/tokens.d.ts +1 -1
  300. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  301. package/dist/theme/syntax/tokens.js +5 -2
  302. package/dist/theme/useTheme.d.ts.map +1 -1
  303. package/dist/theme/useTheme.js +6 -7
  304. package/dist/utils/dateParser.d.ts +5 -8
  305. package/dist/utils/dateParser.d.ts.map +1 -1
  306. package/dist/utils/dateParser.js +10 -11
  307. package/dist/utils/focusOutline.stylex.d.ts +25 -0
  308. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  309. package/dist/utils/focusOutline.stylex.js +15 -0
  310. package/dist/utils/interactionOverlay.stylex.d.ts +26 -0
  311. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -0
  312. package/dist/utils/interactionOverlay.stylex.js +42 -0
  313. package/dist/utils/isApplePlatform.d.ts +18 -0
  314. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  315. package/dist/utils/isApplePlatform.js +37 -0
  316. package/dist/utils/plainDate.d.ts +11 -0
  317. package/dist/utils/plainDate.d.ts.map +1 -1
  318. package/dist/utils/plainDate.js +20 -4
  319. package/locales/af-ZA.json +7 -7
  320. package/locales/ar-SA.json +7 -7
  321. package/locales/ca-ES.json +6 -6
  322. package/locales/cs-CZ.json +7 -7
  323. package/locales/da-DK.json +7 -7
  324. package/locales/de-DE.json +7 -7
  325. package/locales/el-GR.json +7 -7
  326. package/locales/en.json +178 -6
  327. package/locales/es-ES.json +6 -6
  328. package/locales/fi-FI.json +7 -7
  329. package/locales/fr-FR.json +7 -7
  330. package/locales/he-IL.json +7 -7
  331. package/locales/hu-HU.json +7 -7
  332. package/locales/it-IT.json +7 -7
  333. package/locales/ja-JP.json +7 -7
  334. package/locales/ko-KR.json +7 -7
  335. package/locales/nl-NL.json +7 -7
  336. package/locales/no-NO.json +7 -7
  337. package/locales/pl-PL.json +7 -7
  338. package/locales/pseudo.json +130 -1
  339. package/locales/pt-BR.json +7 -7
  340. package/locales/pt-PT.json +7 -7
  341. package/locales/ro-RO.json +7 -7
  342. package/locales/ru-RU.json +7 -7
  343. package/locales/sr-SP.json +7 -7
  344. package/locales/sv-SE.json +7 -7
  345. package/locales/tr-TR.json +7 -7
  346. package/locales/uk-UA.json +7 -7
  347. package/locales/vi-VN.json +7 -7
  348. package/locales/zh-CN.json +7 -7
  349. package/locales/zh-TW.json +7 -7
  350. package/package.json +4 -5
  351. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  352. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  353. package/src/AlertDialog/AlertDialog.tsx +62 -20
  354. package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
  355. package/src/AspectRatio/AspectRatio.tsx +6 -6
  356. package/src/Avatar/Avatar.doc.mjs +12 -2
  357. package/src/Avatar/Avatar.test.tsx +80 -0
  358. package/src/Avatar/Avatar.tsx +64 -14
  359. package/src/Avatar/index.ts +2 -2
  360. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  361. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  362. package/src/AvatarGroup/AvatarGroup.tsx +12 -4
  363. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  364. package/src/AvatarGroup/AvatarGroupOverflow.tsx +12 -12
  365. package/src/Badge/Badge.doc.mjs +3 -2
  366. package/src/Badge/Badge.test.tsx +32 -3
  367. package/src/Badge/Badge.tsx +42 -1
  368. package/src/Banner/Banner.doc.mjs +9 -0
  369. package/src/Banner/Banner.test.tsx +76 -11
  370. package/src/Banner/Banner.tsx +21 -2
  371. package/src/Button/Button.doc.mjs +2 -1
  372. package/src/Button/Button.test.tsx +19 -4
  373. package/src/Button/Button.tsx +9 -29
  374. package/src/ButtonGroup/ButtonGroup.doc.mjs +2 -2
  375. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -0
  376. package/src/Calendar/Calendar.doc.mjs +4 -4
  377. package/src/Calendar/Calendar.test.tsx +112 -0
  378. package/src/Calendar/Calendar.tsx +18 -16
  379. package/src/Calendar/hooks/useCalendarDays.ts +4 -4
  380. package/src/Calendar/hooks/useCalendarNavigation.ts +4 -4
  381. package/src/Calendar/styles.ts +48 -42
  382. package/src/Card/Card.doc.mjs +10 -7
  383. package/src/Card/Card.test.tsx +113 -19
  384. package/src/Card/Card.tsx +67 -89
  385. package/src/Card/index.ts +36 -1
  386. package/src/Carousel/Carousel.doc.mjs +3 -0
  387. package/src/Carousel/Carousel.test.tsx +360 -0
  388. package/src/Carousel/Carousel.tsx +116 -15
  389. package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -1
  390. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  391. package/src/CheckboxInput/CheckboxInput.tsx +5 -0
  392. package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
  393. package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
  394. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  395. package/src/CodeBlock/CodeBlock.tsx +20 -4
  396. package/src/CodeBlock/highlightRanges.ts +1 -1
  397. package/src/CodeBlock/highlightStyles.ts +13 -13
  398. package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
  399. package/src/ComplexSelector/ComplexSelector.doc.mjs +9 -2
  400. package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
  401. package/src/ComplexSelector/ComplexSelector.tsx +22 -12
  402. package/src/DateInput/DateInput.doc.mjs +17 -1
  403. package/src/DateInput/DateInput.test.tsx +9 -4
  404. package/src/DateInput/DateInput.tsx +54 -3
  405. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  406. package/src/DateInput/MonthScroller.tsx +5 -1
  407. package/src/DateInput/MonthYearWheels.tsx +7 -4
  408. package/src/DateInput/NativeDateField.test.tsx +635 -0
  409. package/src/DateInput/NativeDateField.tsx +641 -0
  410. package/src/DateInput/TouchDateField.tsx +83 -33
  411. package/src/DateInput/Wheel.tsx +1 -0
  412. package/src/DateInput/index.ts +1 -0
  413. package/src/DateInput/nativeDateSegments.ts +127 -0
  414. package/src/DateRangeInput/DateRangeInput.doc.mjs +3 -3
  415. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
  416. package/src/DateRangeInput/DateRangeInput.tsx +8 -13
  417. package/src/DateTimeInput/DateTimeInput.doc.mjs +39 -22
  418. package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
  419. package/src/DateTimeInput/DateTimeInput.tsx +54 -20
  420. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
  421. package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
  422. package/src/Dialog/Dialog.test.tsx +185 -18
  423. package/src/Dialog/Dialog.tsx +35 -11
  424. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  425. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  426. package/src/Field/Field.doc.mjs +1 -1
  427. package/src/Field/FieldLabel.test.tsx +29 -0
  428. package/src/Field/FieldLabel.tsx +7 -0
  429. package/src/Field/InputClearButton.test.tsx +15 -1
  430. package/src/Field/InputClearButton.tsx +28 -4
  431. package/src/FieldStatus/FieldStatus.doc.mjs +1 -1
  432. package/src/FileInput/FileInput.doc.mjs +1 -1
  433. package/src/Heading/Heading.tsx +0 -1
  434. package/src/HoverCard/HoverCard.doc.mjs +8 -2
  435. package/src/HoverCard/HoverCard.test.tsx +154 -4
  436. package/src/HoverCard/HoverCard.tsx +137 -3
  437. package/src/HoverCard/useHoverCard.tsx +23 -3
  438. package/src/Icon/Icon.test.tsx +55 -1
  439. package/src/Icon/Icon.tsx +5 -3
  440. package/src/Icon/defaultIcons.tsx +11 -2
  441. package/src/Icon/globalIconRegistry.test.tsx +16 -3
  442. package/src/Icon/globalIconRegistry.tsx +37 -6
  443. package/src/Icon/index.ts +1 -0
  444. package/src/Icon/useIcon.ts +9 -2
  445. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  446. package/src/Indicator/Indicator.doc.mjs +3 -1
  447. package/src/InputGroup/InputGroup.doc.mjs +1 -1
  448. package/src/Item/Item.tsx +2 -7
  449. package/src/Kbd/Kbd.test.tsx +0 -17
  450. package/src/Kbd/Kbd.tsx +2 -26
  451. package/src/Layer/gestureCounter.ts +57 -0
  452. package/src/Layer/useLayer.test.tsx +368 -16
  453. package/src/Layer/useLayer.tsx +208 -35
  454. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  455. package/src/List/List.test.tsx +38 -0
  456. package/src/List/List.tsx +8 -1
  457. package/src/Markdown/Markdown.test.tsx +37 -0
  458. package/src/Markdown/Markdown.tsx +16 -5
  459. package/src/Markdown/parser.test.ts +33 -0
  460. package/src/Markdown/parser.ts +9 -3
  461. package/src/MetadataList/MetadataList.test.tsx +75 -2
  462. package/src/MetadataList/MetadataListItem.tsx +5 -2
  463. package/src/MultiSelector/MultiSelector.doc.mjs +23 -2
  464. package/src/MultiSelector/MultiSelector.test.tsx +205 -0
  465. package/src/MultiSelector/MultiSelector.tsx +103 -16
  466. package/src/MultiSelector/hooks.ts +9 -2
  467. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  468. package/src/NavIcon/NavIcon.test.tsx +9 -0
  469. package/src/NavIcon/NavIcon.tsx +5 -1
  470. package/src/NavItem/navItemStyles.stylex.ts +0 -8
  471. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  472. package/src/NavMenu/NavHeadingMenu.tsx +7 -4
  473. package/src/NumberInput/NumberInput.doc.mjs +27 -8
  474. package/src/NumberInput/NumberInput.test.tsx +563 -8
  475. package/src/NumberInput/NumberInput.tsx +77 -131
  476. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  477. package/src/NumberInput/numberInputCommit.ts +103 -0
  478. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  479. package/src/NumberInput/numberParser.test.ts +222 -0
  480. package/src/NumberInput/numberParser.ts +403 -0
  481. package/src/Outline/Outline.tsx +2 -4
  482. package/src/OverflowList/OverflowList.doc.mjs +102 -21
  483. package/src/OverflowList/OverflowList.test.tsx +550 -4
  484. package/src/OverflowList/OverflowList.tsx +100 -2
  485. package/src/Pagination/Pagination.test.tsx +3 -2
  486. package/src/Popover/Popover.doc.mjs +2 -2
  487. package/src/Popover/Popover.test.tsx +38 -0
  488. package/src/Popover/Popover.tsx +28 -66
  489. package/src/Popover/usePopover.tsx +44 -5
  490. package/src/PowerSearch/PowerSearch.doc.mjs +1 -1
  491. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
  492. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
  493. package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
  494. package/src/PowerSearch/formatFilterValue.test.ts +16 -1
  495. package/src/PowerSearch/formatFilterValue.ts +2 -0
  496. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  497. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  498. package/src/ProgressBar/ProgressBar.tsx +28 -8
  499. package/src/RadioList/RadioList.doc.mjs +1 -1
  500. package/src/Resizable/Resizable.doc.mjs +2 -2
  501. package/src/Resizable/useResizable.doc.mjs +21 -2
  502. package/src/Resizable/useResizable.test.ts +421 -0
  503. package/src/Resizable/useResizable.ts +133 -48
  504. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  505. package/src/SelectableCard/SelectableCard.tsx +16 -0
  506. package/src/Selector/Selector.doc.mjs +15 -1
  507. package/src/Selector/Selector.source-build.test.mjs +65 -0
  508. package/src/Selector/Selector.test.tsx +301 -0
  509. package/src/Selector/Selector.tsx +145 -32
  510. package/src/Selector/hooks.ts +17 -2
  511. package/src/SideNav/SideNav.doc.mjs +2 -2
  512. package/src/SideNav/SideNav.test.tsx +1069 -6
  513. package/src/SideNav/SideNav.tsx +109 -38
  514. package/src/SideNav/SideNavHeading.tsx +5 -2
  515. package/src/SideNav/SideNavItem.doc.mjs +24 -3
  516. package/src/SideNav/SideNavItem.tsx +134 -44
  517. package/src/Slider/Slider.doc.mjs +2 -2
  518. package/src/Slider/Slider.test.tsx +106 -1
  519. package/src/Slider/Slider.tsx +52 -1
  520. package/src/Spinner/Spinner.doc.mjs +17 -5
  521. package/src/Spinner/Spinner.test.tsx +164 -0
  522. package/src/Spinner/Spinner.tsx +252 -22
  523. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  524. package/src/StatusDot/StatusDot.test.tsx +9 -0
  525. package/src/StatusDot/StatusDot.tsx +7 -1
  526. package/src/Stepper/Step.doc.mjs +1 -1
  527. package/src/Stepper/Step.tsx +7 -14
  528. package/src/Switch/Switch.doc.mjs +3 -1
  529. package/src/Switch/Switch.test.tsx +10 -0
  530. package/src/Switch/Switch.tsx +3 -0
  531. package/src/Table/BaseTable.tsx +6 -1
  532. package/src/Table/Table.doc.mjs +5 -3
  533. package/src/Table/Table.tsx +3 -8
  534. package/src/Table/TableBody.doc.mjs +2 -2
  535. package/src/Table/TableFooter.doc.mjs +1 -1
  536. package/src/Table/TableHeader.doc.mjs +1 -1
  537. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  538. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  539. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
  540. package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
  541. package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
  542. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  543. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  544. package/src/Table/useTablePagination.doc.mjs +1 -1
  545. package/src/Table/useTableSelection.doc.mjs +1 -1
  546. package/src/Text/Text.test.tsx +44 -0
  547. package/src/Text/Text.tsx +0 -1
  548. package/src/TextArea/TextArea.doc.mjs +13 -3
  549. package/src/TextArea/TextArea.test.tsx +11 -0
  550. package/src/TextArea/TextArea.tsx +34 -22
  551. package/src/TextInput/TextInput.doc.mjs +1 -1
  552. package/src/TimeInput/TimeInput.doc.mjs +1 -1
  553. package/src/Timestamp/Timestamp.test.tsx +89 -0
  554. package/src/Timestamp/Timestamp.tsx +8 -8
  555. package/src/Timestamp/formatInstant.ts +5 -0
  556. package/src/Toast/Toast.doc.mjs +213 -44
  557. package/src/Toast/Toast.tsx +118 -23
  558. package/src/Toast/ToastViewport.test.tsx +1434 -8
  559. package/src/Toast/ToastViewport.tsx +85 -14
  560. package/src/Toast/index.ts +2 -0
  561. package/src/Toast/types.ts +43 -5
  562. package/src/Toast/useToastGesture.ts +361 -0
  563. package/src/Token/Token.test.tsx +95 -0
  564. package/src/Token/Token.tsx +19 -17
  565. package/src/Token/TokenLink.tsx +12 -3
  566. package/src/Tokenizer/Tokenizer.doc.mjs +17 -4
  567. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  568. package/src/Tokenizer/Tokenizer.tsx +49 -24
  569. package/src/TopNav/TopNavHeading.tsx +2 -2
  570. package/src/TopNav/TopNavItem.tsx +3 -7
  571. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  572. package/src/TopNav/TopNavMegaMenu.tsx +47 -4
  573. package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
  574. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  575. package/src/TopNav/TopNavMenu.tsx +38 -5
  576. package/src/TreeList/TreeList.test.tsx +49 -0
  577. package/src/TreeList/TreeList.tsx +7 -2
  578. package/src/TreeList/TreeListItem.tsx +2 -7
  579. package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
  580. package/src/Typeahead/BaseTypeahead.tsx +96 -6
  581. package/src/Typeahead/Typeahead.doc.mjs +7 -1
  582. package/src/Typeahead/Typeahead.test.tsx +154 -0
  583. package/src/Typeahead/Typeahead.tsx +9 -0
  584. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  585. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  586. package/src/hooks/useAnnounce.doc.mjs +96 -0
  587. package/src/hooks/useDevWarning.doc.mjs +96 -0
  588. package/src/hooks/useHotkeys.test.ts +0 -18
  589. package/src/hooks/useHotkeys.ts +3 -25
  590. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  591. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  592. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  593. package/src/hooks/useLongPress.doc.mjs +123 -0
  594. package/src/hooks/useOverflow.doc.mjs +58 -17
  595. package/src/hooks/useOverflow.ts +16 -4
  596. package/src/hooks/useTypeahead.doc.mjs +153 -0
  597. package/src/i18n/InternationalizationContext.ts +3 -0
  598. package/src/i18n/InternationalizationProvider.tsx +8 -1
  599. package/src/i18n/__tests__/resolve.test.ts +23 -1
  600. package/src/i18n/resolve.ts +46 -49
  601. package/src/i18n/useTranslator.ts +2 -7
  602. package/src/index.ts +2 -0
  603. package/src/raw-import.d.ts +14 -0
  604. package/src/theme/Theme.test.tsx +104 -2
  605. package/src/theme/Theme.tsx +49 -14
  606. package/src/theme/defineTheme.test.ts +23 -0
  607. package/src/theme/defineTheme.ts +12 -3
  608. package/src/theme/derivedVarRegistry.test.ts +87 -3
  609. package/src/theme/derivedVarRegistry.ts +23 -4
  610. package/src/theme/generateThemeRules.test.ts +99 -1
  611. package/src/theme/generateThemeRules.ts +28 -0
  612. package/src/theme/syntax/tokens.ts +5 -2
  613. package/src/theme/useTheme.test.tsx +10 -0
  614. package/src/theme/useTheme.ts +16 -10
  615. package/src/utils/dateParser.test.ts +34 -2
  616. package/src/utils/dateParser.ts +11 -14
  617. package/src/utils/focusOutline.stylex.ts +50 -0
  618. package/src/utils/interactionOverlay.stylex.ts +74 -0
  619. package/src/utils/isApplePlatform.test.ts +61 -0
  620. package/src/utils/isApplePlatform.ts +37 -0
  621. package/src/utils/plainDate.test.ts +46 -0
  622. package/src/utils/plainDate.ts +18 -3
@@ -0,0 +1,403 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file numberParser.ts
5
+ * @input Text a person typed or pasted, plus the resolved BCP 47 locale
6
+ * @output Exports parseLocaleNumber and formatEditableNumber
7
+ * @position Internal to NumberInput; not part of the public surface
8
+ *
9
+ * People paste numbers out of spreadsheets, and a spreadsheet writes them
10
+ * grouped, signed, and decorated. This reads those back. Everything locale
11
+ * specific — the grouping and decimal separators, the group sizes, the digit
12
+ * script — is derived from Intl and Unicode rather than a table, and text that
13
+ * no reading fits returns null so the field stays visibly invalid instead of
14
+ * committing a guess. Where both readings are well formed the locale's wins,
15
+ * the way utils/dateParser.ts settles an ambiguous date by locale preference.
16
+ * Grouping is well formed only when every group fits the locale's own sizes:
17
+ * the last exactly the primary size, each inner one exactly the secondary, the
18
+ * first no longer than that. So de-DE `1.234` is 1234, while `1.2345` (last
19
+ * group too long) and `1234.567` (too much ahead of it) keep the full stop as
20
+ * a decimal point. Groups of three fit every locale, so a separator repeated
21
+ * with three-digit groups is grouping in all of them and `1,234,567` reads the
22
+ * same everywhere; for a space or apostrophe, which no locale writes as a
23
+ * decimal point, one occurrence is enough, so en-US `1 234` is 1234.
24
+ *
25
+ * That paragraph is executable: numberParser.docblock.test.ts implements it as
26
+ * code, quote by quote, and fails when the parser and the words disagree.
27
+ *
28
+ * Which characters may separate digits at all is the one thing that is NOT
29
+ * read off the input: SEPARATOR_CHARS below is a bounded alphabet, the same
30
+ * shape utils/dateParser.ts uses for its `[-/.]` date separators.
31
+ *
32
+ * SYNC: When modified, update these files to stay in sync:
33
+ * - /packages/core/src/NumberInput/NumberInput.tsx
34
+ * - /packages/core/src/NumberInput/numberParser.test.ts
35
+ * - /packages/core/src/NumberInput/numberParser.docblock.test.ts
36
+ */
37
+
38
+ import type {Locale} from '../i18n';
39
+
40
+ interface LocaleNumberSymbols {
41
+ group: string;
42
+ decimal: string;
43
+ /** Digits in the rightmost group — 3 nearly everywhere, 3 in en-IN too. */
44
+ primaryGroupSize: number;
45
+ /** Digits in every group left of it — 2 in en-IN's lakh grouping. */
46
+ secondaryGroupSize: number;
47
+ }
48
+
49
+ const symbolsByLocale = new Map<string, LocaleNumberSymbols>();
50
+
51
+ function getLocaleNumberSymbols(locale: Locale | undefined) {
52
+ const key = locale ?? '';
53
+ let symbols = symbolsByLocale.get(key);
54
+ if (symbols === undefined) {
55
+ let format: Intl.NumberFormat;
56
+ try {
57
+ format = new Intl.NumberFormat(locale);
58
+ } catch {
59
+ format = new Intl.NumberFormat('en');
60
+ }
61
+ const parts = format.formatToParts(12345.6);
62
+ // A probe long enough to expose a second grouping size where one exists.
63
+ const groupSizes = format
64
+ .formatToParts(11111111111)
65
+ .filter(part => part.type === 'integer')
66
+ .map(part => part.value.length);
67
+ const hasGrouping = groupSizes.length > 1;
68
+ symbols = {
69
+ // Normalized so the space-family separators compare equal to the plain
70
+ // space that input text is normalized to.
71
+ group: (parts.find(p => p.type === 'group')?.value ?? ',').normalize(
72
+ 'NFKC',
73
+ ),
74
+ decimal: parts.find(p => p.type === 'decimal')?.value ?? '.',
75
+ primaryGroupSize: hasGrouping ? groupSizes[groupSizes.length - 1] : 3,
76
+ secondaryGroupSize: hasGrouping ? groupSizes[groupSizes.length - 2] : 3,
77
+ };
78
+ symbolsByLocale.set(key, symbols);
79
+ }
80
+ return symbols;
81
+ }
82
+
83
+ // Built at runtime rather than written as literals: Babel's
84
+ // transform-unicode-property-regex rewrites a `\p{...}` regex LITERAL into an
85
+ // enumerated character class, and the copy bundled with Next rejects the
86
+ // General_Category short names, failing the sandbox build. Property escapes are
87
+ // ES2018 and need no transform in any browser this package supports.
88
+ const DECIMAL_DIGIT = new RegExp('\\p{Nd}', 'u');
89
+ const CURRENCY = new RegExp('\\p{Sc}', 'u');
90
+ // Zero-width joiners, bidi isolates and the BOM Excel prepends.
91
+ const INVISIBLES = /[\u200B-\u200D\u200E\u200F\u061C\u2066-\u2069\uFEFF]/g;
92
+ // Hyphen last: inside the character class this builds, a leading one would
93
+ // open a range.
94
+ const MINUS_SIGNS = '\u2212\u2012\u2013-';
95
+
96
+ /**
97
+ * Every character a locale writes between digits. Sweeping every language ICU
98
+ * resolves, in every region, yields seven: comma, full stop, apostrophe,
99
+ * space (the whole space family folds to it under NFKC), the Arabic decimal
100
+ * and thousands separators, and U+060C — which only nqo writes, and which
101
+ * this alphabet leaves out. U+2019 is here in its place: no locale writes it,
102
+ * but the corpus pins it as the Swiss spelling.
103
+ *
104
+ * The alphabet is bounded on purpose. Read the candidates off the input
105
+ * instead and any repeated character is grouping, so a hyphenated ID commits
106
+ * as a number. It bounds characters and not shapes: a full stop is a real
107
+ * separator, so `192.168.100.200` is four well-formed groups.
108
+ */
109
+ const SEPARATOR_CHARS = ",.' \u2019\u066B\u066C";
110
+ const NUMBER_BODY = new RegExp(`^[0-9${SEPARATOR_CHARS}]+$`);
111
+ /** No grouping and at most one full stop: the format `Number()` reads. */
112
+ const MACHINE_NUMBER = /^(?:\d+\.?\d*|\.\d+)$/;
113
+
114
+ /**
115
+ * Value of any Unicode decimal digit. Each digit script lays its ten digits
116
+ * out consecutively, so walking back to the script's zero derives the value
117
+ * for Arabic-Indic, Devanagari, full-width and the rest without shipping a
118
+ * table of them. Returns null in the one shape the walk cannot resolve: two
119
+ * digit blocks adjacent in code space (the mathematical alphanumerics).
120
+ */
121
+ function digitValue(char: string): number | null {
122
+ const codePoint = char.codePointAt(0);
123
+ if (codePoint == null) {
124
+ return null;
125
+ }
126
+ for (let zero = codePoint; codePoint - zero < 10; zero--) {
127
+ if (!DECIMAL_DIGIT.test(String.fromCodePoint(zero - 1))) {
128
+ return codePoint - zero;
129
+ }
130
+ }
131
+ return null;
132
+ }
133
+
134
+ function toAsciiDigits(text: string): string | null {
135
+ let out = '';
136
+ for (const char of text) {
137
+ if (!DECIMAL_DIGIT.test(char)) {
138
+ out += char;
139
+ continue;
140
+ }
141
+ const value = digitValue(char);
142
+ if (value == null) {
143
+ return null;
144
+ }
145
+ out += String(value);
146
+ }
147
+ return out;
148
+ }
149
+
150
+ /**
151
+ * Reduce a digits-and-separators string to a plain machine number under one
152
+ * candidate reading, or null when it is not well formed under that reading.
153
+ * `minGroups` is how many grouping separators the reading has to see before it
154
+ * believes the separator is grouping at all.
155
+ */
156
+ function readUnder(
157
+ core: string,
158
+ group: string,
159
+ decimal: string,
160
+ primaryGroupSize: number,
161
+ secondaryGroupSize: number,
162
+ minGroups: number,
163
+ ): string | null {
164
+ let intText = core;
165
+ let fracText: string | null = null;
166
+
167
+ if (decimal !== '' && core.includes(decimal)) {
168
+ const at = core.indexOf(decimal);
169
+ if (core.includes(decimal, at + decimal.length)) {
170
+ return null;
171
+ }
172
+ intText = core.slice(0, at);
173
+ fracText = core.slice(at + decimal.length);
174
+ if (!/^\d*$/.test(fracText)) {
175
+ return null;
176
+ }
177
+ }
178
+
179
+ let digits: string;
180
+ if (group !== '' && intText.includes(group)) {
181
+ const chunks = intText.split(group);
182
+ if (
183
+ chunks.length - 1 < minGroups ||
184
+ !chunks.every(chunk => /^\d+$/.test(chunk))
185
+ ) {
186
+ return null;
187
+ }
188
+ const first = chunks[0];
189
+ const last = chunks[chunks.length - 1];
190
+ if (last.length !== primaryGroupSize || first.length > secondaryGroupSize) {
191
+ return null;
192
+ }
193
+ for (let i = 1; i < chunks.length - 1; i++) {
194
+ if (chunks[i].length !== secondaryGroupSize) {
195
+ return null;
196
+ }
197
+ }
198
+ digits = chunks.join('');
199
+ } else {
200
+ if (!/^\d*$/.test(intText)) {
201
+ return null;
202
+ }
203
+ digits = intText;
204
+ }
205
+
206
+ if (digits === '' && (fracText == null || fracText === '')) {
207
+ return null;
208
+ }
209
+ return fracText == null ? digits : `${digits}.${fracText}`;
210
+ }
211
+
212
+ /**
213
+ * A separator that no locale uses as a decimal point, so one well-formed group
214
+ * of it is already unambiguous. Everything else needs two before grouping
215
+ * beats the decimal-point reading.
216
+ */
217
+ function isGroupOnlySeparator(separator: string): boolean {
218
+ return /^[\s'\u2019]$/.test(separator);
219
+ }
220
+
221
+ function toPlainNumber(
222
+ core: string,
223
+ locale: Locale | undefined,
224
+ ): string | null {
225
+ if (!NUMBER_BODY.test(core)) {
226
+ return null;
227
+ }
228
+
229
+ const {group, decimal, primaryGroupSize, secondaryGroupSize} =
230
+ getLocaleNumberSymbols(locale);
231
+ const inLocale = readUnder(
232
+ core,
233
+ group,
234
+ decimal,
235
+ primaryGroupSize,
236
+ secondaryGroupSize,
237
+ 1,
238
+ );
239
+ if (inLocale != null) {
240
+ return inLocale;
241
+ }
242
+
243
+ // The machine format, which is what the field read before this parser
244
+ // existed. It comes after the locale rather than before it — dateParser.ts
245
+ // can put ISO first because `2026-01-25` has no second reading, while
246
+ // `1.234` in de-DE has one and grouping is the reading a German means. What
247
+ // reaches here is a full stop the locale could NOT read, so it is not
248
+ // well-formed grouping either, and exactly one reading is left.
249
+ if (MACHINE_NUMBER.test(core)) {
250
+ return core;
251
+ }
252
+
253
+ // A repeated separator with three digits after each occurrence can only be
254
+ // grouping — a decimal point appears once — so that shape reads the same in
255
+ // every locale, which is what lets a `1,234,234,234` pasted out of a
256
+ // spreadsheet land in a de-DE app.
257
+ const separators = [...new Set(core.replace(/\d/g, ''))];
258
+ if (separators.length === 0 || separators.length > 2) {
259
+ return null;
260
+ }
261
+ for (const candidate of separators) {
262
+ const occurrences = core.split(candidate).length - 1;
263
+ const minGroups = isGroupOnlySeparator(candidate) ? 1 : 2;
264
+ if (occurrences < minGroups) {
265
+ continue;
266
+ }
267
+ const other = separators.find(s => s !== candidate) ?? '';
268
+ if (other !== '' && core.split(other).length - 1 !== 1) {
269
+ continue;
270
+ }
271
+ const read = readUnder(core, candidate, other, 3, 3, minGroups);
272
+ if (read != null) {
273
+ return read;
274
+ }
275
+ }
276
+ return null;
277
+ }
278
+
279
+ /**
280
+ * Read a number out of text the way a person in `locale` writes one: their
281
+ * grouping and decimal separators, their group sizes, their digit script, an
282
+ * optional currency symbol, and the shapes a spreadsheet pastes.
283
+ *
284
+ * Returns null rather than a guess. Grouping is validated, so en-US `1,23` —
285
+ * a comma that is neither a decimal point nor a well-formed group — is not
286
+ * silently read as 123, and neither is a number written for another locale.
287
+ * Only the characters some locale writes between digits count as separators,
288
+ * so `123-456-789` is not a number at all.
289
+ *
290
+ * @example
291
+ * ```
292
+ * parseLocaleNumber('1,234,234,234', 'en-US') // 1234234234
293
+ * parseLocaleNumber('1,234,234,234', 'de-DE') // 1234234234
294
+ * parseLocaleNumber('1,5', 'de-DE') // 1.5
295
+ * parseLocaleNumber('1.5', 'de-DE') // 1.5
296
+ * parseLocaleNumber('1,5', 'en-US') // null
297
+ * parseLocaleNumber('123-456-789', 'en-US') // null
298
+ * ```
299
+ */
300
+ export function parseLocaleNumber(
301
+ text: string,
302
+ locale?: Locale,
303
+ ): number | null {
304
+ const normalized = toAsciiDigits(
305
+ text.normalize('NFKC').replace(INVISIBLES, ''),
306
+ );
307
+ if (normalized == null) {
308
+ return null;
309
+ }
310
+
311
+ let rest = normalized.trim();
312
+ let sign = 1;
313
+
314
+ // Accounting negatives: spreadsheets write -1234 as (1,234).
315
+ const accounting = /^\((.*)\)$/s.exec(rest);
316
+ if (accounting) {
317
+ sign = -1;
318
+ rest = accounting[1].trim();
319
+ }
320
+
321
+ rest = stripCurrency(rest);
322
+
323
+ // The sign lands on either end — RTL locales trail it, and Intl writes
324
+ // U+2212 where a keyboard writes a hyphen.
325
+ let hasWrittenSign = false;
326
+ const leadingSign = new RegExp(`^([+${MINUS_SIGNS}])\\s*`).exec(rest);
327
+ if (leadingSign) {
328
+ hasWrittenSign = true;
329
+ sign = leadingSign[1] === '+' ? sign : -sign;
330
+ rest = rest.slice(leadingSign[0].length);
331
+ } else {
332
+ const trailingSign = new RegExp(`\\s*([+${MINUS_SIGNS}])$`).exec(rest);
333
+ if (trailingSign) {
334
+ hasWrittenSign = true;
335
+ sign = trailingSign[1] === '+' ? sign : -sign;
336
+ rest = rest.slice(0, rest.length - trailingSign[0].length);
337
+ }
338
+ }
339
+
340
+ // The parens already say negative, so a sign inside them contradicts or
341
+ // doubles it: `(-1,234)` is -1234 to one reader and +1234 to another.
342
+ if (accounting && hasWrittenSign) {
343
+ return null;
344
+ }
345
+
346
+ rest = stripCurrency(rest);
347
+
348
+ let exponent = 0;
349
+ const exponentMatch = /\s*[eE]\s*([+-]?\d+)$/.exec(rest);
350
+ if (exponentMatch) {
351
+ exponent = Number(exponentMatch[1]);
352
+ rest = rest.slice(0, rest.length - exponentMatch[0].length);
353
+ }
354
+
355
+ const core = rest.trim();
356
+ if (core === '') {
357
+ return null;
358
+ }
359
+
360
+ const plain = toPlainNumber(core, locale);
361
+ if (plain == null) {
362
+ return null;
363
+ }
364
+
365
+ const magnitude = Number(plain);
366
+ if (!Number.isFinite(magnitude)) {
367
+ return null;
368
+ }
369
+
370
+ const scaled =
371
+ exponent === 0
372
+ ? magnitude
373
+ : // 1.23 * 1e3 is 1229.9999999999998 in binary floating point, and a
374
+ // field that commits that instead of 1230 has not round-tripped.
375
+ Number((magnitude * 10 ** exponent).toPrecision(15));
376
+ if (!Number.isFinite(scaled)) {
377
+ return null;
378
+ }
379
+ const result = sign * scaled;
380
+ return Object.is(result, -0) ? 0 : result;
381
+ }
382
+
383
+ function stripCurrency(text: string): string {
384
+ let out = text.trim();
385
+ if (CURRENCY.test(out.charAt(0))) {
386
+ out = out.slice(1).trim();
387
+ }
388
+ if (CURRENCY.test(out.charAt(out.length - 1))) {
389
+ out = out.slice(0, -1).trim();
390
+ }
391
+ return out;
392
+ }
393
+
394
+ /**
395
+ * The text shown while the field is focused: the plain machine number in the
396
+ * locale's decimal separator, so what a person sees mid-edit is what the
397
+ * parser reads back on blur.
398
+ */
399
+ export function formatEditableNumber(value: number, locale?: Locale): string {
400
+ const {decimal} = getLocaleNumberSymbols(locale);
401
+ const raw = String(value);
402
+ return decimal === '.' ? raw : raw.replace('.', decimal);
403
+ }
@@ -43,6 +43,7 @@ import {useScrollSpy} from './useScrollSpy';
43
43
  import type {OutlineItem} from './types';
44
44
  import {themeProps} from '../utils/themeProps';
45
45
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
46
+ import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
46
47
  import {useTranslator} from '../i18n';
47
48
 
48
49
  import {useMergedRefs} from '../hooks/useMergedRefs';
@@ -209,13 +210,9 @@ const styles = stylex.create({
209
210
  lineHeight: typeScaleVars['--text-body-leading'],
210
211
  ':hover:where(:not(:disabled,[aria-disabled="true"]))': {
211
212
  '@media (hover: hover)': {
212
- backgroundColor: colorVars['--color-overlay-hover'],
213
213
  color: colorVars['--color-text-primary'],
214
214
  },
215
215
  },
216
- ':active': {
217
- backgroundColor: colorVars['--color-overlay-pressed'],
218
- },
219
216
  },
220
217
  activeLink: {
221
218
  color: colorVars['--color-text-primary'],
@@ -476,6 +473,7 @@ export function Outline({
476
473
  }),
477
474
  focusOutlineProps.focusVisible(
478
475
  styles.link,
476
+ interactionOverlayStyles.backgroundColor,
479
477
  densityStyles[density],
480
478
  getIndentStyle(item.level),
481
479
  isActive && styles.activeLink,
@@ -48,6 +48,12 @@ export const docs = {
48
48
  description:
49
49
  'Render function for the overflow indicator. Receives the list of hidden items (each with child and index). Only called when items are overflowing.',
50
50
  },
51
+ {
52
+ name: 'onOverflowChange',
53
+ type: '(overflowItems: OverflowItem[]) => void',
54
+ description:
55
+ 'Called whenever the collapsed set changes: with the collapsed items once something collapses, and with an empty array once the row widens back out. Membership and order changes report even when the count stays the same; unrelated re-renders and callback identity changes do not. Silent while nothing overflows, including on mount. Use stable React keys for dynamic items.',
56
+ },
51
57
  {
52
58
  name: 'gap',
53
59
  type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10',
@@ -58,7 +64,8 @@ export const docs = {
58
64
  {
59
65
  name: 'minVisibleItems',
60
66
  type: 'number',
61
- description: 'Minimum number of items to always show, even when overflowing.',
67
+ description:
68
+ 'Minimum number of items to always show, even when overflowing.',
62
69
  default: '0',
63
70
  },
64
71
  {
@@ -96,18 +103,37 @@ export const docs = {
96
103
  },
97
104
  ],
98
105
  theming: {
99
- targets: [
100
- {className: 'astryx-overflow-list'},
101
- ],
106
+ targets: [{className: 'astryx-overflow-list'}],
102
107
  },
103
108
  usage: {
104
109
  description:
105
110
  'A horizontal list that automatically hides items when they exceed the available width. Use OverflowList for breadcrumbs, toolbars, tag lists, or any row that needs to collapse gracefully at smaller sizes.',
106
111
  bestPractices: [
107
- { guidance: true, description: 'Provide a meaningful overflowRenderer: a "+N more" badge, a dropdown, or a count indicator.' },
108
- { guidance: true, description: 'Set minVisibleItems to keep key items visible, and maxVisibleItems to cap the row at a fixed count regardless of available width.' },
109
- { guidance: true, description: 'Use maxRows to let items wrap onto a bounded number of rows (e.g. a two-row tag cloud) before collapsing the rest into the indicator.' },
110
- { guidance: false, description: 'Use OverflowList for a vertical stack; horizontal multi-row wrap is supported via maxRows, but items still flow left-to-right, not top-to-bottom.' },
112
+ {
113
+ guidance: true,
114
+ description:
115
+ 'Provide a meaningful overflowRenderer: a "+N more" badge, a dropdown, or a count indicator.',
116
+ },
117
+ {
118
+ guidance: true,
119
+ description:
120
+ 'When the row already has its own menu, use onOverflowChange to feed the collapsed items into it instead of adding a second anchor with overflowRenderer.',
121
+ },
122
+ {
123
+ guidance: true,
124
+ description:
125
+ 'Set minVisibleItems to keep key items visible, and maxVisibleItems to cap the row at a fixed count regardless of available width.',
126
+ },
127
+ {
128
+ guidance: true,
129
+ description:
130
+ 'Use maxRows to let items wrap onto a bounded number of rows (e.g. a two-row tag cloud) before collapsing the rest into the indicator.',
131
+ },
132
+ {
133
+ guidance: false,
134
+ description:
135
+ 'Use OverflowList for a vertical stack; horizontal multi-row wrap is supported via maxRows, but items still flow left-to-right, not top-to-bottom.',
136
+ },
111
137
  ],
112
138
  },
113
139
  };
@@ -129,6 +155,12 @@ export const docsZh = {
129
155
  description:
130
156
  '溢出指示器的渲染函数。接收隐藏项目列表(每项包含 child 和 index)。仅在有溢出项时调用。',
131
157
  },
158
+ {
159
+ name: 'onOverflowChange',
160
+ type: '(overflowItems: OverflowItem[]) => void',
161
+ description:
162
+ '折叠项集合变化时调用:发生折叠时传入折叠项,行重新变宽、全部放得下时传入空数组。没有溢出时(包括挂载时)不会调用。用于将折叠项交给周围界面已有的菜单,避免列表再挂载一个自己的指示器。',
163
+ },
132
164
  {
133
165
  name: 'gap',
134
166
  type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10',
@@ -180,36 +212,85 @@ export const docsZh = {
180
212
  description:
181
213
  'A horizontal list that automatically hides items when they exceed the available width. Use OverflowList for breadcrumbs, toolbars, tag lists, or any row that needs to collapse gracefully at smaller sizes.',
182
214
  bestPractices: [
183
- { guidance: true, description: 'Provide a meaningful overflowRenderer: a "+N more" badge, a dropdown, or a count indicator.' },
184
- { guidance: true, description: 'Set minVisibleItems to keep key items visible, and maxVisibleItems to cap the row at a fixed count regardless of available width.' },
185
- { guidance: true, description: 'Use maxRows to let items wrap onto a bounded number of rows (e.g. a two-row tag cloud) before collapsing the rest into the indicator.' },
186
- { guidance: false, description: 'Use OverflowList for a vertical stack; horizontal multi-row wrap is supported via maxRows, but items still flow left-to-right, not top-to-bottom.' },
215
+ {
216
+ guidance: true,
217
+ description:
218
+ 'Provide a meaningful overflowRenderer: a "+N more" badge, a dropdown, or a count indicator.',
219
+ },
220
+ {
221
+ guidance: true,
222
+ description:
223
+ 'When the row already has its own menu, use onOverflowChange to feed the collapsed items into it instead of adding a second anchor with overflowRenderer.',
224
+ },
225
+ {
226
+ guidance: true,
227
+ description:
228
+ 'Set minVisibleItems to keep key items visible, and maxVisibleItems to cap the row at a fixed count regardless of available width.',
229
+ },
230
+ {
231
+ guidance: true,
232
+ description:
233
+ 'Use maxRows to let items wrap onto a bounded number of rows (e.g. a two-row tag cloud) before collapsing the rest into the indicator.',
234
+ },
235
+ {
236
+ guidance: false,
237
+ description:
238
+ 'Use OverflowList for a vertical stack; horizontal multi-row wrap is supported via maxRows, but items still flow left-to-right, not top-to-bottom.',
239
+ },
187
240
  ],
188
241
  },
189
242
  };
190
243
 
191
244
  /** @type {import('@astryxdesign/cli/authoring').ComponentTranslationDoc} */
192
245
  export const docsDense = {
193
- description: 'horizontal list w/ overflow indicator: hides items beyond container width',
246
+ description:
247
+ 'horizontal list w/ overflow indicator: hides items beyond container width',
194
248
  usage: {
195
249
  description:
196
250
  'A horizontal list that automatically hides items when they exceed the available width. Use OverflowList for breadcrumbs, toolbars, tag lists, or any row that needs to collapse gracefully at smaller sizes.',
197
251
  bestPractices: [
198
- { guidance: true, description: 'Provide a meaningful overflowRenderer: a "+N more" badge, a dropdown, or a count indicator.' },
199
- { guidance: true, description: 'Set minVisibleItems to keep key items visible, and maxVisibleItems to cap the row at a fixed count regardless of available width.' },
200
- { guidance: true, description: 'Use maxRows to let items wrap onto a bounded number of rows (e.g. a two-row tag cloud) before collapsing the rest into the indicator.' },
201
- { guidance: false, description: 'Use OverflowList for a vertical stack; horizontal multi-row wrap is supported via maxRows, but items still flow left-to-right, not top-to-bottom.' },
252
+ {
253
+ guidance: true,
254
+ description:
255
+ 'Provide a meaningful overflowRenderer: a "+N more" badge, a dropdown, or a count indicator.',
256
+ },
257
+ {
258
+ guidance: true,
259
+ description:
260
+ 'When the row already has its own menu, use onOverflowChange to feed the collapsed items into it instead of adding a second anchor with overflowRenderer.',
261
+ },
262
+ {
263
+ guidance: true,
264
+ description:
265
+ 'Set minVisibleItems to keep key items visible, and maxVisibleItems to cap the row at a fixed count regardless of available width.',
266
+ },
267
+ {
268
+ guidance: true,
269
+ description:
270
+ 'Use maxRows to let items wrap onto a bounded number of rows (e.g. a two-row tag cloud) before collapsing the rest into the indicator.',
271
+ },
272
+ {
273
+ guidance: false,
274
+ description:
275
+ 'Use OverflowList for a vertical stack; horizontal multi-row wrap is supported via maxRows, but items still flow left-to-right, not top-to-bottom.',
276
+ },
202
277
  ],
203
278
  },
204
279
  propDescriptions: {
205
280
  children: 'items to render, each child should be a single element',
206
- overflowRenderer: 'renders overflow indicator, receives hidden items w/ index',
281
+ overflowRenderer:
282
+ 'renders overflow indicator, receives hidden items w/ index',
283
+ onOverflowChange:
284
+ 'fires w/ collapsed items when membership/order changes (empty once the row fits again); ignores unrelated renders/callback identity; stable React keys required for dynamic items',
207
285
  gap: 'item gap as spacing step',
208
286
  minVisibleItems: 'min items always shown even when overflowing',
209
- maxVisibleItems: 'max items ever shown (cap); extra items collapse to indicator; min wins if smaller',
210
- maxRows: 'wrap items across up to N rows then collapse rest (number, not boolean); undefined = single line',
287
+ maxVisibleItems:
288
+ 'max items ever shown (cap); extra items collapse to indicator; min wins if smaller',
289
+ maxRows:
290
+ 'wrap items across up to N rows then collapse rest (number, not boolean); undefined = single line',
211
291
  collapseFrom: 'which end to collapse from',
212
- behavior: 'observeSelf (default) or observeParent for content-sized containers',
292
+ behavior:
293
+ 'observeSelf (default) or observeParent for content-sized containers',
213
294
  xstyle: 'StyleX styles, use stylex.create() values only',
214
295
  },
215
296
  };