@astryxdesign/core 0.5.0 → 0.5.1-canary.8359f1a

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 (612) 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 +3 -3
  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 +2 -0
  390. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  391. package/src/CheckboxInput/CheckboxInput.tsx +5 -0
  392. package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
  393. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  394. package/src/CodeBlock/CodeBlock.tsx +20 -4
  395. package/src/CodeBlock/highlightRanges.ts +1 -1
  396. package/src/CodeBlock/highlightStyles.ts +13 -13
  397. package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
  398. package/src/ComplexSelector/ComplexSelector.doc.mjs +7 -0
  399. package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
  400. package/src/ComplexSelector/ComplexSelector.tsx +22 -12
  401. package/src/DateInput/DateInput.doc.mjs +16 -0
  402. package/src/DateInput/DateInput.test.tsx +9 -4
  403. package/src/DateInput/DateInput.tsx +54 -3
  404. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  405. package/src/DateInput/MonthScroller.tsx +5 -1
  406. package/src/DateInput/MonthYearWheels.tsx +7 -4
  407. package/src/DateInput/NativeDateField.test.tsx +635 -0
  408. package/src/DateInput/NativeDateField.tsx +641 -0
  409. package/src/DateInput/TouchDateField.tsx +83 -33
  410. package/src/DateInput/Wheel.tsx +1 -0
  411. package/src/DateInput/index.ts +1 -0
  412. package/src/DateInput/nativeDateSegments.ts +127 -0
  413. package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
  414. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
  415. package/src/DateRangeInput/DateRangeInput.tsx +8 -13
  416. package/src/DateTimeInput/DateTimeInput.doc.mjs +38 -21
  417. package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
  418. package/src/DateTimeInput/DateTimeInput.tsx +54 -20
  419. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
  420. package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
  421. package/src/Dialog/Dialog.test.tsx +185 -18
  422. package/src/Dialog/Dialog.tsx +35 -11
  423. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  424. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  425. package/src/Field/FieldLabel.test.tsx +29 -0
  426. package/src/Field/FieldLabel.tsx +7 -0
  427. package/src/Field/InputClearButton.test.tsx +15 -1
  428. package/src/Field/InputClearButton.tsx +28 -4
  429. package/src/Heading/Heading.tsx +0 -1
  430. package/src/HoverCard/HoverCard.doc.mjs +8 -2
  431. package/src/HoverCard/HoverCard.test.tsx +154 -4
  432. package/src/HoverCard/HoverCard.tsx +137 -3
  433. package/src/HoverCard/useHoverCard.tsx +23 -3
  434. package/src/Icon/Icon.test.tsx +55 -1
  435. package/src/Icon/Icon.tsx +5 -3
  436. package/src/Icon/defaultIcons.tsx +11 -2
  437. package/src/Icon/globalIconRegistry.test.tsx +16 -3
  438. package/src/Icon/globalIconRegistry.tsx +37 -6
  439. package/src/Icon/index.ts +1 -0
  440. package/src/Icon/useIcon.ts +9 -2
  441. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  442. package/src/Indicator/Indicator.doc.mjs +2 -0
  443. package/src/Item/Item.tsx +2 -7
  444. package/src/Kbd/Kbd.test.tsx +0 -17
  445. package/src/Kbd/Kbd.tsx +2 -26
  446. package/src/Layer/gestureCounter.ts +57 -0
  447. package/src/Layer/useLayer.test.tsx +368 -16
  448. package/src/Layer/useLayer.tsx +208 -35
  449. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  450. package/src/List/List.test.tsx +38 -0
  451. package/src/List/List.tsx +8 -1
  452. package/src/Markdown/Markdown.test.tsx +37 -0
  453. package/src/Markdown/Markdown.tsx +16 -5
  454. package/src/Markdown/parser.test.ts +33 -0
  455. package/src/Markdown/parser.ts +9 -3
  456. package/src/MetadataList/MetadataList.test.tsx +75 -2
  457. package/src/MetadataList/MetadataListItem.tsx +5 -2
  458. package/src/MultiSelector/MultiSelector.doc.mjs +22 -1
  459. package/src/MultiSelector/MultiSelector.test.tsx +205 -0
  460. package/src/MultiSelector/MultiSelector.tsx +103 -16
  461. package/src/MultiSelector/hooks.ts +9 -2
  462. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  463. package/src/NavIcon/NavIcon.test.tsx +9 -0
  464. package/src/NavIcon/NavIcon.tsx +5 -1
  465. package/src/NavItem/navItemStyles.stylex.ts +0 -8
  466. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  467. package/src/NavMenu/NavHeadingMenu.tsx +7 -4
  468. package/src/NumberInput/NumberInput.doc.mjs +26 -7
  469. package/src/NumberInput/NumberInput.test.tsx +563 -8
  470. package/src/NumberInput/NumberInput.tsx +77 -131
  471. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  472. package/src/NumberInput/numberInputCommit.ts +103 -0
  473. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  474. package/src/NumberInput/numberParser.test.ts +222 -0
  475. package/src/NumberInput/numberParser.ts +403 -0
  476. package/src/Outline/Outline.tsx +2 -4
  477. package/src/OverflowList/OverflowList.doc.mjs +102 -21
  478. package/src/OverflowList/OverflowList.test.tsx +550 -4
  479. package/src/OverflowList/OverflowList.tsx +100 -2
  480. package/src/Pagination/Pagination.test.tsx +3 -2
  481. package/src/Popover/Popover.doc.mjs +2 -2
  482. package/src/Popover/Popover.test.tsx +38 -0
  483. package/src/Popover/Popover.tsx +28 -66
  484. package/src/Popover/usePopover.tsx +44 -5
  485. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
  486. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
  487. package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
  488. package/src/PowerSearch/formatFilterValue.test.ts +16 -1
  489. package/src/PowerSearch/formatFilterValue.ts +2 -0
  490. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  491. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  492. package/src/ProgressBar/ProgressBar.tsx +28 -8
  493. package/src/Resizable/Resizable.doc.mjs +2 -2
  494. package/src/Resizable/useResizable.doc.mjs +21 -2
  495. package/src/Resizable/useResizable.test.ts +421 -0
  496. package/src/Resizable/useResizable.ts +133 -48
  497. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  498. package/src/SelectableCard/SelectableCard.tsx +16 -0
  499. package/src/Selector/Selector.doc.mjs +14 -0
  500. package/src/Selector/Selector.source-build.test.mjs +65 -0
  501. package/src/Selector/Selector.test.tsx +301 -0
  502. package/src/Selector/Selector.tsx +145 -32
  503. package/src/Selector/hooks.ts +17 -2
  504. package/src/SideNav/SideNav.doc.mjs +2 -2
  505. package/src/SideNav/SideNav.test.tsx +1069 -6
  506. package/src/SideNav/SideNav.tsx +109 -38
  507. package/src/SideNav/SideNavHeading.tsx +5 -2
  508. package/src/SideNav/SideNavItem.doc.mjs +24 -3
  509. package/src/SideNav/SideNavItem.tsx +134 -44
  510. package/src/Slider/Slider.test.tsx +106 -1
  511. package/src/Slider/Slider.tsx +52 -1
  512. package/src/Spinner/Spinner.doc.mjs +17 -5
  513. package/src/Spinner/Spinner.test.tsx +164 -0
  514. package/src/Spinner/Spinner.tsx +252 -22
  515. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  516. package/src/StatusDot/StatusDot.test.tsx +9 -0
  517. package/src/StatusDot/StatusDot.tsx +7 -1
  518. package/src/Stepper/Step.doc.mjs +1 -1
  519. package/src/Stepper/Step.tsx +7 -14
  520. package/src/Switch/Switch.doc.mjs +2 -0
  521. package/src/Switch/Switch.test.tsx +10 -0
  522. package/src/Switch/Switch.tsx +3 -0
  523. package/src/Table/BaseTable.tsx +6 -1
  524. package/src/Table/Table.doc.mjs +5 -3
  525. package/src/Table/Table.tsx +3 -8
  526. package/src/Table/TableBody.doc.mjs +2 -2
  527. package/src/Table/TableFooter.doc.mjs +1 -1
  528. package/src/Table/TableHeader.doc.mjs +1 -1
  529. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  530. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  531. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
  532. package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
  533. package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
  534. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  535. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  536. package/src/Table/useTablePagination.doc.mjs +1 -1
  537. package/src/Table/useTableSelection.doc.mjs +1 -1
  538. package/src/Text/Text.test.tsx +44 -0
  539. package/src/Text/Text.tsx +0 -1
  540. package/src/TextArea/TextArea.doc.mjs +12 -2
  541. package/src/TextArea/TextArea.test.tsx +11 -0
  542. package/src/TextArea/TextArea.tsx +34 -22
  543. package/src/Timestamp/Timestamp.test.tsx +89 -0
  544. package/src/Timestamp/Timestamp.tsx +8 -8
  545. package/src/Timestamp/formatInstant.ts +5 -0
  546. package/src/Toast/Toast.doc.mjs +213 -44
  547. package/src/Toast/Toast.tsx +118 -23
  548. package/src/Toast/ToastViewport.test.tsx +1434 -8
  549. package/src/Toast/ToastViewport.tsx +85 -14
  550. package/src/Toast/index.ts +2 -0
  551. package/src/Toast/types.ts +43 -5
  552. package/src/Toast/useToastGesture.ts +361 -0
  553. package/src/Token/Token.test.tsx +95 -0
  554. package/src/Token/Token.tsx +19 -17
  555. package/src/Token/TokenLink.tsx +12 -3
  556. package/src/Tokenizer/Tokenizer.doc.mjs +16 -3
  557. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  558. package/src/Tokenizer/Tokenizer.tsx +49 -24
  559. package/src/TopNav/TopNavHeading.tsx +2 -2
  560. package/src/TopNav/TopNavItem.tsx +3 -7
  561. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  562. package/src/TopNav/TopNavMegaMenu.tsx +47 -4
  563. package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
  564. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  565. package/src/TopNav/TopNavMenu.tsx +38 -5
  566. package/src/TreeList/TreeList.test.tsx +49 -0
  567. package/src/TreeList/TreeList.tsx +7 -2
  568. package/src/TreeList/TreeListItem.tsx +2 -7
  569. package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
  570. package/src/Typeahead/BaseTypeahead.tsx +96 -6
  571. package/src/Typeahead/Typeahead.doc.mjs +6 -0
  572. package/src/Typeahead/Typeahead.test.tsx +154 -0
  573. package/src/Typeahead/Typeahead.tsx +9 -0
  574. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  575. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  576. package/src/hooks/useAnnounce.doc.mjs +96 -0
  577. package/src/hooks/useDevWarning.doc.mjs +96 -0
  578. package/src/hooks/useHotkeys.test.ts +0 -18
  579. package/src/hooks/useHotkeys.ts +3 -25
  580. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  581. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  582. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  583. package/src/hooks/useLongPress.doc.mjs +123 -0
  584. package/src/hooks/useOverflow.doc.mjs +58 -17
  585. package/src/hooks/useOverflow.ts +16 -4
  586. package/src/hooks/useTypeahead.doc.mjs +153 -0
  587. package/src/i18n/InternationalizationContext.ts +3 -0
  588. package/src/i18n/InternationalizationProvider.tsx +8 -1
  589. package/src/i18n/__tests__/resolve.test.ts +23 -1
  590. package/src/i18n/resolve.ts +46 -49
  591. package/src/i18n/useTranslator.ts +2 -7
  592. package/src/index.ts +2 -0
  593. package/src/raw-import.d.ts +14 -0
  594. package/src/theme/Theme.test.tsx +104 -2
  595. package/src/theme/Theme.tsx +49 -14
  596. package/src/theme/defineTheme.test.ts +23 -0
  597. package/src/theme/defineTheme.ts +12 -3
  598. package/src/theme/derivedVarRegistry.test.ts +87 -3
  599. package/src/theme/derivedVarRegistry.ts +23 -4
  600. package/src/theme/generateThemeRules.test.ts +99 -1
  601. package/src/theme/generateThemeRules.ts +28 -0
  602. package/src/theme/syntax/tokens.ts +5 -2
  603. package/src/theme/useTheme.test.tsx +10 -0
  604. package/src/theme/useTheme.ts +16 -10
  605. package/src/utils/dateParser.test.ts +34 -2
  606. package/src/utils/dateParser.ts +11 -14
  607. package/src/utils/focusOutline.stylex.ts +50 -0
  608. package/src/utils/interactionOverlay.stylex.ts +74 -0
  609. package/src/utils/isApplePlatform.test.ts +61 -0
  610. package/src/utils/isApplePlatform.ts +37 -0
  611. package/src/utils/plainDate.test.ts +46 -0
  612. package/src/utils/plainDate.ts +18 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,227 @@
1
1
  # @xds/core
2
2
 
3
+ # 0.5.1
4
+
5
+ #### New Features
6
+
7
+ - add shape prop ('circle' | 'rounded' | 'square') to Avatar for non-circular form factors (#4205) (#4327)
8
+ - Card: make the `variant` axis theme-extensible through a `CardVariantMap` interface (#5551)
9
+ `CardVariant` was a hand-written union backed by a closed style record, so a theme could not add a card variant: an unknown value neither type-checked nor rendered. It is now `keyof CardVariantMap`, an interface exported from `@astryxdesign/core/Card` that a theme build augments — the same shape Button, Badge, Section and the other extensible axes already ship.
10
+
11
+ `keyof CardVariantMap` resolves to exactly the thirteen values `CardVariant` had, so no existing call site changes. A variant a theme adds falls through to base styles and the theme's own `card['variant:<name>']` rule paints it.
12
+
13
+ On SelectableCard that variant's selection ring is drawn in `--selectable-card-ring-color`, defaulting to the accent. No token the component could pick is guaranteed to contrast with a fill the component cannot know, so a theme rule that adds a variant sets the ring colour in the same rule as its `backgroundColor`.
14
+
15
+ - CheckboxInput and Switch now name their own label as a theme target: `astryx-checkbox-label` and `astryx-switch-label`, alongside the `astryx-field-label` every label already carries. A theme could previously only reach one `astryx-field-label` target, so styling a checkbox's label — which shares a row with its control — meant styling every form field's label above its input too. The control passes the target down, so the name says what the thing is rather than encoding how it is arranged, and nothing can set it untruthfully. (#5183)
16
+ - The checkbox indicator now exposes stable theme targets for its two marks — `astryx-checkbox-indicator-check` (the checkmark) and `astryx-checkbox-indicator-dash` (the indeterminate bar) — mirroring the existing `astryx-radio-indicator-dot`. Both reflect `size`. A theme restyling the mark itself (stroke weight, colour, the dash's proportions) previously had to reach it with `.astryx-checkbox-indicator > svg` and `> span`, which are element-and-order selectors that break silently on any restructure. Purely additive; no visual change. (#5426)
17
+ - ComplexSelector: `onOpenChange` reports every open and close of the popup — the trigger, the keyboard, a light dismiss, Escape, content calling `close()`, or the imperative handle. Paired with the existing `handleRef`, a consumer can drive and observe the surface without reading the shell's DOM. (#5211)
18
+ - DateInput uses the platform date picker on touch, with `nativePicker` to choose the native or Astryx surface; focused desktop-style native fields reveal their editable segments, the Astryx touch sheet keeps Reset in its header and Save alone in its footer, and both closed surfaces match standard input height (#5261, #5456, #5502, #5534)
19
+ `nativePicker="touch"` is the default, `"always"` uses `<input type="date">` wherever supported, and `"never"` keeps Astryx's sheet or popover. Formatting still returns on blur, and `min`/`max` continue to validate native selections.
20
+ - Add a coarse-pointer DateTimeInput bottom-sheet picker with separate closed Date/Time segments, direct section opening, and a two-step Save date → Save flow. (#5582)
21
+ - Icon APIs and themes accept namespaced extension keys, and NumberInput steppers use `numberInput:stepperDown` without widening the required `IconRegistry` keys (#5466)
22
+ `<Icon icon>`, `useIcon`, and `defineTheme({icons})` accept keys such as `numberInput:stepperDown` and `richtext:bold`; misspelled built-in names remain type errors. NumberInput keeps a compact centered Core fallback, while themes can override its steppers independently from the shared `chevronDown` semantic.
23
+ - `OverflowList` can now hand its collapsed items to a menu you already render, via `onOverflowChange(overflowItems)`. `overflowRenderer` only describes an indicator the list mounts itself, and only while items overflow — so a row that already carries a standing "…" menu had no way to collect the collapsed items into it, and adding an indicator gave the user two menus side by side. Watching from the outside was not reachable either: a reporter component placed inside `overflowRenderer` mounts twice (the hidden measurement copy always receives _every_ item, so it cannot tell you what is actually collapsed), and nothing fires when the row widens back out and the set empties. The new callback reports the collapsed set whenever its membership or order changes, and leaves the anchor entirely to the caller. It fires once measurement has collapsed something, fires again with an empty array once the row widens back out and everything fits, and is silent while nothing overflows — including on mount, so a list that fits from the start never calls it. It never reports the pre-measurement state, which is an empty set whether or not the row actually overflows; hold the collapsed set in state initialised to `[]` and it is correct at every moment. Reports run from a layout effect after measurement, so the menu updates in the same frame as the collapse. The measurement container is now observed for size changes, so child-size changes refresh every OverflowList and direct `useOverflow` consumer even when the available container width does not change. Keyed membership and order changes are re-measured before `onOverflowChange` reports them. Stable React keys distinguish same-count membership and order changes, while unrelated re-renders and callback identity changes do not re-fire it. Both APIs may be used together; using `onOverflowChange` alone adds nothing to the row. (#5199)
24
+ - Selector and MultiSelector: configurable panel empty states via `emptyText` and `emptySearchText`, announced to screen readers as well as shown; a panel with no options now says so instead of rendering blank, and says nothing while `isLoading` (#5462)
25
+ - SideNavItem: new `actions` slot for row-level secondary controls (icon buttons, menus). Content renders as a sibling of the primary link/button — after the expand/collapse toggle, before nested children in DOM and focus order — so interactive controls never nest inside the primary element and every row control is reachable before focus enters the subtree. Passive content (badges, counts) stays in `endContent`; `actions` is hidden while the rail is collapsed, and stays interactive on disabled items since each supplied control owns its own disabled state. An actions row draws its focus ring as a full-row pill for the primary link or button, while the expand/collapse toggle and each supplied action keep their own — adds `focusOutlineProps.focusWithinFirstChild` and `focusOutlineProps.suppressed` for that pairing. Supplied controls inherit the row's control size through `SizeContext`, the way `SideNav` already cascades one size to its footer icons, so an unsized icon button comes out the same box as the built-in toggle; an explicit `size` still wins. (#4988) (#5005)
26
+ - Spinner: the ring's geometry and its two colors are now themeable. The `size` and `shade` props keep their fixed enums; what each named value _resolves to_ is now a theme's to set, through four public custom properties on the `spinner` target — `--spinner-diameter` and `--spinner-stroke-width` under a size variant, `--spinner-color` and `--spinner-track-color` under a shade variant (or on the base target for all of them at once): (#5214)
27
+
28
+ ```ts
29
+ spinner: {
30
+ 'size:xl': {'--spinner-diameter': '2.5rem', '--spinner-stroke-width': '0.375rem'},
31
+ 'shade:subtle': {'--spinner-track-color': 'transparent'},
32
+ }
33
+ ```
34
+
35
+ Any length and any color notation works — `rem`, `em` and `calc()` are resolved by the cascade into the radius and stroke the ring is drawn with, and colors accept `var()`, `color-mix()` and `currentColor`. A stroke width of `0` is honoured as a zero-width stroke — it paints nothing, rather than being read as "unset" and silently drawing the default. The drawn ring and the box around it come from the same values, so they stay in step, including when a media query or a root font-size change moves them after mount.
36
+
37
+ The two private vars the ring resolves into are registered as `<length>` when the module is imported, not when a spinner first mounts. Registering an inherited property with an `initial-value` invalidates style for the whole document, and a spinner is the loading indicator — it arrives on a page that has already rendered, so paying that there is paying it on the full tree: 29 ms against 12 ms for the same mount on an 11k-element page. A build that never imports `Spinner` drops the module and the registration with it.
38
+
39
+ Output is unchanged for every size and shade unless a theme overrides something, and so is every precedence around the box: it is still sized by an inline `width`/`height` written after the caller's `style`, as it has always been, with the composed value in place of the number.
40
+
41
+ - TextArea: the two painted elements inside the wrapper now carry stable theme targets — `astryx-text-area-control` (the `<textarea>` itself) and `astryx-text-area-counter` (the character counter). Only the wrapper was themeable before, so a theme restyling the control's own typography, placeholder or resize affordance, or the counter's supporting text, had to reach in with structural selectors like `.astryx-text-area > textarea`. Purely additive: no existing class, data attribute, or style changes. (#5418)
42
+ Neither carries a `size` axis. `size` moves only the control's block padding (`sm` and `md` are empty; `lg` sets `paddingBlock`), and that is the axis a `padding` translation for this component takes over — so an axis here would be a second way to say the same thing, and the one that stops being true once the translation lands.
43
+
44
+ The start-icon and end-slot overlays are deliberately not targets. They paint nothing — each is `position: absolute; pointer-events: none; display: flex` — and they are placed off the wrapper's `--_textarea-inline-padding`, so a theme that moves the control's inset needs them to move with it rather than to be re-placed one at a time. That inset belongs in a `padding` translation for the component, which is tracked separately.
45
+
46
+ - Toast: `renderContent` on the `showToast` options replaces the content of that toast's card with your own layout. (#5428)
47
+
48
+ ```tsx
49
+ showToast({
50
+ body: 'Your changes have been saved.',
51
+ renderContent: ({body, endContent, dismiss}) => (
52
+ <MyRow>
53
+ <MyTitle>{body}</MyTitle>
54
+ {endContent}
55
+ <Button label="Dismiss notification" onClick={dismiss} />
56
+ </MyRow>
57
+ ),
58
+ });
59
+ ```
60
+
61
+ Astryx keeps the card, its `astryx-toast` theme target, live-region role and auto-hide behavior. The renderer receives the message, `endContent`, resolved toast settings and a `dismiss` callback.
62
+
63
+ Custom content owns its complete layout and every control in it. Call `dismiss` from the control that should close the toast; it may be passed through nested components. Astryx does not register an injected component or add a fallback close behind a custom layout.
64
+
65
+ The API is per-toast. An app can share one layout by wrapping `useToast()` and passing `renderContent` on each call, while other toasts continue to use the ordinary Astryx layout and its translated, themeable dismiss `Button`.
66
+
67
+ New exported types: `ToastContentRenderProps`, `ToastContentRenderFn`.
68
+
69
+ - Toast now supports touch and pen swipe dismissal toward its configured viewport edge. The vertical axis matches each Toast's top/bottom placement and entrance/exit motion, so the dismissal follows the same spatial model instead of introducing a separate side exit. Native touch scrolling is preserved until movement resolves to the dismiss direction, interactive controls do not start a swipe, and swipe continues to report the existing manual dismissal reason. Pen is included as direct-contact input; mouse drag is excluded because desktop users already have the visible close control and dragging can conflict with text selection. (#5375)
70
+ - Typeahead + Tokenizer: minQueryLength holds the search and the menu until the query is long enough (#5385)
71
+ Also fixes a stranded loading state that predates the prop: abandoning an in-flight search — by emptying the field, by falling below the threshold, or by selecting an item while the next search is still out — bumps the search generation, which makes that search's own `finally` decline to clear the loading flag. The field kept reporting "Loading" to assistive technology until another search settled.
72
+
73
+ `hasCreate` is not gated by it. The "Create ..." entry is derived from the typed text rather than fetched for it, so it now reaches the menu through a separate internal path and is offered whatever the threshold says — the threshold exists to avoid a fetch too broad to be worth making, and creating costs no fetch. With `minQueryLength={3}`, typing `QA` offers `Create "QA"` and Enter commits it, while the search source is still never called.
74
+
75
+ One consequence worth naming: the Create entry is appended after the results are cut to `maxMenuItems`, so with `hasCreate` a full menu now shows one option more than the cap — 11 where it used to show 10. The cap bounds how many _results_ a menu shows; creating is a separate capability and is not crowded out by them.
76
+
77
+ #### Fixes
78
+
79
+ - AlertDialog lets Dialog preserve and clamp its preferred width, lets whole actions move to another row when needed, and stacks full-width destructive and Cancel actions at 640px and below while preserving standard single-line Button sizing and labels regardless of pointer type. (#5343)
80
+ - Badge: a long label no longer escapes its container. (#5558)
81
+ `Badge` set `white-space: nowrap` with nothing to clip it — the one pairing that neither wraps nor truncates. A label wider than the space available rendered _outside_ the badge's container and over whatever sat beside it.
82
+
83
+ ```tsx
84
+ <div style={{width: 100}}>
85
+ <Badge variant="pink" label="Awaiting security review" />
86
+ </div>
87
+ ```
88
+
89
+ Measured in Chromium: that badge came out **163px** wide in a 100px column, spilling 63px past it; in a fixed-layout table cell it painted 64px over the text in the next cell. The badge now clamps to the width it is given and cuts the label with an ellipsis.
90
+
91
+ A badge that already fits is untouched — same width, same height, same DOM. Measured before and after, a badge with room to spare is 53px either way; only the cases that were already overflowing change. `Badge` uses no hooks and stays server-renderable.
92
+
93
+ The ellipsis sits on an inner label span rather than the badge itself, because `text-overflow` needs a block container and taking the root off `inline-flex` to get one would cost the icon its centring. With an icon, the icon holds its place and the label gives way.
94
+
95
+ So that a clipped tail is not simply lost, a string or number label is also carried in the badge's `title` — the same shape `BaseTable` already uses for a truncated header cell. That costs no measurement and no hook, so `Badge` still renders the same on the server and stays usable in a server component. A rich `label` is left alone rather than flattened to a guess.
96
+
97
+ Two gaps remain, both needing runtime measurement, and both tracked in #5585: the `title` is set whether or not the label actually fits, and a native `title` is a pointer affordance — it answers hover, not keyboard focus, and not touch at all. The refinement is a tooltip shown only when the text is really cut, reachable by hover and by focus, which makes `Badge` a client component and is its own trade-off to weigh.
98
+
99
+ - Banner names each dismiss control after its string title, so stacked banners no longer expose identical "Dismiss" buttons to screen readers. Rich titles retain the generic translated name unless the consumer supplies an already-translated `dismissLabel`; that override also labels the tooltip. (#5113)
100
+ - Seven components now forward the pass-through props promised by `BaseProps` (#5563)
101
+ `MetadataListItem`, `NavHeadingMenu`, `Timestamp`, `Token`, `TopNavMegaMenu`, `TopNavMenu`, and `TypeaheadItem` now forward neutral `aria-*`, `id`, `tabIndex`, event-handler, and `data-*` props to their rendered DOM element. Styling still merges through `mergeProps`, contract-owned attributes retain precedence, and owned handlers compose through `composeEventHandlers` with the caller first.
102
+
103
+ `MetadataListItem` targets its wrapper `<div>` when stacked and its `<dt>` when inline. A `TypeaheadItem` backed by caller-supplied `item.element` remains unchanged and does not receive forwarded props because that value may not be a cloneable element.
104
+
105
+ This completes [#5254](https://github.com/facebook/astryx/issues/5254) after [#5288](https://github.com/facebook/astryx/pull/5288) by @lexs landed `List` and `Markdown` first, followed by [#5493](https://github.com/facebook/astryx/pull/5493) by @gonzoblasco for `TreeList`.
106
+
107
+ - `Button` now reflects `elevation` as a theme target. The prop selected between four StyleX style objects but was missing from the sibling `themeProps('button')` call, so `data-elevation` never reached the DOM and no theme could style the axis — the same defect fixed on `Card` in #5491, and one `ButtonGroup` already had right. A button inside a `ButtonGroup` reports `none`, because the group owns the surface's elevation and the member paints flat. Every wrapper that forwards `ButtonProps` through to `Button` — `IconButton` — picks the reflection up with it. (`ToggleButton` does not: its props extend `BaseProps`, not `ButtonProps`, so it has no `elevation` to forward and keeps reporting `none`.) Nothing about the rendered button changes: 60 of 64 captured frames are byte-identical, and the four that differ do so only inside the loading spinner's own box. (#5552)
108
+ - Calendar: announce a cleared range in the provider locale, wrap the two-month layout instead of overflowing a narrow viewport, keep the selected date visible under forced colors (#5453)
109
+ - Card: reflect `elevation` as a theme target so a theme can reach it, and correct the documented `padding` default (#5491)
110
+ `elevation` picked a style object but never reached the DOM, so `astryx-card` exposed `data-variant` and nothing for elevation and a theme could not style the four shadow tiers. It now rides `themeProps` alongside `variant`.
111
+
112
+ The `padding` prop documented `4` as its default. With the prop omitted the card reads the theme's card padding, and most shipped themes set that to a different step, so writing the documented default explicitly changed the card's size. The prop docs, the JSDoc and the playground default now say that omitting the prop takes the theme's padding and passing a step overrides it. The four `effectivePadding !== 4` style branches that encoded the same wrong default in code are gone: `container()` already sets every variable they set, verified identical across all eleven padding steps on both a bordered and a borderless card.
113
+
114
+ - Carousel no longer drops keyboard focus to the document body when reaching a scroll edge disables the nav button in use. Focus moves to the opposite arrow instead, on the state transition that disables the button rather than on a prediction from the press, so it holds under reduced motion, under scroll-snap, and on browsers without `scrollend`. The scroll container is also now a documented theme target, `astryx-carousel-scroller`, carrying the gap, padding, snap and edge-fade props it styles, so a theme can reach the spacing and the fade it could not see before. (#5601)
115
+ - The 56 `--color-data-*` defaults now reach runtime CSS and built themes from the same source, while dashboard template fallbacks match those defaults (#5562, #5566)
116
+ The defaults live once at `:root` in `@layer astryx-base`, so nested themes inherit parent overrides and `astryx theme build` matches `<Theme>` while `generateThemeCSS` keeps its existing return shape.
117
+
118
+ **Visual change.** A chart or template that previously painted nothing or used a mismatched hex fallback now paints the data token's default. Pin an explicit color to preserve a previous fallback.
119
+
120
+ - DateRangeInput: allow a same-day range when `minRangeSpan` is 1 (#5581)
121
+ A repeated click on the range start now commits a one-day range when the configured minimum permits it, including when a maximum span is also set. Longer minimum spans keep the existing cancel behaviour so the user can move the start date.
122
+ - Dialog: fullscreen safe-area padding follows writing direction and defers to explicit padding (#5367)
123
+ Two corrections to the fullscreen safe-area padding that shipped in 0.5.0.
124
+
125
+ **The insets were mapped to the wrong edges in RTL.** `env(safe-area-inset-left)` and `env(safe-area-inset-right)` are physical, but they were assigned straight to `padding-inline-start` and `padding-inline-end`, which are logical. That holds in LTR and inverts in RTL, where inline-start is the right edge — so a device notch on the physical left padded the edge away from it and left the notched edge unprotected. Each physical inset now feeds the logical edge that actually faces it, in both directions.
126
+
127
+ **Safe-area protection overrode explicit padding.** The `max()` was applied to the fullscreen surface unconditionally, so it beat both a `padding` prop and a theme's `dialog: {padding: 0}`, and a deliberately full-bleed fullscreen dialog could not be expressed. It now sits in the innermost fallback of the same `--astryx-dialog-padding*` chain `container` already resolves, so it applies only when no padding is set anywhere. An explicit value, `0` included, is honored as written.
128
+
129
+ - Date formatting now defaults to Gregorian calendar semantics across core, charts, and Schedule while still following the selected locale for language, numbering, and field order. (#5303)
130
+ The low-level public `plainDateFormat` helper continues to honor an explicitly supplied `calendar` option for compatibility; Astryx components do not expose that display-only exception and remain Gregorian. The deterministic English fallback also prevents server and browser locale differences from producing hydration mismatches when no provider locale is available. Locale-aware parsing only selects day-first or month-first order for ambiguous ASCII numeric dates; it does not parse localized month names, non-ASCII digits, or arbitrary locale-specific strings.
131
+
132
+ Fixes #5074.
133
+
134
+ - Labelled HoverCard triggers expose a dialog-popup relationship without flattening rich content into a description, and only roles that support `aria-expanded` receive that state (#5419, #5501)
135
+ The trigger now uses `aria-haspopup="dialog"`, `aria-controls`, and a role-gated `aria-expanded`; `useHoverCard` exposes the layer `id` and open state, while `describedBy` remains as a deprecated alias for compatibility. Unlabelled group cards keep their description relationship.
136
+ - Popup triggers no longer fight the browser's own light dismiss: pressing the button of an open Selector, MultiSelector, ComplexSelector, DropdownMenu, or Popover closes it once instead of closing and reopening. MultiSelector's clear and status buttons also keep its popup open when pressed. (#5018)
137
+ - Markdown now applies the same URL safety rule to every image path it parses: reference-style images (`![alt][label]` and the shortcut form) and standalone block images pass through the check inline images and links already used, and the render-side guard normalizes control characters before testing so both layers see a URL the way a browser will. (#5522)
138
+ - Markdown and List forward the rest of `BaseProps` (#5288)
139
+ Both declare `BaseProps`, and `BaseProps` documents that `data-*`, `aria-*` and `role` reach the element — but each destructured a fixed set of props and forwarded only `data-testid`, so an `aria-label` a consumer passed silently disappeared. `<Markdown aria-label="Release notes">` named nothing, and a list could not be labelled by a heading it did not render itself.
140
+
141
+ Consumer props spread first, so what a component sets for itself still wins: the block root stays `role="document"`, the list keeps the explicit `role="list"` that restores Safari/VoiceOver announcements, and a list rendering its own header keeps that association rather than one pointed elsewhere. The `aria-labelledby` for that header is only written when the header exists — writing `undefined` unconditionally would erase a consumer's own label.
142
+
143
+ - NumberInput parses locale-formatted paste safely and commits one complete draft: grouped numbers and machine decimal points work, arbitrary repeated punctuation is refused, out-of-range values clamp to the nearest bound, and fractional stepping cannot cross a rounded bound (#5152, #5450, #5459, #5510, #5546)
144
+ Invalid typed or pasted input preserves the prior value instead of committing a valid prefix. Pagination inherits the complete-draft and bound behavior, while inline Table filtering and PowerSearch keep their existing live and Enter-to-save behavior.
145
+ - Popover: theming `popover.borderRadius` now changes the rendered radius. The `astryx-popover` target moves onto the popup surface — the box that paints background, radius and elevation — and `usePopover` reads the registered `--_popover-radius` there instead of hardcoding `--radius-container`. Content padding moves with it, so a themed `padding` still replaces the default instead of nesting inside it. (#5162)
146
+ - Ensure pressed overlays override hover across interactive surfaces (#5451) (#5516)
147
+ - Stack DateTimeInput's date and time fields when its container is narrower than 400px. (#5609)
148
+ - Selector: a caller-supplied `id` now drives the trigger's whole identity, not just its `id` attribute (#5561)
149
+ `Selector` generated its trigger id with `useId()` and set it on the trigger button before spreading `...rest`, so a caller's `id` — accepted through `BaseProps` — replaced it on the button while the generated value stayed behind as the target of the listbox's `aria-labelledby` and of the `Field` label's `htmlFor`. Passing `id` therefore left the listbox with no accessible name and the field label pointing at an element that does not exist, silently and with a clean typecheck, lint and build.
150
+
151
+ The internal identity is now derived from the caller's `id` when there is one, so the button, the listbox's `aria-labelledby` (both the plain and the `hasSearch` panel) and `Field`'s `inputID` all name the same element. The trigger's own `id` attribute is unchanged in every case; what changes is that references which used to dangle now resolve — including the field label, which consequently regains its native click-to-focus behaviour. With no `id` supplied the rendered output is identical to before.
152
+
153
+ - Selector raw source now compiles when consumer Babel presets lower arrow functions before StyleX extraction (#5508)
154
+ - Platform detection reads the client-hints `Unknown` sentinel as no answer, and lives in one place (#5394)
155
+ Follow-up to #5325, which taught `useHotkeys` and `Kbd` to fall through to `navigator.platform` when `userAgentData.platform` is blank. `Unknown` is the User-Agent Client Hints spec's own value for "cannot say", and it names a platform no more than `''` does, yet it still committed to the client-hints branch and answered "not Apple". It now falls through the same way.
156
+
157
+ The two detections were independent copies kept aligned by a docstring. They are now one internal util that both import, so the next change to this logic cannot land on one surface and miss the other. The util is deliberately not named in `utils/index.ts`, which would publish it as API.
158
+
159
+ - SideNavItem: the standalone expand/collapse toggle on a `collapsible` item with an `href` or `onClick` now carries the box of a `size="sm"` icon button. It had no box of its own, so it shrank to the 24px chevron inside it and painted a smaller hover pill than any icon button sitting beside it in the same row. (#4988) (#5005)
160
+ - SideNav: `collapsible` and `resizable` no longer keep two independently initialized copies of the collapse state. Both props are normalized into one internal collapse config with a single owner — the resize hook when `resizable` is in play, SideNav's own state otherwise — so the hook can no longer restore itself collapsed while SideNav renders the expanded layout at width 0, which is what made a persisted-collapsed nav come back invisible and unrecoverable (#4790) — that the second independently-initialized boolean is the defect, rather than the restore clamp, is @HelloOjasMutreja's diagnosis from #4853. Passing both props stays supported and every configuration that works today resolves to the same collapse state it does now; when the two props genuinely address the same state (`defaultIsCollapsed` on both, or a controlled `collapsible` alongside collapse state on `resizable`) `resizable` wins and a dev warning names the conflicting keys. `useResizable` gains the standard controlled/uncontrolled pair, `defaultIsCollapsed` and `isCollapsed`, alongside the existing `onCollapseChange`: uncontrolled it owns collapse as before, controlled the prop wins and `collapse()`, `expand()` and a drag past the threshold report through the callback instead of mutating. Persisted entries now store `{size, isCollapsed}` where `size` is the _expanded_ size — the encoding is @AKnassa's from #4824 — so a reload restores the collapsed rail and expanding returns to the width the user had rather than `defaultWidth`; legacy entries still load, with a plain number read as a width whose collapse state is unknown and a plain `0` (written by the old collapse path) read as collapsed, so anyone already stuck with an invisible nav recovers without clearing localStorage. `resizable` can now also carry collapse state on its own. Two notification changes ride along: with a single owner, `collapsible.onCollapsedChange` fires once per toggle on a resizable nav instead of twice; and the hook's collapse callbacks now read the live collapse state rather than the value captured at their last render, so one drag past the threshold reports one collapse instead of one per pointer move, dragging back above the threshold re-expands mid-gesture, and `resize()` out of the collapsed state reports the implicit expand. That last fix is @AKnassa's, from #5118. (#5075)
161
+ - Slider: dragging the thumb with a mouse no longer draws the keyboard focus ring (#5463)
162
+ The thumb is a `div[role="slider"]`, and the track's `pointerdown` handler calls `preventDefault()` and then focuses the thumb from script. Chromium treats that script focus as focus-visible, so `:focus-visible` matched on mouse-down and every drag came with a 2px accent ring — measured in Chromium, not inferred.
163
+
164
+ `:focus-visible` stays the CSS condition; it is now narrowed by the existing `interactionModality` utility, the same way PanelSearchInput and Selector narrow theirs. Keyboard focus rings exactly as before, and a mouse grab of a thumb that already had the ring drops it.
165
+
166
+ One deliberate difference from the text-input cases: a keypress after a mouse drag brings the ring back. A text field has a caret to show where input is going, and a slider thumb has nothing else.
167
+
168
+ - Keep useResizable callbacks stable when snap points are omitted. (#5276)
169
+ - Keep useLayer trigger refs and return objects stable when their inputs are unchanged. (#5272)
170
+ - Keep useTheme token resolvers and return values stable when the resolved theme is unchanged. (#5274)
171
+ - Table sticky columns: the pinned-column shadow now reads the theme's `--color-shadow` token instead of a hardcoded `light-dark()` tint, so a theme can retint it. (#5445)
172
+ The tint was `light-dark(rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.32))` written in the component, chosen because `--color-shadow` (10%/30% alpha) read as slightly too faint. A literal in a component is the one place a theme cannot reach: every theme got this exact black regardless of its own shadow colour, and the two-point alpha difference bought nothing for it — rendered, the token version differs by at most 5/255 on any channel in light mode and 1/255 in dark, over the ~0.4% of the frame the two shadow strips occupy.
173
+
174
+ Reading the token instead means the seven bundled themes each tint this shadow with the value they already declare for every other shadow (`chocolate` `#4a35201A`, `stone` `#25252a1a`, and so on), and a custom theme gets the same reach.
175
+
176
+ - Syntax-highlighted punctuation (brackets, commas, semicolons, operators) now meets WCAG 2.1 AA contrast (4.5:1) against the code surface in every bundled theme. (#5414)
177
+ `--color-syntax-punctuation` borrowed `--color-text-disabled`, a token WCAG deliberately exempts from the normal-text contrast requirement because it marks an inactive control. Punctuation in a code sample is always-active, normal text, and measured well under 4.5:1 in three themes: neutral (2.42:1 light, 2.53:1 dark), chocolate (3.06:1 light, 2.56:1 dark), and matcha (3.83:1 light, 2.73:1 dark). The other four themes (butter, gothic, stone, y2k) already defined their own passing punctuation colour and are untouched.
178
+
179
+ The shared default now points at `--color-text-secondary` instead (used for `--color-syntax-comment` too, and already verified to clear AA). Neutral, chocolate and matcha each get a dedicated punctuation colour in their own syntax palette, since they define one rather than inheriting the shared default: neutral `#6e6e6e`/`#a0a0a0` (4.89:1/7.57:1), chocolate `#9e622e`/`#cb884d` (4.84:1/6.12:1), matcha `#566a39`/`#92af6a` (5.19:1/7.02:1).
180
+
181
+ Adds `scripts/check-syntax-punctuation-contrast.test.mjs`, resolving each theme's `--color-syntax-punctuation`/`--color-syntax-background` pair through `light-dark()`/`var()` indirection (the pattern from #4446's badge contrast guard) and holding every theme, both colour schemes, to AA — so a regression here fails the build instead of shipping.
182
+
183
+ - Table keeps grouped headings and selected-row washes visible across frozen columns while scrolling sideways (#5454)
184
+ `useTableGroupedRows` pins its default heading and collapse control to the table's start edge. `useTableSelection` now publishes and withdraws the selected-row overlay with the row background, so the wash continues under sticky cells.
185
+ - Text, Heading: a truncated label shows one tooltip, not two. (#5559)
186
+ When `maxLines` clipped the text, both components rendered Astryx's `Tooltip` **and** set the native `title` attribute to the same string. Hovering drew both: the styled tooltip first, then the browser's own unstyled one on top of it a moment later, saying exactly the same thing.
187
+
188
+ The `title` goes. `Tooltip` already wires `aria-describedby` onto the anchor, and the full text is in the DOM either way — CSS clips it visually, so a screen reader was never reading the truncated version. Nothing is lost but the duplicate.
189
+
190
+ Measured on hover, same story, before and after: `2` tooltips shown to the user, then `1`.
191
+
192
+ - Seven theme target roots that ran a compound component name together are deprecated onto the `<component-kebab>-<part>` spelling the component's name implies: `codeblock` → `code-block` (with `-copy-button`, `-header`, `-title`), `progressbar` → `progress-bar` (with `-fill`, `-mark`, `-track`), `hovercard` → `hover-card`, `statusdot` → `status-dot`, `textarea` → `text-area`, `navicon` → `nav-icon`, and Table's second root `base-table` → `table` (both named the same `<table>` element). A `defineTheme` key that matches no target fails silently — no error, no warning, the rule never emits — so someone who read `ProgressBar` and wrote `'progress-bar'` got nothing and no explanation. Nothing breaks: every component renders both classes and both keys resolve, including the derived vars a renamed key expands into. The old spellings drop in the next major. (#5449)
193
+ - Toast fits narrow and safe-area viewports, aligns wrapped actions and dismissal, uses edge-directed entrance and exit motion, exposes the Notifications landmark only while populated, and keeps exactly the viewport gutter below the final toast (#5353, #5460)
194
+ Inter-toast spacing is 8px, while the visual bottom no longer adds a trailing toast gap on top of viewport padding. Placement, visible-stack limits, auto-hide defaults, announcement semantics, and dismissal reasons are unchanged.
195
+ - TreeList: forward `aria-label`/`aria-labelledby` to the `role="tree"` element so a tree can be named (#5493)
196
+ `TreeList` destructured a fixed set of props with no rest spread, so every `BaseProps` attribute (`aria-*`, `role`, `tabIndex`, `id`, event handlers) was dropped and never reached the DOM. A tree without a visible header could not be named at all - a screen reader announced an unnamed tree with no way to know what it was.
197
+
198
+ The component now spreads the remaining props onto the root element and routes `aria-label`/`aria-labelledby` onto the `<ul role="tree">` itself, so `<TreeList aria-label="File tree">` names the tree. When a visible `header` is rendered, it keeps naming the tree (AT hears the same name the user sees); a consumer-supplied `aria-labelledby` only applies on the headerless path. The contract `role="tree"` is written after the rest spread so a consumer cannot displace it.
199
+
200
+ #### Documentation
201
+
202
+ - `useAnnounce`, `useTypeahead`, `useInteractiveRole`, `useLongPress`, `useInputStatusIcon`, `useDevWarning` and `useIndicatorFocusRing` are now discoverable. The CLI's hook index is built from the `.doc.mjs` files next to each hook, and these seven shipped without one; so `astryx hook <name>` answered "No hook named", `astryx hook` omitted them and `astryx search` never returned them, while the package exported them with full TSDoc. Agents following the documented discovery workflow concluded the primitives did not exist and hand-rolled replacements; for `useAnnounce` that means a hand-built `aria-live` region, which usually does not announce at all. A test now fails when a hook is exported from the barrel without a doc, so the index cannot silently go stale again. (#5109)
203
+
204
+ #### Contributors
205
+
206
+ Thanks to everyone who contributed to this release:
207
+
208
+ - @AKnassa
209
+ - @Astro-Han
210
+ - @bhamodi
211
+ - @cixzhang
212
+ - @ernestt
213
+ - @freddymeta
214
+ - @gonzoblasco
215
+ - @HelloOjasMutreja
216
+ - @imdreamrunner
217
+ - @jiunshinn
218
+ - @josephfarina
219
+ - @lexs
220
+ - @nynexman4464
221
+ - @rubyycheung
222
+
223
+ ---
224
+
3
225
  # 0.5.0
4
226
 
5
227
  #### Breaking Changes
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file AlertDialog.tsx
3
- * @input Uses React, Dialog, Layout, Heading, Text, Button
3
+ * @input Uses React, StyleX, Dialog, Layout, Heading, Text, Button
4
4
  * @output Exports AlertDialog component, AlertDialogProps type
5
5
  * @position Core implementation; consumed by index.ts, tested by AlertDialog.test.tsx
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../../src/AlertDialog/AlertDialog.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAA2B,MAAM,OAAO,CAAC;AAQhD,OAAO,EAAS,KAAK,aAAa,EAAC,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAK5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IACpE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAE3C;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC;IAExB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,WAAW,EACX,WAAW,EAAE,oBAAoB,EACjC,WAAW,EACX,aAA6B,EAC7B,eAAe,EACf,QAAQ,EACR,KAAW,EACX,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,IAAI,EACR,EAAE,gBAAgB,qBAkElB;yBApFe,WAAW"}
1
+ {"version":3,"file":"AlertDialog.d.ts","sourceRoot":"","sources":["../../src/AlertDialog/AlertDialog.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAA2B,MAAM,OAAO,CAAC;AAShD,OAAO,EAAS,KAAK,aAAa,EAAC,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAkB5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IACpE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAE3C;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,QAAQ,EAAE,MAAM,OAAO,CAAC;IAExB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,WAAW,EACX,WAAW,EAAE,oBAAoB,EACjC,WAAW,EACX,aAA6B,EAC7B,eAAe,EACf,QAAQ,EACR,KAAW,EACX,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,IAAI,EACR,EAAE,gBAAgB,qBA8FlB;yBAhHe,WAAW"}
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file AlertDialog.tsx
7
- * @input Uses React, Dialog, Layout, Heading, Text, Button
7
+ * @input Uses React, StyleX, Dialog, Layout, Heading, Text, Button
8
8
  * @output Exports AlertDialog component, AlertDialogProps type
9
9
  * @position Core implementation; consumed by index.ts, tested by AlertDialog.test.tsx
10
10
  *
@@ -16,18 +16,32 @@
16
16
  * - /packages/cli/assets/templates/blocks/components/AlertDialog/ (showcase blocks)
17
17
  */
18
18
  import React, { useId, useCallback } from 'react';
19
+ import * as stylex from '@stylexjs/stylex';
19
20
  import { Dialog } from "../Dialog/index.js";
20
21
  import { Layout } from "../Layout/Layout.js";
21
22
  import { LayoutContent } from "../Layout/LayoutContent.js";
22
23
  import { LayoutFooter } from "../Layout/LayoutFooter.js";
23
- import { HStack } from "../Stack/index.js";
24
+ import { Stack } from "../Stack/index.js";
24
25
  import { Heading } from "../Heading/Heading.js";
25
26
  import { Text } from "../Text/Text.js";
26
27
  import { Button } from "../Button/index.js";
27
28
  import { mergeProps } from "../utils/index.js";
28
29
  import { themeProps } from "../utils/themeProps.js";
29
30
  import { useTranslator } from "../i18n/index.js";
31
+ import { useMediaQuery } from "../hooks/index.js";
30
32
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
33
+ const SMALL_SCREEN_QUERY = '(max-width: 640px)';
34
+ const styles = {
35
+ action: {
36
+ ks0D6T: "x193iq5w",
37
+ k7Eaqz: "xeuugli",
38
+ $$css: true
39
+ },
40
+ stackedAction: {
41
+ kzqmXN: "xh8yej3",
42
+ $$css: true
43
+ }
44
+ };
31
45
  /**
32
46
  * A confirmation dialog for destructive or irreversible actions.
33
47
  *
@@ -77,9 +91,33 @@ export function AlertDialog({
77
91
  const cancelLabel = cancelLabelFromProps ?? t('@astryx.alertDialog.cancel');
78
92
  const titleId = useId();
79
93
  const descriptionId = useId();
94
+ // Width stays delegated to Dialog: this query exists only so AlertDialog can
95
+ // keep narrow visual, DOM, and tab order aligned for its destructive/cancel
96
+ // semantics without coupling action order to pointer or hover capability.
97
+ const isSmallScreen = useMediaQuery(SMALL_SCREEN_QUERY);
80
98
  const handleCancel = useCallback(() => {
81
99
  onOpenChange(false);
82
100
  }, [onOpenChange]);
101
+ const buttonActionStyle = [styles.action, isSmallScreen && styles.stackedAction];
102
+ const cancelButton = /*#__PURE__*/_jsx(Button, {
103
+ variant: "ghost",
104
+ label: cancelLabel,
105
+ onClick: handleCancel,
106
+ xstyle: buttonActionStyle
107
+ // Dialog focuses [data-autofocus] itself after showModal(), because
108
+ // React's autoFocus runs during commit while the dialog is invisible.
109
+ // Cancel is least destructive, so it remains the autofocus target even
110
+ // when small-screen visual order places the destructive action above it.
111
+ ,
112
+ "data-autofocus": true
113
+ }, "cancel");
114
+ const actionButton = /*#__PURE__*/_jsx(Button, {
115
+ variant: actionVariant,
116
+ label: actionLabel,
117
+ onClick: onAction,
118
+ isLoading: isActionLoading,
119
+ xstyle: buttonActionStyle
120
+ }, "action");
83
121
  return /*#__PURE__*/_jsx(Dialog, {
84
122
  ...rest,
85
123
  ref: ref,
@@ -117,25 +155,12 @@ export function AlertDialog({
117
155
  })]
118
156
  }),
119
157
  footer: /*#__PURE__*/_jsx(LayoutFooter, {
120
- children: /*#__PURE__*/_jsxs(HStack, {
158
+ children: /*#__PURE__*/_jsx(Stack, {
159
+ direction: isSmallScreen ? 'vertical' : 'horizontal',
121
160
  gap: 2,
122
- hAlign: "end",
123
- children: [/*#__PURE__*/_jsx(Button, {
124
- variant: "ghost",
125
- label: cancelLabel,
126
- onClick: handleCancel
127
- // Dialog focuses [data-autofocus] itself after showModal(),
128
- // because React's autoFocus runs during commit while the
129
- // dialog is still invisible. Cancel is the least destructive
130
- // choice, so it is the one that should be preselected.
131
- ,
132
- "data-autofocus": true
133
- }), /*#__PURE__*/_jsx(Button, {
134
- variant: actionVariant,
135
- label: actionLabel,
136
- onClick: onAction,
137
- isLoading: isActionLoading
138
- })]
161
+ hAlign: isSmallScreen ? 'stretch' : 'end',
162
+ wrap: isSmallScreen ? 'nowrap' : 'wrap',
163
+ children: isSmallScreen ? [actionButton, cancelButton] : [cancelButton, actionButton]
139
164
  })
140
165
  })
141
166
  })
@@ -44,14 +44,14 @@ export interface AspectRatioProps extends BaseProps<HTMLDivElement> {
44
44
  * `astryx-base` cascade layer, and unlayered CSS wins over layered
45
45
  * rules regardless of specificity.
46
46
  *
47
+ * A responsive ratio is set in CSS, not on the component. For example, a 3:1
48
+ * hero can become 3:2 when its container narrows by targeting the element's
49
+ * class from a container query:
50
+ * `@container gallery (max-width: 720px) { .gallery-hero { aspect-ratio: 3 / 2; } }`.
51
+ *
47
52
  * @example
48
53
  * ```
49
- * // 3:1 hero that becomes 3:2 when its container stacks
50
- * <AspectRatio ratio={3 / 1} className="gallery-hero">…</AspectRatio>
51
- *
52
- * // CSS: @container gallery (max-width: 720px) {
53
- * // .gallery-hero { aspect-ratio: 3 / 2; }
54
- * // }
54
+ * <AspectRatio ratio={3 / 1} className="gallery-hero">...</AspectRatio>
55
55
  * ```
56
56
  */
57
57
  ratio: number;
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import { type ReactNode } from 'react';
18
18
  import type { BaseProps } from '../BaseProps';
19
+ import * as stylex from '@stylexjs/stylex';
19
20
  import type { LinkComponentType } from '../Link/types';
20
21
  /**
21
22
  * Named size options.
@@ -33,10 +34,25 @@ type AvatarNumericSize = 16 | 20 | 24 | 32 | 36 | 40 | 48 | 60 | 64 | 72 | 96 |
33
34
  * Avatar size - can be a named size or a specific pixel value
34
35
  */
35
36
  export type AvatarSize = AvatarNamedSize | AvatarNumericSize;
37
+ /**
38
+ * Avatar shape options
39
+ */
40
+ export type AvatarShape = 'circle' | 'rounded' | 'square';
36
41
  /**
37
42
  * Resolves named sizes to their numeric pixel values
38
43
  */
39
44
  export declare function resolveSize(size: AvatarSize): number;
45
+ export declare const shapeStyles: Readonly<{
46
+ readonly circle: Readonly<{
47
+ readonly '--_avatar-radius': stylex.StyleXClassNameFor<"--_avatar-radius", "9999px">;
48
+ }>;
49
+ readonly rounded: Readonly<{
50
+ readonly '--_avatar-radius': stylex.StyleXClassNameFor<"--_avatar-radius", "8px">;
51
+ }>;
52
+ readonly square: Readonly<{
53
+ readonly '--_avatar-radius': stylex.StyleXClassNameFor<"--_avatar-radius", "0px">;
54
+ }>;
55
+ }>;
40
56
  export interface AvatarProps extends BaseProps<HTMLDivElement> {
41
57
  /** Ref forwarded to the root element */
42
58
  ref?: React.Ref<HTMLDivElement>;
@@ -69,6 +85,14 @@ export interface AvatarProps extends BaseProps<HTMLDivElement> {
69
85
  * @default 'md'
70
86
  */
71
87
  size?: AvatarSize;
88
+ /**
89
+ * Shape variant of the avatar.
90
+ * - 'circle': Full circle (default)
91
+ * - 'rounded': Rounded square
92
+ * - 'square': Sharp square
93
+ * @default 'circle'
94
+ */
95
+ shape?: AvatarShape;
72
96
  /**
73
97
  * The primary image source for the avatar.
74
98
  */
@@ -147,7 +171,7 @@ export interface AvatarProps extends BaseProps<HTMLDivElement> {
147
171
  * <Avatar src="/user.jpg" name="John Doe" onClick={() => openProfile()} />
148
172
  * ```
149
173
  */
150
- export declare function Avatar({ alt, 'data-testid': testId, fallbackSrc, name, size, src, status, tooltip, href, as, target, rel, onClick, xstyle, className, style, ref, ...props }: AvatarProps): import("react").JSX.Element;
174
+ export declare function Avatar({ alt, 'data-testid': testId, fallbackSrc, name, size, shape, src, status, tooltip, href, as, target, rel, onClick, xstyle, className, style, ref, ...props }: AvatarProps): import("react").JSX.Element;
151
175
  export declare namespace Avatar {
152
176
  var displayName: string;
153
177
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/Avatar/Avatar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAsB5C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AA4BrD;;;;;;GAMG;AACH,KAAK,eAAe,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzD;;GAEG;AACH,KAAK,iBAAiB,GACpB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAgBpD;AAgID,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CAChD;AAwHD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,EACrB,GAAG,EACH,aAAa,EAAE,MAAM,EACrB,WAAW,EACX,IAAI,EACJ,IAAW,EACX,GAAG,EACH,MAAM,EACN,OAAc,EACd,IAAI,EACJ,EAAE,EACF,MAAM,EACN,GAAG,EACH,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAkVb;yBArWe,MAAM"}
1
+ {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/Avatar/Avatar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAqB3C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AA4BrD;;;;;;GAMG;AACH,KAAK,eAAe,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzD;;GAEG;AACH,KAAK,iBAAiB,GACpB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1D;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAgBpD;AASD,eAAO,MAAM,WAAW;;;;;;;;;;EAUtB,CAAC;AA6IH,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CAChD;AAwHD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,EACrB,GAAG,EACH,aAAa,EAAE,MAAM,EACrB,WAAW,EACX,IAAI,EACJ,IAAW,EACX,KAAgB,EAChB,GAAG,EACH,MAAM,EACN,OAAc,EACd,IAAI,EACJ,EAAE,EACF,MAAM,EACN,GAAG,EACH,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAsVb;yBA1We,MAAM"}
@@ -77,6 +77,10 @@ const INITIALS_FONT_SIZE_RATIO = 0.4;
77
77
  * Avatar size - can be a named size or a specific pixel value
78
78
  */
79
79
 
80
+ /**
81
+ * Avatar shape options
82
+ */
83
+
80
84
  /**
81
85
  * Resolves named sizes to their numeric pixel values
82
86
  */
@@ -98,6 +102,28 @@ export function resolveSize(size) {
98
102
  }
99
103
  }
100
104
 
105
+ // Sets one local custom property rather than `borderRadius` directly, so
106
+ // every clipping/ring surface that needs the shape's radius (the wrapper,
107
+ // the interactive focus ring, the content div that actually clips via
108
+ // `overflow: hidden`, and AvatarGroupOverflow's "+N" indicator) reads the
109
+ // same value instead of each hardcoding its own borderRadius independently.
110
+ // A theme override only has to reach this one property, not fight the
111
+ // per-surface StyleX class order to change the shape everywhere at once.
112
+ export const shapeStyles = {
113
+ circle: {
114
+ "--_avatar-radius": "xeincmr",
115
+ $$css: true
116
+ },
117
+ rounded: {
118
+ "--_avatar-radius": "xdarwi0",
119
+ $$css: true
120
+ },
121
+ square: {
122
+ "--_avatar-radius": "x877142",
123
+ $$css: true
124
+ }
125
+ };
126
+
101
127
  /**
102
128
  * Base styles for the avatar
103
129
  * Uses a wrapper/content structure so status isn't clipped by overflow:hidden
@@ -107,7 +133,7 @@ const styles = {
107
133
  kVAEAm: "x1n2onr6",
108
134
  k1xSpc: "x3nfvp2",
109
135
  kmuXW: "x2lah0s",
110
- kaIpWk: "xjspbzw",
136
+ kaIpWk: "xbc78cj",
111
137
  $$css: true
112
138
  },
113
139
  fallback: {
@@ -138,7 +164,7 @@ const styles = {
138
164
  kVVagm: "xln7xf2",
139
165
  kybGjl: "x1hl2dhg",
140
166
  kkrTdU: "x1ypdohk x16khyan",
141
- kaIpWk: "xjspbzw",
167
+ kaIpWk: "xbc78cj",
142
168
  $$css: true
143
169
  }
144
170
  };
@@ -168,15 +194,20 @@ const dynamicStyles = {
168
194
  fontSize: size => [_temp, {
169
195
  "--x-fontSize": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(`${size * INITIALS_FONT_SIZE_RATIO}px`)
170
196
  }],
171
- statusPosition: size => [_temp2, {
197
+ statusPositionCircle: size => [_temp2, {
172
198
  "--x-bottom": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(size * CIRCLE_EDGE_OFFSET_RATIO),
173
199
  "--x-insetInlineEnd": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(size * CIRCLE_EDGE_OFFSET_RATIO)
174
- }]
200
+ }],
201
+ statusPositionCorner: {
202
+ krVfgx: "x1ey2m1c",
203
+ kt4wiu: "xtijo5x",
204
+ k3aq6I: "xv8yid9 x10fxb7p",
205
+ $$css: true
206
+ }
175
207
  };
176
208
  const BORDER_WIDTH = 2;
177
209
  const groupStyles = {
178
210
  ring: {
179
- kaIpWk: "xjspbzw",
180
211
  kMzoRj: "xdh2fpr",
181
212
  ksu8eU: "x1y0btm7",
182
213
  kVAM5u: "x1touxvs",
@@ -333,6 +364,7 @@ export function Avatar({
333
364
  fallbackSrc,
334
365
  name,
335
366
  size = 'md',
367
+ shape = 'circle',
336
368
  src,
337
369
  status,
338
370
  tooltip = true,
@@ -384,6 +416,7 @@ export function Avatar({
384
416
  } : undefined;
385
417
  const avatarGroup = useAvatarGroup();
386
418
  const resolvedSize = avatarGroup?.size ?? size;
419
+ const resolvedShape = avatarGroup?.shape ?? shape;
387
420
  const numericSize = useMemo(() => resolveSize(resolvedSize), [resolvedSize]);
388
421
 
389
422
  // Resolve the tooltip content:
@@ -487,7 +520,7 @@ export function Avatar({
487
520
  const visualContent = /*#__PURE__*/_jsxs(_Fragment, {
488
521
  children: [/*#__PURE__*/_jsxs("div", {
489
522
  ...{
490
- className: "x78zum5 x6s0dn4 xl56j7k xh8yej3 x5yr21d xjspbzw xb3r6kr x87ps6o"
523
+ className: "x78zum5 x6s0dn4 xl56j7k xh8yej3 x5yr21d xb3r6kr x87ps6o xbc78cj"
491
524
  },
492
525
  children: [showImage && /*#__PURE__*/_jsx("img", {
493
526
  src: src,
@@ -519,7 +552,7 @@ export function Avatar({
519
552
  })
520
553
  })]
521
554
  }), status && /*#__PURE__*/_jsx("div", {
522
- ...stylex.props(styles.status, dynamicStyles.statusPosition(numericSize)),
555
+ ...stylex.props(styles.status, resolvedShape === 'circle' ? dynamicStyles.statusPositionCircle(numericSize) : dynamicStyles.statusPositionCorner),
523
556
  children: status
524
557
  })]
525
558
  });
@@ -529,8 +562,9 @@ export function Avatar({
529
562
  // tooltip tab-stop focus ring all live here so the interactive
530
563
  // `<a>`/`<button>` and the static `<div>` carry the exact same box.
531
564
  const rootStylexProps = mergeProps(themeProps('avatar', {
532
- size: resolvedSize
533
- }), focusOutlineProps.focusVisible(styles.wrapper, dynamicStyles.size(numericSize), isInteractive && styles.interactive, avatarGroup && groupStyles.ring, avatarGroup && groupStyles.overlap, avatarGroup && groupDynamicStyles.overlap(-avatarGroup.overlap), xstyle), className, style);
565
+ size: resolvedSize,
566
+ shape: resolvedShape
567
+ }), focusOutlineProps.focusVisible(styles.wrapper, dynamicStyles.size(numericSize), isInteractive && styles.interactive, avatarGroup && groupStyles.ring, avatarGroup && groupStyles.overlap, avatarGroup && groupDynamicStyles.overlap(-avatarGroup.overlap), shapeStyles[resolvedShape], xstyle), className, style);
534
568
  let rootElement;
535
569
 
536
570
  // `props` is typed for the default `<div>` root (its event handlers are
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file index.ts
3
3
  * @input Imports Avatar component and types from Avatar.tsx, AvatarStatusDot from AvatarStatusDot.tsx
4
- * @output Exports Avatar, AvatarProps, AvatarSize, AvatarStatusDot, AvatarStatusDotProps, AvatarStatusDotVariant
4
+ * @output Exports Avatar, AvatarProps, AvatarSize, AvatarShape, resolveSize, AvatarStatusDot, AvatarStatusDotProps, AvatarStatusDotVariant
5
5
  * @position Component entry point; re-exported by /packages/core/src/index.ts
6
6
  *
7
7
  * SYNC: When modified, update this header and /packages/core/src/Avatar/Avatar.doc.mjs
@@ -32,7 +32,7 @@ export interface AvatarStatusDotVariantMap {
32
32
  error: true;
33
33
  }
34
34
  export { Avatar, resolveSize } from './Avatar';
35
- export type { AvatarProps, AvatarSize } from './Avatar';
35
+ export type { AvatarProps, AvatarSize, AvatarShape } from './Avatar';
36
36
  export { AvatarStatusDot } from './AvatarStatusDot';
37
37
  export type { AvatarStatusDotProps, AvatarStatusDotVariant, } from './AvatarStatusDot';
38
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Avatar/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;CACb;AAED,OAAO,EAAC,MAAM,EAAE,WAAW,EAAC,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAC,WAAW,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AACtD,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Avatar/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;CACb;AAED,OAAO,EAAC,MAAM,EAAE,WAAW,EAAC,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAC,MAAM,UAAU,CAAC;AACnE,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAClD,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC"}