@astryxdesign/core 0.1.7 → 0.1.8-canary.0c4d8d7

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 (428) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +30 -19
  3. package/dist/AppShell/AppShell.d.ts.map +1 -1
  4. package/dist/AppShell/AppShell.js +6 -2
  5. package/dist/AppShell/AppShellMobileContext.d.ts +8 -0
  6. package/dist/AppShell/AppShellMobileContext.d.ts.map +1 -1
  7. package/dist/Avatar/Avatar.d.ts +10 -5
  8. package/dist/Avatar/Avatar.d.ts.map +1 -1
  9. package/dist/Avatar/Avatar.js +12 -8
  10. package/dist/Avatar/AvatarSizeContext.d.ts +1 -1
  11. package/dist/Avatar/AvatarSizeContext.js +1 -1
  12. package/dist/Avatar/AvatarStatusDot.d.ts +2 -2
  13. package/dist/Avatar/AvatarStatusDot.js +2 -2
  14. package/dist/AvatarGroup/AvatarGroup.d.ts +2 -2
  15. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  16. package/dist/AvatarGroup/AvatarGroup.js +2 -2
  17. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  18. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  19. package/dist/AvatarGroup/AvatarGroupOverflow.js +16 -14
  20. package/dist/Banner/Banner.d.ts +9 -1
  21. package/dist/Banner/Banner.d.ts.map +1 -1
  22. package/dist/Banner/Banner.js +31 -2
  23. package/dist/Button/Button.d.ts +8 -2
  24. package/dist/Button/Button.d.ts.map +1 -1
  25. package/dist/Button/Button.js +31 -2
  26. package/dist/ButtonGroup/ButtonGroup.d.ts +9 -1
  27. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  28. package/dist/ButtonGroup/ButtonGroup.js +30 -1
  29. package/dist/Card/Card.d.ts +8 -2
  30. package/dist/Card/Card.d.ts.map +1 -1
  31. package/dist/Card/Card.js +28 -2
  32. package/dist/Carousel/Carousel.d.ts +6 -2
  33. package/dist/Carousel/Carousel.d.ts.map +1 -1
  34. package/dist/Carousel/Carousel.js +55 -5
  35. package/dist/Chat/ChatComposer.d.ts +8 -0
  36. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  37. package/dist/Chat/ChatComposer.js +31 -6
  38. package/dist/Chat/ChatComposerDrawer.d.ts +2 -0
  39. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  40. package/dist/Chat/ChatComposerDrawer.js +11 -1
  41. package/dist/Chat/ChatComposerInput.d.ts +20 -3
  42. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  43. package/dist/Chat/ChatComposerInput.js +19 -3
  44. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  45. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  46. package/dist/Chat/ChatMessage.d.ts +1 -1
  47. package/dist/Chat/ChatMessage.d.ts.map +1 -1
  48. package/dist/Chat/ChatMessage.js +1 -1
  49. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  50. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  51. package/dist/Chat/ChatToolCalls.d.ts +5 -1
  52. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  53. package/dist/Chat/ChatToolCalls.js +12 -3
  54. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  55. package/dist/Citation/Citation.d.ts.map +1 -1
  56. package/dist/Citation/Citation.js +10 -4
  57. package/dist/ClickableCard/ClickableCard.d.ts +9 -2
  58. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  59. package/dist/ClickableCard/ClickableCard.js +3 -0
  60. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  61. package/dist/CodeBlock/CodeBlock.js +8 -1
  62. package/dist/Collapsible/Collapsible.d.ts +11 -1
  63. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  64. package/dist/Collapsible/Collapsible.js +36 -4
  65. package/dist/CommandPalette/CommandPaletteInput.d.ts +7 -1
  66. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  67. package/dist/CommandPalette/CommandPaletteInput.js +6 -1
  68. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  69. package/dist/ContextMenu/ContextMenu.js +4 -3
  70. package/dist/ContextMenu/index.d.ts +3 -0
  71. package/dist/ContextMenu/index.d.ts.map +1 -1
  72. package/dist/ContextMenu/index.js +7 -1
  73. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  74. package/dist/DateTimeInput/DateTimeInput.js +10 -1
  75. package/dist/Dialog/Dialog.d.ts.map +1 -1
  76. package/dist/Dialog/Dialog.js +2 -1
  77. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  78. package/dist/DropdownMenu/DropdownMenu.js +8 -4
  79. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +88 -0
  80. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -0
  81. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +169 -0
  82. package/dist/DropdownMenu/DropdownMenuContext.d.ts +17 -1
  83. package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
  84. package/dist/DropdownMenu/DropdownMenuContext.js +18 -0
  85. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +68 -0
  86. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -0
  87. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +69 -0
  88. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +69 -0
  89. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -0
  90. package/dist/DropdownMenu/DropdownMenuRadioItem.js +178 -0
  91. package/dist/DropdownMenu/index.d.ts +5 -1
  92. package/dist/DropdownMenu/index.d.ts.map +1 -1
  93. package/dist/DropdownMenu/index.js +10 -1
  94. package/dist/DropdownMenu/menuItemRoles.d.ts +13 -0
  95. package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -0
  96. package/dist/DropdownMenu/menuItemRoles.js +15 -0
  97. package/dist/FieldStatus/FieldStatus.d.ts +8 -0
  98. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  99. package/dist/FieldStatus/FieldStatus.js +22 -4
  100. package/dist/FileInput/FileInput.d.ts.map +1 -1
  101. package/dist/FileInput/FileInput.js +10 -2
  102. package/dist/HoverCard/HoverCard.d.ts +9 -1
  103. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  104. package/dist/HoverCard/HoverCard.js +2 -0
  105. package/dist/HoverCard/useHoverCard.d.ts +8 -0
  106. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  107. package/dist/HoverCard/useHoverCard.js +7 -2
  108. package/dist/Icon/Icon.d.ts +43 -13
  109. package/dist/Icon/Icon.d.ts.map +1 -1
  110. package/dist/Icon/Icon.js +62 -27
  111. package/dist/Layer/useLayer.d.ts +6 -0
  112. package/dist/Layer/useLayer.d.ts.map +1 -1
  113. package/dist/Layer/useLayer.js +2 -0
  114. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  115. package/dist/MobileNav/MobileNav.js +6 -1
  116. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  117. package/dist/MobileNav/MobileNavToggle.js +4 -0
  118. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  119. package/dist/MultiSelector/MultiSelector.js +39 -12
  120. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  121. package/dist/MultiSelector/hooks.js +16 -0
  122. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  123. package/dist/Outline/Outline.d.ts +68 -3
  124. package/dist/Outline/Outline.d.ts.map +1 -1
  125. package/dist/Outline/Outline.js +128 -26
  126. package/dist/Outline/useScrollSpy.d.ts +27 -7
  127. package/dist/Outline/useScrollSpy.d.ts.map +1 -1
  128. package/dist/Outline/useScrollSpy.js +202 -70
  129. package/dist/OverflowList/OverflowList.d.ts +20 -3
  130. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  131. package/dist/OverflowList/OverflowList.js +29 -4
  132. package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
  133. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  134. package/dist/SelectableCard/SelectableCard.d.ts +9 -2
  135. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  136. package/dist/SelectableCard/SelectableCard.js +14 -11
  137. package/dist/Selector/Selector.d.ts.map +1 -1
  138. package/dist/Selector/Selector.js +4 -2
  139. package/dist/Selector/hooks.d.ts.map +1 -1
  140. package/dist/Selector/hooks.js +16 -0
  141. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  142. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  143. package/dist/SideNav/SideNavHeading.js +21 -8
  144. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  145. package/dist/Slider/Slider.d.ts.map +1 -1
  146. package/dist/Slider/Slider.js +15 -1
  147. package/dist/TabList/Tab.d.ts.map +1 -1
  148. package/dist/TabList/Tab.js +2 -2
  149. package/dist/TabList/TabList.d.ts.map +1 -1
  150. package/dist/TabList/TabList.js +2 -0
  151. package/dist/TabList/TabMenu.d.ts.map +1 -1
  152. package/dist/TabList/TabMenu.js +1 -1
  153. package/dist/Table/Table.d.ts +1 -1
  154. package/dist/Table/Table.js +1 -1
  155. package/dist/Table/index.d.ts +4 -0
  156. package/dist/Table/index.d.ts.map +1 -1
  157. package/dist/Table/index.js +2 -0
  158. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  159. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  160. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +24 -2
  161. package/dist/Table/plugins/rowStatus/index.d.ts +3 -0
  162. package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -0
  163. package/dist/Table/plugins/rowStatus/index.js +3 -0
  164. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +60 -0
  165. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -0
  166. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +145 -0
  167. package/dist/Table/plugins/selection/useTableSelection.d.ts +12 -0
  168. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  169. package/dist/Table/plugins/selection/useTableSelection.js +4 -1
  170. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  171. package/dist/Table/plugins/sortable/useTableSortable.js +18 -7
  172. package/dist/Table/plugins/tree/index.d.ts +5 -0
  173. package/dist/Table/plugins/tree/index.d.ts.map +1 -0
  174. package/dist/Table/plugins/tree/index.js +4 -0
  175. package/dist/Table/plugins/tree/useTableTreeData.d.ts +38 -0
  176. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -0
  177. package/dist/Table/plugins/tree/useTableTreeData.js +358 -0
  178. package/dist/Table/plugins/tree/useTableTreeState.d.ts +51 -0
  179. package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -0
  180. package/dist/Table/plugins/tree/useTableTreeState.js +175 -0
  181. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  182. package/dist/Table/useBaseTablePlugins.js +6 -3
  183. package/dist/Thumbnail/Thumbnail.d.ts +8 -1
  184. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  185. package/dist/Thumbnail/Thumbnail.js +46 -8
  186. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  187. package/dist/TimeInput/TimeInput.js +15 -4
  188. package/dist/Tokenizer/Tokenizer.d.ts +1 -1
  189. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  190. package/dist/Tokenizer/Tokenizer.js +16 -4
  191. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  192. package/dist/Toolbar/Toolbar.js +8 -1
  193. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  194. package/dist/TopNav/TopNavHeading.js +18 -8
  195. package/dist/TopNav/TopNavMegaMenu.js +10 -4
  196. package/dist/TopNav/TopNavMenu.d.ts +2 -1
  197. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  198. package/dist/TopNav/TopNavMenu.js +68 -6
  199. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  200. package/dist/TreeList/TreeListItem.js +5 -14
  201. package/dist/astryx.css +51 -16
  202. package/dist/astryx.umd.js +56 -56
  203. package/dist/astryx.umd.js.map +4 -4
  204. package/dist/authoring/doc.d.ts.map +1 -1
  205. package/dist/hooks/computeOverflow.d.ts +47 -0
  206. package/dist/hooks/computeOverflow.d.ts.map +1 -0
  207. package/dist/hooks/computeOverflow.js +213 -0
  208. package/dist/hooks/useOverflow.d.ts +19 -0
  209. package/dist/hooks/useOverflow.d.ts.map +1 -1
  210. package/dist/hooks/useOverflow.js +37 -25
  211. package/dist/theme/Theme.js +1 -1
  212. package/dist/theme/defineTheme.d.ts +1 -1
  213. package/dist/theme/defineTheme.js +1 -1
  214. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  215. package/dist/theme/generateThemeRules.js +51 -0
  216. package/dist/theme/hct.d.ts +0 -1
  217. package/dist/theme/hct.d.ts.map +1 -1
  218. package/dist/theme/hct.js +0 -3
  219. package/dist/utils/types.d.ts +13 -0
  220. package/dist/utils/types.d.ts.map +1 -1
  221. package/docs.mjs +32 -461
  222. package/locales/en.json +212 -172
  223. package/locales/fr-FR.json +10 -0
  224. package/locales/pseudo.json +30 -0
  225. package/package.json +3 -1
  226. package/scripts/postinstall.mjs +93 -0
  227. package/src/AppShell/AppShell.tsx +6 -0
  228. package/src/AppShell/AppShellMobileContext.tsx +8 -0
  229. package/src/AppShell/useAppShellMobile.doc.mjs +8 -0
  230. package/src/Avatar/Avatar.doc.mjs +6 -6
  231. package/src/Avatar/Avatar.tsx +16 -11
  232. package/src/Avatar/AvatarSizeContext.ts +1 -1
  233. package/src/Avatar/AvatarStatusDot.tsx +2 -2
  234. package/src/AvatarGroup/AvatarGroup.doc.mjs +1 -1
  235. package/src/AvatarGroup/AvatarGroup.test.tsx +17 -3
  236. package/src/AvatarGroup/AvatarGroup.tsx +3 -3
  237. package/src/AvatarGroup/AvatarGroupOverflow.doc.mjs +4 -4
  238. package/src/AvatarGroup/AvatarGroupOverflow.tsx +21 -5
  239. package/src/Banner/Banner.doc.mjs +9 -0
  240. package/src/Banner/Banner.test.tsx +30 -0
  241. package/src/Banner/Banner.tsx +47 -3
  242. package/src/Button/Button.doc.mjs +9 -0
  243. package/src/Button/Button.test.tsx +49 -0
  244. package/src/Button/Button.tsx +25 -1
  245. package/src/ButtonGroup/ButtonGroup.doc.mjs +3 -0
  246. package/src/ButtonGroup/ButtonGroup.test.tsx +37 -0
  247. package/src/ButtonGroup/ButtonGroup.tsx +32 -0
  248. package/src/Card/Card.doc.mjs +9 -0
  249. package/src/Card/Card.test.tsx +21 -3
  250. package/src/Card/Card.tsx +35 -2
  251. package/src/Carousel/Carousel.doc.mjs +1 -0
  252. package/src/Carousel/Carousel.test.tsx +149 -1
  253. package/src/Carousel/Carousel.tsx +62 -5
  254. package/src/Chat/Chat.doc.mjs +1 -1
  255. package/src/Chat/ChatComposer.doc.mjs +9 -0
  256. package/src/Chat/ChatComposer.test.tsx +35 -0
  257. package/src/Chat/ChatComposer.tsx +58 -9
  258. package/src/Chat/ChatComposerDrawer.test.tsx +61 -0
  259. package/src/Chat/ChatComposerDrawer.tsx +11 -1
  260. package/src/Chat/ChatComposerInput.doc.mjs +7 -0
  261. package/src/Chat/ChatComposerInput.test.tsx +87 -0
  262. package/src/Chat/ChatComposerInput.tsx +35 -3
  263. package/src/Chat/ChatLayout.tsx +3 -1
  264. package/src/Chat/ChatLayoutScrollButton.tsx +3 -1
  265. package/src/Chat/ChatMessage.tsx +4 -2
  266. package/src/Chat/ChatMessageMetadata.tsx +1 -2
  267. package/src/Chat/ChatSendButton.tsx +5 -1
  268. package/src/Chat/ChatToolCalls.test.tsx +64 -0
  269. package/src/Chat/ChatToolCalls.tsx +13 -1
  270. package/src/Chat/useTriggerMenu.tsx +3 -1
  271. package/src/CheckboxInput/CheckboxInput.doc.mjs +1 -1
  272. package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
  273. package/src/CheckboxList/CheckboxList.test.tsx +9 -1
  274. package/src/Citation/Citation.test.tsx +51 -0
  275. package/src/Citation/Citation.tsx +8 -2
  276. package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
  277. package/src/ClickableCard/ClickableCard.test.tsx +34 -0
  278. package/src/ClickableCard/ClickableCard.tsx +11 -1
  279. package/src/CodeBlock/CodeBlock.test.tsx +56 -0
  280. package/src/CodeBlock/CodeBlock.tsx +9 -1
  281. package/src/Collapsible/Collapsible.doc.mjs +7 -0
  282. package/src/Collapsible/Collapsible.test.tsx +80 -0
  283. package/src/Collapsible/Collapsible.tsx +58 -5
  284. package/src/CommandPalette/CommandPaletteInput.doc.mjs +26 -9
  285. package/src/CommandPalette/CommandPaletteInput.test.tsx +34 -0
  286. package/src/CommandPalette/CommandPaletteInput.tsx +11 -0
  287. package/src/ContextMenu/ContextMenu.test.tsx +75 -1
  288. package/src/ContextMenu/ContextMenu.tsx +10 -5
  289. package/src/ContextMenu/index.ts +15 -0
  290. package/src/DateTimeInput/DateTimeInput.test.tsx +35 -0
  291. package/src/DateTimeInput/DateTimeInput.tsx +14 -2
  292. package/src/Dialog/Dialog.tsx +12 -2
  293. package/src/DropdownMenu/DropdownMenu.doc.mjs +23 -0
  294. package/src/DropdownMenu/DropdownMenu.tsx +11 -6
  295. package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +95 -0
  296. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +236 -0
  297. package/src/DropdownMenu/DropdownMenuContext.tsx +29 -1
  298. package/src/DropdownMenu/DropdownMenuItem.doc.mjs +7 -1
  299. package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +80 -0
  300. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +118 -0
  301. package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +80 -0
  302. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +232 -0
  303. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +163 -0
  304. package/src/DropdownMenu/index.ts +23 -3
  305. package/src/DropdownMenu/menuItemRoles.ts +22 -0
  306. package/src/Field/Field.doc.mjs +1 -1
  307. package/src/Field/Field.test.tsx +57 -12
  308. package/src/Field/FieldLabel.doc.mjs +1 -1
  309. package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
  310. package/src/FieldStatus/FieldStatus.test.tsx +78 -40
  311. package/src/FieldStatus/FieldStatus.tsx +22 -4
  312. package/src/FileInput/FileInput.test.tsx +52 -3
  313. package/src/FileInput/FileInput.tsx +13 -2
  314. package/src/HoverCard/HoverCard.doc.mjs +13 -0
  315. package/src/HoverCard/HoverCard.test.tsx +21 -2
  316. package/src/HoverCard/HoverCard.tsx +11 -0
  317. package/src/HoverCard/useHoverCard.doc.mjs +2 -0
  318. package/src/HoverCard/useHoverCard.tsx +24 -2
  319. package/src/Icon/Icon.doc.mjs +12 -0
  320. package/src/Icon/Icon.test.tsx +142 -0
  321. package/src/Icon/Icon.tsx +98 -30
  322. package/src/IconButton/IconButton.doc.mjs +8 -0
  323. package/src/IconButton/IconButton.test.tsx +15 -18
  324. package/src/Item/Item.doc.mjs +1 -1
  325. package/src/Layer/useLayer.tsx +8 -0
  326. package/src/MobileNav/MobileNav.tsx +12 -1
  327. package/src/MobileNav/MobileNavToggle.test.tsx +116 -0
  328. package/src/MobileNav/MobileNavToggle.tsx +9 -1
  329. package/src/MultiSelector/MultiSelector.doc.mjs +4 -2
  330. package/src/MultiSelector/MultiSelector.test.tsx +162 -1
  331. package/src/MultiSelector/MultiSelector.tsx +55 -12
  332. package/src/MultiSelector/hooks.ts +17 -0
  333. package/src/NumberInput/NumberInput.doc.mjs +2 -2
  334. package/src/NumberInput/NumberInput.test.tsx +11 -7
  335. package/src/NumberInput/NumberInput.tsx +1 -2
  336. package/src/Outline/Outline.doc.mjs +123 -3
  337. package/src/Outline/Outline.test.tsx +735 -0
  338. package/src/Outline/Outline.tsx +183 -33
  339. package/src/Outline/useScrollSpy.ts +248 -72
  340. package/src/OverflowList/OverflowList.doc.mjs +39 -6
  341. package/src/OverflowList/OverflowList.test.tsx +111 -0
  342. package/src/OverflowList/OverflowList.tsx +48 -8
  343. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
  344. package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
  345. package/src/PowerSearch/usePowerSearchSource.ts +1 -2
  346. package/src/SelectableCard/SelectableCard.doc.mjs +2 -0
  347. package/src/SelectableCard/SelectableCard.test.tsx +46 -4
  348. package/src/SelectableCard/SelectableCard.tsx +27 -14
  349. package/src/Selector/Selector.test.tsx +69 -0
  350. package/src/Selector/Selector.tsx +5 -1
  351. package/src/Selector/SelectorOption.doc.mjs +1 -1
  352. package/src/Selector/hooks.ts +17 -0
  353. package/src/SideNav/SideNav.test.tsx +119 -3
  354. package/src/SideNav/SideNavCollapseButton.tsx +6 -1
  355. package/src/SideNav/SideNavHeading.tsx +24 -8
  356. package/src/SideNav/SideNavItem.doc.mjs +2 -2
  357. package/src/SideNav/SideNavItem.tsx +5 -1
  358. package/src/Slider/Slider.test.tsx +62 -2
  359. package/src/Slider/Slider.tsx +15 -1
  360. package/src/Switch/Switch.doc.mjs +1 -1
  361. package/src/Switch/Switch.test.tsx +32 -1
  362. package/src/TabList/Tab.tsx +5 -1
  363. package/src/TabList/TabList.doc.mjs +3 -3
  364. package/src/TabList/TabList.test.tsx +66 -0
  365. package/src/TabList/TabList.tsx +8 -0
  366. package/src/TabList/TabMenu.tsx +4 -1
  367. package/src/Table/Table.doc.mjs +2 -0
  368. package/src/Table/Table.tsx +1 -1
  369. package/src/Table/index.ts +12 -0
  370. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +6 -2
  371. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +90 -1
  372. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +37 -5
  373. package/src/Table/plugins/rowStatus/index.ts +7 -0
  374. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +138 -0
  375. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +189 -0
  376. package/src/Table/plugins/selection/useTableSelection.test.tsx +16 -0
  377. package/src/Table/plugins/selection/useTableSelection.tsx +18 -1
  378. package/src/Table/plugins/sortable/useTableSortable.test.tsx +95 -9
  379. package/src/Table/plugins/sortable/useTableSortable.tsx +23 -7
  380. package/src/Table/plugins/tree/index.ts +12 -0
  381. package/src/Table/plugins/tree/useTableTreeData-perf.test.tsx +163 -0
  382. package/src/Table/plugins/tree/useTableTreeData.test.tsx +594 -0
  383. package/src/Table/plugins/tree/useTableTreeData.tsx +495 -0
  384. package/src/Table/plugins/tree/useTableTreeState.test.tsx +636 -0
  385. package/src/Table/plugins/tree/useTableTreeState.tsx +253 -0
  386. package/src/Table/useBaseTablePlugins.ts +6 -2
  387. package/src/Table/useTableRowStatus.doc.mjs +30 -0
  388. package/src/Table/useTableSelection.doc.mjs +65 -14
  389. package/src/Table/useTableTreeData.doc.mjs +75 -0
  390. package/src/Table/useTableTreeState.doc.mjs +98 -0
  391. package/src/TextArea/TextArea.doc.mjs +1 -1
  392. package/src/TextArea/TextArea.test.tsx +9 -1
  393. package/src/TextInput/TextInput.doc.mjs +1 -1
  394. package/src/Thumbnail/Thumbnail.doc.mjs +9 -0
  395. package/src/Thumbnail/Thumbnail.test.tsx +38 -8
  396. package/src/Thumbnail/Thumbnail.tsx +28 -1
  397. package/src/TimeInput/TimeInput.test.tsx +76 -1
  398. package/src/TimeInput/TimeInput.tsx +19 -6
  399. package/src/Tokenizer/Tokenizer.doc.mjs +1 -1
  400. package/src/Tokenizer/Tokenizer.test.tsx +137 -2
  401. package/src/Tokenizer/Tokenizer.tsx +16 -4
  402. package/src/Toolbar/Toolbar.tsx +10 -3
  403. package/src/TopNav/TopNav.test.tsx +80 -1
  404. package/src/TopNav/TopNavHeading.tsx +24 -8
  405. package/src/TopNav/TopNavMegaMenu.test.tsx +149 -1
  406. package/src/TopNav/TopNavMegaMenu.tsx +10 -4
  407. package/src/TopNav/TopNavMenu.test.tsx +118 -4
  408. package/src/TopNav/TopNavMenu.tsx +83 -5
  409. package/src/TreeList/TreeList.test.tsx +32 -1
  410. package/src/TreeList/TreeListItem.tsx +19 -10
  411. package/src/authoring/doc.ts +1 -3
  412. package/src/docs-script.test.mjs +18 -13
  413. package/src/hooks/computeOverflow.test.ts +422 -0
  414. package/src/hooks/computeOverflow.ts +290 -0
  415. package/src/hooks/useOverflow.test.ts +96 -4
  416. package/src/hooks/useOverflow.ts +77 -33
  417. package/src/postinstall.test.mjs +71 -0
  418. package/src/theme/Theme.doc.mjs +4 -4
  419. package/src/theme/Theme.tsx +1 -1
  420. package/src/theme/defineTheme.ts +1 -1
  421. package/src/theme/generateThemeRules.test.ts +65 -0
  422. package/src/theme/generateThemeRules.ts +56 -0
  423. package/src/theme/hct.ts +0 -4
  424. package/src/utils/types.ts +14 -0
  425. package/dist/TreeList/treeListItem.markers.stylex.d.ts +0 -16
  426. package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +0 -1
  427. package/dist/TreeList/treeListItem.markers.stylex.js +0 -22
  428. package/src/TreeList/treeListItem.markers.stylex.ts +0 -20
@@ -0,0 +1,10 @@
1
+ {
2
+ "@astryx.pagination.previous": {
3
+ "defaultMessage": "Aller à la page précédente",
4
+ "description": "Aria label for the previous-page button."
5
+ },
6
+ "@astryx.pagination.next": {
7
+ "defaultMessage": "Aller à la page suivante",
8
+ "description": "Aria label for the next-page button."
9
+ }
10
+ }
@@ -197,6 +197,9 @@
197
197
  "@astryx.carousel.scrollRight": {
198
198
  "defaultMessage": "⟦Šçřółł říĝĥţ⟧"
199
199
  },
200
+ "@astryx.carousel.slideLabel": {
201
+ "defaultMessage": "⟦Šłíðé {current, number} óƒ {total, number}⟧"
202
+ },
200
203
  "@astryx.chat.status.sending": {
201
204
  "defaultMessage": "⟦Šéñðíñĝ⟧"
202
205
  },
@@ -308,6 +311,9 @@
308
311
  "@astryx.table.selection.selectRow": {
309
312
  "defaultMessage": "⟦Šéłéçţ řóŵ⟧"
310
313
  },
314
+ "@astryx.table.selection.selectRowNamed": {
315
+ "defaultMessage": "⟦Šéłéçţ {label}⟧"
316
+ },
311
317
  "@astryx.table.sort.ascending": {
312
318
  "defaultMessage": "⟦Šóřţ àšçéñðíñĝ⟧"
313
319
  },
@@ -317,6 +323,21 @@
317
323
  "@astryx.table.sort.clear": {
318
324
  "defaultMessage": "⟦Çłéàř šóřţ⟧"
319
325
  },
326
+ "@astryx.table.sort.direction.ascending": {
327
+ "defaultMessage": "⟦àšçéñðíñĝ⟧"
328
+ },
329
+ "@astryx.table.sort.direction.descending": {
330
+ "defaultMessage": "⟦ðéšçéñðíñĝ⟧"
331
+ },
332
+ "@astryx.table.sort.sortBy": {
333
+ "defaultMessage": "⟦Šóřţ ƀý {label}⟧"
334
+ },
335
+ "@astryx.table.sort.sortedBy": {
336
+ "defaultMessage": "⟦Šóřţ ƀý {label}, šóřţéð {direction}⟧"
337
+ },
338
+ "@astryx.table.sort.sortedByWithPriority": {
339
+ "defaultMessage": "⟦Šóřţ ƀý {label}, šóřţéð {direction}, þříóříţý {rank, number} óƒ {total, number}⟧"
340
+ },
320
341
  "@astryx.toast.dismiss": {
321
342
  "defaultMessage": "⟦Ðíšɱíšš ñóţíƒíçàţíóñ⟧"
322
343
  },
@@ -494,6 +515,9 @@
494
515
  "@astryx.fileInput.clearLabel": {
495
516
  "defaultMessage": "⟦Çłéàř {label}⟧"
496
517
  },
518
+ "@astryx.fileInput.triggerWithFiles": {
519
+ "defaultMessage": "⟦{label}, {fileNames}⟧"
520
+ },
497
521
  "@astryx.lightbox.mediaViewer": {
498
522
  "defaultMessage": "⟦Ṁéðíà ṽíéŵéř⟧"
499
523
  },
@@ -542,6 +566,12 @@
542
566
  "@astryx.tableRowExpansion.expandAllRows": {
543
567
  "defaultMessage": "⟦Éẋþàñð àłł řóŵš⟧"
544
568
  },
569
+ "@astryx.tableTree.collapseRow": {
570
+ "defaultMessage": "⟦Çółłàþšé řóŵ⟧"
571
+ },
572
+ "@astryx.tableTree.expandRow": {
573
+ "defaultMessage": "⟦Éẋþàñð řóŵ⟧"
574
+ },
545
575
  "@astryx.textInput.clearLabel": {
546
576
  "defaultMessage": "⟦Çłéàř {label}⟧"
547
577
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/core",
3
- "version": "0.1.7",
3
+ "version": "0.1.8-canary.0c4d8d7",
4
4
  "displayName": "Astryx Core",
5
5
  "description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
6
6
  "author": "Meta Open Source",
@@ -636,6 +636,7 @@
636
636
  "files": [
637
637
  "dist",
638
638
  "src",
639
+ "scripts/postinstall.mjs",
639
640
  "locales",
640
641
  "docs.mjs",
641
642
  "groups.doc.mjs",
@@ -662,6 +663,7 @@
662
663
  "intl-messageformat": "^11.2.9"
663
664
  },
664
665
  "scripts": {
666
+ "postinstall": "node scripts/postinstall.mjs",
665
667
  "build": "rimraf dist && pnpm build:i18n && pnpm build:esm && tsc --project tsconfig.build.json && pnpm build:css && pnpm build:umd && node ../../scripts/check-no-dev-jsx.mjs",
666
668
  "build:i18n": "node scripts/build-pseudo-locale.mjs",
667
669
  "build:esm": "babel src --out-dir dist --extensions .ts,.tsx --out-file-extension .js --ignore \"**/*.test.ts,**/*.test.tsx,**/__tests__/**,**/*.perf.test.*,**/*.doc.mjs,**/*.d.ts,**/*.css,**/*.css.d.ts\" --config-file ./babel.config.json",
@@ -0,0 +1,93 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file @astryxdesign/core postinstall — nudge to run `npx @astryxdesign/cli init`.
5
+ *
6
+ * Enforcement layer 1 of making `astryx init` foolproof: when the design system
7
+ * is installed and the project hasn't run init yet, print a one-line next-step
8
+ * so agents/humans discover it (this is the most common fresh-install entry).
9
+ *
10
+ * Self-contained: core is a separate package and cannot import the CLI, so the
11
+ * agent-doc locations + marker below intentionally DUPLICATE the CLI's agent-doc
12
+ * discovery in packages/cli/src/commands/agent-docs.mjs — keep them aligned with
13
+ * that file. The .hermes.md / HERMES.md entries are an intentional superset (the
14
+ * CLI writes those via `--agent hermes`). Non-interactive, never fails the
15
+ * install, and quiet in the monorepo build, during npx's fetch, and once set up.
16
+ */
17
+
18
+ import fs from 'node:fs';
19
+ import path from 'node:path';
20
+ import {fileURLToPath, pathToFileURL} from 'node:url';
21
+
22
+ const HERE = fileURLToPath(import.meta.url);
23
+
24
+ // Duplicates the CLI's agent-doc locations + markers — keep aligned with
25
+ // packages/cli/src/commands/agent-docs.mjs. Hermes files are an intentional superset.
26
+ const AGENT_DOC_PATHS = [
27
+ 'AGENTS.md',
28
+ 'CLAUDE.md',
29
+ '.claude/CLAUDE.md',
30
+ '.cursorrules',
31
+ '.hermes.md',
32
+ 'HERMES.md',
33
+ ];
34
+ const MARKERS = ['<!-- ASTRYX:START -->', '<!-- XDS:START -->'];
35
+
36
+ /**
37
+ * True when the project already has the Astryx agent prompt installed (an Astryx
38
+ * marker is present in any agent-doc file) — the same check the CLI performs.
39
+ * @param {string} root @returns {boolean}
40
+ */
41
+ export function isAstryxInitialized(root) {
42
+ for (const rel of AGENT_DOC_PATHS) {
43
+ try {
44
+ const content = fs.readFileSync(path.join(root, rel), 'utf-8');
45
+ if (MARKERS.some(m => content.includes(m))) return true;
46
+ } catch {
47
+ // Unreadable/missing — keep checking the others.
48
+ }
49
+ }
50
+ return false;
51
+ }
52
+
53
+ /**
54
+ * Pure decision: should the postinstall print the setup nudge? Unit-testable
55
+ * without an actual npm install.
56
+ * @returns {boolean}
57
+ */
58
+ export function shouldNudge({scriptPath, npmCommand, isSetUp} = {}) {
59
+ if (!scriptPath || !scriptPath.includes('node_modules')) return false; // monorepo/source build
60
+ if (scriptPath.includes('_npx') || npmCommand === 'exec') return false; // npx transient
61
+ if (isSetUp) return false; // already set up — stay quiet
62
+ return true;
63
+ }
64
+
65
+ function main() {
66
+ const root = process.env.INIT_CWD || process.cwd();
67
+ if (
68
+ shouldNudge({
69
+ scriptPath: HERE,
70
+ npmCommand: process.env.npm_command,
71
+ isSetUp: isAstryxInitialized(root),
72
+ })
73
+ ) {
74
+ // Scoped package form (`@astryxdesign/cli`) — always resolves to us, even
75
+ // before the CLI is installed. Bare `npx astryx` would fetch an unrelated
76
+ // look-alike package (see PR #4151). After that lands, switch this to its
77
+ // getCliInvocation() single source of truth.
78
+ process.stdout.write(
79
+ '\nNext step: run `npx @astryxdesign/cli init` to finish setup and install the Astryx agent prompt.\n\n',
80
+ );
81
+ }
82
+ }
83
+
84
+ // Run only when executed directly (`node scripts/postinstall.mjs`), never when
85
+ // imported by tests.
86
+ if (import.meta.url === pathToFileURL(process.argv[1] || '').href) {
87
+ try {
88
+ main();
89
+ } catch {
90
+ // never break an install
91
+ }
92
+ process.exit(0);
93
+ }
@@ -24,6 +24,7 @@ import {
24
24
  isValidElement,
25
25
  useCallback,
26
26
  useEffect,
27
+ useId,
27
28
  useMemo,
28
29
  useRef,
29
30
  useState,
@@ -600,10 +601,14 @@ export function AppShell({
600
601
  // =========================================================================
601
602
  // Mobile context — shared with MobileNavToggle and future TopNav mobile
602
603
  // =========================================================================
604
+ // Stable id shared by the drawer (applied as its `id`) and the toggle
605
+ // (referenced via `aria-controls`) so screen readers know what it controls.
606
+ const mobileNavId = useId();
603
607
  const mobileContextValue = useMemo<AppShellMobileContextValue>(
604
608
  () => ({
605
609
  isMobile: isBelowBreakpoint,
606
610
  isMobileNavOpen,
611
+ mobileNavId,
607
612
  toggleMobileNav: () =>
608
613
  mobileNavEnabled && setMobileNavOpen(!isMobileNavOpen),
609
614
  openMobileNav: () => mobileNavEnabled && setMobileNavOpen(true),
@@ -614,6 +619,7 @@ export function AppShell({
614
619
  [
615
620
  isBelowBreakpoint,
616
621
  isMobileNavOpen,
622
+ mobileNavId,
617
623
  setMobileNavOpen,
618
624
  mobileNavEnabled,
619
625
  mobileNavHasToggle,
@@ -20,6 +20,14 @@ export interface AppShellMobileContextValue {
20
20
  isMobile: boolean;
21
21
  /** Whether the mobile nav drawer is currently open */
22
22
  isMobileNavOpen: boolean;
23
+ /**
24
+ * DOM id of the mobile nav drawer. `AppShell` sets this so the toggle can
25
+ * point its `aria-controls` at the drawer and the drawer can apply it as its
26
+ * `id`. Optional: callers that construct this context by hand may omit it, in
27
+ * which case `MobileNav` falls back to a locally generated id and the toggle
28
+ * simply drops `aria-controls`.
29
+ */
30
+ mobileNavId?: string;
23
31
  /** Toggle the mobile nav drawer open/closed */
24
32
  toggleMobileNav: () => void;
25
33
  /** Open the mobile nav drawer */
@@ -31,6 +31,12 @@ export const docs = {
31
31
  description:
32
32
  'Whether the AppShell-managed mobile navigation drawer is open.',
33
33
  },
34
+ {
35
+ name: 'mobileNavId',
36
+ type: 'string | undefined',
37
+ description:
38
+ 'DOM id of the mobile navigation drawer, set by AppShell. Point aria-controls of a custom toggle at this so screen-reader users know which element the toggle expands. Undefined outside an AppShell that manages the drawer.',
39
+ },
34
40
  {
35
41
  name: 'toggleMobileNav',
36
42
  type: '() => void',
@@ -111,6 +117,8 @@ export const docsDense = {
111
117
  isMobile:
112
118
  'viewport below AppShell mobile nav breakpoint? Use to sync AppShell-adjacent mobile UI',
113
119
  isMobileNavOpen: 'AppShell-managed mobile nav drawer open?',
120
+ mobileNavId:
121
+ 'DOM id of the drawer; point custom toggle aria-controls at it',
114
122
  toggleMobileNav: 'toggle drawer; no-op when mobile nav disabled',
115
123
  openMobileNav: 'open drawer; no-op when mobile nav disabled',
116
124
  closeMobileNav: 'close drawer',
@@ -13,7 +13,7 @@ export const docs = {
13
13
  'Avatar represents a person or team with a profile photo, initials, or a default icon. Use it in comment headers, contact lists, chat messages, user cards, and anywhere you need to identify someone visually.',
14
14
  bestPractices: [
15
15
  {guidance: true, description: 'Always pass a name so the avatar can show initials if the photo fails to load, and so screen readers can announce who it represents.'},
16
- {guidance: true, description: 'Pick a size that matches the context: tiny or xsmall for inline mentions, small or medium for lists and cards, large for profile headers.'},
16
+ {guidance: true, description: 'Pick a size that matches the context: xsm or sm for inline mentions, md or lg for lists and cards, xl for profile headers.'},
17
17
  {guidance: true, description: 'Add a status dot when knowing someone\'s availability matters, like in chat or team views.'},
18
18
  {guidance: false, description: 'Use Avatar for logos, product images, or anything that isn\'t a person or team. Use an image or icon instead.'},
19
19
  {guidance: false, description: 'Force a square or custom shape. Avatars are always circular to stay consistent across the system.'},
@@ -55,9 +55,9 @@ export const docs = {
55
55
  },
56
56
  {
57
57
  name: 'size',
58
- type: "'tiny' | 'xsmall' | 'small' | 'medium' | 'large' | number",
59
- description: "Avatar size. Use a named size ('tiny', 'xsmall', 'small', 'medium', 'large') or a numeric pixel value. Note: short names like 'sm', 'md', 'lg' are NOT valid; use the full words.",
60
- default: "'small'",
58
+ type: "'xsm' | 'sm' | 'md' | 'lg' | 'xl' | number",
59
+ description: "Avatar size. Use a named size ('xsm' 20px, 'sm' 24px, 'md' 36px, 'lg' 48px, 'xl' 128px) or a numeric pixel value. Avatar shares Icon's abbreviated scale, but its tiers are larger because avatars align with media rather than glyphs.",
60
+ default: "'md'",
61
61
  },
62
62
  {
63
63
  name: 'status',
@@ -100,7 +100,7 @@ export const docsDense = {
100
100
  'Avatar represents a person or team with a profile photo, initials, or a default icon. Falls back automatically. Use in comment headers, contact lists, chat, user cards.',
101
101
  bestPractices: [
102
102
  {guidance: true, description: 'Always pass a name for initials fallback and screen reader alt text.'},
103
- {guidance: true, description: 'Match size to context: tiny/xsmall inline, small/medium in lists, large for profiles.'},
103
+ {guidance: true, description: 'Match size to context: xsm/sm inline, md/lg in lists, xl for profiles.'},
104
104
  {guidance: true, description: 'Add a status dot in chat or team views where availability matters.'},
105
105
  {guidance: false, description: 'Use for logos or product images. Use an image or icon instead.'},
106
106
  {guidance: false, description: 'Force a square or custom shape. Avatars are always circular.'},
@@ -111,7 +111,7 @@ export const docsDense = {
111
111
  fallbackSrc: 'fallback image when primary fails',
112
112
  name: 'user name for initials and alt text',
113
113
  alt: 'alt text; falls back to name',
114
- size: "avatar size. Named ('tiny', 'xsmall', 'small', 'medium', 'large') or numeric px. Short names 'sm'/'md'/'lg' are NOT valid; use full words.",
114
+ size: "avatar size. Named ('xsm' 20px, 'sm' 24px, 'md' 36px, 'lg' 48px, 'xl' 128px) or numeric px.",
115
115
  status: 'corner content for status indicators',
116
116
  },
117
117
  components: [
@@ -55,9 +55,13 @@ const CIRCLE_EDGE_OFFSET_RATIO = (1 - 1 / Math.SQRT2) / 2;
55
55
  const INITIALS_FONT_SIZE_RATIO = 0.4;
56
56
 
57
57
  /**
58
- * Named size options
58
+ * Named size options.
59
+ *
60
+ * Avatar uses the same abbreviated scale as Icon (`xsm`/`sm`/`md`/`lg`/`xl`),
61
+ * but the values are larger because avatars align with media rather than
62
+ * glyphs. The tiers match EPS's avatar sizes.
59
63
  */
60
- type AvatarNamedSize = 'tiny' | 'xsmall' | 'small' | 'medium' | 'large';
64
+ type AvatarNamedSize = 'xsm' | 'sm' | 'md' | 'lg' | 'xl';
61
65
 
62
66
  /**
63
67
  * Numeric size options (in pixels)
@@ -78,15 +82,15 @@ export function resolveSize(size: AvatarSize): number {
78
82
  return size;
79
83
  }
80
84
  switch (size) {
81
- case 'tiny':
85
+ case 'xsm':
82
86
  return 20;
83
- case 'xsmall':
87
+ case 'sm':
84
88
  return 24;
85
- case 'small':
89
+ case 'md':
86
90
  return 36;
87
- case 'medium':
91
+ case 'lg':
88
92
  return 48;
89
- case 'large':
93
+ case 'xl':
90
94
  return 128;
91
95
  }
92
96
  }
@@ -198,8 +202,9 @@ export interface AvatarProps extends BaseProps<HTMLDivElement> {
198
202
  */
199
203
  name?: string;
200
204
  /**
201
- * The size of the avatar.
202
- * @default 'small'
205
+ * The size of the avatar. A named size (`xsm` 20px, `sm` 24px, `md` 36px,
206
+ * `lg` 48px, `xl` 128px) or a specific pixel value.
207
+ * @default 'md'
203
208
  */
204
209
  size?: AvatarSize;
205
210
  /**
@@ -258,7 +263,7 @@ function DefaultIcon({size}: {size: number}) {
258
263
  * @example
259
264
  * ```
260
265
  * <Avatar src="/user.jpg" name="John Doe" />
261
- * <Avatar name="Jane Smith" size="large" />
266
+ * <Avatar name="Jane Smith" size="xl" />
262
267
  * <Avatar src="/user.jpg" status={<OnlineIndicator />} />
263
268
  * ```
264
269
  */
@@ -267,7 +272,7 @@ export function Avatar({
267
272
  'data-testid': testId,
268
273
  fallbackSrc,
269
274
  name,
270
- size = 'small',
275
+ size = 'md',
271
276
  src,
272
277
  status,
273
278
  xstyle,
@@ -18,7 +18,7 @@ import {createContext} from 'react';
18
18
  * Context that provides the resolved numeric avatar size (in pixels)
19
19
  * to child components like AvatarStatusDot.
20
20
  *
21
- * Default value of 36 matches the default 'small' avatar size.
21
+ * Default value of 36 matches the default 'md' avatar size.
22
22
  */
23
23
  export const AvatarSizeContext = createContext<number>(36);
24
24
  AvatarSizeContext.displayName = 'AvatarSizeContext';
@@ -168,12 +168,12 @@ const variantStyleMap: Partial<
168
168
  * ```
169
169
  * <Avatar
170
170
  * name="John Doe"
171
- * size="medium"
171
+ * size="lg"
172
172
  * status={<AvatarStatusDot variant="success" label="Online" />}
173
173
  * />
174
174
  * <Avatar
175
175
  * name="Jane Smith"
176
- * size="large"
176
+ * size="xl"
177
177
  * status={<AvatarStatusDot variant="success" label="Verified" icon={<CheckIcon />} />}
178
178
  * />
179
179
  * ```
@@ -47,7 +47,7 @@ export const docs = {
47
47
  name: 'size',
48
48
  type: 'AvatarSize',
49
49
  description: 'Size applied to all avatars via context.',
50
- default: "'small'",
50
+ default: "'md'",
51
51
  },
52
52
  {
53
53
  name: 'ref',
@@ -56,14 +56,14 @@ describe('AvatarGroup', () => {
56
56
 
57
57
  it('applies size class to the group', () => {
58
58
  render(
59
- <AvatarGroup size="medium">
59
+ <AvatarGroup size="lg">
60
60
  <Avatar name="Alice" />
61
61
  </AvatarGroup>,
62
62
  );
63
63
 
64
64
  const group = screen.getByRole('group');
65
65
  expect(group.className).toContain('astryx-avatar-group');
66
- expect(group.className).toContain('medium');
66
+ expect(group.className).toContain('lg');
67
67
  });
68
68
 
69
69
  it('renders empty group when no children', () => {
@@ -134,7 +134,7 @@ describe('AvatarGroupOverflow', () => {
134
134
  const visibleCount = 3;
135
135
 
136
136
  render(
137
- <AvatarGroup size="medium">
137
+ <AvatarGroup size="lg">
138
138
  {users.slice(0, visibleCount).map(name => (
139
139
  <Avatar key={name} name={name} />
140
140
  ))}
@@ -211,4 +211,18 @@ describe('AvatarGroupOverflow — hardening', () => {
211
211
 
212
212
  expect(screen.getByText('+999')).toBeInTheDocument();
213
213
  });
214
+
215
+ it('renders the full "+N" text for wide multi-digit counts', () => {
216
+ // The indicator grows into a pill for long counts, so the entire number
217
+ // must remain present (nothing clipped away in the DOM).
218
+ render(
219
+ <AvatarGroup>
220
+ <Avatar name="Alice" />
221
+ <AvatarGroupOverflow count={4912} />
222
+ </AvatarGroup>,
223
+ );
224
+
225
+ expect(screen.getByText('+4912')).toBeInTheDocument();
226
+ expect(screen.getByLabelText('4912 more')).toBeInTheDocument();
227
+ });
214
228
  });
@@ -39,7 +39,7 @@ export interface AvatarGroupProps extends BaseProps<HTMLDivElement> {
39
39
  children: ReactNode;
40
40
  /**
41
41
  * Size applied to all avatars via context.
42
- * @default 'small'
42
+ * @default 'md'
43
43
  */
44
44
  size?: AvatarSize;
45
45
  /**
@@ -65,7 +65,7 @@ const styles = stylex.create({
65
65
  *
66
66
  * @example
67
67
  * ```
68
- * <AvatarGroup size="medium">
68
+ * <AvatarGroup size="lg">
69
69
  * {users.slice(0, 3).map(u => (
70
70
  * <Avatar key={u.id} src={u.src} name={u.name} />
71
71
  * ))}
@@ -75,7 +75,7 @@ const styles = stylex.create({
75
75
  */
76
76
  export function AvatarGroup({
77
77
  children,
78
- size = 'small',
78
+ size = 'md',
79
79
  'data-testid': testId,
80
80
  'aria-label': ariaLabelFromProps,
81
81
  xstyle,
@@ -51,7 +51,7 @@ export const docs = {
51
51
  'AvatarGroupOverflow appears at the end of an AvatarGroup to summarize people who are not shown individually. Use it when a group is sliced to a small number of visible avatars but the hidden count still matters.',
52
52
  bestPractices: [
53
53
  {guidance: true, description: 'Pass the real hidden count to `count` so the accessible label matches the visible indicator.'},
54
- {guidance: true, description: 'Use short custom text such as `+12` or `99+`; the indicator is sized like an avatar.'},
54
+ {guidance: true, description: 'Use short custom text such as `+12` or `99+`. The indicator is circular for short counts and grows into a pill for wider counts so the number always fits.'},
55
55
  {guidance: true, description: 'Provide `onClick` when the overflow opens a member list, popover, or detail view.'},
56
56
  {guidance: false, description: 'Do not use long labels inside the indicator; place longer participant details next to the group instead.'},
57
57
  ],
@@ -64,7 +64,7 @@ export const docs = {
64
64
  {
65
65
  label: 'Default overflow count',
66
66
  code: `
67
- <AvatarGroup size="medium">
67
+ <AvatarGroup size="lg">
68
68
  {users.slice(0, 3).map(user => (
69
69
  <Avatar key={user.id} src={user.src} name={user.name} />
70
70
  ))}
@@ -75,7 +75,7 @@ export const docs = {
75
75
  {
76
76
  label: 'Custom count text',
77
77
  code: `
78
- <AvatarGroup size="medium">
78
+ <AvatarGroup size="lg">
79
79
  {users.slice(0, 3).map(user => (
80
80
  <Avatar key={user.id} src={user.src} name={user.name} />
81
81
  ))}
@@ -104,7 +104,7 @@ export const docsZh = {
104
104
  'AvatarGroupOverflow 显示在 AvatarGroup 末尾,用来汇总未单独展示的成员。适用于只展示少量头像但仍需要显示隐藏数量的场景。',
105
105
  bestPractices: [
106
106
  {guidance: true, description: '向 `count` 传入真实隐藏数量,确保无障碍标签与可见指示器一致。'},
107
- {guidance: true, description: '使用 `+12` 或 `99+` 等短文本;指示器尺寸与头像相同。'},
107
+ {guidance: true, description: '使用 `+12` 或 `99+` 等短文本;指示器在计数较短时为圆形,计数较宽时会拉伸为胶囊形,确保数字始终完整显示。'},
108
108
  {guidance: true, description: '当溢出项会打开成员列表、弹出层或详情视图时提供 `onClick`。'},
109
109
  {guidance: false, description: '不要在指示器内使用长标签;更长的参与者详情应放在头像组旁边。'},
110
110
  ],
@@ -20,6 +20,7 @@ import {
20
20
  typographyVars,
21
21
  fontWeightVars,
22
22
  radiusVars,
23
+ spacingVars,
23
24
  } from '../theme/tokens.stylex';
24
25
  import {mergeProps} from '../utils';
25
26
  import {useAvatarGroup} from './AvatarGroupContext';
@@ -67,13 +68,21 @@ const styles = stylex.create({
67
68
  borderWidth: BORDER_WIDTH,
68
69
  borderStyle: 'solid',
69
70
  borderColor: colorVars['--color-background-surface'],
70
- boxSizing: 'content-box',
71
+ // border-box so the border and inline padding are included in the box
72
+ // size: a short "+N" stays a circle at exactly the avatar size, while
73
+ // longer content pushes past the min width and grows into a pill.
74
+ boxSizing: 'border-box',
75
+ // Horizontal breathing room so multi-digit "+N" counts don't crowd the
76
+ // edges once the indicator grows into a pill.
77
+ paddingInline: spacingVars['--spacing-2'],
71
78
  // Neutral tint layer (preserves opaque base underneath)
72
79
  backgroundImage: `linear-gradient(${colorVars['--color-neutral']}, ${colorVars['--color-neutral']})`,
73
80
  },
74
81
  button: {
75
82
  cursor: 'pointer',
76
- padding: 0,
83
+ // Reset the UA button's block padding only; the inline padding from `base`
84
+ // provides the pill's breathing room and must be preserved.
85
+ paddingBlock: 0,
77
86
  // Interactive overlay states layered on top via backgroundImage
78
87
  backgroundImage: {
79
88
  default: `linear-gradient(${colorVars['--color-neutral']}, ${colorVars['--color-neutral']})`,
@@ -99,8 +108,15 @@ const styles = stylex.create({
99
108
 
100
109
  const dynamicStyles = stylex.create({
101
110
  size: (s: number) => ({
102
- width: s,
103
- height: s,
111
+ // Pin height to the avatar's rendered size and enforce the same value as a
112
+ // *minimum* width, so short counts (`+5`) render a perfect circle. With
113
+ // border-box, the inline padding lives inside this size; longer content
114
+ // (`+4912`) pushes past the min width and grows into a stadium/pill.
115
+ // The border is added to the declared size (like the avatars' ring, which
116
+ // uses content-box + a 2px border) to keep the indicator the same overall
117
+ // size as its sibling avatars.
118
+ minWidth: s + BORDER_WIDTH * 2,
119
+ height: s + BORDER_WIDTH * 2,
104
120
  }),
105
121
  fontSize: (s: number) => ({
106
122
  fontSize: s * OVERFLOW_FONT_RATIO,
@@ -116,7 +132,7 @@ const dynamicStyles = stylex.create({
116
132
  *
117
133
  * @example
118
134
  * ```
119
- * <AvatarGroup size="medium">
135
+ * <AvatarGroup size="lg">
120
136
  * {users.slice(0, 3).map(u => (
121
137
  * <Avatar key={u.id} src={u.src} name={u.name} />
122
138
  * ))}
@@ -81,6 +81,13 @@ export const docs = {
81
81
  'Container type: card has border-radius; section is full-width with no border-radius for page-level use.',
82
82
  default: "'card'",
83
83
  },
84
+ {
85
+ name: 'elevation',
86
+ type: "'none' | 'low' | 'med' | 'high'",
87
+ description:
88
+ 'Resting shadow depth. Use for a floating banner that hovers above content; `none` is the default inline banner. A `card`-container banner rounds its shadow to match.',
89
+ default: "'none'",
90
+ },
84
91
  {
85
92
  name: 'children',
86
93
  type: 'ReactNode',
@@ -157,6 +164,7 @@ export const docsZh = {
157
164
  {name: 'onDismiss', type: '() => void', description: '点击关闭按钮时调用;无论是否提供此回调,横幅都会自动隐藏。'},
158
165
  {name: 'endContent', type: 'ReactNode', description: '渲染在头部区域末端对齐的操作内容,通常是按钮或链接。'},
159
166
  {name: 'container', type: "'card' | 'section'", description: '视觉变体:card 带圆角;section 无圆角全宽,适用于页面级场景。', default: "'card'"},
167
+ {name: 'elevation', type: "'none' | 'low' | 'med' | 'high'", description: '静止阴影深度。用于悬浮于内容之上的浮动横幅;none 为默认内联横幅。', default: "'none'"},
160
168
  {name: 'children', type: 'ReactNode', description: '渲染在彩色头部下方卡片背景区域的内容。'},
161
169
  {name: 'defaultIsExpanded', type: 'boolean', description: '内容区域(children)是否初始展开。仅在提供 children 时相关。', default: 'false'},
162
170
  {
@@ -230,6 +238,7 @@ export const docsDense = {
230
238
  onDismiss: 'dismiss callback; banner self-hides regardless',
231
239
  endContent: 'end-aligned action in header, typically button/link',
232
240
  container: 'card=border-radius; section=full-width no radius for page-level',
241
+ elevation: 'resting shadow depth: none|low|med|high; raise for a floating banner',
233
242
  children: 'content in card-bg area below colored header',
234
243
  xstyle: 'StyleX layout customization via stylex.create()',
235
244
  },
@@ -368,4 +368,34 @@ describe('Banner', () => {
368
368
  );
369
369
  expect(screen.getByTestId('custom-chevron')).toBeInTheDocument();
370
370
  });
371
+
372
+ describe('elevation', () => {
373
+ it('renders a distinct root class for each elevation level', () => {
374
+ const classFor = (elevation: 'none' | 'low' | 'med' | 'high') => {
375
+ const {container} = render(
376
+ <Banner status="info" title="Heads up" elevation={elevation} />,
377
+ );
378
+ return container.firstElementChild!.className;
379
+ };
380
+ const classes = new Set([
381
+ classFor('none'),
382
+ classFor('low'),
383
+ classFor('med'),
384
+ classFor('high'),
385
+ ]);
386
+ expect(classes.size).toBe(4);
387
+ });
388
+
389
+ it('defaults to flat (elevation none)', () => {
390
+ const {container: def} = render(
391
+ <Banner status="info" title="Heads up" />,
392
+ );
393
+ const {container: none} = render(
394
+ <Banner status="info" title="Heads up" elevation="none" />,
395
+ );
396
+ expect(def.firstElementChild!.className).toBe(
397
+ none.firstElementChild!.className,
398
+ );
399
+ });
400
+ });
371
401
  });