@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
@@ -9,8 +9,9 @@
9
9
  * @position Core hook; used by OverflowList and consumers for overflow patterns
10
10
  *
11
11
  * Measures children rendered in a hidden container to determine how many fit
12
- * in the available width, without flickering. Uses ResizeObserver to react
13
- * to container size changes. Supports an optional item cap (`maxVisibleItems`)
12
+ * in the available width, without flickering. Observes both the visible and
13
+ * hidden measurement containers so changes to available width or measured child
14
+ * sizes recalculate the result. Supports an optional item cap (`maxVisibleItems`)
14
15
  * and bounded multi-row wrapping (`maxRows`); the fit/clamp/row-packing math
15
16
  * lives in the pure `computeOverflow` helper.
16
17
  *
@@ -136,6 +137,7 @@ export function useOverflow(
136
137
  const containerElRef = useRef<HTMLElement | null>(null);
137
138
  const measureElRef = useRef<HTMLElement | null>(null);
138
139
  const observedElRef = useRef<HTMLElement | null>(null);
140
+ const observedMeasureElRef = useRef<HTMLElement | null>(null);
139
141
 
140
142
  const calculate = useCallback(() => {
141
143
  const container = containerElRef.current;
@@ -236,10 +238,20 @@ export function useOverflow(
236
238
 
237
239
  const measureRef = useCallback(
238
240
  (el: HTMLElement | null) => {
241
+ if (observedMeasureElRef.current) {
242
+ unobserveResize(observedMeasureElRef.current);
243
+ observedMeasureElRef.current = null;
244
+ }
245
+
239
246
  measureElRef.current = el;
240
- if (el) {
241
- calculate();
247
+ if (!el) {
248
+ return;
242
249
  }
250
+
251
+ observeResize(el, () => {
252
+ calculate();
253
+ });
254
+ observedMeasureElRef.current = el;
243
255
  },
244
256
  [calculate],
245
257
  );
@@ -0,0 +1,153 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('@astryxdesign/cli/authoring').HookDoc} */
4
+ export const docs = {
5
+ name: 'useTypeahead',
6
+ displayName: 'useTypeahead',
7
+ keywords: [
8
+ 'typeahead',
9
+ 'type to focus',
10
+ 'first character',
11
+ 'keyboard',
12
+ 'search',
13
+ 'jump',
14
+ 'menu',
15
+ 'listbox',
16
+ 'select',
17
+ 'apg',
18
+ 'accessibility',
19
+ 'a11y',
20
+ ],
21
+ params: [
22
+ {
23
+ name: 'options',
24
+ type: 'UseTypeaheadOptions',
25
+ description: 'Configuration object.',
26
+ required: true,
27
+ },
28
+ {
29
+ name: 'options.getItemLabels',
30
+ type: '() => ReadonlyArray<string | null | undefined>',
31
+ description:
32
+ "Returns the item labels in DOM order. A null or empty entry marks a non-matchable slot and keeps indices aligned with the caller's items.",
33
+ required: true,
34
+ },
35
+ {
36
+ name: 'options.onMatch',
37
+ type: '(index: number) => void',
38
+ description:
39
+ "Called with the index of the matched item so the caller can focus or select it; typically useListFocus's focusItem.",
40
+ required: true,
41
+ },
42
+ {
43
+ name: 'options.getCurrentIndex',
44
+ type: '() => number',
45
+ description:
46
+ 'The index to search from, usually the focused item, so repeated presses of one letter cycle through matches. A negative value means nothing is current.',
47
+ default: '() => -1',
48
+ },
49
+ {
50
+ name: 'options.resetMs',
51
+ type: 'number',
52
+ description:
53
+ 'Milliseconds of inactivity after which the typed buffer resets.',
54
+ default: '750',
55
+ },
56
+ {
57
+ name: 'options.isDisabled',
58
+ type: '(index: number) => boolean',
59
+ description: 'Whether an index should be skipped, e.g. disabled items.',
60
+ },
61
+ ],
62
+ returns: [
63
+ {
64
+ name: 'onKeyDown',
65
+ type: '(e: React.KeyboardEvent | KeyboardEvent) => boolean',
66
+ description:
67
+ 'Keydown handler. Returns true when it consumed a printable character, so the caller can stop its own key handling.',
68
+ },
69
+ {
70
+ name: 'reset',
71
+ type: '() => void',
72
+ description:
73
+ 'Clears the pending buffer, e.g. when the collection closes.',
74
+ },
75
+ ],
76
+ usage: {
77
+ description:
78
+ "Adds APG type-to-focus search to a collection: printable keystrokes are buffered (resetting after a pause), and the first item whose label starts with the buffer is reported through onMatch. Pressing the same letter repeatedly cycles through the matches rather than filtering deeper. It moves nothing itself; pair it with the collection's own focus management, most often useListFocus or useGridFocus.",
79
+ bestPractices: [
80
+ {
81
+ guidance: true,
82
+ description:
83
+ 'Wire onMatch to the focus manager you already have (useListFocus.focusItem) instead of moving focus yourself.',
84
+ },
85
+ {
86
+ guidance: true,
87
+ description:
88
+ 'Let it see the key event first and fall through to arrow-key navigation only when it returns false.',
89
+ },
90
+ {
91
+ guidance: true,
92
+ description:
93
+ 'Pass getCurrentIndex so repeated presses of one letter walk through matches instead of sticking on the first.',
94
+ },
95
+ {
96
+ guidance: false,
97
+ description:
98
+ 'Use it on a text input; the field already receives the characters, and typeahead would fight the value.',
99
+ },
100
+ ],
101
+ },
102
+ relatedComponents: ['DropdownMenu', 'Selector', 'TreeList'],
103
+ relatedHooks: ['useListFocus', 'useGridFocus', 'useTreeFocus'],
104
+ importPath: '@astryxdesign/core/hooks',
105
+ category: 'focus',
106
+ };
107
+
108
+ /** @type {import('@astryxdesign/cli/authoring').HookTranslationDoc} */
109
+ export const docsDense = {
110
+ description:
111
+ 'APG type-to-focus search for a collection. Buffers printable keys (resets after pause), matches labels by prefix, reports index via onMatch. Same letter pressed repeatedly cycles matches. Moves nothing itself; pair w/ useListFocus / useGridFocus.',
112
+ paramDescriptions: {
113
+ options: 'config.',
114
+ 'options.getItemLabels':
115
+ 'item labels in DOM order; null / empty = non-matchable slot, indices stay aligned.',
116
+ 'options.onMatch':
117
+ 'called w/ matched index so caller focuses / selects (e.g. useListFocus focusItem).',
118
+ 'options.getCurrentIndex':
119
+ 'index to search from (usually focused item) so repeat presses cycle. negative = nothing current.',
120
+ 'options.resetMs': 'ms of inactivity before typed buffer resets.',
121
+ 'options.isDisabled': 'whether an index is skipped (e.g. disabled items).',
122
+ },
123
+ returnDescriptions: {
124
+ onKeyDown:
125
+ 'keydown handler; true = consumed a printable char, caller can stop its own handling.',
126
+ reset: 'clears pending buffer (e.g. on close).',
127
+ },
128
+ usage: {
129
+ description:
130
+ 'Type-to-jump for menus / listboxes / trees. Buffered prefix match w/ APG same-letter cycling; reports index, caller owns focus.',
131
+ bestPractices: [
132
+ {
133
+ guidance: true,
134
+ description:
135
+ 'Wire onMatch to existing focus manager (useListFocus.focusItem), do not move focus yourself.',
136
+ },
137
+ {
138
+ guidance: true,
139
+ description:
140
+ 'Give it the key event first; fall through to arrow navigation when it returns false.',
141
+ },
142
+ {
143
+ guidance: true,
144
+ description:
145
+ 'Pass getCurrentIndex so repeat presses walk matches instead of sticking on first.',
146
+ },
147
+ {
148
+ guidance: false,
149
+ description: 'Use on a text input; field already gets the characters.',
150
+ },
151
+ ],
152
+ },
153
+ };
package/src/index.ts CHANGED
@@ -135,6 +135,8 @@ export type {
135
135
  ToastOptions,
136
136
  ToastDismissFn,
137
137
  ShowToastFn,
138
+ ToastContentRenderProps,
139
+ ToastContentRenderFn,
138
140
  } from './Toast';
139
141
 
140
142
  // Popover component and hook
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Ambient module declaration for Vite's `?raw` imports.
5
+ *
6
+ * numberParser.docblock.test.ts reads its own subject's source as text, to
7
+ * check the prose in it against the parser's behaviour. Vite serves that with
8
+ * the `?raw` query; without this declaration TypeScript fails with TS2307.
9
+ */
10
+
11
+ declare module '*?raw' {
12
+ const content: string;
13
+ export default content;
14
+ }
@@ -1,10 +1,22 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
- import {describe, it, expect, beforeEach, afterEach} from 'vitest';
3
+ import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
4
4
  import {render, cleanup} from '@testing-library/react';
5
5
  import React from 'react';
6
6
  import {Theme} from './Theme';
7
7
  import {defineTheme} from './defineTheme';
8
+ import {dataTokenDefaults} from './domainTokens';
9
+ import type * as DefineThemeModule from './defineTheme';
10
+
11
+ const {generateThemeCSSSpy} = vi.hoisted(() => ({
12
+ generateThemeCSSSpy: vi.fn(),
13
+ }));
14
+
15
+ vi.mock('./defineTheme', async importOriginal => {
16
+ const actual = await importOriginal<typeof DefineThemeModule>();
17
+ generateThemeCSSSpy.mockImplementation(actual.generateThemeCSS);
18
+ return {...actual, generateThemeCSS: generateThemeCSSSpy};
19
+ });
8
20
 
9
21
  const testTheme = defineTheme({
10
22
  name: 'test',
@@ -25,6 +37,7 @@ describe('Theme', () => {
25
37
  // Clean up documentElement state before each test
26
38
  document.documentElement.removeAttribute('data-theme');
27
39
  document.documentElement.removeAttribute('data-astryx-theme');
40
+ generateThemeCSSSpy.mockClear();
28
41
  });
29
42
 
30
43
  afterEach(() => {
@@ -120,7 +133,9 @@ describe('Theme', () => {
120
133
  'test',
121
134
  );
122
135
  unmount();
123
- expect(document.documentElement.hasAttribute('data-astryx-theme')).toBe(false);
136
+ expect(document.documentElement.hasAttribute('data-astryx-theme')).toBe(
137
+ false,
138
+ );
124
139
  });
125
140
 
126
141
  // =========================================================================
@@ -166,4 +181,91 @@ describe('Theme', () => {
166
181
  expect(nestedWrapper).toBeTruthy();
167
182
  expect(nestedWrapper?.getAttribute('data-theme')).toBe('light');
168
183
  });
184
+
185
+ // =========================================================================
186
+ // Data token defaults — one shared :root block, not one per theme scope
187
+ // =========================================================================
188
+
189
+ const baseTags = () =>
190
+ Array.from(document.head.querySelectorAll('style[data-astryx-theme-base]'));
191
+
192
+ it('injects the data token defaults into @layer astryx-base', () => {
193
+ render(
194
+ <Theme theme={testTheme}>
195
+ <span>child</span>
196
+ </Theme>,
197
+ );
198
+
199
+ expect(baseTags()).toHaveLength(1);
200
+ const css = baseTags()[0].textContent ?? '';
201
+ expect(css).toContain('@layer astryx-base {');
202
+ expect(css).toContain(':root {');
203
+ expect(css).toContain(
204
+ `--color-data-categorical-blue: ${dataTokenDefaults['--color-data-categorical-blue']};`,
205
+ );
206
+ });
207
+
208
+ it('injects one shared block for nested themes, not one per scope', () => {
209
+ render(
210
+ <Theme theme={testTheme}>
211
+ <Theme theme={altTheme}>
212
+ <span>nested</span>
213
+ </Theme>
214
+ </Theme>,
215
+ );
216
+
217
+ expect(baseTags()).toHaveLength(1);
218
+
219
+ // The nested theme declares no --color-data-* of its own, so nothing
220
+ // shadows a value the parent theme set: that is what lets the override
221
+ // inherit through the ordinary cascade.
222
+ const themeTags = Array.from(
223
+ document.head.querySelectorAll('style[data-astryx-theme]'),
224
+ );
225
+ for (const tag of themeTags) {
226
+ expect(tag.textContent).not.toContain('--color-data-');
227
+ }
228
+ });
229
+
230
+ it('keeps the defaults while any theme is still mounted', () => {
231
+ const outer = render(
232
+ <Theme theme={testTheme}>
233
+ <span>a</span>
234
+ </Theme>,
235
+ );
236
+ render(
237
+ <Theme theme={altTheme}>
238
+ <span>b</span>
239
+ </Theme>,
240
+ );
241
+
242
+ outer.unmount();
243
+ expect(baseTags()).toHaveLength(1);
244
+
245
+ cleanup();
246
+ expect(baseTags()).toHaveLength(0);
247
+ });
248
+
249
+ it('generates a theme once across nested and sibling mounts', () => {
250
+ render(
251
+ <Theme theme={testTheme}>
252
+ <Theme theme={testTheme}>
253
+ <span>nested</span>
254
+ </Theme>
255
+ </Theme>,
256
+ );
257
+ render(
258
+ <Theme theme={testTheme}>
259
+ <span>sibling</span>
260
+ </Theme>,
261
+ );
262
+
263
+ expect(generateThemeCSSSpy).toHaveBeenCalledTimes(1);
264
+ expect(baseTags()).toHaveLength(1);
265
+
266
+ const injected = Array.from(document.querySelectorAll('style'))
267
+ .map(tag => tag.textContent ?? '')
268
+ .join('\n');
269
+ expect(injected.match(/:root\s*\{/g)).toHaveLength(1);
270
+ });
169
271
  });
@@ -42,6 +42,7 @@ import * as stylex from '@stylexjs/stylex';
42
42
  import type {ThemeMode} from './types';
43
43
  import {colorVars, typographyVars} from './tokens.stylex';
44
44
  import {generateThemeCSS, type DefinedTheme} from './defineTheme';
45
+ import {generateDataTokenDefaultsCSS} from './generateThemeRules';
45
46
  import {registerTheme} from './themeRegistry';
46
47
  import {dataAttr} from '../naming';
47
48
  import {ThemeContext} from './useTheme';
@@ -98,6 +99,16 @@ ThemeNestingContext.displayName = 'ThemeNestingContext';
98
99
  /** Track which themes have already been injected */
99
100
  const injectedThemes = new Set<string>();
100
101
 
102
+ /**
103
+ * How many mounted `Theme`s are relying on the injected data-token defaults.
104
+ *
105
+ * The defaults are one document-wide `:root` block, shared by every theme, so
106
+ * they are injected once and removed only when the last theme that took a
107
+ * reference unmounts — tearing them down with whichever provider happened to
108
+ * inject them would strip the palette from the providers still mounted.
109
+ */
110
+ let dataTokenDefaultsRefCount = 0;
111
+
101
112
  /**
102
113
  * Hook to inject theme CSS into the document.
103
114
  * Built themes (from `astryx theme build`) skip injection — their CSS
@@ -112,6 +123,8 @@ function useThemeStyleInjection(theme: DefinedTheme): void {
112
123
  return;
113
124
  }
114
125
 
126
+ // Second and later `Theme`s using this theme do no work at all —
127
+ // generation included. Its CSS is document-wide and identical for each.
115
128
  const themeKey = `astryx-theme-${theme.name}`;
116
129
  if (injectedThemes.has(themeKey)) {
117
130
  return;
@@ -130,8 +143,26 @@ function useThemeStyleInjection(theme: DefinedTheme): void {
130
143
  );
131
144
 
132
145
  const {prose, component} = generateThemeCSS(theme);
133
- if (!prose && !component) {
134
- return;
146
+ const base = generateDataTokenDefaultsCSS();
147
+ injectedThemes.add(themeKey);
148
+ const cleanups: (() => void)[] = [() => injectedThemes.delete(themeKey)];
149
+
150
+ // Data token defaults go into @layer astryx-base, where StyleX puts the
151
+ // core token defaults, so a theme's own `--color-data-*` outranks them by
152
+ // layer. Appended (never prepended) so it cannot register `astryx-base`
153
+ // ahead of `reset` and invert the layer order.
154
+ if (base) {
155
+ if (dataTokenDefaultsRefCount++ === 0) {
156
+ const baseStyle = document.createElement('style');
157
+ baseStyle.setAttribute(dataAttr('theme-base'), '');
158
+ baseStyle.textContent = `@layer astryx-base {\n${base}\n}`;
159
+ document.head.appendChild(baseStyle);
160
+ }
161
+ cleanups.push(() => {
162
+ if (--dataTokenDefaultsRefCount === 0) {
163
+ document.querySelector(`style[${dataAttr('theme-base')}]`)?.remove();
164
+ }
165
+ });
135
166
  }
136
167
 
137
168
  // Prose defaults go into @layer reset — lowest priority, scoped to
@@ -154,20 +185,24 @@ function useThemeStyleInjection(theme: DefinedTheme): void {
154
185
  document.head.appendChild(compStyle);
155
186
  }
156
187
 
157
- injectedThemes.add(themeKey);
188
+ if (prose || component) {
189
+ cleanups.push(() => {
190
+ // Matched by the astryx id marker, which is always written above.
191
+ const proseEl = document.querySelector(
192
+ `style[${dataAttr('theme-prose')}="${theme.name}"][${dataAttr('id')}="${id}"]`,
193
+ );
194
+ const compEl = document.querySelector(
195
+ `style[${dataAttr('theme')}="${theme.name}"][${dataAttr('id')}="${id}"]`,
196
+ );
197
+ proseEl?.remove();
198
+ compEl?.remove();
199
+ });
200
+ }
158
201
 
159
202
  return () => {
160
- // Remove both prose and component style tags (matched by the new
161
- // astryx id marker, which is always written above).
162
- const proseEl = document.querySelector(
163
- `style[${dataAttr('theme-prose')}="${theme.name}"][${dataAttr('id')}="${id}"]`,
164
- );
165
- const compEl = document.querySelector(
166
- `style[${dataAttr('theme')}="${theme.name}"][${dataAttr('id')}="${id}"]`,
167
- );
168
- proseEl?.remove();
169
- compEl?.remove();
170
- injectedThemes.delete(themeKey);
203
+ for (const cleanup of cleanups) {
204
+ cleanup();
205
+ }
171
206
  };
172
207
  }, [theme, id]);
173
208
  }
@@ -116,6 +116,29 @@ describe('generateThemeCSS', () => {
116
116
  expect(css).toContain('font-family: var(--font-family-heading)');
117
117
  });
118
118
 
119
+ it('keeps the data palette out of a theme that never mentions it', () => {
120
+ // That the palette IS declared is covered by `seeds the whole palette
121
+ // once, at :root` in generateThemeRules.test.ts. It is theme-independent,
122
+ // so there is nothing about it a theme can be used to assert.
123
+ const {component} = generateThemeCSS(defineTheme({name: 'chartless'}));
124
+ expect(component).not.toContain('--color-data-');
125
+ });
126
+
127
+ it('puts only the named data token in the theme block, not its siblings', () => {
128
+ const theme = defineTheme({
129
+ name: 'brand-charts',
130
+ tokens: {'--color-data-categorical-blue': '#00A3FF'},
131
+ });
132
+ const {component} = generateThemeCSS(theme);
133
+ expect(component).toContain('--color-data-categorical-blue: #00A3FF;');
134
+ // Leaving the siblings out of the theme's own block is what lets a nested
135
+ // theme inherit a parent's override instead of shadowing it.
136
+ expect(component).not.toContain('--color-data-categorical-orange');
137
+ // Defaults reach the stylesheet without entering the theme's own tokens,
138
+ // which are what `astryx theme build` reports as overrides.
139
+ expect(theme.tokens['--color-data-categorical-orange']).toBeUndefined();
140
+ });
141
+
119
142
  it('splits prose into reset layer and components into astryx-theme', () => {
120
143
  const theme = defineTheme({
121
144
  name: 'split-test',
@@ -36,7 +36,16 @@
36
36
  * - /packages/cli/assets/docs/theme.doc.mjs (`astryx docs theme`)
37
37
  */
38
38
 
39
- import type {IconRegistry} from '../Icon/globalIconRegistry';
39
+ import type {ReactNode} from 'react';
40
+ import type {IconName, NamespacedIconName} from '../Icon/globalIconRegistry';
41
+
42
+ /**
43
+ * Icon overrides a theme may declare: any built-in semantic name, plus the
44
+ * namespaced keys components and libraries own (`'richtext:bold'`).
45
+ */
46
+ type ThemeIconOverrides = Partial<
47
+ Record<IconName | NamespacedIconName, ReactNode>
48
+ >;
40
49
  import type {IndicatorRegistry} from '../Indicator/types';
41
50
  import type {TypographyConfig, FontWeight} from './types';
42
51
  import {
@@ -319,7 +328,7 @@ export interface DefineThemeInput {
319
328
  */
320
329
  components?: ComponentStyleMap;
321
330
  /** Icon registry — maps semantic icon names to React nodes */
322
- icons?: Partial<IconRegistry>;
331
+ icons?: ThemeIconOverrides;
323
332
  /**
324
333
  * Indicator overrides — replaces the components that draw stateful control
325
334
  * visuals with the theme's own, by name.
@@ -381,7 +390,7 @@ export interface DefinedTheme {
381
390
  /** Component style overrides */
382
391
  components?: ComponentStyleMap;
383
392
  /** Icon registry */
384
- icons?: Partial<IconRegistry>;
393
+ icons?: ThemeIconOverrides;
385
394
  /** Indicator overrides for stateful control visuals, keyed by name */
386
395
  indicators?: IndicatorRegistry;
387
396
  /** Whether this theme has been pre-compiled by theme build CLI */
@@ -213,6 +213,7 @@ function discoverComponents(): ComponentInfo[] {
213
213
  // ---------------------------------------------------------------------------
214
214
 
215
215
  const DIR_TO_REGISTRY_KEY: Record<string, string> = {
216
+ Avatar: 'avatar',
216
217
  Banner: 'banner',
217
218
  Button: 'button',
218
219
  Card: 'card',
@@ -221,13 +222,13 @@ const DIR_TO_REGISTRY_KEY: Record<string, string> = {
221
222
  Dialog: 'dialog',
222
223
  DropdownMenu: 'dropdown-menu',
223
224
  Field: 'field',
224
- HoverCard: 'hovercard',
225
+ HoverCard: 'hover-card',
225
226
  NumberInput: 'number-input',
226
227
  Popover: 'popover',
227
- ProgressBar: 'progressbar-mark',
228
+ ProgressBar: 'progress-bar-mark',
228
229
  Section: 'section',
229
230
  SegmentedControl: 'segmented-control',
230
- TextArea: 'textarea',
231
+ TextArea: 'text-area',
231
232
  };
232
233
 
233
234
  /**
@@ -279,6 +280,13 @@ const VARS_WITHOUT_DERIVED_MAPPING = new Set([
279
280
  '--_thumbnail-hit-inset',
280
281
  '--_input-clear-hit-inset',
281
282
  '--_input-clear-hit-content',
283
+ // Placement and swipe lifecycle values are private Toast behavior. A theme
284
+ // author controls the surface transform/opacity as a whole, not these values.
285
+ '--_toast-slide-y',
286
+ '--_toast-swipe-y',
287
+ '--_toast-swipe-exit-y',
288
+ '--_toast-swipe-opacity',
289
+ '--_toast-swipe-scale',
282
290
  // Indentation and row-spacing metrics: --tree-list-indent is the authorable
283
291
  // step, --_tree-indent the per-row distance TreeListItem computes from it.
284
292
  // --tree-list-row-gap is applied as half a padding-block on each row wrapper,
@@ -292,6 +300,19 @@ const VARS_WITHOUT_DERIVED_MAPPING = new Set([
292
300
  // other.
293
301
  '--_card-elevation',
294
302
  '--_card-ring',
303
+ // The colour inside that composed ring, for a variant only a theme knows.
304
+ // It is one component of one shadow in the list, so no standard property
305
+ // maps onto it either — a theme sets it beside the fill it has to contrast.
306
+ '--selectable-card-ring-color',
307
+ // The spinner's ring is drawn as an SVG circle, so none of its four vars is
308
+ // a CSS property of the element carrying the theme target: `width` and
309
+ // `borderWidth` would name a box the ring is not, and a `color` mapping
310
+ // would take the label's text color with it. They are public vars a theme
311
+ // sets directly under a size- or shade-variant key.
312
+ '--spinner-diameter',
313
+ '--spinner-stroke-width',
314
+ '--spinner-color',
315
+ '--spinner-track-color',
295
316
  ]);
296
317
 
297
318
  // ---------------------------------------------------------------------------
@@ -418,6 +439,21 @@ describe('getDerivedVars', () => {
418
439
  expect(getDerivedVars('unknown', 'borderRadius')).toEqual([]);
419
440
  });
420
441
 
442
+ it('resolves a deprecated key to the entries of the key that replaced it', () => {
443
+ // A theme written against the old spelling still selects the element (the
444
+ // component emits both classes), so its derived vars must still expand —
445
+ // otherwise the rule lands and the var half of it silently does nothing.
446
+ expect(getDerivedVars('hovercard', 'borderRadius')).toEqual(
447
+ getDerivedVars('hover-card', 'borderRadius'),
448
+ );
449
+ expect(getDerivedVars('textarea', 'paddingInline')).toEqual(
450
+ getDerivedVars('text-area', 'paddingInline'),
451
+ );
452
+ expect(getDerivedVars('progressbar-mark', 'width')).toEqual(
453
+ getDerivedVars('progress-bar-mark', 'width'),
454
+ );
455
+ });
456
+
421
457
  it('returns empty for unregistered property', () => {
422
458
  expect(getDerivedVars('card', 'color')).toEqual([]);
423
459
  });
@@ -441,3 +477,51 @@ describe('getDerivedVars', () => {
441
477
  }
442
478
  });
443
479
  });
480
+
481
+ // ---------------------------------------------------------------------------
482
+ // Read check: a registered var nothing reads is a dead theming knob
483
+ // ---------------------------------------------------------------------------
484
+
485
+ /**
486
+ * Every source file under packages/core/src, concatenated once.
487
+ *
488
+ * `--_popover-radius` shipped documented and registered while `usePopover`
489
+ * hardcoded its radius, so `popover: {borderRadius}` set a var no element ever
490
+ * read. Sync between source, docs and registry cannot catch that: the three
491
+ * agreed with each other, and none of them required a reader.
492
+ */
493
+ function readAllSource(dir: string): string {
494
+ let out = '';
495
+ for (const entry of readdirSync(dir, {withFileTypes: true})) {
496
+ const path = join(dir, entry.name);
497
+ if (entry.isDirectory()) {
498
+ out += readAllSource(path);
499
+ } else if (
500
+ (entry.name.endsWith('.ts') || entry.name.endsWith('.tsx')) &&
501
+ !entry.name.includes('.test.') &&
502
+ !entry.name.endsWith('.d.ts')
503
+ ) {
504
+ out += readFileSync(path, 'utf-8');
505
+ }
506
+ }
507
+ return out;
508
+ }
509
+
510
+ describe('registered derived vars are read by component styles', () => {
511
+ const source = readAllSource(SRC_DIR);
512
+
513
+ for (const [component, entries] of Object.entries(derivedVarRegistry)) {
514
+ for (const varName of entries.flatMap(e => e.vars ?? [])) {
515
+ it(`${component}: ${varName} is read via var()`, () => {
516
+ expect(
517
+ source.includes(`var(${varName})`) ||
518
+ source.includes(`var(${varName},`),
519
+ `${varName} is registered as the derived var for a CSS property on ` +
520
+ `\`${component}\`, but no component reads it. A theme setting that ` +
521
+ `property would write a var nothing consumes. Read it in the ` +
522
+ `element's StyleX styles, or drop the derived entry.`,
523
+ ).toBe(true);
524
+ });
525
+ }
526
+ }
527
+ });