@astryxdesign/core 0.5.0 → 0.5.1-canary.f64186a

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 (597) 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/index.d.ts +1 -1
  278. package/dist/index.d.ts.map +1 -1
  279. package/dist/theme/Theme.d.ts.map +1 -1
  280. package/dist/theme/Theme.js +46 -10
  281. package/dist/theme/defineTheme.d.ts +9 -3
  282. package/dist/theme/defineTheme.d.ts.map +1 -1
  283. package/dist/theme/defineTheme.js +5 -0
  284. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  285. package/dist/theme/derivedVarRegistry.js +24 -4
  286. package/dist/theme/generateThemeRules.d.ts +21 -0
  287. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  288. package/dist/theme/generateThemeRules.js +26 -0
  289. package/dist/theme/syntax/tokens.d.ts +1 -1
  290. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  291. package/dist/theme/syntax/tokens.js +5 -2
  292. package/dist/theme/useTheme.d.ts.map +1 -1
  293. package/dist/theme/useTheme.js +6 -7
  294. package/dist/utils/dateParser.d.ts +5 -8
  295. package/dist/utils/dateParser.d.ts.map +1 -1
  296. package/dist/utils/dateParser.js +10 -11
  297. package/dist/utils/focusOutline.stylex.d.ts +25 -0
  298. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  299. package/dist/utils/focusOutline.stylex.js +15 -0
  300. package/dist/utils/interactionOverlay.stylex.d.ts +26 -0
  301. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -0
  302. package/dist/utils/interactionOverlay.stylex.js +42 -0
  303. package/dist/utils/isApplePlatform.d.ts +18 -0
  304. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  305. package/dist/utils/isApplePlatform.js +37 -0
  306. package/dist/utils/plainDate.d.ts +11 -0
  307. package/dist/utils/plainDate.d.ts.map +1 -1
  308. package/dist/utils/plainDate.js +20 -4
  309. package/locales/af-ZA.json +7 -7
  310. package/locales/ar-SA.json +7 -7
  311. package/locales/ca-ES.json +6 -6
  312. package/locales/cs-CZ.json +7 -7
  313. package/locales/da-DK.json +7 -7
  314. package/locales/de-DE.json +7 -7
  315. package/locales/el-GR.json +7 -7
  316. package/locales/en.json +178 -6
  317. package/locales/es-ES.json +6 -6
  318. package/locales/fi-FI.json +7 -7
  319. package/locales/fr-FR.json +7 -7
  320. package/locales/he-IL.json +7 -7
  321. package/locales/hu-HU.json +7 -7
  322. package/locales/it-IT.json +7 -7
  323. package/locales/ja-JP.json +7 -7
  324. package/locales/ko-KR.json +7 -7
  325. package/locales/nl-NL.json +7 -7
  326. package/locales/no-NO.json +7 -7
  327. package/locales/pl-PL.json +7 -7
  328. package/locales/pseudo.json +130 -1
  329. package/locales/pt-BR.json +7 -7
  330. package/locales/pt-PT.json +7 -7
  331. package/locales/ro-RO.json +7 -7
  332. package/locales/ru-RU.json +7 -7
  333. package/locales/sr-SP.json +7 -7
  334. package/locales/sv-SE.json +7 -7
  335. package/locales/tr-TR.json +7 -7
  336. package/locales/uk-UA.json +7 -7
  337. package/locales/vi-VN.json +7 -7
  338. package/locales/zh-CN.json +7 -7
  339. package/locales/zh-TW.json +7 -7
  340. package/package.json +4 -5
  341. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  342. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  343. package/src/AlertDialog/AlertDialog.tsx +62 -20
  344. package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
  345. package/src/AspectRatio/AspectRatio.tsx +6 -6
  346. package/src/Avatar/Avatar.doc.mjs +12 -2
  347. package/src/Avatar/Avatar.test.tsx +80 -0
  348. package/src/Avatar/Avatar.tsx +64 -14
  349. package/src/Avatar/index.ts +2 -2
  350. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  351. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  352. package/src/AvatarGroup/AvatarGroup.tsx +12 -4
  353. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  354. package/src/AvatarGroup/AvatarGroupOverflow.tsx +12 -12
  355. package/src/Badge/Badge.doc.mjs +3 -2
  356. package/src/Badge/Badge.test.tsx +32 -3
  357. package/src/Badge/Badge.tsx +42 -1
  358. package/src/Banner/Banner.doc.mjs +9 -0
  359. package/src/Banner/Banner.test.tsx +76 -11
  360. package/src/Banner/Banner.tsx +21 -2
  361. package/src/Button/Button.doc.mjs +2 -1
  362. package/src/Button/Button.test.tsx +19 -4
  363. package/src/Button/Button.tsx +9 -29
  364. package/src/ButtonGroup/ButtonGroup.doc.mjs +2 -2
  365. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -0
  366. package/src/Calendar/Calendar.doc.mjs +3 -3
  367. package/src/Calendar/Calendar.test.tsx +112 -0
  368. package/src/Calendar/Calendar.tsx +18 -16
  369. package/src/Calendar/hooks/useCalendarDays.ts +4 -4
  370. package/src/Calendar/hooks/useCalendarNavigation.ts +4 -4
  371. package/src/Calendar/styles.ts +48 -42
  372. package/src/Card/Card.doc.mjs +10 -7
  373. package/src/Card/Card.test.tsx +113 -19
  374. package/src/Card/Card.tsx +67 -89
  375. package/src/Card/index.ts +36 -1
  376. package/src/Carousel/Carousel.doc.mjs +3 -0
  377. package/src/Carousel/Carousel.test.tsx +360 -0
  378. package/src/Carousel/Carousel.tsx +116 -15
  379. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  380. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  381. package/src/CheckboxInput/CheckboxInput.tsx +5 -0
  382. package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
  383. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  384. package/src/CodeBlock/CodeBlock.tsx +20 -4
  385. package/src/CodeBlock/highlightRanges.ts +1 -1
  386. package/src/CodeBlock/highlightStyles.ts +13 -13
  387. package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
  388. package/src/ComplexSelector/ComplexSelector.doc.mjs +7 -0
  389. package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
  390. package/src/ComplexSelector/ComplexSelector.tsx +22 -12
  391. package/src/DateInput/DateInput.doc.mjs +16 -0
  392. package/src/DateInput/DateInput.test.tsx +9 -4
  393. package/src/DateInput/DateInput.tsx +54 -3
  394. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  395. package/src/DateInput/MonthScroller.tsx +5 -1
  396. package/src/DateInput/MonthYearWheels.tsx +7 -4
  397. package/src/DateInput/NativeDateField.test.tsx +635 -0
  398. package/src/DateInput/NativeDateField.tsx +641 -0
  399. package/src/DateInput/TouchDateField.tsx +83 -33
  400. package/src/DateInput/Wheel.tsx +1 -0
  401. package/src/DateInput/index.ts +1 -0
  402. package/src/DateInput/nativeDateSegments.ts +127 -0
  403. package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
  404. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
  405. package/src/DateRangeInput/DateRangeInput.tsx +8 -13
  406. package/src/DateTimeInput/DateTimeInput.doc.mjs +38 -21
  407. package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
  408. package/src/DateTimeInput/DateTimeInput.tsx +54 -20
  409. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
  410. package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
  411. package/src/Dialog/Dialog.test.tsx +185 -18
  412. package/src/Dialog/Dialog.tsx +35 -11
  413. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  414. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  415. package/src/Field/FieldLabel.test.tsx +29 -0
  416. package/src/Field/FieldLabel.tsx +7 -0
  417. package/src/Field/InputClearButton.test.tsx +15 -1
  418. package/src/Field/InputClearButton.tsx +28 -4
  419. package/src/Heading/Heading.tsx +0 -1
  420. package/src/HoverCard/HoverCard.doc.mjs +8 -2
  421. package/src/HoverCard/HoverCard.test.tsx +154 -4
  422. package/src/HoverCard/HoverCard.tsx +137 -3
  423. package/src/HoverCard/useHoverCard.tsx +23 -3
  424. package/src/Icon/Icon.test.tsx +55 -1
  425. package/src/Icon/Icon.tsx +5 -3
  426. package/src/Icon/defaultIcons.tsx +11 -2
  427. package/src/Icon/globalIconRegistry.test.tsx +16 -3
  428. package/src/Icon/globalIconRegistry.tsx +37 -6
  429. package/src/Icon/index.ts +1 -0
  430. package/src/Icon/useIcon.ts +9 -2
  431. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  432. package/src/Indicator/Indicator.doc.mjs +2 -0
  433. package/src/Item/Item.tsx +2 -7
  434. package/src/Kbd/Kbd.test.tsx +0 -17
  435. package/src/Kbd/Kbd.tsx +2 -26
  436. package/src/Layer/gestureCounter.ts +57 -0
  437. package/src/Layer/useLayer.test.tsx +368 -16
  438. package/src/Layer/useLayer.tsx +208 -35
  439. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  440. package/src/List/List.test.tsx +38 -0
  441. package/src/List/List.tsx +8 -1
  442. package/src/Markdown/Markdown.test.tsx +37 -0
  443. package/src/Markdown/Markdown.tsx +16 -5
  444. package/src/Markdown/parser.test.ts +33 -0
  445. package/src/Markdown/parser.ts +9 -3
  446. package/src/MetadataList/MetadataList.test.tsx +75 -2
  447. package/src/MetadataList/MetadataListItem.tsx +5 -2
  448. package/src/MultiSelector/MultiSelector.doc.mjs +22 -1
  449. package/src/MultiSelector/MultiSelector.test.tsx +205 -0
  450. package/src/MultiSelector/MultiSelector.tsx +103 -16
  451. package/src/MultiSelector/hooks.ts +9 -2
  452. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  453. package/src/NavIcon/NavIcon.test.tsx +9 -0
  454. package/src/NavIcon/NavIcon.tsx +5 -1
  455. package/src/NavItem/navItemStyles.stylex.ts +0 -8
  456. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  457. package/src/NavMenu/NavHeadingMenu.tsx +7 -4
  458. package/src/NumberInput/NumberInput.doc.mjs +26 -7
  459. package/src/NumberInput/NumberInput.test.tsx +563 -8
  460. package/src/NumberInput/NumberInput.tsx +77 -131
  461. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  462. package/src/NumberInput/numberInputCommit.ts +103 -0
  463. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  464. package/src/NumberInput/numberParser.test.ts +222 -0
  465. package/src/NumberInput/numberParser.ts +403 -0
  466. package/src/Outline/Outline.tsx +2 -4
  467. package/src/OverflowList/OverflowList.doc.mjs +102 -21
  468. package/src/OverflowList/OverflowList.test.tsx +550 -4
  469. package/src/OverflowList/OverflowList.tsx +100 -2
  470. package/src/Pagination/Pagination.test.tsx +3 -2
  471. package/src/Popover/Popover.doc.mjs +2 -2
  472. package/src/Popover/Popover.test.tsx +38 -0
  473. package/src/Popover/Popover.tsx +28 -66
  474. package/src/Popover/usePopover.tsx +44 -5
  475. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
  476. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
  477. package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
  478. package/src/PowerSearch/formatFilterValue.test.ts +16 -1
  479. package/src/PowerSearch/formatFilterValue.ts +2 -0
  480. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  481. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  482. package/src/ProgressBar/ProgressBar.tsx +28 -8
  483. package/src/Resizable/Resizable.doc.mjs +2 -2
  484. package/src/Resizable/useResizable.doc.mjs +21 -2
  485. package/src/Resizable/useResizable.test.ts +421 -0
  486. package/src/Resizable/useResizable.ts +133 -48
  487. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  488. package/src/SelectableCard/SelectableCard.tsx +16 -0
  489. package/src/Selector/Selector.doc.mjs +14 -0
  490. package/src/Selector/Selector.source-build.test.mjs +65 -0
  491. package/src/Selector/Selector.test.tsx +301 -0
  492. package/src/Selector/Selector.tsx +145 -32
  493. package/src/Selector/hooks.ts +17 -2
  494. package/src/SideNav/SideNav.doc.mjs +2 -2
  495. package/src/SideNav/SideNav.test.tsx +1069 -6
  496. package/src/SideNav/SideNav.tsx +109 -38
  497. package/src/SideNav/SideNavHeading.tsx +5 -2
  498. package/src/SideNav/SideNavItem.doc.mjs +24 -3
  499. package/src/SideNav/SideNavItem.tsx +134 -44
  500. package/src/Slider/Slider.test.tsx +106 -1
  501. package/src/Slider/Slider.tsx +52 -1
  502. package/src/Spinner/Spinner.doc.mjs +17 -5
  503. package/src/Spinner/Spinner.test.tsx +164 -0
  504. package/src/Spinner/Spinner.tsx +252 -22
  505. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  506. package/src/StatusDot/StatusDot.test.tsx +9 -0
  507. package/src/StatusDot/StatusDot.tsx +7 -1
  508. package/src/Stepper/Step.doc.mjs +1 -1
  509. package/src/Stepper/Step.tsx +7 -14
  510. package/src/Switch/Switch.doc.mjs +2 -0
  511. package/src/Switch/Switch.test.tsx +10 -0
  512. package/src/Switch/Switch.tsx +3 -0
  513. package/src/Table/BaseTable.tsx +6 -1
  514. package/src/Table/Table.doc.mjs +5 -3
  515. package/src/Table/Table.tsx +3 -8
  516. package/src/Table/TableBody.doc.mjs +2 -2
  517. package/src/Table/TableFooter.doc.mjs +1 -1
  518. package/src/Table/TableHeader.doc.mjs +1 -1
  519. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  520. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  521. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
  522. package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
  523. package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
  524. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  525. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  526. package/src/Table/useTablePagination.doc.mjs +1 -1
  527. package/src/Table/useTableSelection.doc.mjs +1 -1
  528. package/src/Text/Text.test.tsx +44 -0
  529. package/src/Text/Text.tsx +0 -1
  530. package/src/TextArea/TextArea.doc.mjs +12 -2
  531. package/src/TextArea/TextArea.test.tsx +11 -0
  532. package/src/TextArea/TextArea.tsx +34 -22
  533. package/src/Timestamp/Timestamp.test.tsx +89 -0
  534. package/src/Timestamp/Timestamp.tsx +8 -8
  535. package/src/Timestamp/formatInstant.ts +5 -0
  536. package/src/Toast/Toast.doc.mjs +213 -44
  537. package/src/Toast/Toast.tsx +118 -23
  538. package/src/Toast/ToastViewport.test.tsx +1434 -8
  539. package/src/Toast/ToastViewport.tsx +85 -14
  540. package/src/Toast/index.ts +2 -0
  541. package/src/Toast/types.ts +43 -5
  542. package/src/Toast/useToastGesture.ts +361 -0
  543. package/src/Token/Token.test.tsx +95 -0
  544. package/src/Token/Token.tsx +19 -17
  545. package/src/Token/TokenLink.tsx +12 -3
  546. package/src/Tokenizer/Tokenizer.doc.mjs +16 -3
  547. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  548. package/src/Tokenizer/Tokenizer.tsx +49 -24
  549. package/src/TopNav/TopNavHeading.tsx +2 -2
  550. package/src/TopNav/TopNavItem.tsx +3 -7
  551. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  552. package/src/TopNav/TopNavMegaMenu.tsx +47 -4
  553. package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
  554. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  555. package/src/TopNav/TopNavMenu.tsx +38 -5
  556. package/src/TreeList/TreeList.test.tsx +49 -0
  557. package/src/TreeList/TreeList.tsx +7 -2
  558. package/src/TreeList/TreeListItem.tsx +2 -7
  559. package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
  560. package/src/Typeahead/BaseTypeahead.tsx +96 -6
  561. package/src/Typeahead/Typeahead.doc.mjs +6 -0
  562. package/src/Typeahead/Typeahead.test.tsx +154 -0
  563. package/src/Typeahead/Typeahead.tsx +9 -0
  564. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  565. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  566. package/src/hooks/useAnnounce.doc.mjs +96 -0
  567. package/src/hooks/useDevWarning.doc.mjs +96 -0
  568. package/src/hooks/useHotkeys.test.ts +0 -18
  569. package/src/hooks/useHotkeys.ts +3 -25
  570. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  571. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  572. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  573. package/src/hooks/useLongPress.doc.mjs +123 -0
  574. package/src/hooks/useOverflow.doc.mjs +58 -17
  575. package/src/hooks/useOverflow.ts +16 -4
  576. package/src/hooks/useTypeahead.doc.mjs +153 -0
  577. package/src/index.ts +2 -0
  578. package/src/raw-import.d.ts +14 -0
  579. package/src/theme/Theme.test.tsx +104 -2
  580. package/src/theme/Theme.tsx +49 -14
  581. package/src/theme/defineTheme.test.ts +23 -0
  582. package/src/theme/defineTheme.ts +12 -3
  583. package/src/theme/derivedVarRegistry.test.ts +87 -3
  584. package/src/theme/derivedVarRegistry.ts +23 -4
  585. package/src/theme/generateThemeRules.test.ts +99 -1
  586. package/src/theme/generateThemeRules.ts +28 -0
  587. package/src/theme/syntax/tokens.ts +5 -2
  588. package/src/theme/useTheme.test.tsx +10 -0
  589. package/src/theme/useTheme.ts +16 -10
  590. package/src/utils/dateParser.test.ts +34 -2
  591. package/src/utils/dateParser.ts +11 -14
  592. package/src/utils/focusOutline.stylex.ts +50 -0
  593. package/src/utils/interactionOverlay.stylex.ts +74 -0
  594. package/src/utils/isApplePlatform.test.ts +61 -0
  595. package/src/utils/isApplePlatform.ts +37 -0
  596. package/src/utils/plainDate.test.ts +46 -0
  597. package/src/utils/plainDate.ts +18 -3
@@ -43,6 +43,7 @@ export interface DerivedVarEntry {
43
43
  * entries share the same property.
44
44
  */
45
45
  export const derivedVarRegistry: Record<string, DerivedVarEntry[]> = {
46
+ avatar: [{property: 'borderRadius', vars: ['--_avatar-radius']}],
46
47
  banner: [{property: 'borderRadius', vars: ['--_banner-radius']}],
47
48
  button: [{property: 'borderRadius', vars: ['--_button-radius']}],
48
49
  card: [
@@ -66,13 +67,13 @@ export const derivedVarRegistry: Record<string, DerivedVarEntry[]> = {
66
67
  {property: 'padding', vars: ['--_dropdown-menu-padding']},
67
68
  ],
68
69
  field: [{property: 'borderRadius', vars: ['--_field-radius']}],
69
- hovercard: [{property: 'borderRadius', vars: ['--_hovercard-radius']}],
70
+ 'hover-card': [{property: 'borderRadius', vars: ['--_hovercard-radius']}],
70
71
  'number-input': [
71
72
  {property: 'padding', expand: 'container'},
72
73
  {property: 'borderRadius', vars: ['--_field-radius']},
73
74
  ],
74
75
  popover: [{property: 'borderRadius', vars: ['--_popover-radius']}],
75
- 'progressbar-mark': [
76
+ 'progress-bar-mark': [
76
77
  {property: 'width', vars: ['--_progressbar-mark-width'], replaces: true},
77
78
  {property: 'height', vars: ['--_progressbar-mark-height'], replaces: true},
78
79
  ],
@@ -81,7 +82,7 @@ export const derivedVarRegistry: Record<string, DerivedVarEntry[]> = {
81
82
  {property: 'borderRadius', vars: ['--_segmented-control-radius']},
82
83
  {property: 'padding', vars: ['--_segmented-control-padding']},
83
84
  ],
84
- textarea: [
85
+ 'text-area': [
85
86
  {
86
87
  property: 'paddingInline',
87
88
  vars: ['--_textarea-inline-padding'],
@@ -90,6 +91,21 @@ export const derivedVarRegistry: Record<string, DerivedVarEntry[]> = {
90
91
  ],
91
92
  };
92
93
 
94
+ /**
95
+ * Deprecated component keys → the key that superseded them.
96
+ *
97
+ * A renamed target keeps emitting its old class, so a theme written against
98
+ * the old key still selects the element. Without this the rule would land but
99
+ * its derived vars would not expand, and the half that travels through a var
100
+ * (a hover card's radius, a text area's inline padding) would silently do
101
+ * nothing. Drop these with the classes, in the next major.
102
+ */
103
+ const DEPRECATED_REGISTRY_KEYS: Record<string, string> = {
104
+ hovercard: 'hover-card',
105
+ 'progressbar-mark': 'progress-bar-mark',
106
+ textarea: 'text-area',
107
+ };
108
+
93
109
  /**
94
110
  * Look up derived var entries for a component + CSS property.
95
111
  * Returns matching entries in priority order, or empty array if none.
@@ -98,7 +114,10 @@ export function getDerivedVars(
98
114
  component: string,
99
115
  property: string,
100
116
  ): DerivedVarEntry[] {
101
- const entries = derivedVarRegistry[component];
117
+ const renamedTo = DEPRECATED_REGISTRY_KEYS[component];
118
+ const entries =
119
+ derivedVarRegistry[component] ??
120
+ (renamedTo ? derivedVarRegistry[renamedTo] : undefined);
102
121
  if (!entries) {
103
122
  return [];
104
123
  }
@@ -7,7 +7,13 @@
7
7
  */
8
8
 
9
9
  import {describe, it, expect} from 'vitest';
10
- import {defineTheme, generateThemeCSS, generateThemeRules} from './index';
10
+ import {
11
+ dataTokenDefaults,
12
+ defineTheme,
13
+ generateThemeCSS,
14
+ generateThemeRules,
15
+ } from './index';
16
+ import {generateDataTokenDefaultsCSS} from './generateThemeRules';
11
17
 
12
18
  const defaultInput = {
13
19
  name: 'default',
@@ -702,3 +708,95 @@ describe('physical padding longhands', () => {
702
708
  expect(rule).not.toContain('--_dropdown-menu-padding');
703
709
  });
704
710
  });
711
+
712
+ describe('renamed theme targets', () => {
713
+ // The renamed targets emit both classes, so a rule written against either
714
+ // key selects the element. What is easy to miss is the derived-var half: a
715
+ // key the registry does not know still emits a rule, minus every var the
716
+ // component actually reads — the same silent nothing a misspelled key gives.
717
+ it('expands derived vars for a renamed key and its deprecated spelling', () => {
718
+ const rules = (component: string, styles: Record<string, string>) =>
719
+ generateThemeRules(
720
+ defineTheme({
721
+ name: `test-renamed-${component}`,
722
+ components: {[component]: {base: styles}},
723
+ }),
724
+ ).join('\n');
725
+
726
+ const hoverCard = rules('hover-card', {borderRadius: '9px'});
727
+ expect(hoverCard).toContain('.astryx-hover-card');
728
+ expect(hoverCard).toContain('--_hovercard-radius: 9px');
729
+ expect(rules('hovercard', {borderRadius: '9px'})).toContain(
730
+ '--_hovercard-radius: 9px',
731
+ );
732
+
733
+ const textArea = rules('text-area', {paddingInline: '11px'});
734
+ expect(textArea).toContain('.astryx-text-area');
735
+ expect(textArea).toContain('--_textarea-inline-padding: 11px');
736
+ expect(rules('textarea', {paddingInline: '11px'})).toContain(
737
+ '--_textarea-inline-padding: 11px',
738
+ );
739
+
740
+ const mark = rules('progress-bar-mark', {width: '3px'});
741
+ expect(mark).toContain('.astryx-progress-bar-mark');
742
+ expect(mark).toContain('--_progressbar-mark-width: 3px');
743
+ expect(rules('progressbar-mark', {width: '3px'})).toContain(
744
+ '--_progressbar-mark-width: 3px',
745
+ );
746
+ });
747
+ });
748
+
749
+ describe('data visualization tokens', () => {
750
+ const scopeBlock = (theme: Parameters<typeof generateThemeRules>[0]) =>
751
+ generateThemeRules(theme).find(r => r.includes(':scope'));
752
+
753
+ it('seeds the whole palette once, at :root', () => {
754
+ const css = generateDataTokenDefaultsCSS();
755
+
756
+ expect(css.startsWith(':root {')).toBe(true);
757
+ for (const [name, value] of Object.entries(dataTokenDefaults)) {
758
+ expect(css).toContain(`${name}: ${value};`);
759
+ }
760
+ });
761
+
762
+ it('leaves the defaults out of a theme scope block', () => {
763
+ // A scope block that re-declared them would shadow a parent theme's
764
+ // override in every nested <Theme>, which no other token family does.
765
+ expect(scopeBlock(defineTheme({name: 'data-bare'}))).toBeUndefined();
766
+ });
767
+
768
+ it("puts only the theme's own data token in its scope block", () => {
769
+ const block = scopeBlock(
770
+ defineTheme({
771
+ name: 'data-override',
772
+ tokens: {'--color-data-categorical-blue': ['#123456', '#654321']},
773
+ }),
774
+ )!;
775
+
776
+ expect(block).toContain(
777
+ '--color-data-categorical-blue: light-dark(#123456, #654321);',
778
+ );
779
+ expect(block.match(/--color-data-/g)).toHaveLength(1);
780
+ expect(block).not.toContain('--color-data-categorical-orange');
781
+ });
782
+
783
+ it('keeps the palette out of the scoped stylesheet', () => {
784
+ // The palette's own contents are asserted once, against
785
+ // `dataTokenDefaults`, in `seeds the whole palette once, at :root` above.
786
+ const {component, prose} = generateThemeCSS(
787
+ defineTheme({name: 'data-css'}),
788
+ );
789
+
790
+ expect(component).not.toContain('--color-data-');
791
+ expect(prose).not.toContain('--color-data-');
792
+ });
793
+
794
+ it('keeps generateThemeCSS to its two scoped blocks', () => {
795
+ // The defaults are theme-independent, so they are not part of the theme
796
+ // CSS contract: `astryx theme build` formats them from the public
797
+ // `dataTokenDefaults` export instead.
798
+ expect(
799
+ Object.keys(generateThemeCSS(defineTheme({name: 'data-shape'}))).sort(),
800
+ ).toEqual(['component', 'prose']);
801
+ });
802
+ });
@@ -18,6 +18,7 @@
18
18
  import type {DefinedTheme} from './defineTheme';
19
19
  import {parseStyleKey} from '../utils/parseStyleKey';
20
20
  import {getDerivedVars} from './derivedVarRegistry';
21
+ import {dataTokenDefaults} from './domainTokens/dataTokens';
21
22
  import {cssVar, classPrefix, dataAttrNamespace} from '../naming';
22
23
 
23
24
  /**
@@ -758,6 +759,30 @@ export function generateOnMediaCSS(theme: DefinedTheme): string {
758
759
  return `@scope (${scopeSelector}) to (${THEME_SCOPE_TO}) {\n${inner}\n}`;
759
760
  }
760
761
 
762
+ /**
763
+ * The `--color-data-*` defaults as one unscoped `:root` block.
764
+ *
765
+ * Core tokens reach CSS once, at `:root`, from StyleX's `defineVars` output in
766
+ * `@layer astryx-base`; a theme's own scope block then carries only the tokens
767
+ * that theme overrides, which is why a nested theme inherits its parent's
768
+ * override instead of shadowing it. Data tokens are not StyleX vars, so nothing
769
+ * declares them — this is their equivalent, and callers put it in
770
+ * `@layer astryx-base` so a theme's override wins by layer rather than by
771
+ * specificity. Seeding it per theme scope instead re-declares the default
772
+ * inside every nested theme, which is the shadowing this shape avoids.
773
+ *
774
+ * @internal Not exported from `@astryxdesign/core/theme`: the `<Theme>`
775
+ * runtime is the only caller. `astryx theme build` formats the same block from
776
+ * the public `dataTokenDefaults` export, and a CLI test asserts the two are
777
+ * byte-identical.
778
+ */
779
+ export function generateDataTokenDefaultsCSS(): string {
780
+ const declarations = Object.entries(dataTokenDefaults)
781
+ .map(([prop, value]) => ` ${prop}: ${value};`)
782
+ .join('\n');
783
+ return `:root {\n${declarations}\n}`;
784
+ }
785
+
761
786
  /**
762
787
  * Generate layered CSS for a theme — runtime path.
763
788
  *
@@ -768,6 +793,9 @@ export function generateOnMediaCSS(theme: DefinedTheme): string {
768
793
  * This separation ensures prose defaults (what bare HTML looks like in a theme)
769
794
  * sit at reset-layer priority where any class-based style wins, while component
770
795
  * overrides sit above StyleX so themes can restyle components intentionally.
796
+ *
797
+ * The theme-independent `--color-data-*` defaults are not part of this output:
798
+ * see `generateDataTokenDefaultsCSS`.
771
799
  */
772
800
  export function generateThemeCSS(theme: DefinedTheme): ThemeCSSOutput {
773
801
  const {component, prose} = generateThemeRulesSplit(theme);
@@ -44,8 +44,11 @@ export const syntaxTokenDefaults = {
44
44
  '--color-syntax-attribute': 'var(--color-text-teal)',
45
45
  // property -> cyan text (object properties)
46
46
  '--color-syntax-property': 'var(--color-text-cyan)',
47
- // punctuation -> disabled text (brackets, semicolons)
48
- '--color-syntax-punctuation': 'var(--color-text-disabled)',
47
+ // punctuation -> secondary text (brackets, semicolons). Not disabled text:
48
+ // disabled grey is calibrated to fail AA on purpose (WCAG exempts inactive
49
+ // controls), and punctuation in a code sample is normal, always-active
50
+ // text — see #5386.
51
+ '--color-syntax-punctuation': 'var(--color-text-secondary)',
49
52
  // background -> muted surface
50
53
  '--color-syntax-background': 'var(--color-background-muted)',
51
54
  } as const;
@@ -108,6 +108,16 @@ describe('useTheme', () => {
108
108
  expect(result.current.token('--color-text-primary')).toBe('#DFE2E5');
109
109
  });
110
110
 
111
+ it('keeps the token resolver and return object stable across rerenders', () => {
112
+ const {result, rerender} = renderHook(() => useTheme());
113
+ const first = result.current;
114
+
115
+ rerender();
116
+
117
+ expect(result.current.token).toBe(first.token);
118
+ expect(result.current).toBe(first);
119
+ });
120
+
111
121
  it('returns empty string for unknown tokens', () => {
112
122
  const {result} = renderHook(() => useTheme(), {
113
123
  wrapper: ({children}) => wrapper({children, mode: 'light'}),
@@ -21,7 +21,13 @@
21
21
  * - /packages/core/src/theme/index.ts
22
22
  */
23
23
 
24
- import {createContext, use, useMemo, useSyncExternalStore} from 'react';
24
+ import {
25
+ createContext,
26
+ use,
27
+ useCallback,
28
+ useMemo,
29
+ useSyncExternalStore,
30
+ } from 'react';
25
31
  import type {ThemeMode} from './types';
26
32
  import type {DefinedTheme} from './defineTheme';
27
33
  import {resolveThemeTokens} from './tokens';
@@ -281,14 +287,14 @@ export function useTheme(): UseThemeReturn {
281
287
  [theme, effectiveMode],
282
288
  );
283
289
 
284
- const token = (name: string): string => {
285
- return tokens[name] ?? '';
286
- };
290
+ const token = useCallback(
291
+ (name: string): string => tokens[name] ?? '',
292
+ [tokens],
293
+ );
294
+ const name = theme?.name ?? 'default';
287
295
 
288
- return {
289
- name: theme?.name ?? 'default',
290
- mode: effectiveMode,
291
- token,
292
- tokens,
293
- };
296
+ return useMemo(
297
+ () => ({name, mode: effectiveMode, token, tokens}),
298
+ [name, effectiveMode, token, tokens],
299
+ );
294
300
  }
@@ -9,8 +9,8 @@
9
9
  * SYNC: When dateParser.ts changes, update tests to match new behavior
10
10
  */
11
11
 
12
- import {describe, it, expect} from 'vitest';
13
- import {parseDateInput} from './dateParser';
12
+ import {describe, it, expect, vi} from 'vitest';
13
+ import {isLocaleDayFirst, parseDateInput} from './dateParser';
14
14
 
15
15
  describe('parseDateInput', () => {
16
16
  describe('ISO format (YYYY-MM-DD)', () => {
@@ -280,6 +280,14 @@ describe('parseDateInput', () => {
280
280
  describe('ambiguous numeric formats follow the passed locale (#5074)', () => {
281
281
  // Both numbers are <= 12, so the day/month order is genuinely ambiguous
282
282
  // and resolved by isLocaleDayFirst(locale) rather than the host locale.
283
+ it('defaults ambiguous input to English month-first order', () => {
284
+ expect(parseDateInput('3/4/2026')).toEqual({
285
+ year: 2026,
286
+ month: 3,
287
+ day: 4,
288
+ });
289
+ });
290
+
283
291
  it('reads month-first for en-US', () => {
284
292
  expect(parseDateInput('3/4/2026', 'en-US')).toEqual({
285
293
  year: 2026,
@@ -297,6 +305,30 @@ describe('parseDateInput', () => {
297
305
  });
298
306
  });
299
307
 
308
+ describe('isLocaleDayFirst', () => {
309
+ it('defaults to English month-first order', () => {
310
+ expect(isLocaleDayFirst()).toBe(false);
311
+ });
312
+
313
+ it('requests Gregorian calendar data for locale ordering', () => {
314
+ const OriginalDateTimeFormat = globalThis.Intl.DateTimeFormat;
315
+ const dateTimeFormatSpy = vi
316
+ .spyOn(globalThis.Intl, 'DateTimeFormat')
317
+ .mockImplementation(function DateTimeFormat(locale, options) {
318
+ return new OriginalDateTimeFormat(locale, options);
319
+ });
320
+
321
+ try {
322
+ isLocaleDayFirst('en-US-u-ca-buddhist');
323
+ expect(dateTimeFormatSpy).toHaveBeenCalledWith('en-US-u-ca-buddhist', {
324
+ calendar: 'gregory',
325
+ });
326
+ } finally {
327
+ dateTimeFormatSpy.mockRestore();
328
+ }
329
+ });
330
+ });
331
+
300
332
  describe('edge cases', () => {
301
333
  it('returns null for empty string', () => {
302
334
  expect(parseDateInput('')).toBeNull();
@@ -23,10 +23,10 @@ export {
23
23
  * Detects if the locale uses day-first date format (DD/MM/YYYY).
24
24
  * US and a few others use month-first (MM/DD/YYYY).
25
25
  */
26
- export function isLocaleDayFirst(locale?: Locale): boolean {
27
- const parts = new Intl.DateTimeFormat(locale).formatToParts(
28
- new Date(2000, 0, 15),
29
- );
26
+ export function isLocaleDayFirst(locale: Locale = 'en'): boolean {
27
+ const parts = new Intl.DateTimeFormat(locale, {
28
+ calendar: 'gregory',
29
+ }).formatToParts(new Date(2000, 0, 15));
30
30
  const dayIndex = parts.findIndex(p => p.type === 'day');
31
31
  const monthIndex = parts.findIndex(p => p.type === 'month');
32
32
  return dayIndex < monthIndex;
@@ -35,20 +35,17 @@ export function isLocaleDayFirst(locale?: Locale): boolean {
35
35
  /**
36
36
  * Parses user input into a PlainDate.
37
37
  *
38
- * Supports:
39
- * - ISO format: "2026-01-25"
40
- * - Full month names: "January 25, 2026", "25 January 2026"
41
- * - Full month names without year: "January 25", "25 January" (defaults to current year)
42
- * - Numeric formats: "1/25/2026", "25/1/2026" (locale-aware with heuristics)
43
- * - Numeric formats without year: "1/25", "25/1" (defaults to current year)
44
- *
45
- * For ambiguous numeric formats (both numbers ≤ 12), uses locale preference.
38
+ * Supports ISO dates, English month names, and ASCII numeric dates with or
39
+ * without a year. For ambiguous ASCII numeric input where both fields are at
40
+ * most 12, `locale` selects month-first versus day-first order. It does not
41
+ * localize month-name parsing, accept non-ASCII digits, or provide a general
42
+ * locale-aware parser.
46
43
  *
47
44
  * @returns PlainDate if valid, null if unparseable
48
45
  */
49
46
  export function parseDateInput(
50
47
  input: string,
51
- locale?: Locale,
48
+ locale: Locale = 'en',
52
49
  ): PlainDate | null {
53
50
  const trimmed = input.trim();
54
51
  if (!trimmed) {
@@ -157,7 +154,7 @@ function parseNumericDate(
157
154
  first: number,
158
155
  second: number,
159
156
  year: number,
160
- locale?: Locale,
157
+ locale: Locale,
161
158
  ): PlainDate | null {
162
159
  let day: number;
163
160
  let month: number;
@@ -124,6 +124,52 @@ export const focusOutlineStyles = stylex.create({
124
124
  },
125
125
  outlineOffset: {default: '0', ':has(:focus-visible)': FOCUS_OUTLINE_OFFSET},
126
126
  },
127
+ /**
128
+ * Like {@link focusOutlineStyles.focusWithin}, but only for the element's
129
+ * FIRST child — for a wrapper that paints the ring on behalf of one primary
130
+ * control while its siblings ring themselves.
131
+ *
132
+ * `focusWithin` matches any descendant, so a row holding more than one tab
133
+ * stop lights the whole row *on top of* the focused control's own ring: two
134
+ * outlines for one tab stop. Scoping to `> :first-child` keeps the ring the
135
+ * primary's, and leaves every sibling control ringing itself.
136
+ *
137
+ * The wrapper owns the coupling: the primary has to be its first child, and
138
+ * the wrapper must not be a tab stop (its own `:focus-visible` would never
139
+ * match). Pair it with {@link focusOutlineStyles.suppressed} on the primary.
140
+ */
141
+ focusWithinFirstChild: {
142
+ outlineWidth: {
143
+ default: '0',
144
+ ':has(> :first-child:focus-visible)': focusOutlineLonghands.outlineWidth,
145
+ },
146
+ outlineStyle: {
147
+ default: 'none',
148
+ ':has(> :first-child:focus-visible)': focusOutlineLonghands.outlineStyle,
149
+ },
150
+ outlineColor: {
151
+ default: null,
152
+ ':has(> :first-child:focus-visible)': focusOutlineLonghands.outlineColor,
153
+ },
154
+ outlineOffset: {
155
+ default: '0',
156
+ ':has(> :first-child:focus-visible)': FOCUS_OUTLINE_OFFSET,
157
+ },
158
+ },
159
+ /**
160
+ * Draws no ring, and keeps the UA's own off — for an element whose ring an
161
+ * ancestor paints.
162
+ *
163
+ * The reset is not optional. Every other style here suppresses the browser
164
+ * default through its `default` branch, so dropping the ring from a control
165
+ * drops that suppression with it, and a bare `<a>` or `<button>` goes back
166
+ * to the UA focus ring — painted *inside* the ancestor's.
167
+ */
168
+ suppressed: {
169
+ outlineWidth: '0',
170
+ outlineStyle: 'none',
171
+ outlineOffset: '0',
172
+ },
127
173
  publishFocusVisibleVars: {
128
174
  '--_focus-outline': {
129
175
  default: 'none',
@@ -168,6 +214,10 @@ function makeFocusOutlineProps(style: StyleXPropsArg) {
168
214
  export const focusOutlineProps = {
169
215
  focusVisible: makeFocusOutlineProps(focusOutlineStyles.focusVisible),
170
216
  focusWithin: makeFocusOutlineProps(focusOutlineStyles.focusWithin),
217
+ focusWithinFirstChild: makeFocusOutlineProps(
218
+ focusOutlineStyles.focusWithinFirstChild,
219
+ ),
220
+ suppressed: makeFocusOutlineProps(focusOutlineStyles.suppressed),
171
221
  publishFocusVisibleVars: makeFocusOutlineProps(
172
222
  focusOutlineStyles.publishFocusVisibleVars,
173
223
  ),
@@ -0,0 +1,74 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /* eslint-disable @astryx/no-hover-on-disabled -- Every hover branch is
4
+ * nested beneath ENABLED below. Keeping that shared guard outside the media
5
+ * branch is what gives hover and active matching generated specificity. */
6
+
7
+ /**
8
+ * @file Shared hover and pressed overlay states
9
+ * @input Uses StyleX and the semantic interaction-overlay color tokens
10
+ * @output Exports reusable background-color and background-image state styles
11
+ * @position Internal styling utility for interactive core surfaces
12
+ *
13
+ * Keep the enabled guard outside the individual states. StyleX assigns an
14
+ * extra priority bucket (and generated selector specificity) to media-nested
15
+ * rules. Repeating `:active` inside the hover-capable branch gives hover and
16
+ * press the same generated specificity; StyleX's native pseudo-state ordering
17
+ * then emits `:active` last. The bare `:active` branch remains the touch
18
+ * fallback, where `(hover: hover)` does not match.
19
+ */
20
+
21
+ import * as stylex from '@stylexjs/stylex';
22
+ import {colorVars} from '../theme/tokens.stylex';
23
+
24
+ const ENABLED = ':where(:not(:disabled,[aria-disabled="true"]))';
25
+ const HOVER_HOVER = '@media (hover: hover)';
26
+
27
+ const hoverImage = `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']})`;
28
+ const pressedImage = `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`;
29
+ const neutralImage = `linear-gradient(${colorVars['--color-neutral']}, ${colorVars['--color-neutral']})`;
30
+
31
+ export const interactionOverlayStyles = stylex.create({
32
+ backgroundColor: {
33
+ backgroundColor: {
34
+ default: 'transparent',
35
+ [ENABLED]: {
36
+ default: null,
37
+ ':active': colorVars['--color-overlay-pressed'],
38
+ [HOVER_HOVER]: {
39
+ default: null,
40
+ ':hover': colorVars['--color-overlay-hover'],
41
+ ':active': colorVars['--color-overlay-pressed'],
42
+ },
43
+ },
44
+ },
45
+ },
46
+ backgroundImage: {
47
+ backgroundImage: {
48
+ default: null,
49
+ [ENABLED]: {
50
+ default: null,
51
+ ':active': pressedImage,
52
+ [HOVER_HOVER]: {
53
+ default: null,
54
+ ':hover': hoverImage,
55
+ ':active': pressedImage,
56
+ },
57
+ },
58
+ },
59
+ },
60
+ backgroundImageOnNeutral: {
61
+ backgroundImage: {
62
+ default: neutralImage,
63
+ [ENABLED]: {
64
+ default: null,
65
+ ':active': `${pressedImage}, ${neutralImage}`,
66
+ [HOVER_HOVER]: {
67
+ default: null,
68
+ ':hover': `${hoverImage}, ${neutralImage}`,
69
+ ':active': `${pressedImage}, ${neutralImage}`,
70
+ },
71
+ },
72
+ },
73
+ },
74
+ });
@@ -0,0 +1,61 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file isApplePlatform.test.ts
5
+ * @input Uses vitest, isApplePlatform
6
+ * @output Unit tests for isApplePlatform
7
+ * @position Testing; validates isApplePlatform.ts implementation
8
+ */
9
+
10
+ import {describe, it, expect, vi, afterEach} from 'vitest';
11
+ import {isApplePlatform} from './isApplePlatform';
12
+
13
+ afterEach(() => {
14
+ vi.unstubAllGlobals();
15
+ });
16
+
17
+ describe('isApplePlatform', () => {
18
+ it('trusts a client-hints platform that names one', () => {
19
+ vi.stubGlobal('navigator', {
20
+ userAgentData: {platform: 'macOS'},
21
+ platform: 'Win32',
22
+ });
23
+ expect(isApplePlatform()).toBe(true);
24
+
25
+ vi.stubGlobal('navigator', {
26
+ userAgentData: {platform: 'Windows'},
27
+ platform: 'MacIntel',
28
+ });
29
+ expect(isApplePlatform()).toBe(false);
30
+ });
31
+
32
+ it.each([
33
+ ['blank', ''],
34
+ ['whitespace', ' '],
35
+ ['the spec Unknown sentinel', 'Unknown'],
36
+ ['unknown in any case', 'UNKNOWN'],
37
+ ['a non-string', null],
38
+ ])('falls through to navigator.platform on %s', (_label, platform) => {
39
+ vi.stubGlobal('navigator', {
40
+ userAgentData: {platform},
41
+ platform: 'MacIntel',
42
+ });
43
+ expect(isApplePlatform()).toBe(true);
44
+
45
+ vi.stubGlobal('navigator', {userAgentData: {platform}, platform: 'Win32'});
46
+ expect(isApplePlatform()).toBe(false);
47
+ });
48
+
49
+ it('falls back to navigator.platform when client hints are absent', () => {
50
+ vi.stubGlobal('navigator', {platform: 'iPhone'});
51
+ expect(isApplePlatform()).toBe(true);
52
+
53
+ vi.stubGlobal('navigator', {platform: 'Linux x86_64'});
54
+ expect(isApplePlatform()).toBe(false);
55
+ });
56
+
57
+ it('answers false when there is no navigator at all', () => {
58
+ vi.stubGlobal('navigator', undefined);
59
+ expect(isApplePlatform()).toBe(false);
60
+ });
61
+ });
@@ -0,0 +1,37 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file isApplePlatform.ts
5
+ * @input Reads navigator.userAgentData.platform and navigator.platform
6
+ * @output Exports isApplePlatform
7
+ * @position Internal util; the single platform detection behind useHotkeys and Kbd
8
+ *
9
+ * Deliberately absent from utils/index.ts: packages/core/src/index.ts does
10
+ * `export * from './utils'`, so naming it there would publish it as API.
11
+ * Import it by path, as interactionModality is imported.
12
+ */
13
+
14
+ /**
15
+ * Detects whether the current platform is macOS/iOS.
16
+ * Prefers the User-Agent Client Hints API when it names a platform (modern
17
+ * Chrome/Edge), falls back to navigator.platform (deprecated but universally
18
+ * supported) when it names none.
19
+ */
20
+ export function isApplePlatform(): boolean {
21
+ if (typeof navigator === 'undefined') {
22
+ return false;
23
+ }
24
+ const uaData = 'userAgentData' in navigator ? navigator.userAgentData : null;
25
+ if (uaData && typeof uaData === 'object' && 'platform' in uaData) {
26
+ const uaPlatform = (uaData as {platform?: unknown}).platform;
27
+ const named = typeof uaPlatform === 'string' ? uaPlatform.trim() : '';
28
+ // A value that names nothing is no answer, not a negative one: builds that
29
+ // rewrite their client-hints identity ship '', and 'Unknown' is the spec's
30
+ // own sentinel for "cannot say". Both fall through rather than reading as
31
+ // "not Apple".
32
+ if (named !== '' && named.toLowerCase() !== 'unknown') {
33
+ return /mac/i.test(named);
34
+ }
35
+ }
36
+ return /Mac|iPhone|iPad|iPod/.test(navigator.platform ?? '');
37
+ }