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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (622) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +45 -20
  5. package/dist/AspectRatio/AspectRatio.d.ts +6 -6
  6. package/dist/Avatar/Avatar.d.ts +25 -1
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +43 -9
  9. package/dist/Avatar/index.d.ts +2 -2
  10. package/dist/Avatar/index.d.ts.map +1 -1
  11. package/dist/Avatar/index.js +1 -1
  12. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  13. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroup.js +5 -2
  15. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  16. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  17. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroupOverflow.js +11 -7
  19. package/dist/Badge/Badge.d.ts.map +1 -1
  20. package/dist/Badge/Badge.js +26 -2
  21. package/dist/Banner/Banner.d.ts +10 -1
  22. package/dist/Banner/Banner.d.ts.map +1 -1
  23. package/dist/Banner/Banner.js +11 -2
  24. package/dist/Button/Button.d.ts.map +1 -1
  25. package/dist/Button/Button.js +8 -7
  26. package/dist/Calendar/Calendar.d.ts +4 -2
  27. package/dist/Calendar/Calendar.d.ts.map +1 -1
  28. package/dist/Calendar/Calendar.js +15 -21
  29. package/dist/Calendar/hooks/useCalendarDays.js +4 -6
  30. package/dist/Calendar/hooks/useCalendarNavigation.js +4 -6
  31. package/dist/Calendar/styles.d.ts +5 -20
  32. package/dist/Calendar/styles.d.ts.map +1 -1
  33. package/dist/Calendar/styles.js +15 -17
  34. package/dist/Card/Card.d.ts +12 -12
  35. package/dist/Card/Card.d.ts.map +1 -1
  36. package/dist/Card/Card.js +17 -9
  37. package/dist/Card/index.d.ts +35 -1
  38. package/dist/Card/index.d.ts.map +1 -1
  39. package/dist/Card/index.js +21 -1
  40. package/dist/Carousel/Carousel.d.ts.map +1 -1
  41. package/dist/Carousel/Carousel.js +108 -7
  42. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  43. package/dist/CheckboxInput/CheckboxInput.js +7 -1
  44. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  45. package/dist/CodeBlock/CodeBlock.js +15 -4
  46. package/dist/CodeBlock/highlightRanges.js +1 -1
  47. package/dist/CodeBlock/highlightStyles.js +13 -13
  48. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  49. package/dist/CommandPalette/CommandPaletteItem.js +2 -7
  50. package/dist/ComplexSelector/ComplexSelector.d.ts +10 -2
  51. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  52. package/dist/ComplexSelector/ComplexSelector.js +14 -7
  53. package/dist/DateInput/DateInput.d.ts +43 -0
  54. package/dist/DateInput/DateInput.d.ts.map +1 -1
  55. package/dist/DateInput/DateInput.js +22 -5
  56. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  57. package/dist/DateInput/MonthScroller.js +5 -3
  58. package/dist/DateInput/MonthYearWheels.d.ts.map +1 -1
  59. package/dist/DateInput/MonthYearWheels.js +6 -4
  60. package/dist/DateInput/NativeDateField.d.ts +10 -0
  61. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  62. package/dist/DateInput/NativeDateField.js +494 -0
  63. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  64. package/dist/DateInput/TouchDateField.js +52 -25
  65. package/dist/DateInput/Wheel.d.ts.map +1 -1
  66. package/dist/DateInput/Wheel.js +1 -0
  67. package/dist/DateInput/index.d.ts +1 -1
  68. package/dist/DateInput/index.d.ts.map +1 -1
  69. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  70. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  71. package/dist/DateInput/nativeDateSegments.js +111 -0
  72. package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
  73. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  74. package/dist/DateRangeInput/DateRangeInput.js +3 -5
  75. package/dist/DateTimeInput/DateTimeInput.d.ts +23 -24
  76. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  77. package/dist/DateTimeInput/DateTimeInput.js +35 -10
  78. package/dist/DateTimeInput/TouchDateTimeField.d.ts +6 -0
  79. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -0
  80. package/dist/DateTimeInput/TouchDateTimeField.js +1021 -0
  81. package/dist/Dialog/Dialog.d.ts +16 -2
  82. package/dist/Dialog/Dialog.d.ts.map +1 -1
  83. package/dist/Dialog/Dialog.js +28 -7
  84. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  85. package/dist/DropdownMenu/DropdownMenu.js +4 -13
  86. package/dist/Field/FieldLabel.d.ts.map +1 -1
  87. package/dist/Field/FieldLabel.js +9 -1
  88. package/dist/Field/InputClearButton.d.ts +9 -3
  89. package/dist/Field/InputClearButton.d.ts.map +1 -1
  90. package/dist/Field/InputClearButton.js +14 -3
  91. package/dist/Heading/Heading.d.ts.map +1 -1
  92. package/dist/Heading/Heading.js +0 -1
  93. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  94. package/dist/HoverCard/HoverCard.js +104 -3
  95. package/dist/HoverCard/useHoverCard.d.ts +14 -2
  96. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  97. package/dist/HoverCard/useHoverCard.js +7 -1
  98. package/dist/Icon/Icon.d.ts +4 -2
  99. package/dist/Icon/Icon.d.ts.map +1 -1
  100. package/dist/Icon/defaultIcons.d.ts +3 -2
  101. package/dist/Icon/defaultIcons.d.ts.map +1 -1
  102. package/dist/Icon/defaultIcons.js +7 -0
  103. package/dist/Icon/globalIconRegistry.d.ts +13 -0
  104. package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
  105. package/dist/Icon/globalIconRegistry.js +34 -6
  106. package/dist/Icon/index.d.ts +1 -1
  107. package/dist/Icon/index.d.ts.map +1 -1
  108. package/dist/Icon/useIcon.d.ts +5 -2
  109. package/dist/Icon/useIcon.d.ts.map +1 -1
  110. package/dist/Icon/useIcon.js +3 -0
  111. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  112. package/dist/Indicator/CheckboxIndicator.js +6 -2
  113. package/dist/Item/Item.d.ts.map +1 -1
  114. package/dist/Item/Item.js +2 -2
  115. package/dist/Kbd/Kbd.d.ts.map +1 -1
  116. package/dist/Kbd/Kbd.js +2 -26
  117. package/dist/Layer/gestureCounter.d.ts +8 -0
  118. package/dist/Layer/gestureCounter.d.ts.map +1 -0
  119. package/dist/Layer/gestureCounter.js +53 -0
  120. package/dist/Layer/useLayer.d.ts +23 -13
  121. package/dist/Layer/useLayer.d.ts.map +1 -1
  122. package/dist/Layer/useLayer.js +146 -24
  123. package/dist/List/List.d.ts +1 -1
  124. package/dist/List/List.d.ts.map +1 -1
  125. package/dist/List/List.js +15 -4
  126. package/dist/Markdown/Markdown.d.ts +1 -1
  127. package/dist/Markdown/Markdown.d.ts.map +1 -1
  128. package/dist/Markdown/Markdown.js +20 -7
  129. package/dist/Markdown/parser.d.ts.map +1 -1
  130. package/dist/Markdown/parser.js +5 -3
  131. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  132. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  133. package/dist/MetadataList/MetadataListItem.js +4 -1
  134. package/dist/MultiSelector/MultiSelector.d.ts +18 -1
  135. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  136. package/dist/MultiSelector/MultiSelector.js +58 -11
  137. package/dist/MultiSelector/hooks.d.ts +7 -1
  138. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  139. package/dist/MultiSelector/hooks.js +3 -2
  140. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  141. package/dist/NavIcon/NavIcon.js +5 -1
  142. package/dist/NavItem/navItemStyles.stylex.d.ts +0 -8
  143. package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
  144. package/dist/NavItem/navItemStyles.stylex.js +0 -2
  145. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  146. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  147. package/dist/NavMenu/NavHeadingMenu.js +7 -4
  148. package/dist/NumberInput/NumberInput.d.ts +6 -1
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +95 -126
  151. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  152. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  153. package/dist/NumberInput/numberInputCommit.js +71 -0
  154. package/dist/NumberInput/numberParser.d.ts +64 -0
  155. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  156. package/dist/NumberInput/numberParser.js +350 -0
  157. package/dist/Outline/Outline.d.ts.map +1 -1
  158. package/dist/Outline/Outline.js +2 -3
  159. package/dist/OverflowList/OverflowList.d.ts +41 -1
  160. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  161. package/dist/OverflowList/OverflowList.js +43 -2
  162. package/dist/Popover/Popover.d.ts.map +1 -1
  163. package/dist/Popover/Popover.js +8 -14
  164. package/dist/Popover/usePopover.d.ts +15 -41
  165. package/dist/Popover/usePopover.d.ts.map +1 -1
  166. package/dist/Popover/usePopover.js +26 -7
  167. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchValueEditor.js +91 -18
  169. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  170. package/dist/PowerSearch/formatFilterValue.js +4 -2
  171. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  172. package/dist/ProgressBar/ProgressBar.js +18 -5
  173. package/dist/Resizable/useResizable.d.ts +19 -1
  174. package/dist/Resizable/useResizable.d.ts.map +1 -1
  175. package/dist/Resizable/useResizable.js +104 -38
  176. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  177. package/dist/SelectableCard/SelectableCard.js +9 -0
  178. package/dist/Selector/Selector.d.ts +18 -1
  179. package/dist/Selector/Selector.d.ts.map +1 -1
  180. package/dist/Selector/Selector.js +92 -21
  181. package/dist/Selector/hooks.d.ts +7 -1
  182. package/dist/Selector/hooks.d.ts.map +1 -1
  183. package/dist/Selector/hooks.js +3 -2
  184. package/dist/SideNav/SideNav.d.ts +6 -1
  185. package/dist/SideNav/SideNav.d.ts.map +1 -1
  186. package/dist/SideNav/SideNav.js +57 -27
  187. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  188. package/dist/SideNav/SideNavHeading.js +5 -4
  189. package/dist/SideNav/SideNavItem.d.ts +29 -4
  190. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  191. package/dist/SideNav/SideNavItem.js +75 -20
  192. package/dist/Slider/Slider.d.ts.map +1 -1
  193. package/dist/Slider/Slider.js +34 -2
  194. package/dist/Spinner/Spinner.d.ts +3 -1
  195. package/dist/Spinner/Spinner.d.ts.map +1 -1
  196. package/dist/Spinner/Spinner.js +199 -20
  197. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  198. package/dist/StatusDot/StatusDot.js +6 -1
  199. package/dist/Stepper/Step.d.ts.map +1 -1
  200. package/dist/Stepper/Step.js +7 -6
  201. package/dist/Switch/Switch.d.ts.map +1 -1
  202. package/dist/Switch/Switch.js +5 -1
  203. package/dist/Table/BaseTable.d.ts.map +1 -1
  204. package/dist/Table/BaseTable.js +6 -1
  205. package/dist/Table/Table.d.ts.map +1 -1
  206. package/dist/Table/Table.js +3 -6
  207. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  208. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  209. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
  210. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  211. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +34 -3
  212. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  213. package/dist/Table/plugins/selection/useTableSelection.js +25 -1
  214. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  215. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  216. package/dist/Text/Text.d.ts.map +1 -1
  217. package/dist/Text/Text.js +0 -1
  218. package/dist/TextArea/TextArea.d.ts.map +1 -1
  219. package/dist/TextArea/TextArea.js +13 -8
  220. package/dist/Timestamp/Timestamp.d.ts +1 -1
  221. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  222. package/dist/Timestamp/Timestamp.js +10 -18
  223. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  224. package/dist/Timestamp/formatInstant.js +10 -5
  225. package/dist/Toast/Toast.d.ts +17 -2
  226. package/dist/Toast/Toast.d.ts.map +1 -1
  227. package/dist/Toast/Toast.js +77 -11
  228. package/dist/Toast/ToastViewport.d.ts +1 -0
  229. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  230. package/dist/Toast/ToastViewport.js +76 -21
  231. package/dist/Toast/index.d.ts +1 -1
  232. package/dist/Toast/index.d.ts.map +1 -1
  233. package/dist/Toast/types.d.ts +38 -0
  234. package/dist/Toast/types.d.ts.map +1 -1
  235. package/dist/Toast/useToastGesture.d.ts +26 -0
  236. package/dist/Toast/useToastGesture.d.ts.map +1 -0
  237. package/dist/Toast/useToastGesture.js +223 -0
  238. package/dist/Token/Token.d.ts +1 -1
  239. package/dist/Token/Token.d.ts.map +1 -1
  240. package/dist/Token/Token.js +23 -12
  241. package/dist/Token/TokenLink.d.ts +1 -1
  242. package/dist/Token/TokenLink.d.ts.map +1 -1
  243. package/dist/Token/TokenLink.js +5 -2
  244. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  245. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  246. package/dist/Tokenizer/Tokenizer.js +31 -21
  247. package/dist/TopNav/TopNavHeading.js +2 -2
  248. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  249. package/dist/TopNav/TopNavItem.js +3 -3
  250. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  251. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  252. package/dist/TopNav/TopNavMegaMenu.js +30 -9
  253. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  254. package/dist/TopNav/TopNavMegaMenuItem.js +3 -3
  255. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  256. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMenu.js +21 -6
  258. package/dist/TreeList/TreeList.d.ts +1 -1
  259. package/dist/TreeList/TreeList.d.ts.map +1 -1
  260. package/dist/TreeList/TreeList.js +7 -2
  261. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  262. package/dist/TreeList/TreeListItem.js +2 -2
  263. package/dist/Typeahead/BaseTypeahead.d.ts +33 -0
  264. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  265. package/dist/Typeahead/BaseTypeahead.js +51 -8
  266. package/dist/Typeahead/Typeahead.d.ts +8 -1
  267. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  268. package/dist/Typeahead/Typeahead.js +2 -0
  269. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  270. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  271. package/dist/Typeahead/TypeaheadItem.js +7 -2
  272. package/dist/astryx.css +87 -22
  273. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  274. package/dist/hooks/useHotkeys.js +3 -25
  275. package/dist/hooks/useOverflow.d.ts.map +1 -1
  276. package/dist/hooks/useOverflow.js +14 -4
  277. package/dist/i18n/InternationalizationContext.d.ts +2 -0
  278. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  279. package/dist/i18n/InternationalizationContext.js +3 -1
  280. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  281. package/dist/i18n/InternationalizationProvider.js +3 -1
  282. package/dist/i18n/resolve.d.ts +1 -1
  283. package/dist/i18n/resolve.d.ts.map +1 -1
  284. package/dist/i18n/resolve.js +37 -38
  285. package/dist/i18n/useTranslator.d.ts.map +1 -1
  286. package/dist/i18n/useTranslator.js +2 -3
  287. package/dist/index.d.ts +1 -1
  288. package/dist/index.d.ts.map +1 -1
  289. package/dist/theme/Theme.d.ts.map +1 -1
  290. package/dist/theme/Theme.js +46 -10
  291. package/dist/theme/defineTheme.d.ts +9 -3
  292. package/dist/theme/defineTheme.d.ts.map +1 -1
  293. package/dist/theme/defineTheme.js +5 -0
  294. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  295. package/dist/theme/derivedVarRegistry.js +24 -4
  296. package/dist/theme/generateThemeRules.d.ts +21 -0
  297. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  298. package/dist/theme/generateThemeRules.js +26 -0
  299. package/dist/theme/syntax/tokens.d.ts +1 -1
  300. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  301. package/dist/theme/syntax/tokens.js +5 -2
  302. package/dist/theme/useTheme.d.ts.map +1 -1
  303. package/dist/theme/useTheme.js +6 -7
  304. package/dist/utils/dateParser.d.ts +5 -8
  305. package/dist/utils/dateParser.d.ts.map +1 -1
  306. package/dist/utils/dateParser.js +10 -11
  307. package/dist/utils/focusOutline.stylex.d.ts +25 -0
  308. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  309. package/dist/utils/focusOutline.stylex.js +15 -0
  310. package/dist/utils/interactionOverlay.stylex.d.ts +26 -0
  311. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -0
  312. package/dist/utils/interactionOverlay.stylex.js +42 -0
  313. package/dist/utils/isApplePlatform.d.ts +18 -0
  314. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  315. package/dist/utils/isApplePlatform.js +37 -0
  316. package/dist/utils/plainDate.d.ts +11 -0
  317. package/dist/utils/plainDate.d.ts.map +1 -1
  318. package/dist/utils/plainDate.js +20 -4
  319. package/locales/af-ZA.json +7 -7
  320. package/locales/ar-SA.json +7 -7
  321. package/locales/ca-ES.json +6 -6
  322. package/locales/cs-CZ.json +7 -7
  323. package/locales/da-DK.json +7 -7
  324. package/locales/de-DE.json +7 -7
  325. package/locales/el-GR.json +7 -7
  326. package/locales/en.json +178 -6
  327. package/locales/es-ES.json +6 -6
  328. package/locales/fi-FI.json +7 -7
  329. package/locales/fr-FR.json +7 -7
  330. package/locales/he-IL.json +7 -7
  331. package/locales/hu-HU.json +7 -7
  332. package/locales/it-IT.json +7 -7
  333. package/locales/ja-JP.json +7 -7
  334. package/locales/ko-KR.json +7 -7
  335. package/locales/nl-NL.json +7 -7
  336. package/locales/no-NO.json +7 -7
  337. package/locales/pl-PL.json +7 -7
  338. package/locales/pseudo.json +130 -1
  339. package/locales/pt-BR.json +7 -7
  340. package/locales/pt-PT.json +7 -7
  341. package/locales/ro-RO.json +7 -7
  342. package/locales/ru-RU.json +7 -7
  343. package/locales/sr-SP.json +7 -7
  344. package/locales/sv-SE.json +7 -7
  345. package/locales/tr-TR.json +7 -7
  346. package/locales/uk-UA.json +7 -7
  347. package/locales/vi-VN.json +7 -7
  348. package/locales/zh-CN.json +7 -7
  349. package/locales/zh-TW.json +7 -7
  350. package/package.json +4 -5
  351. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  352. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  353. package/src/AlertDialog/AlertDialog.tsx +62 -20
  354. package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
  355. package/src/AspectRatio/AspectRatio.tsx +6 -6
  356. package/src/Avatar/Avatar.doc.mjs +12 -2
  357. package/src/Avatar/Avatar.test.tsx +80 -0
  358. package/src/Avatar/Avatar.tsx +64 -14
  359. package/src/Avatar/index.ts +2 -2
  360. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  361. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  362. package/src/AvatarGroup/AvatarGroup.tsx +12 -4
  363. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  364. package/src/AvatarGroup/AvatarGroupOverflow.tsx +12 -12
  365. package/src/Badge/Badge.doc.mjs +3 -2
  366. package/src/Badge/Badge.test.tsx +32 -3
  367. package/src/Badge/Badge.tsx +42 -1
  368. package/src/Banner/Banner.doc.mjs +9 -0
  369. package/src/Banner/Banner.test.tsx +76 -11
  370. package/src/Banner/Banner.tsx +21 -2
  371. package/src/Button/Button.doc.mjs +2 -1
  372. package/src/Button/Button.test.tsx +19 -4
  373. package/src/Button/Button.tsx +9 -29
  374. package/src/ButtonGroup/ButtonGroup.doc.mjs +2 -2
  375. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -0
  376. package/src/Calendar/Calendar.doc.mjs +4 -4
  377. package/src/Calendar/Calendar.test.tsx +112 -0
  378. package/src/Calendar/Calendar.tsx +18 -16
  379. package/src/Calendar/hooks/useCalendarDays.ts +4 -4
  380. package/src/Calendar/hooks/useCalendarNavigation.ts +4 -4
  381. package/src/Calendar/styles.ts +48 -42
  382. package/src/Card/Card.doc.mjs +10 -7
  383. package/src/Card/Card.test.tsx +113 -19
  384. package/src/Card/Card.tsx +67 -89
  385. package/src/Card/index.ts +36 -1
  386. package/src/Carousel/Carousel.doc.mjs +3 -0
  387. package/src/Carousel/Carousel.test.tsx +360 -0
  388. package/src/Carousel/Carousel.tsx +116 -15
  389. package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -1
  390. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  391. package/src/CheckboxInput/CheckboxInput.tsx +5 -0
  392. package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
  393. package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
  394. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  395. package/src/CodeBlock/CodeBlock.tsx +20 -4
  396. package/src/CodeBlock/highlightRanges.ts +1 -1
  397. package/src/CodeBlock/highlightStyles.ts +13 -13
  398. package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
  399. package/src/ComplexSelector/ComplexSelector.doc.mjs +9 -2
  400. package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
  401. package/src/ComplexSelector/ComplexSelector.tsx +22 -12
  402. package/src/DateInput/DateInput.doc.mjs +17 -1
  403. package/src/DateInput/DateInput.test.tsx +9 -4
  404. package/src/DateInput/DateInput.tsx +54 -3
  405. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  406. package/src/DateInput/MonthScroller.tsx +5 -1
  407. package/src/DateInput/MonthYearWheels.tsx +7 -4
  408. package/src/DateInput/NativeDateField.test.tsx +635 -0
  409. package/src/DateInput/NativeDateField.tsx +641 -0
  410. package/src/DateInput/TouchDateField.tsx +83 -33
  411. package/src/DateInput/Wheel.tsx +1 -0
  412. package/src/DateInput/index.ts +1 -0
  413. package/src/DateInput/nativeDateSegments.ts +127 -0
  414. package/src/DateRangeInput/DateRangeInput.doc.mjs +3 -3
  415. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
  416. package/src/DateRangeInput/DateRangeInput.tsx +8 -13
  417. package/src/DateTimeInput/DateTimeInput.doc.mjs +39 -22
  418. package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
  419. package/src/DateTimeInput/DateTimeInput.tsx +54 -20
  420. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
  421. package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
  422. package/src/Dialog/Dialog.test.tsx +185 -18
  423. package/src/Dialog/Dialog.tsx +35 -11
  424. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  425. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  426. package/src/Field/Field.doc.mjs +1 -1
  427. package/src/Field/FieldLabel.test.tsx +29 -0
  428. package/src/Field/FieldLabel.tsx +7 -0
  429. package/src/Field/InputClearButton.test.tsx +15 -1
  430. package/src/Field/InputClearButton.tsx +28 -4
  431. package/src/FieldStatus/FieldStatus.doc.mjs +1 -1
  432. package/src/FileInput/FileInput.doc.mjs +1 -1
  433. package/src/Heading/Heading.tsx +0 -1
  434. package/src/HoverCard/HoverCard.doc.mjs +8 -2
  435. package/src/HoverCard/HoverCard.test.tsx +154 -4
  436. package/src/HoverCard/HoverCard.tsx +137 -3
  437. package/src/HoverCard/useHoverCard.tsx +23 -3
  438. package/src/Icon/Icon.test.tsx +55 -1
  439. package/src/Icon/Icon.tsx +5 -3
  440. package/src/Icon/defaultIcons.tsx +11 -2
  441. package/src/Icon/globalIconRegistry.test.tsx +16 -3
  442. package/src/Icon/globalIconRegistry.tsx +37 -6
  443. package/src/Icon/index.ts +1 -0
  444. package/src/Icon/useIcon.ts +9 -2
  445. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  446. package/src/Indicator/Indicator.doc.mjs +3 -1
  447. package/src/InputGroup/InputGroup.doc.mjs +1 -1
  448. package/src/Item/Item.tsx +2 -7
  449. package/src/Kbd/Kbd.test.tsx +0 -17
  450. package/src/Kbd/Kbd.tsx +2 -26
  451. package/src/Layer/gestureCounter.ts +57 -0
  452. package/src/Layer/useLayer.test.tsx +368 -16
  453. package/src/Layer/useLayer.tsx +208 -35
  454. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  455. package/src/List/List.test.tsx +38 -0
  456. package/src/List/List.tsx +8 -1
  457. package/src/Markdown/Markdown.test.tsx +37 -0
  458. package/src/Markdown/Markdown.tsx +16 -5
  459. package/src/Markdown/parser.test.ts +33 -0
  460. package/src/Markdown/parser.ts +9 -3
  461. package/src/MetadataList/MetadataList.test.tsx +75 -2
  462. package/src/MetadataList/MetadataListItem.tsx +5 -2
  463. package/src/MultiSelector/MultiSelector.doc.mjs +23 -2
  464. package/src/MultiSelector/MultiSelector.test.tsx +205 -0
  465. package/src/MultiSelector/MultiSelector.tsx +103 -16
  466. package/src/MultiSelector/hooks.ts +9 -2
  467. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  468. package/src/NavIcon/NavIcon.test.tsx +9 -0
  469. package/src/NavIcon/NavIcon.tsx +5 -1
  470. package/src/NavItem/navItemStyles.stylex.ts +0 -8
  471. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  472. package/src/NavMenu/NavHeadingMenu.tsx +7 -4
  473. package/src/NumberInput/NumberInput.doc.mjs +27 -8
  474. package/src/NumberInput/NumberInput.test.tsx +563 -8
  475. package/src/NumberInput/NumberInput.tsx +77 -131
  476. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  477. package/src/NumberInput/numberInputCommit.ts +103 -0
  478. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  479. package/src/NumberInput/numberParser.test.ts +222 -0
  480. package/src/NumberInput/numberParser.ts +403 -0
  481. package/src/Outline/Outline.tsx +2 -4
  482. package/src/OverflowList/OverflowList.doc.mjs +102 -21
  483. package/src/OverflowList/OverflowList.test.tsx +550 -4
  484. package/src/OverflowList/OverflowList.tsx +100 -2
  485. package/src/Pagination/Pagination.test.tsx +3 -2
  486. package/src/Popover/Popover.doc.mjs +2 -2
  487. package/src/Popover/Popover.test.tsx +38 -0
  488. package/src/Popover/Popover.tsx +28 -66
  489. package/src/Popover/usePopover.tsx +44 -5
  490. package/src/PowerSearch/PowerSearch.doc.mjs +1 -1
  491. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
  492. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
  493. package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
  494. package/src/PowerSearch/formatFilterValue.test.ts +16 -1
  495. package/src/PowerSearch/formatFilterValue.ts +2 -0
  496. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  497. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  498. package/src/ProgressBar/ProgressBar.tsx +28 -8
  499. package/src/RadioList/RadioList.doc.mjs +1 -1
  500. package/src/Resizable/Resizable.doc.mjs +2 -2
  501. package/src/Resizable/useResizable.doc.mjs +21 -2
  502. package/src/Resizable/useResizable.test.ts +421 -0
  503. package/src/Resizable/useResizable.ts +133 -48
  504. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  505. package/src/SelectableCard/SelectableCard.tsx +16 -0
  506. package/src/Selector/Selector.doc.mjs +15 -1
  507. package/src/Selector/Selector.source-build.test.mjs +65 -0
  508. package/src/Selector/Selector.test.tsx +301 -0
  509. package/src/Selector/Selector.tsx +145 -32
  510. package/src/Selector/hooks.ts +17 -2
  511. package/src/SideNav/SideNav.doc.mjs +2 -2
  512. package/src/SideNav/SideNav.test.tsx +1069 -6
  513. package/src/SideNav/SideNav.tsx +109 -38
  514. package/src/SideNav/SideNavHeading.tsx +5 -2
  515. package/src/SideNav/SideNavItem.doc.mjs +24 -3
  516. package/src/SideNav/SideNavItem.tsx +134 -44
  517. package/src/Slider/Slider.doc.mjs +2 -2
  518. package/src/Slider/Slider.test.tsx +106 -1
  519. package/src/Slider/Slider.tsx +52 -1
  520. package/src/Spinner/Spinner.doc.mjs +17 -5
  521. package/src/Spinner/Spinner.test.tsx +164 -0
  522. package/src/Spinner/Spinner.tsx +252 -22
  523. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  524. package/src/StatusDot/StatusDot.test.tsx +9 -0
  525. package/src/StatusDot/StatusDot.tsx +7 -1
  526. package/src/Stepper/Step.doc.mjs +1 -1
  527. package/src/Stepper/Step.tsx +7 -14
  528. package/src/Switch/Switch.doc.mjs +3 -1
  529. package/src/Switch/Switch.test.tsx +10 -0
  530. package/src/Switch/Switch.tsx +3 -0
  531. package/src/Table/BaseTable.tsx +6 -1
  532. package/src/Table/Table.doc.mjs +5 -3
  533. package/src/Table/Table.tsx +3 -8
  534. package/src/Table/TableBody.doc.mjs +2 -2
  535. package/src/Table/TableFooter.doc.mjs +1 -1
  536. package/src/Table/TableHeader.doc.mjs +1 -1
  537. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  538. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  539. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
  540. package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
  541. package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
  542. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  543. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  544. package/src/Table/useTablePagination.doc.mjs +1 -1
  545. package/src/Table/useTableSelection.doc.mjs +1 -1
  546. package/src/Text/Text.test.tsx +44 -0
  547. package/src/Text/Text.tsx +0 -1
  548. package/src/TextArea/TextArea.doc.mjs +13 -3
  549. package/src/TextArea/TextArea.test.tsx +11 -0
  550. package/src/TextArea/TextArea.tsx +34 -22
  551. package/src/TextInput/TextInput.doc.mjs +1 -1
  552. package/src/TimeInput/TimeInput.doc.mjs +1 -1
  553. package/src/Timestamp/Timestamp.test.tsx +89 -0
  554. package/src/Timestamp/Timestamp.tsx +8 -8
  555. package/src/Timestamp/formatInstant.ts +5 -0
  556. package/src/Toast/Toast.doc.mjs +213 -44
  557. package/src/Toast/Toast.tsx +118 -23
  558. package/src/Toast/ToastViewport.test.tsx +1434 -8
  559. package/src/Toast/ToastViewport.tsx +85 -14
  560. package/src/Toast/index.ts +2 -0
  561. package/src/Toast/types.ts +43 -5
  562. package/src/Toast/useToastGesture.ts +361 -0
  563. package/src/Token/Token.test.tsx +95 -0
  564. package/src/Token/Token.tsx +19 -17
  565. package/src/Token/TokenLink.tsx +12 -3
  566. package/src/Tokenizer/Tokenizer.doc.mjs +17 -4
  567. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  568. package/src/Tokenizer/Tokenizer.tsx +49 -24
  569. package/src/TopNav/TopNavHeading.tsx +2 -2
  570. package/src/TopNav/TopNavItem.tsx +3 -7
  571. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  572. package/src/TopNav/TopNavMegaMenu.tsx +47 -4
  573. package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
  574. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  575. package/src/TopNav/TopNavMenu.tsx +38 -5
  576. package/src/TreeList/TreeList.test.tsx +49 -0
  577. package/src/TreeList/TreeList.tsx +7 -2
  578. package/src/TreeList/TreeListItem.tsx +2 -7
  579. package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
  580. package/src/Typeahead/BaseTypeahead.tsx +96 -6
  581. package/src/Typeahead/Typeahead.doc.mjs +7 -1
  582. package/src/Typeahead/Typeahead.test.tsx +154 -0
  583. package/src/Typeahead/Typeahead.tsx +9 -0
  584. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  585. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  586. package/src/hooks/useAnnounce.doc.mjs +96 -0
  587. package/src/hooks/useDevWarning.doc.mjs +96 -0
  588. package/src/hooks/useHotkeys.test.ts +0 -18
  589. package/src/hooks/useHotkeys.ts +3 -25
  590. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  591. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  592. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  593. package/src/hooks/useLongPress.doc.mjs +123 -0
  594. package/src/hooks/useOverflow.doc.mjs +58 -17
  595. package/src/hooks/useOverflow.ts +16 -4
  596. package/src/hooks/useTypeahead.doc.mjs +153 -0
  597. package/src/i18n/InternationalizationContext.ts +3 -0
  598. package/src/i18n/InternationalizationProvider.tsx +8 -1
  599. package/src/i18n/__tests__/resolve.test.ts +23 -1
  600. package/src/i18n/resolve.ts +46 -49
  601. package/src/i18n/useTranslator.ts +2 -7
  602. package/src/index.ts +2 -0
  603. package/src/raw-import.d.ts +14 -0
  604. package/src/theme/Theme.test.tsx +104 -2
  605. package/src/theme/Theme.tsx +49 -14
  606. package/src/theme/defineTheme.test.ts +23 -0
  607. package/src/theme/defineTheme.ts +12 -3
  608. package/src/theme/derivedVarRegistry.test.ts +87 -3
  609. package/src/theme/derivedVarRegistry.ts +23 -4
  610. package/src/theme/generateThemeRules.test.ts +99 -1
  611. package/src/theme/generateThemeRules.ts +28 -0
  612. package/src/theme/syntax/tokens.ts +5 -2
  613. package/src/theme/useTheme.test.tsx +10 -0
  614. package/src/theme/useTheme.ts +16 -10
  615. package/src/utils/dateParser.test.ts +34 -2
  616. package/src/utils/dateParser.ts +11 -14
  617. package/src/utils/focusOutline.stylex.ts +50 -0
  618. package/src/utils/interactionOverlay.stylex.ts +74 -0
  619. package/src/utils/isApplePlatform.test.ts +61 -0
  620. package/src/utils/isApplePlatform.ts +37 -0
  621. package/src/utils/plainDate.test.ts +46 -0
  622. package/src/utils/plainDate.ts +18 -3
package/src/Card/Card.tsx CHANGED
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * @file Card.tsx
5
5
  * @input Uses container utility, StyleX
6
- * @output Exports Card component and CardProps
6
+ * @output Exports Card component, CardProps, CardVariant types
7
7
  * @position Core card container component
8
8
  *
9
9
  * SYNC: When modified, update these files to stay in sync:
@@ -15,6 +15,7 @@
15
15
 
16
16
  import type {ReactNode} from 'react';
17
17
  import * as stylex from '@stylexjs/stylex';
18
+ import type {StyleXStyles} from '@stylexjs/stylex';
18
19
  import {
19
20
  borderVars,
20
21
  colorVars,
@@ -23,24 +24,21 @@ import {
23
24
  } from '../theme/tokens.stylex';
24
25
  import {container} from '../Layout/container.stylex';
25
26
  import type {SpacingToken} from '../Layout/container.stylex';
26
- import {
27
- paddingStyles,
28
- containerPaddingInlineVarStyles,
29
- containerPaddingBlockStartVarStyles,
30
- containerPaddingBlockEndVarStyles,
31
- spacingStepToToken,
32
- } from '../Layout/padding.stylex';
27
+ import {spacingStepToToken} from '../Layout/padding.stylex';
33
28
  import type {Elevation, SizeValue, SpacingStep} from '../utils/types';
34
29
  import {mergeProps} from '../utils';
35
30
  import type {BaseProps} from '../BaseProps';
36
31
  import {themeProps} from '../utils/themeProps';
32
+ import type {CardVariantMap} from './index';
37
33
 
38
34
  // =============================================================================
39
35
  // Variant type
40
36
  // =============================================================================
41
37
 
42
38
  /**
43
- * Background color variant for Card.
39
+ * Background color variant for Card, derived from CardVariantMap.
40
+ * Extensible via module augmentation of CardVariantMap.
41
+ *
44
42
  * - `default`: standard card background with visible border
45
43
  * - `transparent`: no background, no visible border — for grouping content without visual weight
46
44
  * - `muted`: subtle muted background for de-emphasised cards
@@ -52,20 +50,7 @@ import {themeProps} from '../utils/themeProps';
52
50
  * keeping content geometry faithful to the spacing scale and identical to the
53
51
  * borderless variants. Themes can override borderWidth/borderColor.
54
52
  */
55
- export type CardVariant =
56
- | 'default'
57
- | 'transparent'
58
- | 'muted'
59
- | 'blue'
60
- | 'cyan'
61
- | 'gray'
62
- | 'green'
63
- | 'orange'
64
- | 'pink'
65
- | 'purple'
66
- | 'red'
67
- | 'teal'
68
- | 'yellow';
53
+ export type CardVariant = keyof CardVariantMap;
69
54
 
70
55
  // =============================================================================
71
56
  // Styles
@@ -102,48 +87,53 @@ const styles = stylex.create({
102
87
  },
103
88
  });
104
89
 
105
- // Background variant styles — each maps to a design token
106
- const variantStyles = stylex.create({
107
- default: {
108
- backgroundColor: colorVars['--color-background-card'],
109
- },
110
- transparent: {
111
- backgroundColor: 'transparent',
112
- },
113
- muted: {
114
- backgroundColor: colorVars['--color-background-muted'],
115
- },
116
- blue: {
117
- backgroundColor: colorVars['--color-background-blue'],
118
- },
119
- cyan: {
120
- backgroundColor: colorVars['--color-background-cyan'],
121
- },
122
- gray: {
123
- backgroundColor: colorVars['--color-background-gray'],
124
- },
125
- green: {
126
- backgroundColor: colorVars['--color-background-green'],
127
- },
128
- orange: {
129
- backgroundColor: colorVars['--color-background-orange'],
130
- },
131
- pink: {
132
- backgroundColor: colorVars['--color-background-pink'],
90
+ // Background variant styles — each maps to a design token. Typed as PARTIAL
91
+ // over CardVariant: a theme can add a variant, and the record deliberately has
92
+ // no entry for it, so the lookup is undefined, StyleX drops it, and the card
93
+ // takes base styles for the theme rule to paint over.
94
+ const variantStyles: Partial<Record<CardVariant, StyleXStyles>> = stylex.create(
95
+ {
96
+ default: {
97
+ backgroundColor: colorVars['--color-background-card'],
98
+ },
99
+ transparent: {
100
+ backgroundColor: 'transparent',
101
+ },
102
+ muted: {
103
+ backgroundColor: colorVars['--color-background-muted'],
104
+ },
105
+ blue: {
106
+ backgroundColor: colorVars['--color-background-blue'],
107
+ },
108
+ cyan: {
109
+ backgroundColor: colorVars['--color-background-cyan'],
110
+ },
111
+ gray: {
112
+ backgroundColor: colorVars['--color-background-gray'],
113
+ },
114
+ green: {
115
+ backgroundColor: colorVars['--color-background-green'],
116
+ },
117
+ orange: {
118
+ backgroundColor: colorVars['--color-background-orange'],
119
+ },
120
+ pink: {
121
+ backgroundColor: colorVars['--color-background-pink'],
122
+ },
123
+ purple: {
124
+ backgroundColor: colorVars['--color-background-purple'],
125
+ },
126
+ red: {
127
+ backgroundColor: colorVars['--color-background-red'],
128
+ },
129
+ teal: {
130
+ backgroundColor: colorVars['--color-background-teal'],
131
+ },
132
+ yellow: {
133
+ backgroundColor: colorVars['--color-background-yellow'],
134
+ },
133
135
  },
134
- purple: {
135
- backgroundColor: colorVars['--color-background-purple'],
136
- },
137
- red: {
138
- backgroundColor: colorVars['--color-background-red'],
139
- },
140
- teal: {
141
- backgroundColor: colorVars['--color-background-teal'],
142
- },
143
- yellow: {
144
- backgroundColor: colorVars['--color-background-yellow'],
145
- },
146
- });
136
+ );
147
137
 
148
138
  // Elevation → shadow-token map. Sets the private --_card-elevation variable
149
139
  // (not box-shadow directly) so it composes with --_card-ring in the shadow
@@ -176,14 +166,6 @@ export type {SizeValue} from '../utils/types';
176
166
 
177
167
  export interface CardProps extends BaseProps<HTMLDivElement> {
178
168
  ref?: React.Ref<HTMLDivElement>;
179
- /**
180
- * CSS class name(s) appended to the root element.
181
- */
182
- className?: string;
183
- /**
184
- * Inline styles to apply to the root element.
185
- */
186
- style?: React.CSSProperties;
187
169
  /**
188
170
  * Width of the card.
189
171
  * Numbers are treated as pixels, strings are used as-is.
@@ -217,7 +199,12 @@ export interface CardProps extends BaseProps<HTMLDivElement> {
217
199
  /**
218
200
  * Internal padding of the card using the spacing scale.
219
201
  * Accepts numeric spacing steps: 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10.
220
- * @default 4 (16px)
202
+ *
203
+ * Omit it and the card takes the theme's card padding rather than a step, so
204
+ * passing a step is a decision to override the theme, not a way to restate
205
+ * the default.
206
+ *
207
+ * @default the theme's card padding (spacing step 4 with no theme)
221
208
  */
222
209
  padding?: SpacingStep;
223
210
 
@@ -293,16 +280,19 @@ export function Card({
293
280
 
294
281
  // When no explicit padding prop, use theme default (set via container tokens)
295
282
  const useThemeDefault = padding == null;
296
- const effectivePadding = padding ?? 4;
297
- const paddingToken = spacingStepToToken[effectivePadding] as SpacingToken;
283
+ const paddingToken = useThemeDefault
284
+ ? undefined
285
+ : (spacingStepToToken[padding] as SpacingToken);
298
286
 
299
287
  return (
300
288
  <div
301
289
  ref={ref}
302
290
  {...mergeProps(
303
- themeProps('card', {variant}),
291
+ themeProps('card', {variant, elevation}),
304
292
  stylex.props(
305
293
  styles.card,
294
+ // A theme's own variant is not a key here: the lookup is undefined,
295
+ // StyleX drops it, and the theme rule paints over base styles.
306
296
  variantStyles[variant],
307
297
  elevationStyles[elevation],
308
298
  hasFixedHeight && styles.scrollable,
@@ -313,7 +303,7 @@ export function Card({
313
303
  minHeight ?? null,
314
304
  ),
315
305
  ...container(
316
- useThemeDefault
306
+ paddingToken == null
317
307
  ? {useThemeDefault: 'card'}
318
308
  : {
319
309
  paddingInnerX: paddingToken,
@@ -322,18 +312,6 @@ export function Card({
322
312
  paddingOuterY: paddingToken,
323
313
  },
324
314
  ),
325
- !useThemeDefault &&
326
- effectivePadding !== 4 &&
327
- paddingStyles[effectivePadding],
328
- !useThemeDefault &&
329
- effectivePadding !== 4 &&
330
- containerPaddingInlineVarStyles[effectivePadding],
331
- !useThemeDefault &&
332
- effectivePadding !== 4 &&
333
- containerPaddingBlockStartVarStyles[effectivePadding],
334
- !useThemeDefault &&
335
- effectivePadding !== 4 &&
336
- containerPaddingBlockEndVarStyles[effectivePadding],
337
315
  // Applied after the container padding so the border-inset calc wins;
338
316
  // it reads the --container-padding-* vars set above.
339
317
  variant === 'default' && styles.withBorder,
package/src/Card/index.ts CHANGED
@@ -3,11 +3,46 @@
3
3
  /**
4
4
  * @file index.ts
5
5
  * @input Imports Card component
6
- * @output Exports Card component and types
6
+ * @output Exports Card, CardProps, CardVariant, CardVariantMap
7
7
  * @position Entry point for @astryxdesign/core/Card module
8
8
  *
9
9
  * SYNC: When modified, update /packages/core/src/Card/Card.doc.mjs
10
10
  */
11
11
 
12
+ /**
13
+ * Extensible variant map for Card.
14
+ *
15
+ * Theme packages can add custom variants via TypeScript module augmentation:
16
+ * @example
17
+ * ```
18
+ * declare module '@astryxdesign/core/Card' {
19
+ * interface CardVariantMap {
20
+ * 'brand': true;
21
+ * }
22
+ * }
23
+ * ```
24
+ *
25
+ * Pair the theme rule's `backgroundColor` with `--selectable-card-ring-color`.
26
+ * SelectableCard rings an added variant in that var, defaulting to the accent —
27
+ * no token the component could pick is guaranteed to contrast with a fill it
28
+ * cannot know, so the theme that supplied the fill picks the ring, in the same
29
+ * rule.
30
+ */
31
+ export interface CardVariantMap {
32
+ default: true;
33
+ transparent: true;
34
+ muted: true;
35
+ blue: true;
36
+ cyan: true;
37
+ gray: true;
38
+ green: true;
39
+ orange: true;
40
+ pink: true;
41
+ purple: true;
42
+ red: true;
43
+ teal: true;
44
+ yellow: true;
45
+ }
46
+
12
47
  export {Card} from './Card';
13
48
  export type {CardProps, CardVariant, SizeValue} from './Card';
@@ -14,6 +14,7 @@ export const docs = {
14
14
  {guidance: true, description: 'Enable scroll-snap when each item should land precisely at the start edge, like a gallery or product list.'},
15
15
  {guidance: true, description: 'Reach for hasLoop on small, cyclable sets like a photo gallery, where wrapping past the last item back to the first feels natural.'},
16
16
  {guidance: true, description: 'Always provide an aria-label that describes what the carousel contains, like "Featured products" or "Team members".'},
17
+ {guidance: true, description: 'Carousel implements the WAI-ARIA APG carousel pattern (https://www.w3.org/WAI/ARIA/apg/patterns/carousel/) without auto-rotation: the region is labelled and carries aria-roledescription="carousel", each item is a group named "Slide N of M", and the scroll container is a tab stop so keyboard users can pan it with the arrow keys.'},
17
18
  {guidance: true, description: 'Use a consistent gap and item width so the carousel looks intentional, not like content overflowing by accident.'},
18
19
  {guidance: true, description: 'Trust the built-in navigation: trackpad users can swipe horizontally, and mouse users can hold Shift while scrolling the wheel to move through items.'},
19
20
  {guidance: false, description: 'Use a carousel for content every user must see. Not everyone scrolls horizontally, so put critical content above the fold.'},
@@ -55,6 +56,7 @@ export const docs = {
55
56
  theming: {
56
57
  targets: [
57
58
  {className: 'astryx-carousel'},
59
+ {className: 'astryx-carousel-scroller', visualProps: ['gap', 'padding', 'snap', 'edgeFade']},
58
60
  ],
59
61
  },
60
62
  };
@@ -68,6 +70,7 @@ export const docsZh = {
68
70
  {guidance: true, description: '当每个项目应精确对齐到起始边缘时启用滚动吸附,例如画廊或产品列表。'},
69
71
  {guidance: true, description: '在小型可循环的集合(如照片画廊)上使用 hasLoop,此时从最后一项绕回第一项的滚动更自然。'},
70
72
  {guidance: true, description: '始终提供描述轮播内容的 aria-label,例如"精选产品"或"团队成员"。'},
73
+ {guidance: true, description: 'Carousel 实现不含自动轮播的 WAI-ARIA APG carousel 模式(https://www.w3.org/WAI/ARIA/apg/patterns/carousel/):区域带有标签和 aria-roledescription="carousel",每个项目是名为“第 N 张,共 M 张”的 group,滚动容器可获得焦点,键盘用户可用方向键平移。'},
71
74
  {guidance: true, description: '使用一致的间距和项目宽度,让轮播看起来是有意为之,而不是内容意外溢出。'},
72
75
  {guidance: true, description: '信任内置导航:触控板用户可水平滑动,鼠标用户可按住 Shift 滚动滚轮来浏览项目。'},
73
76
  {guidance: false, description: '将每位用户都必须看到的内容放入轮播。并非所有人都会水平滚动,关键内容应放在首屏。'},
@@ -3,6 +3,7 @@
3
3
  import {describe, it, expect, vi} from 'vitest';
4
4
  import {createRef} from 'react';
5
5
  import {render, screen, fireEvent} from '@testing-library/react';
6
+ import userEvent from '@testing-library/user-event';
6
7
  import {Carousel, type CarouselHandle} from './Carousel';
7
8
 
8
9
  // Mock ResizeObserver (not available in jsdom)
@@ -490,4 +491,363 @@ describe('Carousel', () => {
490
491
  expect(scrollBy.mock.calls[0][0]).toHaveProperty('left');
491
492
  });
492
493
  });
494
+
495
+ describe('keyboard focus at the edges', () => {
496
+ function getScroller() {
497
+ const region = screen.getByRole('region');
498
+ return region.firstElementChild as HTMLElement;
499
+ }
500
+
501
+ // jsdom has no layout, so fake an overflowing container whose scrollBy
502
+ // moves scrollLeft and fires scroll, which is what drives the overflow
503
+ // state the buttons and the focus hand-off both read. `land` decides where
504
+ // the container comes to rest: the default clamps to the requested delta,
505
+ // and the snap arm overrides it to model mandatory scroll-snap carrying the
506
+ // container past what the press asked for.
507
+ function makeScrollable(
508
+ el: HTMLElement,
509
+ scrollWidth: number,
510
+ land?: (requested: number, maxScroll: number) => number,
511
+ ) {
512
+ const clientWidth = 200;
513
+ const maxScroll = scrollWidth - clientWidth;
514
+ Object.defineProperty(el, 'scrollWidth', {
515
+ value: scrollWidth,
516
+ configurable: true,
517
+ });
518
+ Object.defineProperty(el, 'clientWidth', {
519
+ value: clientWidth,
520
+ configurable: true,
521
+ });
522
+ Object.defineProperty(el, 'scrollLeft', {
523
+ value: 0,
524
+ writable: true,
525
+ configurable: true,
526
+ });
527
+ el.scrollBy = ((options: ScrollToOptions) => {
528
+ const requested = Math.max(
529
+ 0,
530
+ Math.min(maxScroll, el.scrollLeft + (options.left ?? 0)),
531
+ );
532
+ el.scrollLeft = land ? land(requested, maxScroll) : requested;
533
+ fireEvent.scroll(el);
534
+ }) as HTMLElement['scrollBy'];
535
+ fireEvent.scroll(el);
536
+ }
537
+
538
+ it('hands focus to the opposite button when the edge disables the one in use', async () => {
539
+ const user = userEvent.setup();
540
+ render(
541
+ <Carousel aria-label="Gallery">
542
+ <div>Item 1</div>
543
+ <div>Item 2</div>
544
+ <div>Item 3</div>
545
+ </Carousel>,
546
+ );
547
+ // clientWidth 200 against a 200px step, so one press lands exactly on the
548
+ // trailing edge and the trailing button disables.
549
+ makeScrollable(getScroller(), 400);
550
+
551
+ const next = screen.getByLabelText('Scroll right');
552
+ await user.click(next);
553
+
554
+ expect(next).toBeDisabled();
555
+ expect(document.activeElement).toBe(screen.getByLabelText('Scroll left'));
556
+ expect(document.activeElement).not.toBe(document.body);
557
+ });
558
+
559
+ it('hands off in the leading direction too', async () => {
560
+ const user = userEvent.setup();
561
+ render(
562
+ <Carousel aria-label="Gallery">
563
+ <div>Item 1</div>
564
+ <div>Item 2</div>
565
+ <div>Item 3</div>
566
+ </Carousel>,
567
+ );
568
+ const scroller = getScroller();
569
+ makeScrollable(scroller, 400);
570
+ // Park at the far end so the leading button is the one that runs out.
571
+ scroller.scrollLeft = 200;
572
+ fireEvent.scroll(scroller);
573
+
574
+ const previous = screen.getByLabelText('Scroll left');
575
+ await user.click(previous);
576
+
577
+ expect(previous).toBeDisabled();
578
+ expect(document.activeElement).toBe(
579
+ screen.getByLabelText('Scroll right'),
580
+ );
581
+ });
582
+
583
+ it('hands off under RTL, where the scroll axis is inverted', async () => {
584
+ const user = userEvent.setup();
585
+ render(
586
+ <Carousel aria-label="Gallery">
587
+ <div>Item 1</div>
588
+ <div>Item 2</div>
589
+ <div>Item 3</div>
590
+ </Carousel>,
591
+ );
592
+ const scroller = getScroller();
593
+ // The component resolves direction with getComputedStyle, and jsdom does
594
+ // not inherit `dir` down to it, so set it on the element itself. RTL then
595
+ // scrolls negative, which the mock below mirrors.
596
+ scroller.style.direction = 'rtl';
597
+ const maxScroll = 200;
598
+ Object.defineProperty(scroller, 'scrollWidth', {
599
+ value: 400,
600
+ configurable: true,
601
+ });
602
+ Object.defineProperty(scroller, 'clientWidth', {
603
+ value: 200,
604
+ configurable: true,
605
+ });
606
+ Object.defineProperty(scroller, 'scrollLeft', {
607
+ value: 0,
608
+ writable: true,
609
+ configurable: true,
610
+ });
611
+ scroller.scrollBy = ((options: ScrollToOptions) => {
612
+ scroller.scrollLeft = Math.max(
613
+ -maxScroll,
614
+ Math.min(0, scroller.scrollLeft + (options.left ?? 0)),
615
+ );
616
+ fireEvent.scroll(scroller);
617
+ }) as HTMLElement['scrollBy'];
618
+ fireEvent.scroll(scroller);
619
+
620
+ const next = screen.getByLabelText('Scroll right');
621
+ await user.click(next);
622
+
623
+ expect(next).toBeDisabled();
624
+ expect(document.activeElement).toBe(screen.getByLabelText('Scroll left'));
625
+ });
626
+
627
+ it('hands off when scroll-snap carries the container past what the press asked for', async () => {
628
+ const user = userEvent.setup();
629
+ render(
630
+ <Carousel hasSnap aria-label="Gallery">
631
+ <div>Item 1</div>
632
+ <div>Item 2</div>
633
+ <div>Item 3</div>
634
+ </Carousel>,
635
+ );
636
+ // 700 gives 500 of travel against a 200 step, so the press alone lands
637
+ // mid-run. Mandatory snapping then carries it to the end, which is the
638
+ // landing position no press can predict.
639
+ makeScrollable(getScroller(), 700, (_requested, maxScroll) => maxScroll);
640
+
641
+ const next = screen.getByLabelText('Scroll right');
642
+ await user.click(next);
643
+
644
+ expect(next).toBeDisabled();
645
+ expect(document.activeElement).toBe(screen.getByLabelText('Scroll left'));
646
+ });
647
+
648
+ it('falls back to the scroll container when the carousel stops overflowing', async () => {
649
+ const user = userEvent.setup();
650
+ render(
651
+ <Carousel aria-label="Gallery">
652
+ <div>Item 1</div>
653
+ <div>Item 2</div>
654
+ </Carousel>,
655
+ );
656
+ const scroller = getScroller();
657
+ // The content shrinks to fit during the press, so BOTH buttons disable
658
+ // and there is no opposite control left to receive focus.
659
+ makeScrollable(scroller, 400, () => {
660
+ Object.defineProperty(scroller, 'scrollWidth', {
661
+ value: 200,
662
+ configurable: true,
663
+ });
664
+ return 0;
665
+ });
666
+
667
+ await user.click(screen.getByLabelText('Scroll right'));
668
+
669
+ expect(screen.getByLabelText('Scroll right')).toBeDisabled();
670
+ expect(screen.getByLabelText('Scroll left')).toBeDisabled();
671
+ expect(document.activeElement).toBe(scroller);
672
+ expect(document.activeElement).not.toBe(document.body);
673
+ });
674
+
675
+ it('does not pull focus back after the person has left the button', () => {
676
+ render(
677
+ <Carousel aria-label="Gallery">
678
+ <div>Item 1</div>
679
+ <div>Item 2</div>
680
+ <div>Item 3</div>
681
+ </Carousel>,
682
+ );
683
+ const scroller = getScroller();
684
+ makeScrollable(scroller, 400);
685
+
686
+ // Touch an arrow, then leave it without pressing it. Landing on <body> is
687
+ // the case that matters: focus somewhere else is already ignored, so a
688
+ // stale tracker only bites when there is nothing else holding focus.
689
+ const next = screen.getByLabelText('Scroll right');
690
+ next.focus();
691
+ next.blur();
692
+ expect(document.activeElement).toBe(document.body);
693
+
694
+ // The carousel reaches the edge on its own: a swipe, a resize, anything
695
+ // that is not this person. Their focus is not the carousel's to take.
696
+ scroller.scrollLeft = 200;
697
+ fireEvent.scroll(scroller);
698
+
699
+ expect(screen.getByLabelText('Scroll right')).toBeDisabled();
700
+ expect(document.activeElement).toBe(document.body);
701
+ });
702
+
703
+ it('hands off on a press, with the blur handlers in place', async () => {
704
+ const user = userEvent.setup();
705
+ render(
706
+ <Carousel aria-label="Gallery">
707
+ <div>Item 1</div>
708
+ <div>Item 2</div>
709
+ <div>Item 3</div>
710
+ </Carousel>,
711
+ );
712
+ makeScrollable(getScroller(), 400);
713
+
714
+ // The Effect clears the tracker itself before focusing, so the commit's
715
+ // own blur finds nothing left to clear and the guard is not what makes
716
+ // this pass. It is here so that deleting the blur handlers outright --
717
+ // rather than loosening the guard -- is caught.
718
+ await user.click(screen.getByLabelText('Scroll right'));
719
+
720
+ expect(document.activeElement).toBe(screen.getByLabelText('Scroll left'));
721
+ });
722
+
723
+ it('does not move focus on a press that leaves the direction available', async () => {
724
+ const user = userEvent.setup();
725
+ render(
726
+ <Carousel aria-label="Gallery">
727
+ <div>Item 1</div>
728
+ <div>Item 2</div>
729
+ <div>Item 3</div>
730
+ </Carousel>,
731
+ );
732
+ makeScrollable(getScroller(), 600);
733
+
734
+ const next = screen.getByLabelText('Scroll right');
735
+ await user.click(next);
736
+
737
+ expect(next).toBeEnabled();
738
+ expect(document.activeElement).toBe(next);
739
+ });
740
+
741
+ it('does not move focus when hasLoop keeps both buttons enabled', async () => {
742
+ const user = userEvent.setup();
743
+ render(
744
+ <Carousel hasLoop aria-label="Looping">
745
+ <div>Item 1</div>
746
+ <div>Item 2</div>
747
+ </Carousel>,
748
+ );
749
+ makeScrollable(getScroller(), 400);
750
+
751
+ const next = screen.getByLabelText('Scroll right');
752
+ await user.click(next);
753
+
754
+ expect(next).toBeEnabled();
755
+ expect(document.activeElement).toBe(next);
756
+ });
757
+
758
+ it('takes focus without scrolling the receiver into view', async () => {
759
+ const user = userEvent.setup();
760
+ render(
761
+ <Carousel aria-label="Gallery">
762
+ <div>Item 1</div>
763
+ <div>Item 2</div>
764
+ </Carousel>,
765
+ );
766
+ makeScrollable(getScroller(), 400);
767
+ const previous = screen.getByLabelText('Scroll left');
768
+ const focus = vi.spyOn(previous, 'focus');
769
+
770
+ await user.click(screen.getByLabelText('Scroll right'));
771
+
772
+ // A plain focus() scrolls its element into view, which on the scroll
773
+ // container cancels the scroll the same press started.
774
+ expect(focus).toHaveBeenCalledWith({preventScroll: true});
775
+ });
776
+
777
+ it('leaves focus alone when the imperative handle drives the scroll', () => {
778
+ const handle = createRef<CarouselHandle>();
779
+ render(
780
+ <Carousel handleRef={handle} aria-label="Gallery">
781
+ <div>Item 1</div>
782
+ <div>Item 2</div>
783
+ </Carousel>,
784
+ );
785
+ makeScrollable(getScroller(), 400);
786
+ const outside = document.createElement('button');
787
+ document.body.appendChild(outside);
788
+ outside.focus();
789
+
790
+ handle.current?.scrollNext();
791
+
792
+ expect(document.activeElement).toBe(outside);
793
+ outside.remove();
794
+ });
795
+
796
+ it('does not move focus a second time for one transition', async () => {
797
+ const user = userEvent.setup();
798
+ const {rerender} = render(
799
+ <Carousel aria-label="Gallery">
800
+ <div>Item 1</div>
801
+ <div>Item 2</div>
802
+ <div>Item 3</div>
803
+ </Carousel>,
804
+ );
805
+ makeScrollable(getScroller(), 400);
806
+ await user.click(screen.getByLabelText('Scroll right'));
807
+
808
+ const previous = screen.getByLabelText('Scroll left');
809
+ expect(document.activeElement).toBe(previous);
810
+ // Park focus outside and re-render: the transition is spent, so nothing
811
+ // may pull focus back in.
812
+ const outside = document.createElement('button');
813
+ document.body.appendChild(outside);
814
+ outside.focus();
815
+ rerender(
816
+ <Carousel aria-label="Gallery">
817
+ <div>Item 1</div>
818
+ <div>Item 2</div>
819
+ <div>Item 3</div>
820
+ </Carousel>,
821
+ );
822
+
823
+ expect(document.activeElement).toBe(outside);
824
+ outside.remove();
825
+ });
826
+
827
+ it('reflects the scroll container as a theme target carrying its style-driving props', () => {
828
+ render(
829
+ <Carousel gap={2} padding={3} hasSnap aria-label="Gallery">
830
+ <div>Item 1</div>
831
+ </Carousel>,
832
+ );
833
+ const scroller = getScroller();
834
+ expect(scroller).toHaveClass('astryx-carousel-scroller');
835
+ expect(scroller).toHaveAttribute('data-gap', '2');
836
+ expect(scroller).toHaveAttribute('data-padding', '3');
837
+ expect(scroller).toHaveAttribute('data-snap', 'snap');
838
+ expect(scroller).toHaveAttribute('data-edge-fade', 'edge-fade');
839
+ });
840
+
841
+ it('omits the opt-out attributes a theme should not see', () => {
842
+ render(
843
+ <Carousel hasEdgeFade={false} aria-label="Gallery">
844
+ <div>Item 1</div>
845
+ </Carousel>,
846
+ );
847
+ const scroller = getScroller();
848
+ expect(scroller).not.toHaveAttribute('data-edge-fade');
849
+ expect(scroller).not.toHaveAttribute('data-snap');
850
+ expect(scroller).not.toHaveAttribute('data-padding');
851
+ });
852
+ });
493
853
  });