@astryxdesign/core 0.5.0 → 0.5.1-canary.f64186a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (597) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +45 -20
  5. package/dist/AspectRatio/AspectRatio.d.ts +6 -6
  6. package/dist/Avatar/Avatar.d.ts +25 -1
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +43 -9
  9. package/dist/Avatar/index.d.ts +2 -2
  10. package/dist/Avatar/index.d.ts.map +1 -1
  11. package/dist/Avatar/index.js +1 -1
  12. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  13. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroup.js +5 -2
  15. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  16. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  17. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroupOverflow.js +11 -7
  19. package/dist/Badge/Badge.d.ts.map +1 -1
  20. package/dist/Badge/Badge.js +26 -2
  21. package/dist/Banner/Banner.d.ts +10 -1
  22. package/dist/Banner/Banner.d.ts.map +1 -1
  23. package/dist/Banner/Banner.js +11 -2
  24. package/dist/Button/Button.d.ts.map +1 -1
  25. package/dist/Button/Button.js +8 -7
  26. package/dist/Calendar/Calendar.d.ts +4 -2
  27. package/dist/Calendar/Calendar.d.ts.map +1 -1
  28. package/dist/Calendar/Calendar.js +15 -21
  29. package/dist/Calendar/hooks/useCalendarDays.js +4 -6
  30. package/dist/Calendar/hooks/useCalendarNavigation.js +4 -6
  31. package/dist/Calendar/styles.d.ts +5 -20
  32. package/dist/Calendar/styles.d.ts.map +1 -1
  33. package/dist/Calendar/styles.js +15 -17
  34. package/dist/Card/Card.d.ts +12 -12
  35. package/dist/Card/Card.d.ts.map +1 -1
  36. package/dist/Card/Card.js +17 -9
  37. package/dist/Card/index.d.ts +35 -1
  38. package/dist/Card/index.d.ts.map +1 -1
  39. package/dist/Card/index.js +21 -1
  40. package/dist/Carousel/Carousel.d.ts.map +1 -1
  41. package/dist/Carousel/Carousel.js +108 -7
  42. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  43. package/dist/CheckboxInput/CheckboxInput.js +7 -1
  44. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  45. package/dist/CodeBlock/CodeBlock.js +15 -4
  46. package/dist/CodeBlock/highlightRanges.js +1 -1
  47. package/dist/CodeBlock/highlightStyles.js +13 -13
  48. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  49. package/dist/CommandPalette/CommandPaletteItem.js +2 -7
  50. package/dist/ComplexSelector/ComplexSelector.d.ts +10 -2
  51. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  52. package/dist/ComplexSelector/ComplexSelector.js +14 -7
  53. package/dist/DateInput/DateInput.d.ts +43 -0
  54. package/dist/DateInput/DateInput.d.ts.map +1 -1
  55. package/dist/DateInput/DateInput.js +22 -5
  56. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  57. package/dist/DateInput/MonthScroller.js +5 -3
  58. package/dist/DateInput/MonthYearWheels.d.ts.map +1 -1
  59. package/dist/DateInput/MonthYearWheels.js +6 -4
  60. package/dist/DateInput/NativeDateField.d.ts +10 -0
  61. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  62. package/dist/DateInput/NativeDateField.js +494 -0
  63. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  64. package/dist/DateInput/TouchDateField.js +52 -25
  65. package/dist/DateInput/Wheel.d.ts.map +1 -1
  66. package/dist/DateInput/Wheel.js +1 -0
  67. package/dist/DateInput/index.d.ts +1 -1
  68. package/dist/DateInput/index.d.ts.map +1 -1
  69. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  70. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  71. package/dist/DateInput/nativeDateSegments.js +111 -0
  72. package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
  73. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  74. package/dist/DateRangeInput/DateRangeInput.js +3 -5
  75. package/dist/DateTimeInput/DateTimeInput.d.ts +23 -24
  76. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  77. package/dist/DateTimeInput/DateTimeInput.js +35 -10
  78. package/dist/DateTimeInput/TouchDateTimeField.d.ts +6 -0
  79. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -0
  80. package/dist/DateTimeInput/TouchDateTimeField.js +1021 -0
  81. package/dist/Dialog/Dialog.d.ts +16 -2
  82. package/dist/Dialog/Dialog.d.ts.map +1 -1
  83. package/dist/Dialog/Dialog.js +28 -7
  84. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  85. package/dist/DropdownMenu/DropdownMenu.js +4 -13
  86. package/dist/Field/FieldLabel.d.ts.map +1 -1
  87. package/dist/Field/FieldLabel.js +9 -1
  88. package/dist/Field/InputClearButton.d.ts +9 -3
  89. package/dist/Field/InputClearButton.d.ts.map +1 -1
  90. package/dist/Field/InputClearButton.js +14 -3
  91. package/dist/Heading/Heading.d.ts.map +1 -1
  92. package/dist/Heading/Heading.js +0 -1
  93. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  94. package/dist/HoverCard/HoverCard.js +104 -3
  95. package/dist/HoverCard/useHoverCard.d.ts +14 -2
  96. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  97. package/dist/HoverCard/useHoverCard.js +7 -1
  98. package/dist/Icon/Icon.d.ts +4 -2
  99. package/dist/Icon/Icon.d.ts.map +1 -1
  100. package/dist/Icon/defaultIcons.d.ts +3 -2
  101. package/dist/Icon/defaultIcons.d.ts.map +1 -1
  102. package/dist/Icon/defaultIcons.js +7 -0
  103. package/dist/Icon/globalIconRegistry.d.ts +13 -0
  104. package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
  105. package/dist/Icon/globalIconRegistry.js +34 -6
  106. package/dist/Icon/index.d.ts +1 -1
  107. package/dist/Icon/index.d.ts.map +1 -1
  108. package/dist/Icon/useIcon.d.ts +5 -2
  109. package/dist/Icon/useIcon.d.ts.map +1 -1
  110. package/dist/Icon/useIcon.js +3 -0
  111. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  112. package/dist/Indicator/CheckboxIndicator.js +6 -2
  113. package/dist/Item/Item.d.ts.map +1 -1
  114. package/dist/Item/Item.js +2 -2
  115. package/dist/Kbd/Kbd.d.ts.map +1 -1
  116. package/dist/Kbd/Kbd.js +2 -26
  117. package/dist/Layer/gestureCounter.d.ts +8 -0
  118. package/dist/Layer/gestureCounter.d.ts.map +1 -0
  119. package/dist/Layer/gestureCounter.js +53 -0
  120. package/dist/Layer/useLayer.d.ts +23 -13
  121. package/dist/Layer/useLayer.d.ts.map +1 -1
  122. package/dist/Layer/useLayer.js +146 -24
  123. package/dist/List/List.d.ts +1 -1
  124. package/dist/List/List.d.ts.map +1 -1
  125. package/dist/List/List.js +15 -4
  126. package/dist/Markdown/Markdown.d.ts +1 -1
  127. package/dist/Markdown/Markdown.d.ts.map +1 -1
  128. package/dist/Markdown/Markdown.js +20 -7
  129. package/dist/Markdown/parser.d.ts.map +1 -1
  130. package/dist/Markdown/parser.js +5 -3
  131. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  132. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  133. package/dist/MetadataList/MetadataListItem.js +4 -1
  134. package/dist/MultiSelector/MultiSelector.d.ts +18 -1
  135. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  136. package/dist/MultiSelector/MultiSelector.js +58 -11
  137. package/dist/MultiSelector/hooks.d.ts +7 -1
  138. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  139. package/dist/MultiSelector/hooks.js +3 -2
  140. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  141. package/dist/NavIcon/NavIcon.js +5 -1
  142. package/dist/NavItem/navItemStyles.stylex.d.ts +0 -8
  143. package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
  144. package/dist/NavItem/navItemStyles.stylex.js +0 -2
  145. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  146. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  147. package/dist/NavMenu/NavHeadingMenu.js +7 -4
  148. package/dist/NumberInput/NumberInput.d.ts +6 -1
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +95 -126
  151. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  152. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  153. package/dist/NumberInput/numberInputCommit.js +71 -0
  154. package/dist/NumberInput/numberParser.d.ts +64 -0
  155. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  156. package/dist/NumberInput/numberParser.js +350 -0
  157. package/dist/Outline/Outline.d.ts.map +1 -1
  158. package/dist/Outline/Outline.js +2 -3
  159. package/dist/OverflowList/OverflowList.d.ts +41 -1
  160. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  161. package/dist/OverflowList/OverflowList.js +43 -2
  162. package/dist/Popover/Popover.d.ts.map +1 -1
  163. package/dist/Popover/Popover.js +8 -14
  164. package/dist/Popover/usePopover.d.ts +15 -41
  165. package/dist/Popover/usePopover.d.ts.map +1 -1
  166. package/dist/Popover/usePopover.js +26 -7
  167. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchValueEditor.js +91 -18
  169. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  170. package/dist/PowerSearch/formatFilterValue.js +4 -2
  171. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  172. package/dist/ProgressBar/ProgressBar.js +18 -5
  173. package/dist/Resizable/useResizable.d.ts +19 -1
  174. package/dist/Resizable/useResizable.d.ts.map +1 -1
  175. package/dist/Resizable/useResizable.js +104 -38
  176. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  177. package/dist/SelectableCard/SelectableCard.js +9 -0
  178. package/dist/Selector/Selector.d.ts +18 -1
  179. package/dist/Selector/Selector.d.ts.map +1 -1
  180. package/dist/Selector/Selector.js +92 -21
  181. package/dist/Selector/hooks.d.ts +7 -1
  182. package/dist/Selector/hooks.d.ts.map +1 -1
  183. package/dist/Selector/hooks.js +3 -2
  184. package/dist/SideNav/SideNav.d.ts +6 -1
  185. package/dist/SideNav/SideNav.d.ts.map +1 -1
  186. package/dist/SideNav/SideNav.js +57 -27
  187. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  188. package/dist/SideNav/SideNavHeading.js +5 -4
  189. package/dist/SideNav/SideNavItem.d.ts +29 -4
  190. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  191. package/dist/SideNav/SideNavItem.js +75 -20
  192. package/dist/Slider/Slider.d.ts.map +1 -1
  193. package/dist/Slider/Slider.js +34 -2
  194. package/dist/Spinner/Spinner.d.ts +3 -1
  195. package/dist/Spinner/Spinner.d.ts.map +1 -1
  196. package/dist/Spinner/Spinner.js +199 -20
  197. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  198. package/dist/StatusDot/StatusDot.js +6 -1
  199. package/dist/Stepper/Step.d.ts.map +1 -1
  200. package/dist/Stepper/Step.js +7 -6
  201. package/dist/Switch/Switch.d.ts.map +1 -1
  202. package/dist/Switch/Switch.js +5 -1
  203. package/dist/Table/BaseTable.d.ts.map +1 -1
  204. package/dist/Table/BaseTable.js +6 -1
  205. package/dist/Table/Table.d.ts.map +1 -1
  206. package/dist/Table/Table.js +3 -6
  207. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  208. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  209. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
  210. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  211. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +34 -3
  212. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  213. package/dist/Table/plugins/selection/useTableSelection.js +25 -1
  214. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  215. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  216. package/dist/Text/Text.d.ts.map +1 -1
  217. package/dist/Text/Text.js +0 -1
  218. package/dist/TextArea/TextArea.d.ts.map +1 -1
  219. package/dist/TextArea/TextArea.js +13 -8
  220. package/dist/Timestamp/Timestamp.d.ts +1 -1
  221. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  222. package/dist/Timestamp/Timestamp.js +10 -18
  223. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  224. package/dist/Timestamp/formatInstant.js +10 -5
  225. package/dist/Toast/Toast.d.ts +17 -2
  226. package/dist/Toast/Toast.d.ts.map +1 -1
  227. package/dist/Toast/Toast.js +77 -11
  228. package/dist/Toast/ToastViewport.d.ts +1 -0
  229. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  230. package/dist/Toast/ToastViewport.js +76 -21
  231. package/dist/Toast/index.d.ts +1 -1
  232. package/dist/Toast/index.d.ts.map +1 -1
  233. package/dist/Toast/types.d.ts +38 -0
  234. package/dist/Toast/types.d.ts.map +1 -1
  235. package/dist/Toast/useToastGesture.d.ts +26 -0
  236. package/dist/Toast/useToastGesture.d.ts.map +1 -0
  237. package/dist/Toast/useToastGesture.js +223 -0
  238. package/dist/Token/Token.d.ts +1 -1
  239. package/dist/Token/Token.d.ts.map +1 -1
  240. package/dist/Token/Token.js +23 -12
  241. package/dist/Token/TokenLink.d.ts +1 -1
  242. package/dist/Token/TokenLink.d.ts.map +1 -1
  243. package/dist/Token/TokenLink.js +5 -2
  244. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  245. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  246. package/dist/Tokenizer/Tokenizer.js +31 -21
  247. package/dist/TopNav/TopNavHeading.js +2 -2
  248. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  249. package/dist/TopNav/TopNavItem.js +3 -3
  250. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  251. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  252. package/dist/TopNav/TopNavMegaMenu.js +30 -9
  253. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  254. package/dist/TopNav/TopNavMegaMenuItem.js +3 -3
  255. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  256. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMenu.js +21 -6
  258. package/dist/TreeList/TreeList.d.ts +1 -1
  259. package/dist/TreeList/TreeList.d.ts.map +1 -1
  260. package/dist/TreeList/TreeList.js +7 -2
  261. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  262. package/dist/TreeList/TreeListItem.js +2 -2
  263. package/dist/Typeahead/BaseTypeahead.d.ts +33 -0
  264. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  265. package/dist/Typeahead/BaseTypeahead.js +51 -8
  266. package/dist/Typeahead/Typeahead.d.ts +8 -1
  267. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  268. package/dist/Typeahead/Typeahead.js +2 -0
  269. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  270. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  271. package/dist/Typeahead/TypeaheadItem.js +7 -2
  272. package/dist/astryx.css +87 -22
  273. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  274. package/dist/hooks/useHotkeys.js +3 -25
  275. package/dist/hooks/useOverflow.d.ts.map +1 -1
  276. package/dist/hooks/useOverflow.js +14 -4
  277. package/dist/index.d.ts +1 -1
  278. package/dist/index.d.ts.map +1 -1
  279. package/dist/theme/Theme.d.ts.map +1 -1
  280. package/dist/theme/Theme.js +46 -10
  281. package/dist/theme/defineTheme.d.ts +9 -3
  282. package/dist/theme/defineTheme.d.ts.map +1 -1
  283. package/dist/theme/defineTheme.js +5 -0
  284. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  285. package/dist/theme/derivedVarRegistry.js +24 -4
  286. package/dist/theme/generateThemeRules.d.ts +21 -0
  287. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  288. package/dist/theme/generateThemeRules.js +26 -0
  289. package/dist/theme/syntax/tokens.d.ts +1 -1
  290. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  291. package/dist/theme/syntax/tokens.js +5 -2
  292. package/dist/theme/useTheme.d.ts.map +1 -1
  293. package/dist/theme/useTheme.js +6 -7
  294. package/dist/utils/dateParser.d.ts +5 -8
  295. package/dist/utils/dateParser.d.ts.map +1 -1
  296. package/dist/utils/dateParser.js +10 -11
  297. package/dist/utils/focusOutline.stylex.d.ts +25 -0
  298. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  299. package/dist/utils/focusOutline.stylex.js +15 -0
  300. package/dist/utils/interactionOverlay.stylex.d.ts +26 -0
  301. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -0
  302. package/dist/utils/interactionOverlay.stylex.js +42 -0
  303. package/dist/utils/isApplePlatform.d.ts +18 -0
  304. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  305. package/dist/utils/isApplePlatform.js +37 -0
  306. package/dist/utils/plainDate.d.ts +11 -0
  307. package/dist/utils/plainDate.d.ts.map +1 -1
  308. package/dist/utils/plainDate.js +20 -4
  309. package/locales/af-ZA.json +7 -7
  310. package/locales/ar-SA.json +7 -7
  311. package/locales/ca-ES.json +6 -6
  312. package/locales/cs-CZ.json +7 -7
  313. package/locales/da-DK.json +7 -7
  314. package/locales/de-DE.json +7 -7
  315. package/locales/el-GR.json +7 -7
  316. package/locales/en.json +178 -6
  317. package/locales/es-ES.json +6 -6
  318. package/locales/fi-FI.json +7 -7
  319. package/locales/fr-FR.json +7 -7
  320. package/locales/he-IL.json +7 -7
  321. package/locales/hu-HU.json +7 -7
  322. package/locales/it-IT.json +7 -7
  323. package/locales/ja-JP.json +7 -7
  324. package/locales/ko-KR.json +7 -7
  325. package/locales/nl-NL.json +7 -7
  326. package/locales/no-NO.json +7 -7
  327. package/locales/pl-PL.json +7 -7
  328. package/locales/pseudo.json +130 -1
  329. package/locales/pt-BR.json +7 -7
  330. package/locales/pt-PT.json +7 -7
  331. package/locales/ro-RO.json +7 -7
  332. package/locales/ru-RU.json +7 -7
  333. package/locales/sr-SP.json +7 -7
  334. package/locales/sv-SE.json +7 -7
  335. package/locales/tr-TR.json +7 -7
  336. package/locales/uk-UA.json +7 -7
  337. package/locales/vi-VN.json +7 -7
  338. package/locales/zh-CN.json +7 -7
  339. package/locales/zh-TW.json +7 -7
  340. package/package.json +4 -5
  341. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  342. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  343. package/src/AlertDialog/AlertDialog.tsx +62 -20
  344. package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
  345. package/src/AspectRatio/AspectRatio.tsx +6 -6
  346. package/src/Avatar/Avatar.doc.mjs +12 -2
  347. package/src/Avatar/Avatar.test.tsx +80 -0
  348. package/src/Avatar/Avatar.tsx +64 -14
  349. package/src/Avatar/index.ts +2 -2
  350. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  351. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  352. package/src/AvatarGroup/AvatarGroup.tsx +12 -4
  353. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  354. package/src/AvatarGroup/AvatarGroupOverflow.tsx +12 -12
  355. package/src/Badge/Badge.doc.mjs +3 -2
  356. package/src/Badge/Badge.test.tsx +32 -3
  357. package/src/Badge/Badge.tsx +42 -1
  358. package/src/Banner/Banner.doc.mjs +9 -0
  359. package/src/Banner/Banner.test.tsx +76 -11
  360. package/src/Banner/Banner.tsx +21 -2
  361. package/src/Button/Button.doc.mjs +2 -1
  362. package/src/Button/Button.test.tsx +19 -4
  363. package/src/Button/Button.tsx +9 -29
  364. package/src/ButtonGroup/ButtonGroup.doc.mjs +2 -2
  365. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -0
  366. package/src/Calendar/Calendar.doc.mjs +3 -3
  367. package/src/Calendar/Calendar.test.tsx +112 -0
  368. package/src/Calendar/Calendar.tsx +18 -16
  369. package/src/Calendar/hooks/useCalendarDays.ts +4 -4
  370. package/src/Calendar/hooks/useCalendarNavigation.ts +4 -4
  371. package/src/Calendar/styles.ts +48 -42
  372. package/src/Card/Card.doc.mjs +10 -7
  373. package/src/Card/Card.test.tsx +113 -19
  374. package/src/Card/Card.tsx +67 -89
  375. package/src/Card/index.ts +36 -1
  376. package/src/Carousel/Carousel.doc.mjs +3 -0
  377. package/src/Carousel/Carousel.test.tsx +360 -0
  378. package/src/Carousel/Carousel.tsx +116 -15
  379. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  380. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  381. package/src/CheckboxInput/CheckboxInput.tsx +5 -0
  382. package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
  383. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  384. package/src/CodeBlock/CodeBlock.tsx +20 -4
  385. package/src/CodeBlock/highlightRanges.ts +1 -1
  386. package/src/CodeBlock/highlightStyles.ts +13 -13
  387. package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
  388. package/src/ComplexSelector/ComplexSelector.doc.mjs +7 -0
  389. package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
  390. package/src/ComplexSelector/ComplexSelector.tsx +22 -12
  391. package/src/DateInput/DateInput.doc.mjs +16 -0
  392. package/src/DateInput/DateInput.test.tsx +9 -4
  393. package/src/DateInput/DateInput.tsx +54 -3
  394. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  395. package/src/DateInput/MonthScroller.tsx +5 -1
  396. package/src/DateInput/MonthYearWheels.tsx +7 -4
  397. package/src/DateInput/NativeDateField.test.tsx +635 -0
  398. package/src/DateInput/NativeDateField.tsx +641 -0
  399. package/src/DateInput/TouchDateField.tsx +83 -33
  400. package/src/DateInput/Wheel.tsx +1 -0
  401. package/src/DateInput/index.ts +1 -0
  402. package/src/DateInput/nativeDateSegments.ts +127 -0
  403. package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
  404. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
  405. package/src/DateRangeInput/DateRangeInput.tsx +8 -13
  406. package/src/DateTimeInput/DateTimeInput.doc.mjs +38 -21
  407. package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
  408. package/src/DateTimeInput/DateTimeInput.tsx +54 -20
  409. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
  410. package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
  411. package/src/Dialog/Dialog.test.tsx +185 -18
  412. package/src/Dialog/Dialog.tsx +35 -11
  413. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  414. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  415. package/src/Field/FieldLabel.test.tsx +29 -0
  416. package/src/Field/FieldLabel.tsx +7 -0
  417. package/src/Field/InputClearButton.test.tsx +15 -1
  418. package/src/Field/InputClearButton.tsx +28 -4
  419. package/src/Heading/Heading.tsx +0 -1
  420. package/src/HoverCard/HoverCard.doc.mjs +8 -2
  421. package/src/HoverCard/HoverCard.test.tsx +154 -4
  422. package/src/HoverCard/HoverCard.tsx +137 -3
  423. package/src/HoverCard/useHoverCard.tsx +23 -3
  424. package/src/Icon/Icon.test.tsx +55 -1
  425. package/src/Icon/Icon.tsx +5 -3
  426. package/src/Icon/defaultIcons.tsx +11 -2
  427. package/src/Icon/globalIconRegistry.test.tsx +16 -3
  428. package/src/Icon/globalIconRegistry.tsx +37 -6
  429. package/src/Icon/index.ts +1 -0
  430. package/src/Icon/useIcon.ts +9 -2
  431. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  432. package/src/Indicator/Indicator.doc.mjs +2 -0
  433. package/src/Item/Item.tsx +2 -7
  434. package/src/Kbd/Kbd.test.tsx +0 -17
  435. package/src/Kbd/Kbd.tsx +2 -26
  436. package/src/Layer/gestureCounter.ts +57 -0
  437. package/src/Layer/useLayer.test.tsx +368 -16
  438. package/src/Layer/useLayer.tsx +208 -35
  439. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  440. package/src/List/List.test.tsx +38 -0
  441. package/src/List/List.tsx +8 -1
  442. package/src/Markdown/Markdown.test.tsx +37 -0
  443. package/src/Markdown/Markdown.tsx +16 -5
  444. package/src/Markdown/parser.test.ts +33 -0
  445. package/src/Markdown/parser.ts +9 -3
  446. package/src/MetadataList/MetadataList.test.tsx +75 -2
  447. package/src/MetadataList/MetadataListItem.tsx +5 -2
  448. package/src/MultiSelector/MultiSelector.doc.mjs +22 -1
  449. package/src/MultiSelector/MultiSelector.test.tsx +205 -0
  450. package/src/MultiSelector/MultiSelector.tsx +103 -16
  451. package/src/MultiSelector/hooks.ts +9 -2
  452. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  453. package/src/NavIcon/NavIcon.test.tsx +9 -0
  454. package/src/NavIcon/NavIcon.tsx +5 -1
  455. package/src/NavItem/navItemStyles.stylex.ts +0 -8
  456. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  457. package/src/NavMenu/NavHeadingMenu.tsx +7 -4
  458. package/src/NumberInput/NumberInput.doc.mjs +26 -7
  459. package/src/NumberInput/NumberInput.test.tsx +563 -8
  460. package/src/NumberInput/NumberInput.tsx +77 -131
  461. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  462. package/src/NumberInput/numberInputCommit.ts +103 -0
  463. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  464. package/src/NumberInput/numberParser.test.ts +222 -0
  465. package/src/NumberInput/numberParser.ts +403 -0
  466. package/src/Outline/Outline.tsx +2 -4
  467. package/src/OverflowList/OverflowList.doc.mjs +102 -21
  468. package/src/OverflowList/OverflowList.test.tsx +550 -4
  469. package/src/OverflowList/OverflowList.tsx +100 -2
  470. package/src/Pagination/Pagination.test.tsx +3 -2
  471. package/src/Popover/Popover.doc.mjs +2 -2
  472. package/src/Popover/Popover.test.tsx +38 -0
  473. package/src/Popover/Popover.tsx +28 -66
  474. package/src/Popover/usePopover.tsx +44 -5
  475. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
  476. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
  477. package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
  478. package/src/PowerSearch/formatFilterValue.test.ts +16 -1
  479. package/src/PowerSearch/formatFilterValue.ts +2 -0
  480. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  481. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  482. package/src/ProgressBar/ProgressBar.tsx +28 -8
  483. package/src/Resizable/Resizable.doc.mjs +2 -2
  484. package/src/Resizable/useResizable.doc.mjs +21 -2
  485. package/src/Resizable/useResizable.test.ts +421 -0
  486. package/src/Resizable/useResizable.ts +133 -48
  487. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  488. package/src/SelectableCard/SelectableCard.tsx +16 -0
  489. package/src/Selector/Selector.doc.mjs +14 -0
  490. package/src/Selector/Selector.source-build.test.mjs +65 -0
  491. package/src/Selector/Selector.test.tsx +301 -0
  492. package/src/Selector/Selector.tsx +145 -32
  493. package/src/Selector/hooks.ts +17 -2
  494. package/src/SideNav/SideNav.doc.mjs +2 -2
  495. package/src/SideNav/SideNav.test.tsx +1069 -6
  496. package/src/SideNav/SideNav.tsx +109 -38
  497. package/src/SideNav/SideNavHeading.tsx +5 -2
  498. package/src/SideNav/SideNavItem.doc.mjs +24 -3
  499. package/src/SideNav/SideNavItem.tsx +134 -44
  500. package/src/Slider/Slider.test.tsx +106 -1
  501. package/src/Slider/Slider.tsx +52 -1
  502. package/src/Spinner/Spinner.doc.mjs +17 -5
  503. package/src/Spinner/Spinner.test.tsx +164 -0
  504. package/src/Spinner/Spinner.tsx +252 -22
  505. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  506. package/src/StatusDot/StatusDot.test.tsx +9 -0
  507. package/src/StatusDot/StatusDot.tsx +7 -1
  508. package/src/Stepper/Step.doc.mjs +1 -1
  509. package/src/Stepper/Step.tsx +7 -14
  510. package/src/Switch/Switch.doc.mjs +2 -0
  511. package/src/Switch/Switch.test.tsx +10 -0
  512. package/src/Switch/Switch.tsx +3 -0
  513. package/src/Table/BaseTable.tsx +6 -1
  514. package/src/Table/Table.doc.mjs +5 -3
  515. package/src/Table/Table.tsx +3 -8
  516. package/src/Table/TableBody.doc.mjs +2 -2
  517. package/src/Table/TableFooter.doc.mjs +1 -1
  518. package/src/Table/TableHeader.doc.mjs +1 -1
  519. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  520. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  521. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
  522. package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
  523. package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
  524. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  525. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  526. package/src/Table/useTablePagination.doc.mjs +1 -1
  527. package/src/Table/useTableSelection.doc.mjs +1 -1
  528. package/src/Text/Text.test.tsx +44 -0
  529. package/src/Text/Text.tsx +0 -1
  530. package/src/TextArea/TextArea.doc.mjs +12 -2
  531. package/src/TextArea/TextArea.test.tsx +11 -0
  532. package/src/TextArea/TextArea.tsx +34 -22
  533. package/src/Timestamp/Timestamp.test.tsx +89 -0
  534. package/src/Timestamp/Timestamp.tsx +8 -8
  535. package/src/Timestamp/formatInstant.ts +5 -0
  536. package/src/Toast/Toast.doc.mjs +213 -44
  537. package/src/Toast/Toast.tsx +118 -23
  538. package/src/Toast/ToastViewport.test.tsx +1434 -8
  539. package/src/Toast/ToastViewport.tsx +85 -14
  540. package/src/Toast/index.ts +2 -0
  541. package/src/Toast/types.ts +43 -5
  542. package/src/Toast/useToastGesture.ts +361 -0
  543. package/src/Token/Token.test.tsx +95 -0
  544. package/src/Token/Token.tsx +19 -17
  545. package/src/Token/TokenLink.tsx +12 -3
  546. package/src/Tokenizer/Tokenizer.doc.mjs +16 -3
  547. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  548. package/src/Tokenizer/Tokenizer.tsx +49 -24
  549. package/src/TopNav/TopNavHeading.tsx +2 -2
  550. package/src/TopNav/TopNavItem.tsx +3 -7
  551. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  552. package/src/TopNav/TopNavMegaMenu.tsx +47 -4
  553. package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
  554. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  555. package/src/TopNav/TopNavMenu.tsx +38 -5
  556. package/src/TreeList/TreeList.test.tsx +49 -0
  557. package/src/TreeList/TreeList.tsx +7 -2
  558. package/src/TreeList/TreeListItem.tsx +2 -7
  559. package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
  560. package/src/Typeahead/BaseTypeahead.tsx +96 -6
  561. package/src/Typeahead/Typeahead.doc.mjs +6 -0
  562. package/src/Typeahead/Typeahead.test.tsx +154 -0
  563. package/src/Typeahead/Typeahead.tsx +9 -0
  564. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  565. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  566. package/src/hooks/useAnnounce.doc.mjs +96 -0
  567. package/src/hooks/useDevWarning.doc.mjs +96 -0
  568. package/src/hooks/useHotkeys.test.ts +0 -18
  569. package/src/hooks/useHotkeys.ts +3 -25
  570. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  571. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  572. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  573. package/src/hooks/useLongPress.doc.mjs +123 -0
  574. package/src/hooks/useOverflow.doc.mjs +58 -17
  575. package/src/hooks/useOverflow.ts +16 -4
  576. package/src/hooks/useTypeahead.doc.mjs +153 -0
  577. package/src/index.ts +2 -0
  578. package/src/raw-import.d.ts +14 -0
  579. package/src/theme/Theme.test.tsx +104 -2
  580. package/src/theme/Theme.tsx +49 -14
  581. package/src/theme/defineTheme.test.ts +23 -0
  582. package/src/theme/defineTheme.ts +12 -3
  583. package/src/theme/derivedVarRegistry.test.ts +87 -3
  584. package/src/theme/derivedVarRegistry.ts +23 -4
  585. package/src/theme/generateThemeRules.test.ts +99 -1
  586. package/src/theme/generateThemeRules.ts +28 -0
  587. package/src/theme/syntax/tokens.ts +5 -2
  588. package/src/theme/useTheme.test.tsx +10 -0
  589. package/src/theme/useTheme.ts +16 -10
  590. package/src/utils/dateParser.test.ts +34 -2
  591. package/src/utils/dateParser.ts +11 -14
  592. package/src/utils/focusOutline.stylex.ts +50 -0
  593. package/src/utils/interactionOverlay.stylex.ts +74 -0
  594. package/src/utils/isApplePlatform.test.ts +61 -0
  595. package/src/utils/isApplePlatform.ts +37 -0
  596. package/src/utils/plainDate.test.ts +46 -0
  597. package/src/utils/plainDate.ts +18 -3
@@ -97,6 +97,11 @@ type AvatarNumericSize =
97
97
  */
98
98
  export type AvatarSize = AvatarNamedSize | AvatarNumericSize;
99
99
 
100
+ /**
101
+ * Avatar shape options
102
+ */
103
+ export type AvatarShape = 'circle' | 'rounded' | 'square';
104
+
100
105
  /**
101
106
  * Resolves named sizes to their numeric pixel values
102
107
  */
@@ -118,6 +123,25 @@ export function resolveSize(size: AvatarSize): number {
118
123
  }
119
124
  }
120
125
 
126
+ // Sets one local custom property rather than `borderRadius` directly, so
127
+ // every clipping/ring surface that needs the shape's radius (the wrapper,
128
+ // the interactive focus ring, the content div that actually clips via
129
+ // `overflow: hidden`, and AvatarGroupOverflow's "+N" indicator) reads the
130
+ // same value instead of each hardcoding its own borderRadius independently.
131
+ // A theme override only has to reach this one property, not fight the
132
+ // per-surface StyleX class order to change the shape everywhere at once.
133
+ export const shapeStyles = stylex.create({
134
+ circle: {
135
+ '--_avatar-radius': radiusVars['--radius-full'],
136
+ },
137
+ rounded: {
138
+ '--_avatar-radius': radiusVars['--radius-element'],
139
+ },
140
+ square: {
141
+ '--_avatar-radius': radiusVars['--radius-none'],
142
+ },
143
+ });
144
+
121
145
  /**
122
146
  * Base styles for the avatar
123
147
  * Uses a wrapper/content structure so status isn't clipped by overflow:hidden
@@ -127,10 +151,10 @@ const styles = stylex.create({
127
151
  position: 'relative',
128
152
  display: 'inline-flex',
129
153
  flexShrink: 0,
130
- // The wrapper carries the avatar's box as well as its radius, so a theme
131
- // rule on the `.astryx-avatar` target reaches both: the size the `size`
132
- // visual prop selects on is set here, and the content below fills it.
133
- borderRadius: radiusVars['--radius-full'],
154
+ // Reads the shape variant's `--_avatar-radius` (set by `shapeStyles`
155
+ // below) rather than a hardcoded value, so `shape` actually changes the
156
+ // wrapper's own radius instead of only the content div's clip.
157
+ borderRadius: 'var(--_avatar-radius)',
134
158
  },
135
159
  content: {
136
160
  display: 'flex',
@@ -138,9 +162,14 @@ const styles = stylex.create({
138
162
  justifyContent: 'center',
139
163
  width: '100%',
140
164
  height: '100%',
141
- borderRadius: radiusVars['--radius-full'],
142
165
  overflow: 'hidden',
143
166
  userSelect: 'none',
167
+ // The content div is the one that actually clips (via overflow: hidden
168
+ // above), so it needs its own border-radius matching the wrapper's.
169
+ // It inherits `--_avatar-radius` from the wrapper, since custom
170
+ // properties cascade to descendants even though border-radius itself
171
+ // does not.
172
+ borderRadius: 'var(--_avatar-radius)',
144
173
  },
145
174
  image: {
146
175
  width: '100%',
@@ -167,9 +196,6 @@ const styles = stylex.create({
167
196
  status: {
168
197
  position: 'absolute',
169
198
  },
170
- // Visible focus ring for the name-tooltip tab stop, matching the repo-wide
171
- // focus-visible outline treatment (see Timestamp, Token, Thumbnail). Only
172
- // applied when a tooltip is active so keyboard users can reveal it.
173
199
  // Reset the intrinsic styling of the interactive element (<a>/<button>) so it
174
200
  // is a transparent, correctly-sized wrapper around the avatar visuals. The
175
201
  // element carries the focus-visible accent ring for keyboard users.
@@ -187,8 +213,9 @@ const styles = stylex.create({
187
213
  default: 'pointer',
188
214
  ':is(:disabled,[aria-disabled="true"])': 'default',
189
215
  },
190
- // Match the avatar's circular shape so the focus ring hugs it.
191
- borderRadius: radiusVars['--radius-full'],
216
+ // Match the avatar's shape (via `--_avatar-radius`) so the focus ring
217
+ // hugs it, whichever shape variant is in effect.
218
+ borderRadius: 'var(--_avatar-radius)',
192
219
  },
193
220
  });
194
221
 
@@ -207,7 +234,7 @@ const dynamicStyles = stylex.create({
207
234
  fontSize: (size: number) => ({
208
235
  fontSize: `${size * INITIALS_FONT_SIZE_RATIO}px`,
209
236
  }),
210
- statusPosition: (size: number) => ({
237
+ statusPositionCircle: (size: number) => ({
211
238
  bottom: size * CIRCLE_EDGE_OFFSET_RATIO,
212
239
  insetInlineEnd: size * CIRCLE_EDGE_OFFSET_RATIO,
213
240
  // `insetInlineEnd` anchors to the right edge in LTR / left in RTL, so the
@@ -217,13 +244,23 @@ const dynamicStyles = stylex.create({
217
244
  ':is([dir="rtl"] *)': 'translate(-50%, 50%)',
218
245
  },
219
246
  }),
247
+ statusPositionCorner: {
248
+ bottom: 0,
249
+ insetInlineEnd: 0,
250
+ // Same RTL mirroring as statusPositionCircle above: insetInlineEnd
251
+ // anchors to the right edge in LTR / left in RTL, so the outward push
252
+ // must flip sign too.
253
+ transform: {
254
+ default: 'translate(25%, 25%)',
255
+ ':is([dir="rtl"] *)': 'translate(-25%, 25%)',
256
+ },
257
+ },
220
258
  });
221
259
 
222
260
  const BORDER_WIDTH = 2;
223
261
 
224
262
  const groupStyles = stylex.create({
225
263
  ring: {
226
- borderRadius: radiusVars['--radius-full'],
227
264
  borderWidth: BORDER_WIDTH,
228
265
  borderStyle: 'solid',
229
266
  borderColor: colorVars['--color-background-surface'],
@@ -276,6 +313,14 @@ export interface AvatarProps extends BaseProps<HTMLDivElement> {
276
313
  * @default 'md'
277
314
  */
278
315
  size?: AvatarSize;
316
+ /**
317
+ * Shape variant of the avatar.
318
+ * - 'circle': Full circle (default)
319
+ * - 'rounded': Rounded square
320
+ * - 'square': Sharp square
321
+ * @default 'circle'
322
+ */
323
+ shape?: AvatarShape;
279
324
  /**
280
325
  * The primary image source for the avatar.
281
326
  */
@@ -479,6 +524,7 @@ export function Avatar({
479
524
  fallbackSrc,
480
525
  name,
481
526
  size = 'md',
527
+ shape = 'circle',
482
528
  src,
483
529
  status,
484
530
  tooltip = true,
@@ -538,6 +584,7 @@ export function Avatar({
538
584
  : undefined;
539
585
  const avatarGroup = useAvatarGroup();
540
586
  const resolvedSize = avatarGroup?.size ?? size;
587
+ const resolvedShape = avatarGroup?.shape ?? shape;
541
588
  const numericSize = useMemo(() => resolveSize(resolvedSize), [resolvedSize]);
542
589
 
543
590
  // Resolve the tooltip content:
@@ -723,7 +770,9 @@ export function Avatar({
723
770
  <div
724
771
  {...stylex.props(
725
772
  styles.status,
726
- dynamicStyles.statusPosition(numericSize),
773
+ resolvedShape === 'circle'
774
+ ? dynamicStyles.statusPositionCircle(numericSize)
775
+ : dynamicStyles.statusPositionCorner,
727
776
  )}>
728
777
  {status}
729
778
  </div>
@@ -736,7 +785,7 @@ export function Avatar({
736
785
  // tooltip tab-stop focus ring all live here so the interactive
737
786
  // `<a>`/`<button>` and the static `<div>` carry the exact same box.
738
787
  const rootStylexProps = mergeProps(
739
- themeProps('avatar', {size: resolvedSize}),
788
+ themeProps('avatar', {size: resolvedSize, shape: resolvedShape}),
740
789
  focusOutlineProps.focusVisible(
741
790
  styles.wrapper,
742
791
  dynamicStyles.size(numericSize),
@@ -744,6 +793,7 @@ export function Avatar({
744
793
  avatarGroup && groupStyles.ring,
745
794
  avatarGroup && groupStyles.overlap,
746
795
  avatarGroup && groupDynamicStyles.overlap(-avatarGroup.overlap),
796
+ shapeStyles[resolvedShape],
747
797
  xstyle,
748
798
  ),
749
799
  className,
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @file index.ts
7
7
  * @input Imports Avatar component and types from Avatar.tsx, AvatarStatusDot from AvatarStatusDot.tsx
8
- * @output Exports Avatar, AvatarProps, AvatarSize, AvatarStatusDot, AvatarStatusDotProps, AvatarStatusDotVariant
8
+ * @output Exports Avatar, AvatarProps, AvatarSize, AvatarShape, resolveSize, AvatarStatusDot, AvatarStatusDotProps, AvatarStatusDotVariant
9
9
  * @position Component entry point; re-exported by /packages/core/src/index.ts
10
10
  *
11
11
  * SYNC: When modified, update this header and /packages/core/src/Avatar/Avatar.doc.mjs
@@ -38,7 +38,7 @@ export interface AvatarStatusDotVariantMap {
38
38
  }
39
39
 
40
40
  export {Avatar, resolveSize} from './Avatar';
41
- export type {AvatarProps, AvatarSize} from './Avatar';
41
+ export type {AvatarProps, AvatarSize, AvatarShape} from './Avatar';
42
42
  export {AvatarStatusDot} from './AvatarStatusDot';
43
43
  export type {
44
44
  AvatarStatusDotProps,
@@ -25,8 +25,8 @@ export const docs = {
25
25
  },
26
26
  theming: {
27
27
  targets: [
28
- {className: 'astryx-avatar-group', visualProps: ['size']},
29
- {className: 'astryx-avatar-group-overflow', visualProps: ['size']},
28
+ {className: 'astryx-avatar-group', visualProps: ['size', 'shape']},
29
+ {className: 'astryx-avatar-group-overflow', visualProps: ['size', 'shape']},
30
30
  ],
31
31
  },
32
32
  description: 'Stacked avatar display with overlapping layout and optional overflow indicator. Children are Avatar elements.',
@@ -52,6 +52,12 @@ export const docs = {
52
52
  "Size applied to all avatars via context. This wins over each child Avatar's own size prop, including when it is left at the default, so set the size here rather than on the children.",
53
53
  default: "'md'",
54
54
  },
55
+ {
56
+ name: 'shape',
57
+ type: "'circle' | 'rounded' | 'square'",
58
+ description: "Shape applied to all avatars via context, overriding each avatar's own shape prop. Also applied to AvatarGroupOverflow's \"+N\" indicator.",
59
+ default: "'circle'",
60
+ },
55
61
  {
56
62
  name: 'ref',
57
63
  type: 'React.Ref<HTMLDivElement>',
@@ -118,6 +118,30 @@ describe('AvatarGroupOverflow', () => {
118
118
  expect(overflow).toHaveAttribute('data-size', 'lg');
119
119
  });
120
120
 
121
+ it('applies the group shape to the overflow chip, matching its avatars', () => {
122
+ render(
123
+ <AvatarGroup shape="square">
124
+ <Avatar name="Alice" />
125
+ <AvatarGroupOverflow count={5} />
126
+ </AvatarGroup>,
127
+ );
128
+
129
+ const overflow = screen.getByLabelText('5 more');
130
+ expect(overflow).toHaveAttribute('data-shape', 'square');
131
+ });
132
+
133
+ it('defaults the overflow chip to circle shape with no explicit AvatarGroup shape', () => {
134
+ render(
135
+ <AvatarGroup>
136
+ <Avatar name="Alice" />
137
+ <AvatarGroupOverflow count={5} />
138
+ </AvatarGroup>,
139
+ );
140
+
141
+ const overflow = screen.getByLabelText('5 more');
142
+ expect(overflow).toHaveAttribute('data-shape', 'circle');
143
+ });
144
+
121
145
  it('renders as button when onClick is provided', () => {
122
146
  render(
123
147
  <AvatarGroup>
@@ -26,7 +26,7 @@
26
26
 
27
27
  import {useId, useMemo, useState, type ReactNode} from 'react';
28
28
  import type {BaseProps} from '../BaseProps';
29
- import {resolveSize, type AvatarSize} from '../Avatar';
29
+ import {resolveSize, type AvatarShape, type AvatarSize} from '../Avatar';
30
30
  import * as stylex from '@stylexjs/stylex';
31
31
  import {mergeProps} from '../utils';
32
32
  import {composeEventHandlers} from '../utils/composeEventHandlers';
@@ -55,6 +55,13 @@ export interface AvatarGroupProps extends BaseProps<HTMLDivElement> {
55
55
  * @default 'md'
56
56
  */
57
57
  size?: AvatarSize;
58
+ /**
59
+ * Shape applied to all avatars via context, overriding each avatar's own
60
+ * `shape` prop so a group stays visually uniform. Also applied to the
61
+ * `AvatarGroupOverflow` "+N" indicator, so it matches the group.
62
+ * @default 'circle'
63
+ */
64
+ shape?: AvatarShape;
58
65
  /**
59
66
  * Test ID for integration testing.
60
67
  */
@@ -89,6 +96,7 @@ const styles = stylex.create({
89
96
  export function AvatarGroup({
90
97
  children,
91
98
  size = 'md',
99
+ shape = 'circle',
92
100
  'data-testid': testId,
93
101
  'aria-label': ariaLabelFromProps,
94
102
  'aria-describedby': ariaDescribedByFromProps,
@@ -106,8 +114,8 @@ export function AvatarGroup({
106
114
  const overlap = Math.round(numericSize * OVERLAP_RATIO);
107
115
 
108
116
  const contextValue = useMemo(
109
- () => ({size, overlap, numericSize}),
110
- [size, overlap, numericSize],
117
+ () => ({size, shape, overlap, numericSize}),
118
+ [size, shape, overlap, numericSize],
111
119
  );
112
120
 
113
121
  // The keyboard hint and roving tab stop only make sense once the group has
@@ -152,7 +160,7 @@ export function AvatarGroup({
152
160
  onKeyDown={composeEventHandlers(onKeyDown, handleKeyDown)}
153
161
  onFocus={composeEventHandlers(onFocus, handleFocus)}
154
162
  {...mergeProps(
155
- themeProps('avatar-group', {size}),
163
+ themeProps('avatar-group', {size, shape}),
156
164
  stylex.props(styles.root, xstyle),
157
165
  className,
158
166
  style,
@@ -9,16 +9,18 @@
9
9
  */
10
10
 
11
11
  import {createContext, use} from 'react';
12
- import type {AvatarSize} from '../Avatar';
12
+ import type {AvatarShape, AvatarSize} from '../Avatar';
13
13
 
14
14
  export interface AvatarGroupContextValue {
15
15
  size: AvatarSize;
16
+ shape: AvatarShape;
16
17
  overlap: number;
17
18
  numericSize: number;
18
19
  }
19
20
 
20
- export const AvatarGroupContext =
21
- createContext<AvatarGroupContextValue | null>(null);
21
+ export const AvatarGroupContext = createContext<AvatarGroupContextValue | null>(
22
+ null,
23
+ );
22
24
  AvatarGroupContext.displayName = 'AvatarGroupContext';
23
25
 
24
26
  export function useAvatarGroup(): AvatarGroupContextValue | null {
@@ -20,15 +20,16 @@ import {
20
20
  typographyVars,
21
21
  typeScaleVars,
22
22
  fontWeightVars,
23
- radiusVars,
24
23
  spacingVars,
25
24
  } from '../theme/tokens.stylex';
25
+ import {shapeStyles} from '../Avatar/Avatar';
26
26
  import {mergeProps} from '../utils';
27
27
  import {resolveSize} from '../Avatar';
28
28
  import {useAvatarGroup} from './AvatarGroupContext';
29
29
  import type {BaseProps} from '../BaseProps';
30
30
  import {themeProps} from '../utils/themeProps';
31
31
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
32
+ import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
32
33
  import {useTranslator} from '../i18n';
33
34
 
34
35
  const BORDER_WIDTH = 2;
@@ -65,7 +66,10 @@ const styles = stylex.create({
65
66
  display: 'inline-flex',
66
67
  alignItems: 'center',
67
68
  justifyContent: 'center',
68
- borderRadius: radiusVars['--radius-full'],
69
+ // Reads the shape variant's `--_avatar-radius` (set via `shapeStyles`,
70
+ // shared with Avatar) so the overflow indicator matches the group's
71
+ // shape instead of always staying a circle.
72
+ borderRadius: 'var(--_avatar-radius)',
69
73
  // Use opaque background to prevent avatar bleed-through
70
74
  backgroundColor: colorVars['--color-background-surface'],
71
75
  color: colorVars['--color-text-secondary'],
@@ -93,14 +97,6 @@ const styles = stylex.create({
93
97
  // Reset the UA button's block padding only; the inline padding from `base`
94
98
  // provides the pill's breathing room and must be preserved.
95
99
  paddingBlock: 0,
96
- // Interactive overlay states layered on top via backgroundImage
97
- backgroundImage: {
98
- default: `linear-gradient(${colorVars['--color-neutral']}, ${colorVars['--color-neutral']})`,
99
- ':hover:where(:not(:disabled,[aria-disabled="true"]))': {
100
- '@media (hover: hover)': `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']}), linear-gradient(${colorVars['--color-neutral']}, ${colorVars['--color-neutral']})`,
101
- },
102
- ':active': `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']}), linear-gradient(${colorVars['--color-neutral']}, ${colorVars['--color-neutral']})`,
103
- },
104
100
  // Focus ring via focus-visible
105
101
  },
106
102
  overlap: {
@@ -166,6 +162,7 @@ export function AvatarGroupOverflow({
166
162
  const t = useTranslator();
167
163
  const group = useAvatarGroup();
168
164
  const size = group?.size ?? 'md';
165
+ const shape = group?.shape ?? 'circle';
169
166
  const numericSize = group?.numericSize ?? resolveSize('md');
170
167
  const overlap = group?.overlap ?? 0;
171
168
 
@@ -186,14 +183,16 @@ export function AvatarGroupOverflow({
186
183
  aria-label={label}
187
184
  data-avatar-item=""
188
185
  {...mergeProps(
189
- themeProps('avatar-group-overflow', {size}),
186
+ themeProps('avatar-group-overflow', {size, shape}),
190
187
  focusOutlineProps.focusVisible(
191
188
  styles.base,
192
189
  styles.button,
190
+ interactionOverlayStyles.backgroundImageOnNeutral,
193
191
  styles.overlap,
194
192
  dynamicStyles.size(numericSize),
195
193
  dynamicStyles.fontSize(numericSize),
196
194
  dynamicStyles.overlap(-overlap),
195
+ shapeStyles[shape],
197
196
  xstyle,
198
197
  ),
199
198
  className,
@@ -210,13 +209,14 @@ export function AvatarGroupOverflow({
210
209
  {...rest}
211
210
  aria-label={label}
212
211
  {...mergeProps(
213
- themeProps('avatar-group-overflow', {size}),
212
+ themeProps('avatar-group-overflow', {size, shape}),
214
213
  stylex.props(
215
214
  styles.base,
216
215
  styles.overlap,
217
216
  dynamicStyles.size(numericSize),
218
217
  dynamicStyles.fontSize(numericSize),
219
218
  dynamicStyles.overlap(-overlap),
219
+ shapeStyles[shape],
220
220
  xstyle,
221
221
  ),
222
222
  className,
@@ -18,7 +18,8 @@ export const docs = {
18
18
  {
19
19
  name: 'label',
20
20
  type: 'ReactNode',
21
- description: 'Badge text content.',
21
+ description:
22
+ 'Badge text content. A badge is one line, so a label wider than the space available is cut with an ellipsis rather than escaping its container; a string or number label is also set as the badge\'s title so the full text stays reachable on hover.',
22
23
  },
23
24
  {
24
25
  name: 'icon',
@@ -132,7 +133,7 @@ export const docsDense = {
132
133
  },
133
134
  propDescriptions: {
134
135
  variant: 'visual style variant',
135
- label: 'badge text content',
136
+ label: 'badge text content; over-wide labels clip with an ellipsis, full text in title',
136
137
  icon: 'optional leading icon',
137
138
  },
138
139
  };
@@ -37,9 +37,7 @@ describe('Badge', () => {
37
37
  'yellow',
38
38
  ] as const;
39
39
 
40
- const {rerender} = render(
41
- <Badge variant={colors[0]} label={colors[0]} />,
42
- );
40
+ const {rerender} = render(<Badge variant={colors[0]} label={colors[0]} />);
43
41
  expect(screen.getByText(colors[0])).toBeInTheDocument();
44
42
 
45
43
  for (const color of colors.slice(1)) {
@@ -74,6 +72,37 @@ describe('Badge', () => {
74
72
  expect(screen.getByTestId('custom-badge')).toBeInTheDocument();
75
73
  });
76
74
 
75
+ describe('full-label fallback', () => {
76
+ it('carries the full text in title for a string label', () => {
77
+ // The label is clipped when it does not fit, so the full text has to be
78
+ // reachable. No measurement is involved, so this holds on the server too.
79
+ const {container} = render(<Badge label="Awaiting security review" />);
80
+ expect(container.firstElementChild).toHaveAttribute(
81
+ 'title',
82
+ 'Awaiting security review',
83
+ );
84
+ });
85
+
86
+ it('carries a number label too', () => {
87
+ const {container} = render(<Badge label={42} />);
88
+ expect(container.firstElementChild).toHaveAttribute('title', '42');
89
+ });
90
+
91
+ it('sets no title for a rich label', () => {
92
+ // Flattening a subtree to a string renders a guess — an icon or nested
93
+ // element reads differently — so it is left alone rather than guessed at.
94
+ const {container} = render(<Badge label={<strong>Rich</strong>} />);
95
+ expect(container.firstElementChild).not.toHaveAttribute('title');
96
+ });
97
+
98
+ it('sets no title for an empty string label', () => {
99
+ // Nothing to recover, so nothing to announce — the same guard
100
+ // `BaseTable` applies to a truncated header cell.
101
+ const {container} = render(<Badge label="" />);
102
+ expect(container.firstElementChild).not.toHaveAttribute('title');
103
+ });
104
+ });
105
+
77
106
  it('renders astryx-* class names for theme targeting', () => {
78
107
  const {container} = render(<Badge variant="success" label="Active" />);
79
108
  const root = container.firstElementChild!;
@@ -46,6 +46,24 @@ const styles = stylex.create({
46
46
  lineHeight: typeScaleVars['--text-supporting-leading'],
47
47
  fontWeight: fontWeightVars['--font-weight-medium'],
48
48
  whiteSpace: 'nowrap',
49
+ // A badge is one line by construction — fixed height, `nowrap` — so a
50
+ // label wider than the space available has to go somewhere. Without these
51
+ // it went *outside* its container: `nowrap` with nothing to clip it
52
+ // neither wraps nor truncates, it just escapes, and lands on whatever sits
53
+ // beside it. `minWidth: 0` matters as much as the max: as a flex item the
54
+ // automatic minimum size would otherwise hold the badge at its full text
55
+ // width and push the clamp back out again.
56
+ maxWidth: '100%',
57
+ minWidth: 0,
58
+ },
59
+ // The ellipsis goes on the label rather than the badge itself, because
60
+ // `text-overflow` needs a block container and taking the root off
61
+ // `inline-flex` to get one would cost the icon its centring. The label is a
62
+ // flex item, so it needs its own `minWidth: 0` for the same reason as above.
63
+ label: {
64
+ overflow: 'hidden',
65
+ textOverflow: 'ellipsis',
66
+ minWidth: 0,
49
67
  },
50
68
  });
51
69
 
@@ -163,6 +181,28 @@ export function Badge({
163
181
  ref,
164
182
  ...props
165
183
  }: BadgeProps) {
184
+ // Clipping a label makes its tail unrecoverable, so the full text has to
185
+ // stay reachable somewhere. `title` is the half of that answer which costs
186
+ // nothing: no measurement, no hook, so `Badge` renders the same on the
187
+ // server and stays usable in a server component. It follows the shape
188
+ // `BaseTable` already uses for a truncated header cell (BaseTable.tsx) —
189
+ // string content only, and only when there is something to show.
190
+ //
191
+ // A rich label is left alone: it is a subtree whose text would have to be
192
+ // flattened to a string, and flattening renders a guess — an icon, a
193
+ // `<strong>`, a nested element all read differently.
194
+ //
195
+ // It is set whether or not the label actually fits, because knowing that
196
+ // requires measuring. The refinement — a tooltip only when the text is
197
+ // really cut, reachable by hover and by focus — needs that measurement and
198
+ // a client component, so it is tracked in #5585.
199
+ const labelTitle =
200
+ typeof label === 'number'
201
+ ? String(label)
202
+ : typeof label === 'string' && label.length > 0
203
+ ? label
204
+ : undefined;
205
+
166
206
  return (
167
207
  <span
168
208
  ref={ref}
@@ -172,9 +212,10 @@ export function Badge({
172
212
  className,
173
213
  style,
174
214
  )}
215
+ title={labelTitle}
175
216
  {...props}>
176
217
  {icon}
177
- {label}
218
+ <span {...stylex.props(styles.label)}>{label}</span>
178
219
  </span>
179
220
  );
180
221
  }
@@ -67,6 +67,12 @@ export const docs = {
67
67
  description:
68
68
  'Called when the dismiss button is clicked; banner hides itself regardless of whether this is provided.',
69
69
  },
70
+ {
71
+ name: 'dismissLabel',
72
+ type: 'string',
73
+ description:
74
+ 'Accessible name and visible tooltip for the dismiss button (pass it already translated). Defaults to "Dismiss <title>" for a string title, so stacked banners are distinguishable; set it when the title is a ReactNode.',
75
+ },
70
76
  {
71
77
  name: 'endContent',
72
78
  type: 'ReactNode',
@@ -165,6 +171,7 @@ export const docsZh = {
165
171
  {name: 'icon', type: 'ReactNode', description: '覆盖默认的状态图标。'},
166
172
  {name: 'isDismissable', type: 'boolean', description: '横幅是否可被用户关闭。', default: 'false'},
167
173
  {name: 'onDismiss', type: '() => void', description: '点击关闭按钮时调用;无论是否提供此回调,横幅都会自动隐藏。'},
174
+ {name: 'dismissLabel', type: 'string', description: '关闭按钮的无障碍名称和可见工具提示(请传入已翻译的字符串)。字符串标题默认生成“关闭 <标题>”;富文本标题请设置此属性。'},
168
175
  {name: 'endContent', type: 'ReactNode', description: '渲染在头部区域末端对齐的操作内容,通常是按钮或链接。头部过窄时会整体换行到文本下方,自成一行。'},
169
176
  {name: 'container', type: "'card' | 'section'", description: '视觉变体:card 带圆角;section 无圆角全宽,适用于页面级场景。', default: "'card'"},
170
177
  {name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: '静止阴影深度。用于悬浮于内容之上的浮动横幅;none 为默认内联横幅。', default: "'none'"},
@@ -241,6 +248,8 @@ export const docsDense = {
241
248
  icon: 'override default status icon',
242
249
  isDismissable: 'user can dismiss banner',
243
250
  onDismiss: 'dismiss callback; banner self-hides regardless',
251
+ dismissLabel:
252
+ 'a11y name + visible tooltip for dismiss; defaults to "Dismiss <title>"',
244
253
  endContent: 'end-aligned action in header, typically button/link; wraps to its own row when the header is too narrow',
245
254
  container: 'card=border-radius; section=full-width no radius for page-level',
246
255
  elevation: 'resting shadow depth: none|low|med|high; raise for a floating banner',