@astryxdesign/core 0.1.8 → 0.1.9-canary.75d2d03

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 (512) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/dist/AppShell/AppShell.d.ts.map +1 -1
  3. package/dist/AppShell/AppShell.js +6 -2
  4. package/dist/AppShell/AppShellMobileContext.d.ts +8 -0
  5. package/dist/AppShell/AppShellMobileContext.d.ts.map +1 -1
  6. package/dist/Avatar/Avatar.d.ts +18 -2
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +63 -7
  9. package/dist/Avatar/AvatarStatusDot.d.ts +33 -5
  10. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  11. package/dist/Avatar/AvatarStatusDot.js +144 -19
  12. package/dist/Banner/Banner.d.ts +9 -1
  13. package/dist/Banner/Banner.d.ts.map +1 -1
  14. package/dist/Banner/Banner.js +31 -2
  15. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +31 -2
  16. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  17. package/dist/Breadcrumbs/BreadcrumbItem.js +208 -6
  18. package/dist/Breadcrumbs/index.d.ts +5 -0
  19. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  20. package/dist/Breadcrumbs/index.js +9 -1
  21. package/dist/Button/Button.d.ts +8 -2
  22. package/dist/Button/Button.d.ts.map +1 -1
  23. package/dist/Button/Button.js +31 -2
  24. package/dist/ButtonGroup/ButtonGroup.d.ts +9 -1
  25. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  26. package/dist/ButtonGroup/ButtonGroup.js +30 -1
  27. package/dist/Calendar/Calendar.d.ts.map +1 -1
  28. package/dist/Calendar/Calendar.js +30 -2
  29. package/dist/Calendar/dayCellUtils.js +1 -1
  30. package/dist/Card/Card.d.ts +8 -2
  31. package/dist/Card/Card.d.ts.map +1 -1
  32. package/dist/Card/Card.js +28 -2
  33. package/dist/Carousel/Carousel.d.ts +4 -1
  34. package/dist/Carousel/Carousel.d.ts.map +1 -1
  35. package/dist/Carousel/Carousel.js +24 -4
  36. package/dist/Chat/ChatComposer.d.ts +8 -0
  37. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  38. package/dist/Chat/ChatComposer.js +46 -7
  39. package/dist/Chat/ChatComposerDrawer.d.ts +2 -0
  40. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  41. package/dist/Chat/ChatComposerDrawer.js +11 -1
  42. package/dist/Chat/ChatComposerInput.d.ts +20 -3
  43. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  44. package/dist/Chat/ChatComposerInput.js +35 -3
  45. package/dist/Chat/ChatContext.d.ts +33 -0
  46. package/dist/Chat/ChatContext.d.ts.map +1 -1
  47. package/dist/Chat/ChatContext.js +16 -2
  48. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  49. package/dist/Chat/ChatDictationButton.js +1 -1
  50. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  51. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  52. package/dist/Chat/ChatLayoutScrollButton.js +4 -4
  53. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  54. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  55. package/dist/Chat/ChatSendButton.js +7 -1
  56. package/dist/Chat/ChatToolCalls.d.ts +5 -1
  57. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  58. package/dist/Chat/ChatToolCalls.js +18 -9
  59. package/dist/Chat/index.d.ts +2 -1
  60. package/dist/Chat/index.d.ts.map +1 -1
  61. package/dist/Chat/index.js +1 -1
  62. package/dist/Chat/useChatStreamScroll.d.ts +2 -1
  63. package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
  64. package/dist/Chat/useChatStreamScroll.js +22 -8
  65. package/dist/Chat/useSpeechRecognition.d.ts +0 -1
  66. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  67. package/dist/Chat/useSpeechRecognition.js +1 -1
  68. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  69. package/dist/CheckboxInput/CheckboxInput.js +1 -1
  70. package/dist/CheckboxList/CheckboxListItem.d.ts +20 -1
  71. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  72. package/dist/CheckboxList/CheckboxListItem.js +11 -1
  73. package/dist/ClickableCard/ClickableCard.d.ts +9 -2
  74. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  75. package/dist/ClickableCard/ClickableCard.js +5 -2
  76. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  77. package/dist/CodeBlock/CodeBlock.js +8 -1
  78. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  79. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  80. package/dist/CommandPalette/CommandPalette.js +3 -1
  81. package/dist/CommandPalette/CommandPaletteGroup.d.ts.map +1 -1
  82. package/dist/CommandPalette/CommandPaletteGroup.js +9 -2
  83. package/dist/CommandPalette/CommandPaletteInput.d.ts +7 -1
  84. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  85. package/dist/CommandPalette/CommandPaletteInput.js +6 -1
  86. package/dist/DateInput/DateInput.d.ts +47 -1
  87. package/dist/DateInput/DateInput.d.ts.map +1 -1
  88. package/dist/DateInput/DateInput.js +26 -2
  89. package/dist/DateInput/index.d.ts +1 -1
  90. package/dist/DateInput/index.d.ts.map +1 -1
  91. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  92. package/dist/DateTimeInput/DateTimeInput.js +10 -1
  93. package/dist/Dialog/Dialog.d.ts +3 -0
  94. package/dist/Dialog/Dialog.d.ts.map +1 -1
  95. package/dist/Dialog/Dialog.js +57 -6
  96. package/dist/Dialog/DialogContext.d.ts +7 -0
  97. package/dist/Dialog/DialogContext.d.ts.map +1 -1
  98. package/dist/Dialog/DialogContext.js +2 -2
  99. package/dist/Dialog/DialogHeader.d.ts +5 -2
  100. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  101. package/dist/Dialog/DialogHeader.js +6 -1
  102. package/dist/Divider/Divider.js +1 -1
  103. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +1 -2
  104. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  105. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +1 -2
  106. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -2
  107. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  108. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -2
  109. package/dist/Field/Field.d.ts.map +1 -1
  110. package/dist/Field/Field.js +2 -3
  111. package/dist/Field/FieldLabel.d.ts +1 -1
  112. package/dist/Field/FieldLabel.d.ts.map +1 -1
  113. package/dist/Field/FieldLabel.js +42 -15
  114. package/dist/FieldStatus/FieldStatus.d.ts +8 -0
  115. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  116. package/dist/FieldStatus/FieldStatus.js +22 -4
  117. package/dist/FileInput/FileInput.d.ts.map +1 -1
  118. package/dist/FileInput/FileInput.js +10 -2
  119. package/dist/HoverCard/HoverCard.d.ts +9 -1
  120. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  121. package/dist/HoverCard/HoverCard.js +2 -0
  122. package/dist/HoverCard/useHoverCard.d.ts +8 -0
  123. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  124. package/dist/HoverCard/useHoverCard.js +7 -2
  125. package/dist/Icon/Icon.d.ts +7 -2
  126. package/dist/Icon/Icon.d.ts.map +1 -1
  127. package/dist/Item/Item.d.ts +6 -1
  128. package/dist/Item/Item.d.ts.map +1 -1
  129. package/dist/Item/Item.js +22 -1
  130. package/dist/Layer/useLayer.d.ts +6 -0
  131. package/dist/Layer/useLayer.d.ts.map +1 -1
  132. package/dist/Layer/useLayer.js +2 -0
  133. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  134. package/dist/MobileNav/MobileNav.js +6 -1
  135. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  136. package/dist/MobileNav/MobileNavToggle.js +4 -0
  137. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  138. package/dist/MultiSelector/MultiSelector.js +39 -12
  139. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  140. package/dist/MultiSelector/hooks.js +16 -0
  141. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  142. package/dist/Outline/Outline.d.ts +0 -1
  143. package/dist/Outline/Outline.d.ts.map +1 -1
  144. package/dist/Outline/Outline.js +0 -1
  145. package/dist/OverflowList/OverflowList.d.ts +20 -3
  146. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  147. package/dist/OverflowList/OverflowList.js +29 -4
  148. package/dist/Pagination/Pagination.d.ts.map +1 -1
  149. package/dist/Pagination/Pagination.js +11 -3
  150. package/dist/Popover/Popover.d.ts.map +1 -1
  151. package/dist/Popover/Popover.js +3 -2
  152. package/dist/Popover/usePopover.d.ts.map +1 -1
  153. package/dist/Popover/usePopover.js +3 -9
  154. package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
  155. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  156. package/dist/SelectableCard/SelectableCard.d.ts +9 -2
  157. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  158. package/dist/SelectableCard/SelectableCard.js +16 -13
  159. package/dist/Selector/Selector.d.ts.map +1 -1
  160. package/dist/Selector/Selector.js +4 -2
  161. package/dist/Selector/hooks.d.ts.map +1 -1
  162. package/dist/Selector/hooks.js +16 -0
  163. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  164. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  165. package/dist/SideNav/SideNavHeading.js +21 -8
  166. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  167. package/dist/Slider/Slider.d.ts.map +1 -1
  168. package/dist/Slider/Slider.js +19 -2
  169. package/dist/Stack/stack.stylex.d.ts +9 -9
  170. package/dist/Table/BaseTable.d.ts.map +1 -1
  171. package/dist/Table/BaseTable.js +3 -2
  172. package/dist/Table/index.d.ts +2 -0
  173. package/dist/Table/index.d.ts.map +1 -1
  174. package/dist/Table/index.js +1 -0
  175. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  176. package/dist/Table/plugins/rowStatus/index.d.ts +3 -0
  177. package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -0
  178. package/dist/Table/plugins/rowStatus/index.js +3 -0
  179. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +60 -0
  180. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -0
  181. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +145 -0
  182. package/dist/Table/plugins/selection/useTableSelection.d.ts +13 -0
  183. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  184. package/dist/Table/plugins/selection/useTableSelection.js +4 -1
  185. package/dist/Table/plugins/tree/useTableTreeData.d.ts +16 -0
  186. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  187. package/dist/Table/plugins/tree/useTableTreeData.js +87 -0
  188. package/dist/Table/plugins/tree/useTableTreeState.d.ts +6 -0
  189. package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -1
  190. package/dist/Table/plugins/tree/useTableTreeState.js +22 -1
  191. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  192. package/dist/Table/useBaseTablePlugins.js +5 -3
  193. package/dist/Thumbnail/Thumbnail.d.ts +26 -5
  194. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  195. package/dist/Thumbnail/Thumbnail.js +97 -54
  196. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +9 -0
  197. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +1 -0
  198. package/dist/Thumbnail/thumbnail.markers.stylex.js +14 -0
  199. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  200. package/dist/TimeInput/TimeInput.js +15 -4
  201. package/dist/Timestamp/Timestamp.d.ts +3 -1
  202. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  203. package/dist/Timestamp/Timestamp.js +8 -6
  204. package/dist/Toast/useToast.d.ts.map +1 -1
  205. package/dist/Toast/useToast.js +2 -5
  206. package/dist/ToggleButton/ToggleButtonGroup.d.ts +0 -1
  207. package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
  208. package/dist/ToggleButton/ToggleButtonGroup.js +1 -1
  209. package/dist/Tokenizer/Tokenizer.d.ts +1 -1
  210. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  211. package/dist/Tokenizer/Tokenizer.js +16 -4
  212. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  213. package/dist/TopNav/TopNavHeading.js +18 -8
  214. package/dist/TopNav/TopNavMegaMenu.js +10 -4
  215. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +9 -1
  216. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
  217. package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +8 -1
  218. package/dist/TopNav/TopNavMenu.d.ts +2 -1
  219. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  220. package/dist/TopNav/TopNavMenu.js +68 -6
  221. package/dist/TreeList/TreeList.d.ts +12 -3
  222. package/dist/TreeList/TreeList.d.ts.map +1 -1
  223. package/dist/TreeList/TreeList.js +2 -0
  224. package/dist/TreeList/TreeListBranches.d.ts +5 -0
  225. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  226. package/dist/TreeList/TreeListBranches.js +10 -4
  227. package/dist/TreeList/TreeListItem.d.ts +8 -2
  228. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  229. package/dist/TreeList/TreeListItem.js +27 -7
  230. package/dist/TreeList/TreeListTypes.d.ts +25 -1
  231. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  232. package/dist/TreeList/index.d.ts +2 -2
  233. package/dist/TreeList/index.d.ts.map +1 -1
  234. package/dist/astryx.css +28 -18
  235. package/dist/astryx.umd.js +51 -51
  236. package/dist/astryx.umd.js.map +4 -4
  237. package/dist/authoring/doc.d.ts.map +1 -1
  238. package/dist/docs-types.d.ts +8 -0
  239. package/dist/docs-types.d.ts.map +1 -1
  240. package/dist/hooks/computeOverflow.d.ts +47 -0
  241. package/dist/hooks/computeOverflow.d.ts.map +1 -0
  242. package/dist/hooks/computeOverflow.js +213 -0
  243. package/dist/hooks/index.d.ts +1 -0
  244. package/dist/hooks/index.d.ts.map +1 -1
  245. package/dist/hooks/index.js +2 -1
  246. package/dist/hooks/useDevWarning.d.ts +18 -0
  247. package/dist/hooks/useDevWarning.d.ts.map +1 -0
  248. package/dist/hooks/useDevWarning.js +49 -0
  249. package/dist/hooks/useOverflow.d.ts +19 -0
  250. package/dist/hooks/useOverflow.d.ts.map +1 -1
  251. package/dist/hooks/useOverflow.js +36 -25
  252. package/dist/i18n/InternationalizationContext.d.ts +1 -0
  253. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  254. package/dist/i18n/InternationalizationContext.js +3 -0
  255. package/dist/i18n/InternationalizationProvider.d.ts +8 -1
  256. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  257. package/dist/i18n/InternationalizationProvider.js +5 -1
  258. package/dist/i18n/getLocaleDirection.d.ts +18 -0
  259. package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
  260. package/dist/i18n/getLocaleDirection.js +29 -0
  261. package/dist/i18n/index.d.ts +6 -0
  262. package/dist/i18n/index.d.ts.map +1 -1
  263. package/dist/i18n/index.js +7 -1
  264. package/dist/i18n/resolve.d.ts.map +1 -1
  265. package/dist/i18n/resolve.js +7 -18
  266. package/dist/i18n/useDirection.d.ts +2 -0
  267. package/dist/i18n/useDirection.d.ts.map +1 -0
  268. package/dist/i18n/useDirection.js +27 -0
  269. package/dist/theme/Theme.d.ts.map +1 -1
  270. package/dist/theme/Theme.js +2 -7
  271. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  272. package/dist/theme/generateThemeRules.js +51 -0
  273. package/dist/theme/hct.d.ts +0 -1
  274. package/dist/theme/hct.d.ts.map +1 -1
  275. package/dist/theme/hct.js +1 -1
  276. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  277. package/dist/theme/syntax/defineSyntaxTheme.js +2 -1
  278. package/dist/utils/devWarning.d.ts +42 -0
  279. package/dist/utils/devWarning.d.ts.map +1 -0
  280. package/dist/utils/devWarning.js +88 -0
  281. package/dist/utils/index.d.ts +3 -1
  282. package/dist/utils/index.d.ts.map +1 -1
  283. package/dist/utils/index.js +3 -2
  284. package/dist/utils/plainDate.d.ts +30 -0
  285. package/dist/utils/plainDate.d.ts.map +1 -1
  286. package/dist/utils/plainDate.js +53 -0
  287. package/dist/utils/types.d.ts +13 -0
  288. package/dist/utils/types.d.ts.map +1 -1
  289. package/locales/en.json +24 -0
  290. package/locales/fr-FR.json +14 -0
  291. package/locales/pseudo.json +18 -0
  292. package/package.json +1 -1
  293. package/src/AppShell/AppShell.tsx +6 -0
  294. package/src/AppShell/AppShellMobileContext.tsx +8 -0
  295. package/src/AppShell/useAppShellMobile.doc.mjs +8 -0
  296. package/src/Avatar/Avatar.doc.mjs +15 -3
  297. package/src/Avatar/Avatar.test.tsx +156 -1
  298. package/src/Avatar/Avatar.tsx +96 -4
  299. package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
  300. package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
  301. package/src/Avatar/AvatarStatusDot.tsx +178 -21
  302. package/src/Banner/Banner.doc.mjs +9 -0
  303. package/src/Banner/Banner.test.tsx +30 -0
  304. package/src/Banner/Banner.tsx +47 -3
  305. package/src/Breadcrumbs/BreadcrumbItem.doc.mjs +26 -0
  306. package/src/Breadcrumbs/BreadcrumbItem.tsx +333 -14
  307. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +2 -0
  308. package/src/Breadcrumbs/Breadcrumbs.test.tsx +284 -2
  309. package/src/Breadcrumbs/index.ts +27 -0
  310. package/src/Button/Button.doc.mjs +9 -0
  311. package/src/Button/Button.test.tsx +49 -0
  312. package/src/Button/Button.tsx +25 -1
  313. package/src/ButtonGroup/ButtonGroup.doc.mjs +3 -0
  314. package/src/ButtonGroup/ButtonGroup.test.tsx +37 -0
  315. package/src/ButtonGroup/ButtonGroup.tsx +32 -0
  316. package/src/Calendar/Calendar.doc.mjs +12 -1
  317. package/src/Calendar/Calendar.test.tsx +193 -0
  318. package/src/Calendar/Calendar.tsx +38 -16
  319. package/src/Calendar/dayCellUtils.test.ts +5 -0
  320. package/src/Calendar/dayCellUtils.ts +1 -1
  321. package/src/Card/Card.doc.mjs +9 -0
  322. package/src/Card/Card.test.tsx +21 -3
  323. package/src/Card/Card.tsx +35 -2
  324. package/src/Carousel/Carousel.doc.mjs +1 -0
  325. package/src/Carousel/Carousel.test.tsx +53 -0
  326. package/src/Carousel/Carousel.tsx +34 -4
  327. package/src/Chat/ChatComposer.doc.mjs +12 -3
  328. package/src/Chat/ChatComposer.test.tsx +115 -0
  329. package/src/Chat/ChatComposer.tsx +73 -9
  330. package/src/Chat/ChatComposerDrawer.test.tsx +61 -0
  331. package/src/Chat/ChatComposerDrawer.tsx +11 -1
  332. package/src/Chat/ChatComposerInput.doc.mjs +7 -0
  333. package/src/Chat/ChatComposerInput.test.tsx +103 -0
  334. package/src/Chat/ChatComposerInput.tsx +49 -3
  335. package/src/Chat/ChatContext.tsx +37 -10
  336. package/src/Chat/ChatDictationButton.tsx +4 -1
  337. package/src/Chat/ChatLayout.tsx +3 -1
  338. package/src/Chat/ChatLayoutScrollButton.tsx +7 -2
  339. package/src/Chat/ChatMessageMetadata.tsx +1 -2
  340. package/src/Chat/ChatSendButton.tsx +11 -1
  341. package/src/Chat/ChatToolCalls.test.tsx +64 -0
  342. package/src/Chat/ChatToolCalls.tsx +25 -4
  343. package/src/Chat/index.ts +5 -1
  344. package/src/Chat/useChatStreamScroll.test.tsx +49 -0
  345. package/src/Chat/useChatStreamScroll.ts +27 -10
  346. package/src/Chat/useSpeechRecognition.ts +1 -1
  347. package/src/Chat/useTriggerMenu.tsx +3 -1
  348. package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
  349. package/src/CheckboxInput/CheckboxInput.tsx +1 -1
  350. package/src/CheckboxList/CheckboxList.test.tsx +81 -3
  351. package/src/CheckboxList/CheckboxListItem.doc.mjs +33 -5
  352. package/src/CheckboxList/CheckboxListItem.tsx +41 -5
  353. package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
  354. package/src/ClickableCard/ClickableCard.test.tsx +34 -0
  355. package/src/ClickableCard/ClickableCard.tsx +13 -3
  356. package/src/CodeBlock/CodeBlock.test.tsx +56 -0
  357. package/src/CodeBlock/CodeBlock.tsx +9 -1
  358. package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
  359. package/src/CommandPalette/CommandPalette.tsx +3 -1
  360. package/src/CommandPalette/CommandPaletteGroup.test.tsx +71 -0
  361. package/src/CommandPalette/CommandPaletteGroup.tsx +12 -1
  362. package/src/CommandPalette/CommandPaletteInput.doc.mjs +26 -9
  363. package/src/CommandPalette/CommandPaletteInput.test.tsx +34 -0
  364. package/src/CommandPalette/CommandPaletteInput.tsx +11 -0
  365. package/src/ContextMenu/ContextMenu.test.tsx +193 -0
  366. package/src/DateInput/DateInput.doc.mjs +16 -0
  367. package/src/DateInput/DateInput.test.tsx +108 -0
  368. package/src/DateInput/DateInput.tsx +68 -3
  369. package/src/DateInput/index.ts +1 -0
  370. package/src/DateTimeInput/DateTimeInput.test.tsx +35 -0
  371. package/src/DateTimeInput/DateTimeInput.tsx +14 -2
  372. package/src/Dialog/Dialog.doc.mjs +2 -2
  373. package/src/Dialog/Dialog.test.tsx +77 -4
  374. package/src/Dialog/Dialog.tsx +89 -5
  375. package/src/Dialog/DialogContext.ts +9 -2
  376. package/src/Dialog/DialogHeader.doc.mjs +2 -2
  377. package/src/Dialog/DialogHeader.tsx +9 -2
  378. package/src/Divider/Divider.tsx +2 -2
  379. package/src/DropdownMenu/DropdownMenu.test.tsx +169 -0
  380. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +1 -2
  381. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
  382. package/src/Field/Field.test.tsx +57 -12
  383. package/src/Field/Field.tsx +6 -5
  384. package/src/Field/FieldLabel.tsx +8 -0
  385. package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
  386. package/src/FieldStatus/FieldStatus.test.tsx +78 -40
  387. package/src/FieldStatus/FieldStatus.tsx +22 -4
  388. package/src/FileInput/FileInput.test.tsx +52 -3
  389. package/src/FileInput/FileInput.tsx +13 -2
  390. package/src/HoverCard/HoverCard.doc.mjs +13 -0
  391. package/src/HoverCard/HoverCard.test.tsx +21 -2
  392. package/src/HoverCard/HoverCard.tsx +11 -0
  393. package/src/HoverCard/useHoverCard.doc.mjs +2 -0
  394. package/src/HoverCard/useHoverCard.tsx +24 -2
  395. package/src/Icon/Icon.doc.mjs +3 -2
  396. package/src/Icon/Icon.tsx +7 -2
  397. package/src/IconButton/IconButton.doc.mjs +8 -0
  398. package/src/IconButton/IconButton.test.tsx +15 -18
  399. package/src/Item/Item.test.tsx +40 -18
  400. package/src/Item/Item.tsx +38 -2
  401. package/src/Layer/useLayer.tsx +8 -0
  402. package/src/List/List.test.tsx +9 -8
  403. package/src/MobileNav/MobileNav.tsx +12 -1
  404. package/src/MobileNav/MobileNavToggle.test.tsx +116 -0
  405. package/src/MobileNav/MobileNavToggle.tsx +9 -1
  406. package/src/MultiSelector/MultiSelector.doc.mjs +4 -2
  407. package/src/MultiSelector/MultiSelector.test.tsx +172 -3
  408. package/src/MultiSelector/MultiSelector.tsx +55 -12
  409. package/src/MultiSelector/hooks.ts +17 -0
  410. package/src/NumberInput/NumberInput.test.tsx +11 -7
  411. package/src/NumberInput/NumberInput.tsx +1 -2
  412. package/src/Outline/Outline.tsx +0 -1
  413. package/src/OverflowList/OverflowList.doc.mjs +39 -6
  414. package/src/OverflowList/OverflowList.test.tsx +111 -0
  415. package/src/OverflowList/OverflowList.tsx +48 -8
  416. package/src/Pagination/Pagination.tsx +11 -3
  417. package/src/Popover/Popover.tsx +7 -4
  418. package/src/Popover/usePopover.tsx +9 -13
  419. package/src/PowerSearch/PowerSearch.doc.mjs +14 -0
  420. package/src/PowerSearch/PowerSearch.test.tsx +20 -0
  421. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
  422. package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
  423. package/src/PowerSearch/usePowerSearchSource.ts +1 -2
  424. package/src/SelectableCard/SelectableCard.doc.mjs +2 -0
  425. package/src/SelectableCard/SelectableCard.test.tsx +46 -4
  426. package/src/SelectableCard/SelectableCard.tsx +29 -16
  427. package/src/Selector/Selector.test.tsx +69 -0
  428. package/src/Selector/Selector.tsx +5 -1
  429. package/src/Selector/hooks.ts +17 -0
  430. package/src/SideNav/SideNav.test.tsx +119 -3
  431. package/src/SideNav/SideNavCollapseButton.tsx +6 -1
  432. package/src/SideNav/SideNavHeading.tsx +24 -8
  433. package/src/SideNav/SideNavItem.tsx +5 -1
  434. package/src/Slider/Slider.test.tsx +75 -2
  435. package/src/Slider/Slider.tsx +21 -5
  436. package/src/Switch/Switch.test.tsx +32 -1
  437. package/src/Table/BaseTable.tsx +3 -5
  438. package/src/Table/index.ts +5 -0
  439. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +6 -2
  440. package/src/Table/plugins/rowStatus/index.ts +7 -0
  441. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +138 -0
  442. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +189 -0
  443. package/src/Table/plugins/selection/useTableSelection.test.tsx +16 -0
  444. package/src/Table/plugins/selection/useTableSelection.tsx +19 -1
  445. package/src/Table/plugins/tree/useTableTreeData.test.tsx +135 -3
  446. package/src/Table/plugins/tree/useTableTreeData.tsx +128 -1
  447. package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
  448. package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
  449. package/src/Table/useBaseTablePlugins.ts +10 -6
  450. package/src/Table/useTableRowStatus.doc.mjs +30 -0
  451. package/src/Table/useTableSelection.doc.mjs +65 -14
  452. package/src/Table/useTableTreeData.doc.mjs +29 -0
  453. package/src/Table/useTableTreeState.doc.mjs +2 -2
  454. package/src/TextArea/TextArea.test.tsx +9 -1
  455. package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
  456. package/src/Thumbnail/Thumbnail.test.tsx +98 -7
  457. package/src/Thumbnail/Thumbnail.tsx +141 -41
  458. package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
  459. package/src/TimeInput/TimeInput.test.tsx +76 -1
  460. package/src/TimeInput/TimeInput.tsx +19 -6
  461. package/src/Timestamp/Timestamp.doc.mjs +4 -4
  462. package/src/Timestamp/Timestamp.test.tsx +32 -0
  463. package/src/Timestamp/Timestamp.tsx +28 -8
  464. package/src/Toast/useToast.tsx +7 -8
  465. package/src/ToggleButton/ToggleButtonGroup.tsx +1 -1
  466. package/src/Tokenizer/Tokenizer.doc.mjs +15 -1
  467. package/src/Tokenizer/Tokenizer.test.tsx +183 -2
  468. package/src/Tokenizer/Tokenizer.tsx +16 -4
  469. package/src/TopNav/TopNav.test.tsx +125 -1
  470. package/src/TopNav/TopNavHeading.tsx +24 -8
  471. package/src/TopNav/TopNavMegaMenu.test.tsx +149 -1
  472. package/src/TopNav/TopNavMegaMenu.tsx +10 -4
  473. package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +3 -3
  474. package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +19 -2
  475. package/src/TopNav/TopNavMenu.test.tsx +118 -4
  476. package/src/TopNav/TopNavMenu.tsx +83 -5
  477. package/src/TreeList/TreeList.doc.mjs +22 -0
  478. package/src/TreeList/TreeList.test.tsx +232 -0
  479. package/src/TreeList/TreeList.tsx +18 -2
  480. package/src/TreeList/TreeListBranches.tsx +16 -2
  481. package/src/TreeList/TreeListItem.tsx +51 -11
  482. package/src/TreeList/TreeListTypes.ts +27 -1
  483. package/src/TreeList/index.ts +2 -2
  484. package/src/authoring/doc.ts +1 -3
  485. package/src/docs-types.ts +5 -0
  486. package/src/hooks/computeOverflow.test.ts +422 -0
  487. package/src/hooks/computeOverflow.ts +290 -0
  488. package/src/hooks/index.ts +2 -0
  489. package/src/hooks/useDevWarning.test.tsx +45 -0
  490. package/src/hooks/useDevWarning.ts +54 -0
  491. package/src/hooks/useOverflow.test.ts +96 -4
  492. package/src/hooks/useOverflow.ts +74 -33
  493. package/src/i18n/InternationalizationContext.ts +4 -0
  494. package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
  495. package/src/i18n/InternationalizationProvider.tsx +12 -2
  496. package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
  497. package/src/i18n/__tests__/useDirection.test.tsx +66 -0
  498. package/src/i18n/getLocaleDirection.ts +29 -0
  499. package/src/i18n/index.ts +6 -0
  500. package/src/i18n/resolve.ts +9 -21
  501. package/src/i18n/useDirection.ts +29 -0
  502. package/src/theme/Theme.tsx +11 -14
  503. package/src/theme/generateThemeRules.test.ts +65 -0
  504. package/src/theme/generateThemeRules.ts +56 -0
  505. package/src/theme/hct.ts +1 -1
  506. package/src/theme/syntax/defineSyntaxTheme.ts +5 -6
  507. package/src/utils/devWarning.test.ts +56 -0
  508. package/src/utils/devWarning.ts +102 -0
  509. package/src/utils/index.ts +6 -0
  510. package/src/utils/plainDate.test.ts +22 -0
  511. package/src/utils/plainDate.ts +61 -0
  512. package/src/utils/types.ts +14 -0
@@ -161,6 +161,15 @@ export const DATE_FORMAT_WITH_WEEKDAY = {
161
161
  day: 'numeric'
162
162
  };
163
163
 
164
+ // e.g. "Wed, May 21, 2026" (locale-dependent) — short weekday + short month.
165
+ // Backs the shared `date_weekday` format used by both Timestamp and DateInput.
166
+ export const DATE_FORMAT_SHORT_WITH_WEEKDAY = {
167
+ weekday: 'short',
168
+ month: 'short',
169
+ day: 'numeric',
170
+ year: 'numeric'
171
+ };
172
+
164
173
  // e.g. "May 21, 2026" (locale-dependent)
165
174
  export const DATE_FORMAT_LONG = {
166
175
  year: 'numeric',
@@ -188,4 +197,48 @@ export const DATE_FORMAT_SHORT_WITH_YEAR = {
188
197
  };
189
198
  export function plainDateFormat(pd, options) {
190
199
  return new Intl.DateTimeFormat(undefined, options).format(plainDateToDate(pd));
200
+ }
201
+
202
+ // =============================================================================
203
+ // Shared date-only format vocabulary
204
+ // =============================================================================
205
+
206
+ /**
207
+ * The date-only members of Timestamp's `format` vocabulary that a
208
+ * calendar-date field (no time-of-day) can render. Both Timestamp and
209
+ * DateInput share these string literals and the mapping below so that the same
210
+ * literal renders the same date shape in either component.
211
+ *
212
+ * - `date`: locale short-month date, e.g. "Mar 21, 2026"
213
+ * - `date_long`: locale long-month date, e.g. "March 21, 2026"
214
+ * - `date_weekday`: short weekday + short-month date, e.g. "Wed, Mar 21, 2026"
215
+ * - `system_date`: ISO 8601 calendar date, e.g. "2026-03-21"
216
+ */
217
+
218
+ /**
219
+ * Intl option bags for the locale-aware shared date members. `system_date` is
220
+ * intentionally absent — it is emitted as a fixed ISO `YYYY-MM-DD` string, not
221
+ * via `Intl` — and is handled directly by {@link formatSharedDate}.
222
+ *
223
+ * This is the single source of truth consumed by both Timestamp's
224
+ * `formatTimestamp` switch and DateInput's display path, so the two never
225
+ * drift for the members they share.
226
+ */
227
+ export const SHARED_DATE_FORMAT_OPTIONS = {
228
+ date: DATE_FORMAT_SHORT_WITH_YEAR,
229
+ date_long: DATE_FORMAT_LONG,
230
+ date_weekday: DATE_FORMAT_SHORT_WITH_WEEKDAY
231
+ };
232
+
233
+ /**
234
+ * Renders a {@link PlainDate} using one of the {@link SharedDateFormat}
235
+ * members. The shared entry point DateInput uses for the named-format path;
236
+ * Timestamp maps the same members onto {@link SHARED_DATE_FORMAT_OPTIONS} in
237
+ * its own `formatTimestamp` switch (its input is a `Date`, not a `PlainDate`).
238
+ */
239
+ export function formatSharedDate(pd, format) {
240
+ if (format === 'system_date') {
241
+ return plainDateToISO(pd);
242
+ }
243
+ return plainDateFormat(pd, SHARED_DATE_FORMAT_OPTIONS[format]);
191
244
  }
@@ -8,6 +8,19 @@
8
8
  * Size value type - accepts numbers (treated as pixels) or strings (e.g., '100%', '50vh').
9
9
  */
10
10
  export type SizeValue = number | string;
11
+ /**
12
+ * Resting elevation level for configurable surfaces.
13
+ *
14
+ * Maps to the shadow token scale:
15
+ * - `none` = flat (`box-shadow: none`)
16
+ * - `low` = `--shadow-low`
17
+ * - `med` = `--shadow-med`
18
+ * - `high` = `--shadow-high`
19
+ *
20
+ * Components narrow this union to the steps they actually need — e.g. Card
21
+ * exposes all four, while ChatComposer exposes only `'none' | 'low'`.
22
+ */
23
+ export type Elevation = 'none' | 'low' | 'med' | 'high';
11
24
  /**
12
25
  * Numeric spacing step from the Astryx spacing scale.
13
26
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAExC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAExC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAExD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC"}
package/locales/en.json CHANGED
@@ -263,6 +263,10 @@
263
263
  "defaultMessage": "Scroll right",
264
264
  "description": "Screen-reader-only label on the right arrow button in a Carousel. Pairs with `carousel.scrollLeft`; same RTL note."
265
265
  },
266
+ "@astryx.carousel.slideLabel": {
267
+ "defaultMessage": "Slide {current, number} of {total, number}",
268
+ "description": "Screen-reader accessible name for one slide in a Carousel, giving its position. `current` is the 1-based slide number; `total` is the slide count."
269
+ },
266
270
  "@astryx.chat.status.sending": {
267
271
  "defaultMessage": "Sending",
268
272
  "description": "Chat send-status caption under an outgoing message while it is being transmitted. Part of the set sending → sent → delivered → read (or failed) — keep tense/aspect consistent."
@@ -411,6 +415,10 @@
411
415
  "defaultMessage": "Select row",
412
416
  "description": "Aria label for the \"select row\" checkbox on a Table row."
413
417
  },
418
+ "@astryx.table.selection.selectRowNamed": {
419
+ "defaultMessage": "Select {label}",
420
+ "description": "Aria label for a Table row's selection checkbox when a per-row label is available (via getRowLabel). `label` is the row's human-readable identity, e.g. \"Alice\"."
421
+ },
414
422
  "@astryx.table.sort.ascending": {
415
423
  "defaultMessage": "Sort ascending",
416
424
  "description": "Screen-reader-only label on a column header button that will sort the column ascending. Part of a set with `sort.descending` and `sort.clear` — keep parallel."
@@ -679,6 +687,10 @@
679
687
  "defaultMessage": "Clear {label}",
680
688
  "description": "Screen-reader-only label on the X that removes the selected file from a FileInput. Example: `Clear Attachment`, `Clear Résumé`."
681
689
  },
690
+ "@astryx.fileInput.triggerWithFiles": {
691
+ "defaultMessage": "{label}, {fileNames}",
692
+ "description": "Accessible name for a FileInput trigger that has files attached, composing the field label with the selected filenames. Example: `Attachments, report.pdf, notes.txt`."
693
+ },
682
694
  "@astryx.lightbox.mediaViewer": {
683
695
  "defaultMessage": "Media viewer",
684
696
  "description": "Screen-reader-only fallback name for the Lightbox dialog when the current media item has no alt text. Should rarely render — consumers should provide alt."
@@ -751,6 +763,14 @@
751
763
  "defaultMessage": "Expand row",
752
764
  "description": "Aria label for the Table tree-data expander chevron when the row is currently collapsed."
753
765
  },
766
+ "@astryx.tableTree.collapseAllRows": {
767
+ "defaultMessage": "Collapse all rows",
768
+ "description": "Aria label for the Table tree-data header toggle when all rows are expanded and clicking it collapses them."
769
+ },
770
+ "@astryx.tableTree.expandAllRows": {
771
+ "defaultMessage": "Expand all rows",
772
+ "description": "Aria label for the Table tree-data header toggle when rows are collapsed and clicking it expands them."
773
+ },
754
774
  "@astryx.textInput.clearLabel": {
755
775
  "defaultMessage": "Clear {label}",
756
776
  "description": "Screen-reader-only label on the X that clears the value from a TextInput. Example: `Clear Email`, `Clear Name`."
@@ -763,6 +783,10 @@
763
783
  "defaultMessage": "Open {accessibleName}",
764
784
  "description": "\"Open\" = launch/reveal (not \"unfold\" or the adjective). Screen-reader-only name on a clickable Thumbnail — example: `Open Sunset photo`."
765
785
  },
786
+ "@astryx.thumbnail.fallbackName": {
787
+ "defaultMessage": "Thumbnail",
788
+ "description": "Generic screen-reader name for a Thumbnail (image preview) that has no `alt` or `label`. Last-resort fallback so the control is never nameless; prefer a real name via `alt` or `label`."
789
+ },
766
790
  "@astryx.timeInput.clearLabel": {
767
791
  "defaultMessage": "Clear {label}",
768
792
  "description": "Screen-reader-only label on the X that clears the value from a TimeInput. Example: `Clear Start time`."
@@ -0,0 +1,14 @@
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
+ "@astryx.selector.placeholder": {
11
+ "defaultMessage": "Sélectionner…",
12
+ "description": "Placeholder text on an empty Selector trigger button (a dropdown). Imperative verb; trailing `…` is one character. Very short — appears on the button face."
13
+ }
14
+ }
@@ -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
  },
@@ -509,6 +515,9 @@
509
515
  "@astryx.fileInput.clearLabel": {
510
516
  "defaultMessage": "⟦Çłéàř {label}⟧"
511
517
  },
518
+ "@astryx.fileInput.triggerWithFiles": {
519
+ "defaultMessage": "⟦{label}, {fileNames}⟧"
520
+ },
512
521
  "@astryx.lightbox.mediaViewer": {
513
522
  "defaultMessage": "⟦Ṁéðíà ṽíéŵéř⟧"
514
523
  },
@@ -563,6 +572,12 @@
563
572
  "@astryx.tableTree.expandRow": {
564
573
  "defaultMessage": "⟦Éẋþàñð řóŵ⟧"
565
574
  },
575
+ "@astryx.tableTree.collapseAllRows": {
576
+ "defaultMessage": "⟦Çółłàþšé àłł řóŵš⟧"
577
+ },
578
+ "@astryx.tableTree.expandAllRows": {
579
+ "defaultMessage": "⟦Éẋþàñð àłł řóŵš⟧"
580
+ },
566
581
  "@astryx.textInput.clearLabel": {
567
582
  "defaultMessage": "⟦Çłéàř {label}⟧"
568
583
  },
@@ -572,6 +587,9 @@
572
587
  "@astryx.thumbnail.open": {
573
588
  "defaultMessage": "⟦Óþéñ {accessibleName}⟧"
574
589
  },
590
+ "@astryx.thumbnail.fallbackName": {
591
+ "defaultMessage": "⟦Ţĥúɱƀñàíł⟧"
592
+ },
575
593
  "@astryx.timeInput.clearLabel": {
576
594
  "defaultMessage": "⟦Çłéàř {label}⟧"
577
595
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/core",
3
- "version": "0.1.8",
3
+ "version": "0.1.9-canary.75d2d03",
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",
@@ -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',
@@ -15,6 +15,7 @@ export const docs = {
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
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
+ {guidance: true, description: 'When wrapping an Avatar in your own Tooltip or HoverCard, set tooltip={false} so the built-in name tooltip does not overlap yours.'},
18
19
  {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
20
  {guidance: false, description: 'Force a square or custom shape. Avatars are always circular to stay consistent across the system.'},
20
21
  ],
@@ -22,13 +23,14 @@ export const docs = {
22
23
  {name: 'Photo', required: false, description: 'The profile image, loaded from the src URL. Shown when available.'},
23
24
  {name: 'Initials', required: false, description: 'One or two letters extracted from the name. Shown when no photo is available.'},
24
25
  {name: 'Default icon', required: false, description: 'A generic person silhouette. Shown when there is no photo or name.'},
25
- {name: 'Status dot', required: false, description: 'A small indicator in the bottom-right corner showing availability (online, away, busy).'},
26
+ {name: 'Status dot', required: false, description: 'A small indicator in the bottom-right corner showing availability (online, away, busy). Each variant pairs colour with a distinct shape so status does not rely on colour alone.'},
26
27
  ],
27
28
  },
28
29
  theming: {
29
30
  targets: [
30
31
  {className: 'astryx-avatar', visualProps: ['size']},
31
32
  {className: 'astryx-avatar-status-dot', visualProps: ['variant']},
33
+ {className: 'astryx-avatar-status-dot-glyph', visualProps: ['shape']},
32
34
  ],
33
35
  },
34
36
  description: 'Displays a user avatar with image, initials fallback, and optional status indicator.',
@@ -65,13 +67,21 @@ export const docs = {
65
67
  description: 'Corner content for status indicators.',
66
68
  slotElements: [
67
69
  {
68
- __element: 'StatusDot',
70
+ __element: 'AvatarStatusDot',
69
71
  props: {
70
- variant: 'online',
72
+ variant: 'success',
73
+ label: 'Online',
71
74
  },
72
75
  },
73
76
  ],
74
77
  },
78
+ {
79
+ name: 'tooltip',
80
+ type: 'string | boolean',
81
+ description:
82
+ "Tooltip shown on hover and keyboard focus. Omitted or true shows the avatar's name; a string shows that text instead; false shows no tooltip. Not auto-disabled when wrapped in your own Tooltip/HoverCard — set tooltip={false} if you supply your own overlay. No tooltip is shown when tooltip is true/omitted and there is no name.",
83
+ default: 'true',
84
+ },
75
85
  ],
76
86
  components: [
77
87
  {name: 'AvatarStatusDot'},
@@ -113,6 +123,8 @@ export const docsDense = {
113
123
  alt: 'alt text; falls back to name',
114
124
  size: "avatar size. Named ('xsm' 20px, 'sm' 24px, 'md' 36px, 'lg' 48px, 'xl' 128px) or numeric px.",
115
125
  status: 'corner content for status indicators',
126
+ tooltip:
127
+ "hover/focus tooltip. true/omitted → name; string → that text; false → none. Owns its tooltip; set false when wrapping in your own Tooltip/HoverCard. Default true.",
116
128
  },
117
129
  components: [
118
130
  {name: 'AvatarStatusDot', description: 'size-aware status indicator rendered in the Avatar corner'},
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
- import {describe, it, expect} from 'vitest';
3
+ import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
4
4
  import {render, screen, fireEvent} from '@testing-library/react';
5
5
  import {Avatar} from './Avatar';
6
6
 
@@ -65,4 +65,159 @@ describe('Avatar', () => {
65
65
  expect(img).not.toBeNull();
66
66
  expect(img).toHaveAttribute('src', 'https://example.com/ada.jpg');
67
67
  });
68
+
69
+ // --- Name tooltip (tooltip?: string | boolean) ---
70
+ describe('name tooltip', () => {
71
+ const originalShowPopover = HTMLElement.prototype.showPopover;
72
+ const originalHidePopover = HTMLElement.prototype.hidePopover;
73
+
74
+ beforeEach(() => {
75
+ // jsdom does not implement the Popover API the tooltip layer uses.
76
+ HTMLElement.prototype.showPopover = vi.fn();
77
+ HTMLElement.prototype.hidePopover = vi.fn();
78
+ });
79
+
80
+ afterEach(() => {
81
+ HTMLElement.prototype.showPopover = originalShowPopover;
82
+ HTMLElement.prototype.hidePopover = originalHidePopover;
83
+ });
84
+
85
+ it('shows the name in a tooltip by default', () => {
86
+ render(<Avatar name="Ada Lovelace" />);
87
+ const tooltip = screen.getByRole('tooltip', {hidden: true});
88
+ expect(tooltip).toHaveTextContent('Ada Lovelace');
89
+ });
90
+
91
+ it('shows a custom string tooltip instead of the name', () => {
92
+ render(<Avatar name="alovelace" tooltip="Ada Lovelace, Mathematician" />);
93
+ const tooltip = screen.getByRole('tooltip', {hidden: true});
94
+ expect(tooltip).toHaveTextContent('Ada Lovelace, Mathematician');
95
+ expect(tooltip).not.toHaveTextContent('alovelace');
96
+ });
97
+
98
+ it('renders no tooltip when tooltip={false}', () => {
99
+ render(<Avatar name="Ada Lovelace" tooltip={false} />);
100
+ expect(screen.queryByRole('tooltip', {hidden: true})).toBeNull();
101
+ });
102
+
103
+ it('renders no tooltip for a decorative avatar (no name/alt)', () => {
104
+ render(<Avatar src="https://example.com/x.jpg" />);
105
+ expect(screen.queryByRole('tooltip', {hidden: true})).toBeNull();
106
+ });
107
+
108
+ it('renders no tooltip when tooltip is true/default but name is empty', () => {
109
+ render(<Avatar name=" " alt="Profile photo" data-testid="a" />);
110
+ // A whitespace-only name yields nothing to show, and the default tooltip
111
+ // uses `name` (not `alt`), so there is no tooltip.
112
+ expect(screen.queryByRole('tooltip', {hidden: true})).toBeNull();
113
+ // The accessible name still comes from alt, unaffected.
114
+ expect(
115
+ screen.getByRole('img', {name: 'Profile photo'}),
116
+ ).toBeInTheDocument();
117
+ });
118
+
119
+ it('still shows a custom string tooltip when there is no name', () => {
120
+ render(<Avatar tooltip="Anonymous user" data-testid="a" />);
121
+ const tooltip = screen.getByRole('tooltip', {hidden: true});
122
+ expect(tooltip).toHaveTextContent('Anonymous user');
123
+ });
124
+
125
+ it('makes the root focusable while a tooltip is attached', () => {
126
+ render(<Avatar name="Ada Lovelace" data-testid="a" />);
127
+ expect(screen.getByTestId('a')).toHaveAttribute('tabindex', '0');
128
+ });
129
+
130
+ it('does not add a tab stop when the tooltip is disabled', () => {
131
+ render(<Avatar name="Ada Lovelace" tooltip={false} data-testid="a" />);
132
+ expect(screen.getByTestId('a')).not.toHaveAttribute('tabindex');
133
+ });
134
+
135
+ it('keeps the accessible name on the root regardless of the tooltip', () => {
136
+ const {rerender} = render(<Avatar name="Ada Lovelace" />);
137
+ expect(
138
+ screen.getByRole('img', {name: 'Ada Lovelace'}),
139
+ ).toBeInTheDocument();
140
+
141
+ rerender(<Avatar name="Ada Lovelace" tooltip={false} />);
142
+ expect(
143
+ screen.getByRole('img', {name: 'Ada Lovelace'}),
144
+ ).toBeInTheDocument();
145
+
146
+ rerender(<Avatar name="alovelace" tooltip="Ada Lovelace, Eng" />);
147
+ // alt||name still drives the accessible name — not the custom tooltip.
148
+ expect(screen.getByRole('img', {name: 'alovelace'})).toBeInTheDocument();
149
+
150
+ rerender(<Avatar name="alovelace" alt="Ada's profile photo" />);
151
+ expect(
152
+ screen.getByRole('img', {name: "Ada's profile photo"}),
153
+ ).toBeInTheDocument();
154
+ });
155
+
156
+ it('does not describe the root with the default name tooltip (no double-announce)', () => {
157
+ render(<Avatar name="Ada Lovelace" data-testid="a" />);
158
+ // The default name tooltip is visual-only: its text duplicates the root
159
+ // aria-label, so we deliberately do NOT wire aria-describedby (OQ-4).
160
+ expect(screen.getByTestId('a')).not.toHaveAttribute('aria-describedby');
161
+ });
162
+
163
+ it('describes the root with a custom string tooltip (matches Button)', () => {
164
+ render(
165
+ <Avatar
166
+ name="alovelace"
167
+ tooltip="Ada Lovelace, Mathematician"
168
+ data-testid="a"
169
+ />,
170
+ );
171
+ const root = screen.getByTestId('a');
172
+ const describedBy = root.getAttribute('aria-describedby');
173
+ expect(describedBy).toBeTruthy();
174
+ // aria-describedby points at the rendered tooltip layer.
175
+ const tooltip = screen.getByRole('tooltip', {hidden: true});
176
+ expect(tooltip.id).toBeTruthy();
177
+ expect(describedBy).toContain(tooltip.id);
178
+ });
179
+
180
+ it('composes a consumer aria-describedby with the custom tooltip description', () => {
181
+ render(
182
+ <>
183
+ <span id="extra-desc">extra description</span>
184
+ <Avatar
185
+ name="alovelace"
186
+ tooltip="Ada Lovelace, Eng"
187
+ aria-describedby="extra-desc"
188
+ data-testid="a"
189
+ />
190
+ </>,
191
+ );
192
+ const describedBy = screen
193
+ .getByTestId('a')
194
+ .getAttribute('aria-describedby');
195
+ expect(describedBy).toContain('extra-desc');
196
+ });
197
+
198
+ it('preserves a consumer aria-describedby with the default name tooltip', () => {
199
+ render(
200
+ <>
201
+ <span id="extra-desc">extra description</span>
202
+ <Avatar
203
+ name="Ada Lovelace"
204
+ aria-describedby="extra-desc"
205
+ data-testid="a"
206
+ />
207
+ </>,
208
+ );
209
+ // Default name tooltip does not touch aria-describedby, so the consumer
210
+ // value passes through untouched.
211
+ expect(screen.getByTestId('a')).toHaveAttribute(
212
+ 'aria-describedby',
213
+ 'extra-desc',
214
+ );
215
+ });
216
+
217
+ it('forwards the consumer ref to the root while a tooltip is attached', () => {
218
+ const ref = {current: null as HTMLDivElement | null};
219
+ render(<Avatar name="Ada Lovelace" ref={ref} data-testid="a" />);
220
+ expect(ref.current).toBe(screen.getByTestId('a'));
221
+ });
222
+ });
68
223
  });