@astryxdesign/core 0.1.9-canary.fef7dca → 0.2.0-canary.0f56f82

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 (419) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/dist/Avatar/Avatar.d.ts +6 -1
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +40 -7
  5. package/dist/Avatar/AvatarStatusDot.d.ts +6 -4
  6. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  7. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  8. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  9. package/dist/AvatarGroup/AvatarGroupOverflow.js +6 -2
  10. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  11. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -4
  12. package/dist/Breadcrumbs/index.d.ts +1 -0
  13. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  14. package/dist/Breadcrumbs/index.js +2 -1
  15. package/dist/Button/Button.d.ts +1 -1
  16. package/dist/Button/Button.d.ts.map +1 -1
  17. package/dist/Button/Button.js +4 -2
  18. package/dist/Calendar/Calendar.d.ts.map +1 -1
  19. package/dist/Calendar/Calendar.js +45 -4
  20. package/dist/Card/Card.js +1 -1
  21. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  22. package/dist/Chat/ChatMessageBubble.js +8 -8
  23. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  24. package/dist/CheckboxInput/CheckboxInput.js +6 -6
  25. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  26. package/dist/CheckboxList/CheckboxListItem.js +19 -4
  27. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  28. package/dist/CodeBlock/CodeBlock.js +15 -9
  29. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  30. package/dist/Collapsible/Collapsible.js +3 -1
  31. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  32. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  33. package/dist/CommandPalette/CommandPalette.js +42 -3
  34. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  35. package/dist/ContextMenu/ContextMenu.js +23 -5
  36. package/dist/ContextMenu/index.d.ts +1 -0
  37. package/dist/ContextMenu/index.d.ts.map +1 -1
  38. package/dist/ContextMenu/index.js +3 -1
  39. package/dist/DateInput/DateInput.d.ts +1 -0
  40. package/dist/DateInput/DateInput.d.ts.map +1 -1
  41. package/dist/DateInput/DateInput.js +31 -19
  42. package/dist/DateRangeInput/DateRangeInput.d.ts +1 -0
  43. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  44. package/dist/DateRangeInput/DateRangeInput.js +20 -19
  45. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  46. package/dist/DateTimeInput/DateTimeInput.js +17 -18
  47. package/dist/Divider/Divider.d.ts +2 -2
  48. package/dist/Divider/Divider.d.ts.map +1 -1
  49. package/dist/Divider/Divider.js +13 -0
  50. package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
  51. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  52. package/dist/DropdownMenu/DropdownMenu.js +13 -5
  53. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +8 -11
  54. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  55. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +3 -1
  56. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +1 -1
  57. package/dist/DropdownMenu/DropdownMenuRadioItem.js +1 -1
  58. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
  59. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
  60. package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
  61. package/dist/DropdownMenu/index.d.ts +10 -0
  62. package/dist/DropdownMenu/index.d.ts.map +1 -1
  63. package/dist/DropdownMenu/index.js +13 -0
  64. package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
  65. package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
  66. package/dist/DropdownMenu/menuItemRoles.js +10 -1
  67. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  68. package/dist/DropdownMenu/renderDropdownItems.js +21 -6
  69. package/dist/Field/Field.d.ts +3 -1
  70. package/dist/Field/Field.d.ts.map +1 -1
  71. package/dist/Field/Field.js +4 -1
  72. package/dist/Field/FieldLabel.d.ts +2 -1
  73. package/dist/Field/FieldLabel.d.ts.map +1 -1
  74. package/dist/Field/FieldLabel.js +7 -3
  75. package/dist/Field/inputStyles.stylex.d.ts +1 -0
  76. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  77. package/dist/Field/inputStyles.stylex.js +1 -0
  78. package/dist/FieldStatus/FieldStatus.d.ts +4 -1
  79. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  80. package/dist/FieldStatus/FieldStatus.js +16 -4
  81. package/dist/FileInput/FileInput.d.ts +1 -0
  82. package/dist/FileInput/FileInput.d.ts.map +1 -1
  83. package/dist/FileInput/FileInput.js +77 -63
  84. package/dist/Icon/Icon.d.ts +15 -1
  85. package/dist/Icon/Icon.d.ts.map +1 -1
  86. package/dist/Icon/Icon.js +19 -3
  87. package/dist/Item/Item.d.ts +16 -3
  88. package/dist/Item/Item.d.ts.map +1 -1
  89. package/dist/Item/Item.js +31 -6
  90. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  91. package/dist/Layer/layerAnimations.stylex.js +10 -2
  92. package/dist/List/List.d.ts.map +1 -1
  93. package/dist/List/List.js +6 -3
  94. package/dist/List/ListItem.d.ts +11 -1
  95. package/dist/List/ListItem.d.ts.map +1 -1
  96. package/dist/List/ListItem.js +2 -0
  97. package/dist/Markdown/Markdown.d.ts.map +1 -1
  98. package/dist/Markdown/Markdown.js +7 -0
  99. package/dist/MetadataList/MetadataList.d.ts +1 -1
  100. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  101. package/dist/MetadataList/MetadataList.js +4 -2
  102. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  103. package/dist/MultiSelector/MultiSelector.js +30 -3
  104. package/dist/NumberInput/NumberInput.d.ts +1 -0
  105. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  106. package/dist/NumberInput/NumberInput.js +15 -17
  107. package/dist/Outline/Outline.js +2 -2
  108. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  109. package/dist/ProgressBar/ProgressBar.js +6 -1
  110. package/dist/RadioList/RadioList.d.ts +2 -2
  111. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  112. package/dist/RadioList/RadioListItem.js +5 -5
  113. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  114. package/dist/Resizable/ResizeHandle.js +49 -19
  115. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  116. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  117. package/dist/SegmentedControl/SegmentedControlItem.js +5 -3
  118. package/dist/Selector/Selector.d.ts.map +1 -1
  119. package/dist/Selector/Selector.js +22 -1
  120. package/dist/SideNav/SideNav.d.ts.map +1 -1
  121. package/dist/SideNav/SideNav.js +5 -5
  122. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  123. package/dist/SideNav/SideNavCollapseButton.js +13 -10
  124. package/dist/SideNav/SideNavItem.d.ts +1 -1
  125. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  126. package/dist/SideNav/SideNavItem.js +12 -10
  127. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  128. package/dist/Skeleton/Skeleton.js +2 -2
  129. package/dist/Slider/Slider.d.ts.map +1 -1
  130. package/dist/Slider/Slider.js +87 -34
  131. package/dist/Spinner/Spinner.d.ts +3 -2
  132. package/dist/Spinner/Spinner.d.ts.map +1 -1
  133. package/dist/Spinner/Spinner.js +11 -2
  134. package/dist/Switch/Switch.d.ts.map +1 -1
  135. package/dist/Switch/Switch.js +23 -12
  136. package/dist/TabList/TabList.d.ts +2 -11
  137. package/dist/TabList/TabList.d.ts.map +1 -1
  138. package/dist/TabList/TabList.js +5 -9
  139. package/dist/TabList/TabListContext.d.ts +0 -5
  140. package/dist/TabList/TabListContext.d.ts.map +1 -1
  141. package/dist/TabList/TabListContext.js +0 -5
  142. package/dist/Table/BaseTable.d.ts.map +1 -1
  143. package/dist/Table/BaseTable.js +30 -4
  144. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  145. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +1 -1
  146. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  147. package/dist/Table/plugins/selection/useTableSelection.js +3 -0
  148. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  149. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +14 -6
  150. package/dist/Table/types.d.ts +32 -0
  151. package/dist/Table/types.d.ts.map +1 -1
  152. package/dist/TextArea/TextArea.d.ts +1 -0
  153. package/dist/TextArea/TextArea.d.ts.map +1 -1
  154. package/dist/TextArea/TextArea.js +16 -19
  155. package/dist/TextInput/TextInput.d.ts +1 -0
  156. package/dist/TextInput/TextInput.d.ts.map +1 -1
  157. package/dist/TextInput/TextInput.js +15 -17
  158. package/dist/TimeInput/TimeInput.d.ts +1 -0
  159. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  160. package/dist/TimeInput/TimeInput.js +15 -17
  161. package/dist/Timestamp/Timestamp.d.ts +31 -3
  162. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  163. package/dist/Timestamp/Timestamp.js +47 -76
  164. package/dist/Timestamp/formatInstant.d.ts +41 -0
  165. package/dist/Timestamp/formatInstant.d.ts.map +1 -0
  166. package/dist/Timestamp/formatInstant.js +177 -0
  167. package/dist/Timestamp/index.d.ts +1 -0
  168. package/dist/Timestamp/index.d.ts.map +1 -1
  169. package/dist/Timestamp/tooltipEntries.d.ts +56 -0
  170. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -0
  171. package/dist/Timestamp/tooltipEntries.js +163 -0
  172. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  173. package/dist/Toast/ToastViewport.js +61 -9
  174. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  175. package/dist/ToggleButton/ToggleButton.js +3 -1
  176. package/dist/Token/Token.d.ts +34 -4
  177. package/dist/Token/Token.d.ts.map +1 -1
  178. package/dist/Token/Token.js +85 -45
  179. package/dist/Token/TokenLink.d.ts +62 -0
  180. package/dist/Token/TokenLink.d.ts.map +1 -0
  181. package/dist/Token/TokenLink.js +76 -0
  182. package/dist/Token/index.d.ts +1 -1
  183. package/dist/Token/index.d.ts.map +1 -1
  184. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  185. package/dist/Tokenizer/Tokenizer.js +2 -2
  186. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  187. package/dist/Tooltip/useTooltip.js +17 -1
  188. package/dist/TopNav/TopNavItem.d.ts +3 -1
  189. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  190. package/dist/TopNav/TopNavItem.js +30 -3
  191. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  192. package/dist/TopNav/TopNavMegaMenu.js +9 -3
  193. package/dist/TreeList/TreeList.d.ts.map +1 -1
  194. package/dist/TreeList/TreeList.js +1 -0
  195. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  196. package/dist/TreeList/TreeListBranches.js +8 -6
  197. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  198. package/dist/TreeList/TreeListItem.js +32 -14
  199. package/dist/Typeahead/BaseTypeahead.d.ts +9 -0
  200. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  201. package/dist/Typeahead/BaseTypeahead.js +2 -0
  202. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  203. package/dist/Typeahead/Typeahead.js +9 -2
  204. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  205. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  206. package/dist/Typeahead/TypeaheadItem.js +20 -10
  207. package/dist/astryx.css +52 -16
  208. package/dist/astryx.umd.js +49 -49
  209. package/dist/astryx.umd.js.map +4 -4
  210. package/dist/hooks/index.d.ts +2 -0
  211. package/dist/hooks/index.d.ts.map +1 -1
  212. package/dist/hooks/index.js +1 -0
  213. package/dist/hooks/useAnnounce.d.ts +3 -0
  214. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  215. package/dist/hooks/useAnnounce.js +39 -1
  216. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  217. package/dist/hooks/useFocusTrap.js +52 -11
  218. package/dist/hooks/useHotkeys.d.ts +9 -0
  219. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  220. package/dist/hooks/useHotkeys.js +9 -0
  221. package/dist/hooks/useInputStatusIcon.d.ts +38 -0
  222. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
  223. package/dist/hooks/useInputStatusIcon.js +169 -0
  224. package/dist/hooks/useKeyboardHint.d.ts +1 -1
  225. package/dist/hooks/useKeyboardHint.d.ts.map +1 -1
  226. package/dist/hooks/useKeyboardHint.js +4 -2
  227. package/dist/hooks/useListFocus.d.ts +33 -0
  228. package/dist/hooks/useListFocus.d.ts.map +1 -1
  229. package/dist/hooks/useListFocus.js +42 -5
  230. package/dist/utils/plainDate.d.ts +17 -0
  231. package/dist/utils/plainDate.d.ts.map +1 -1
  232. package/dist/utils/plainDate.js +23 -4
  233. package/locales/en.json +88 -0
  234. package/locales/pseudo.json +66 -0
  235. package/package.json +1 -1
  236. package/src/Avatar/Avatar.doc.mjs +4 -3
  237. package/src/Avatar/Avatar.test.tsx +93 -0
  238. package/src/Avatar/Avatar.tsx +44 -6
  239. package/src/Avatar/AvatarStatusDot.doc.mjs +3 -3
  240. package/src/Avatar/AvatarStatusDot.tsx +6 -4
  241. package/src/AvatarGroup/AvatarGroup.test.tsx +37 -2
  242. package/src/AvatarGroup/AvatarGroupOverflow.tsx +4 -2
  243. package/src/Breadcrumbs/BreadcrumbItem.tsx +10 -10
  244. package/src/Breadcrumbs/Breadcrumbs.test.tsx +52 -1
  245. package/src/Breadcrumbs/index.ts +4 -0
  246. package/src/Button/Button.test.tsx +16 -0
  247. package/src/Button/Button.tsx +4 -2
  248. package/src/Calendar/Calendar.test.tsx +153 -4
  249. package/src/Calendar/Calendar.tsx +60 -3
  250. package/src/Card/Card.tsx +1 -1
  251. package/src/Chat/ChatMessageBubble.tsx +15 -10
  252. package/src/Chat/ChatSystemMessage.test.tsx +5 -0
  253. package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
  254. package/src/CheckboxInput/CheckboxInput.test.tsx +23 -0
  255. package/src/CheckboxInput/CheckboxInput.tsx +21 -6
  256. package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
  257. package/src/CheckboxList/CheckboxList.test.tsx +94 -3
  258. package/src/CheckboxList/CheckboxListItem.tsx +17 -10
  259. package/src/CodeBlock/CodeBlock.test.tsx +17 -0
  260. package/src/CodeBlock/CodeBlock.tsx +37 -10
  261. package/src/Collapsible/Collapsible.doc.mjs +1 -0
  262. package/src/Collapsible/Collapsible.test.tsx +7 -0
  263. package/src/Collapsible/Collapsible.tsx +16 -6
  264. package/src/CommandPalette/CommandPalette.test.tsx +95 -1
  265. package/src/CommandPalette/CommandPalette.tsx +41 -2
  266. package/src/ContextMenu/ContextMenu.test.tsx +59 -2
  267. package/src/ContextMenu/ContextMenu.tsx +22 -11
  268. package/src/ContextMenu/index.ts +5 -0
  269. package/src/DateInput/DateInput.doc.mjs +15 -5
  270. package/src/DateInput/DateInput.test.tsx +210 -3
  271. package/src/DateInput/DateInput.tsx +41 -29
  272. package/src/DateRangeInput/DateRangeInput.doc.mjs +11 -3
  273. package/src/DateRangeInput/DateRangeInput.test.tsx +120 -3
  274. package/src/DateRangeInput/DateRangeInput.tsx +29 -27
  275. package/src/DateTimeInput/DateTimeInput.doc.mjs +6 -0
  276. package/src/DateTimeInput/DateTimeInput.tsx +18 -25
  277. package/src/Divider/Divider.test.tsx +32 -8
  278. package/src/Divider/Divider.tsx +14 -1
  279. package/src/DropdownMenu/DropdownMenu.tsx +22 -12
  280. package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +4 -12
  281. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +9 -10
  282. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +1 -1
  283. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +20 -2
  284. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
  285. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
  286. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
  287. package/src/DropdownMenu/index.ts +16 -0
  288. package/src/DropdownMenu/menuItemRoles.ts +9 -0
  289. package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
  290. package/src/Field/Field.doc.mjs +4 -0
  291. package/src/Field/Field.tsx +14 -9
  292. package/src/Field/FieldLabel.test.tsx +25 -0
  293. package/src/Field/FieldLabel.tsx +11 -2
  294. package/src/Field/inputStyles.stylex.ts +2 -0
  295. package/src/FieldStatus/FieldStatus.doc.mjs +1 -0
  296. package/src/FieldStatus/FieldStatus.test.tsx +61 -0
  297. package/src/FieldStatus/FieldStatus.tsx +24 -7
  298. package/src/FileInput/FileInput.doc.mjs +12 -6
  299. package/src/FileInput/FileInput.test.tsx +24 -7
  300. package/src/FileInput/FileInput.tsx +80 -67
  301. package/src/Icon/Icon.doc.mjs +13 -0
  302. package/src/Icon/Icon.test.tsx +89 -0
  303. package/src/Icon/Icon.tsx +51 -3
  304. package/src/Item/Item.doc.mjs +5 -0
  305. package/src/Item/Item.test.tsx +88 -0
  306. package/src/Item/Item.tsx +57 -11
  307. package/src/Layer/layerAnimations.stylex.ts +23 -0
  308. package/src/List/List.test.tsx +17 -29
  309. package/src/List/List.tsx +6 -1
  310. package/src/List/ListItem.doc.mjs +12 -0
  311. package/src/List/ListItem.tsx +13 -0
  312. package/src/Markdown/Markdown.test.tsx +21 -0
  313. package/src/Markdown/Markdown.tsx +4 -0
  314. package/src/MetadataList/MetadataList.test.tsx +24 -0
  315. package/src/MetadataList/MetadataList.tsx +6 -2
  316. package/src/MultiSelector/MultiSelector.doc.mjs +11 -0
  317. package/src/MultiSelector/MultiSelector.test.tsx +316 -3
  318. package/src/MultiSelector/MultiSelector.tsx +48 -12
  319. package/src/NumberInput/NumberInput.doc.mjs +11 -5
  320. package/src/NumberInput/NumberInput.tsx +16 -25
  321. package/src/Outline/Outline.test.tsx +12 -12
  322. package/src/Outline/Outline.tsx +2 -2
  323. package/src/ProgressBar/ProgressBar.test.tsx +34 -0
  324. package/src/ProgressBar/ProgressBar.tsx +16 -1
  325. package/src/RadioList/RadioList.doc.mjs +6 -0
  326. package/src/RadioList/RadioList.test.tsx +26 -4
  327. package/src/RadioList/RadioList.tsx +2 -2
  328. package/src/RadioList/RadioListItem.tsx +12 -5
  329. package/src/Resizable/ResizeHandle.test.tsx +94 -0
  330. package/src/Resizable/ResizeHandle.tsx +70 -20
  331. package/src/SegmentedControl/SegmentedControl.test.tsx +28 -0
  332. package/src/SegmentedControl/SegmentedControlItem.tsx +22 -2
  333. package/src/Selector/Selector.doc.mjs +8 -0
  334. package/src/Selector/Selector.test.tsx +239 -11
  335. package/src/Selector/Selector.tsx +33 -4
  336. package/src/SideNav/SideNav.tsx +1 -8
  337. package/src/SideNav/SideNavCollapseButton.tsx +9 -7
  338. package/src/SideNav/SideNavItem.tsx +5 -3
  339. package/src/Skeleton/Skeleton.test.tsx +16 -0
  340. package/src/Skeleton/Skeleton.tsx +13 -1
  341. package/src/Slider/Slider.doc.mjs +6 -0
  342. package/src/Slider/Slider.test.tsx +240 -12
  343. package/src/Slider/Slider.tsx +96 -23
  344. package/src/Spinner/Spinner.test.tsx +10 -8
  345. package/src/Spinner/Spinner.tsx +15 -5
  346. package/src/Switch/Switch.doc.mjs +137 -43
  347. package/src/Switch/Switch.test.tsx +89 -0
  348. package/src/Switch/Switch.tsx +71 -11
  349. package/src/TabList/TabList.doc.mjs +0 -6
  350. package/src/TabList/TabList.test.tsx +3 -15
  351. package/src/TabList/TabList.tsx +6 -17
  352. package/src/TabList/TabListContext.ts +0 -6
  353. package/src/Table/BaseTable.tsx +34 -2
  354. package/src/Table/Table.doc.mjs +11 -0
  355. package/src/Table/Table.test.tsx +85 -0
  356. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +19 -0
  357. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +3 -1
  358. package/src/Table/plugins/selection/useTableSelection.test.tsx +61 -3
  359. package/src/Table/plugins/selection/useTableSelection.tsx +3 -0
  360. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +37 -8
  361. package/src/Table/types.ts +33 -0
  362. package/src/TextArea/TextArea.doc.mjs +11 -5
  363. package/src/TextArea/TextArea.tsx +17 -26
  364. package/src/TextInput/TextInput.doc.mjs +11 -5
  365. package/src/TextInput/TextInput.test.tsx +109 -3
  366. package/src/TextInput/TextInput.tsx +16 -25
  367. package/src/TimeInput/TimeInput.doc.mjs +11 -5
  368. package/src/TimeInput/TimeInput.tsx +14 -25
  369. package/src/Timestamp/Timestamp.doc.mjs +32 -6
  370. package/src/Timestamp/Timestamp.test.tsx +371 -0
  371. package/src/Timestamp/Timestamp.tsx +96 -93
  372. package/src/Timestamp/formatInstant.ts +218 -0
  373. package/src/Timestamp/index.ts +4 -0
  374. package/src/Timestamp/tooltipEntries.test.ts +552 -0
  375. package/src/Timestamp/tooltipEntries.ts +210 -0
  376. package/src/Toast/ToastViewport.test.tsx +218 -8
  377. package/src/Toast/ToastViewport.tsx +71 -12
  378. package/src/ToggleButton/ToggleButton.test.tsx +24 -0
  379. package/src/ToggleButton/ToggleButton.tsx +19 -1
  380. package/src/Token/Token.test.tsx +166 -15
  381. package/src/Token/Token.tsx +104 -47
  382. package/src/Token/TokenLink.tsx +107 -0
  383. package/src/Token/index.ts +1 -1
  384. package/src/Tokenizer/Tokenizer.doc.mjs +8 -1
  385. package/src/Tokenizer/Tokenizer.tsx +4 -2
  386. package/src/Tooltip/Tooltip.test.tsx +46 -0
  387. package/src/Tooltip/useTooltip.tsx +20 -0
  388. package/src/TopNav/TopNav.test.tsx +93 -2
  389. package/src/TopNav/TopNavItem.doc.mjs +3 -3
  390. package/src/TopNav/TopNavItem.tsx +35 -6
  391. package/src/TopNav/TopNavMegaMenu.tsx +26 -2
  392. package/src/TreeList/TreeList.doc.mjs +6 -0
  393. package/src/TreeList/TreeList.test.tsx +50 -10
  394. package/src/TreeList/TreeList.tsx +5 -0
  395. package/src/TreeList/TreeListBranches.tsx +8 -6
  396. package/src/TreeList/TreeListItem.tsx +33 -11
  397. package/src/Typeahead/BaseTypeahead.tsx +12 -0
  398. package/src/Typeahead/Typeahead.doc.mjs +6 -0
  399. package/src/Typeahead/Typeahead.test.tsx +62 -0
  400. package/src/Typeahead/Typeahead.tsx +7 -1
  401. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  402. package/src/__tests__/forcedColors.ts +60 -0
  403. package/src/__tests__/inputWidthContract.test.tsx +62 -0
  404. package/src/doc-mjs.d.ts +19 -0
  405. package/src/hooks/index.ts +6 -0
  406. package/src/hooks/useAnnounce.test.tsx +75 -2
  407. package/src/hooks/useAnnounce.ts +47 -1
  408. package/src/hooks/useFocusTrap.test.tsx +104 -0
  409. package/src/hooks/useFocusTrap.ts +61 -12
  410. package/src/hooks/useHotkeys.ts +9 -0
  411. package/src/hooks/useInputStatusIcon.test.tsx +221 -0
  412. package/src/hooks/useInputStatusIcon.tsx +235 -0
  413. package/src/hooks/useKeyboardHint.test.tsx +22 -0
  414. package/src/hooks/useKeyboardHint.tsx +6 -2
  415. package/src/hooks/useListFocus.doc.mjs +22 -0
  416. package/src/hooks/useListFocus.test.tsx +86 -0
  417. package/src/hooks/useListFocus.ts +81 -4
  418. package/src/utils/plainDate.test.ts +24 -6
  419. package/src/utils/plainDate.ts +18 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,112 @@
1
1
  # @xds/core
2
2
 
3
+ # 0.2.0
4
+
5
+ #### Breaking Changes
6
+
7
+ - TabList: remove orientation prop (misleading no-op). The prop did not render vertical tabs; it only toggled the keyboard-hint badge arrows. Arrow navigation has always accepted both axes (horizontal and vertical) via orientation: both in useListFocus. Run astryx upgrade to auto-strip the prop from your code.
8
+
9
+ #### New Features
10
+
11
+ - `Avatar` gains optional interactivity via `href`/`onClick` (with `as`/`target`/`rel`), following Button's element-swap trichotomy: `href` renders a link through `useLinkComponent`, `onClick` (no href) renders a `<button type="button">`, and with neither the avatar stays the static, non-focusable element it is today (non-breaking default). Interactive avatars get the focus-visible accent ring and a required accessible name (from `alt`/`name`). Inside `AvatarGroup`, interactive avatars — and an interactive `AvatarGroupOverflow` — now share a single Tab stop with roving ArrowLeft/ArrowRight focus, and the group exposes a screen-reader keyboard hint via `aria-describedby`. A purely static facepile is unchanged. (#4170)
12
+ - Citation: `CitationSource.icon` now accepts a `ReactNode` (e.g. an Astryx `<Icon>`, an SVG, or a custom element) in addition to an image URL string, and a new `CitationSource.src` field holds a favicon/logo image URL (mirroring `Avatar`/`Thumbnail`). Additive and non-breaking: a string `icon` still renders as the favicon `<img>`, so existing callers are unaffected. When both a node `icon` and `src` are set, the node wins. The icon stays decorative — the accessible name still comes solely from the citation's `aria-label`.
13
+ - CodeBlock: move the collapse chevron to the left of the title/language label, following the leading-disclosure convention (points right `>` when collapsed, down `v` when expanded). It grows into place (width + inline margin) so it slides the title over smoothly instead of popping in and shifting the header. Respects `prefers-reduced-motion` (#4513)
14
+ - Collapsible: expose the trigger button as a distinct theming target (`astryx-collapsible-trigger`) so themes can style the trigger independently from the content — e.g. a heading font on the trigger while the content keeps the body font.
15
+ - DateInput: add `astryx-date-input-clear-icon` and `astryx-date-input-toggle-icon` theme targets on the clear and calendar-toggle glyphs, so consumers can recolor, resize, and hover-style each icon — and style the toggle's open/closed state — via `defineTheme` instead of a fragile descendant selector or raw CSS. The toggle reflects its open/closed state as a `data-state` attribute. `Icon` now fully handles its styling props (`className`, `style`, `xstyle`) so they compose with its base styles instead of being dropped. Default rendering is unchanged.
16
+ - DateRangeInput: add `astryx-date-range-input-clear-icon` and `astryx-date-range-input-toggle-icon` theme targets on the clear and calendar-toggle glyphs, so consumers can recolor, hover-morph, and resize them via `defineTheme` instead of a fragile descendant selector or raw CSS. The toggle icon reflects its open/closed state as a `data-state` attribute. `Icon` now fully handles its styling props (`className`, `style`, `xstyle`) so they compose with its base styles instead of being dropped. Default rendering is unchanged.
17
+ - DateTimeInput: add `astryx-date-time-input-date-segment` and `astryx-date-time-input-time-segment` theme targets on the two segment wrappers, so a theme can restyle their geometry (padding/height/font) via `defineTheme` instead of being unable to reach them at all. Both reflect `size` and `status` as data attributes, mirroring the root target. Default rendering is unchanged.
18
+ - DropdownMenu: add submenus via a single `DropdownMenuSubMenu` component (or a nested `items` array in data mode). The row adopts DropdownMenuItem semantics (label / icon / description / isDisabled) and its children — or an `items` array — become the flyout content. Flyouts open inline-end with auto-flip, hover-intent, and full keyboard support (Right/Enter/Space opens and focuses the first item; Left/Escape closes and returns focus to the trigger).
19
+ - Bordered inputs gain a `statusVariant="tooltip"` option that hides the status message box and surfaces the status as an info-tip on the on-field status icon. The icon is a real focusable button so the status is reachable by everyone: keyboard users tab to it (with a visible focus ring) and see the message on focus, pointer users see it on hover, and touch users tap to toggle it. The message is piped into both the input's and the button's `aria-describedby`, and the tooltip is dismissible with Escape. Added to TextInput, TextArea, NumberInput, DateInput, DateRangeInput, TimeInput, and FileInput.
20
+ - The bordered input family now accepts a `statusVariant` prop (`'attached' | 'detached'`, default `'attached'`) that forwards to the underlying `Field`, letting you float the status message below the input with spacing instead of overlapping it. Added to TextInput, TextArea, NumberInput, DateInput, DateRangeInput, TimeInput, Selector, MultiSelector, Typeahead, Tokenizer, FileInput, and PowerSearch. Non-breaking: the default matches today's behavior. (#4187)
21
+ - Add RTL direction API: `useDirection()` hook, `getLocaleDirection(locale)` server-safe helper, and an optional `dir` prop on `InternationalizationProvider`.
22
+ - RTL: mirror directional disclosure/navigation chevrons under RTL via a shared `rtlStyles.mirror` CSS transform, applied to the icon wrapper in Lightbox and the Table tree / grouped-rows / row-expansion plugins. The mirror composes correctly with the Table chevrons' state-rotation (expanded chevrons still point down under RTL). Semantic aria-labels are unchanged.
23
+ - Selector & MultiSelector: add `astryx-selector-clear-icon`, `astryx-selector-indicator-icon`, `astryx-multi-selector-clear-icon`, and `astryx-multi-selector-indicator-icon` theme targets on the clear and chevron glyphs, so consumers can recolor, resize, and hover-style each icon — and style the chevron's open/closed state — via `defineTheme` instead of a fragile descendant selector or raw CSS. Each chevron reflects its open/closed state as a `data-state` attribute. `Icon` now fully handles its styling props (`className`, `style`, `xstyle`) so they compose with its base styles instead of being dropped. Default rendering is unchanged.
24
+ - add size prop (sm / md) to Switch to match CheckboxInput and RadioList boolean control scales (#4230)
25
+ - Table: `rowIndexStart` and `rowCount` props expose row numbering as a table-level ARIA concern, so `aria-rowindex`/`aria-rowcount` reflect a row's position in the full dataset: correct across pagination and even when no visible index column is rendered. Opt-in; tables that set neither prop are unchanged. Closes #3939.
26
+ - Timestamp: new `tooltipEntries` prop renders the hover tooltip across several time zones and/or formats at once — one line per entry, each with an optional `timezoneID` (IANA id; omit it or pass `'local'` for the viewer's zone), `format` (every non-relative `TimestampFormat` plus `'full'`), and `label`. The default is unchanged: with no entries the tooltip stays the single full absolute line in the viewer's zone. Configuring entries also attaches the tooltip to absolute formats, which previously had none — note that this gives those timestamps a tab stop and focus ring, as relative timestamps already have, so a column of them gains one tab stop per row. `hasTooltip={false}` still suppresses the tooltip, and an empty array counts as no configuration. Also corrects `isTimezoneShown`'s documentation, which claimed it applied to the `system_date_time` and `system_time` formats; it never has, and those formats stay machine-readable. (#4188)
27
+ - Token: make the `color` prop extensible via module augmentation. `TokenColor` is now derived from a `TokenColorMap` interface, so theme packages can add custom colors (and `astryx theme build` generates the type augmentation), matching Badge and Button.
28
+ - TreeList: the per-level indentation step is now the themeable `--tree-list-indent` variable (default `var(--spacing-4)`), so a theme can retune the indent metric via `defineTheme` on the `tree-list` target instead of the previously hardcoded, unreachable step (#4308).
29
+ - TreeList: add a `variant` prop (`'lineGuides' | 'noGuides'`, default `'lineGuides'`) to select the base hierarchy guide-line look. `noGuides` hides the connector lines while keeping indentation intact. Orthogonal to `density` (spacing); the guides stay themeable via the `astryx-tree-list-guide` target. Non-breaking — omitting the prop renders exactly as before.
30
+
31
+ #### Fixes
32
+
33
+ - Avatar: compose the status dot's label into the avatar's accessible name so assistive tech can reach the status the `role="img"` root previously pruned (WCAG 4.1.2)
34
+ - Calendar: expose selected state in day-button accessible names, announce range-selection progress and completion via the polite live region, and set aria-multiselectable on the grid in range mode
35
+ - CommandPalette: announce result counts, empty, and loading states to screen readers via the shared polite live region (WCAG 4.1.3)
36
+ - Divider: expose the label as the separator's accessible name via aria-labelledby; Spinner: name the status element from the visible label instead of duplicating it as aria-label
37
+ - FileInput: announce the required state via a visually hidden description on the trigger (aria-required is unsupported on role="button") and announce validation errors exactly once
38
+ - hooks: resolve focus-trap Escape by DOM depth instead of push order, exclude aria-hidden subtrees from trap tab cycles, and auto-clear live regions after announcing so stale status text does not linger
39
+ - List: keep list semantics for all listStyle variants by always emitting an explicit role="list", since the base style strips list-style-type for every variant and Safari/VoiceOver drops implicit list roles for such lists (WCAG 1.3.1)
40
+ - NumberInput: announce the units text through the input's accessible description, and stop TextInput/NumberInput from referencing the non-rendered status message id in aria-describedby inside InputGroup
41
+ - reset: stop suppressing `:focus-visible` outlines on coarse-pointer devices so keyboard users keep the WCAG 2.4.7 focus indicator
42
+ - hooks: auto-detect RTL direction for arrow-key navigation in useListFocus and useGridFocus (WCAG 1.3.2)
43
+ - Slider: constrain range thumb aria-valuemin/aria-valuemax by the sibling thumb (including minStepsBetweenThumbs) and render the label as a group label wired via aria-labelledby instead of an inert <label htmlFor>
44
+ - TopNav: disabled TopNavItems now render href-less anchors so they no longer navigate or fire clicks, and Outline's active item uses aria-current="location"
45
+ - Avatar: avoid remounting the avatar subtree when the name tooltip toggles — render the tooltip as a conditional sibling instead of forking the return so the avatar keeps its position in the React tree (and its image-load state) across tooltip changes.
46
+ - Card: rest the bordered variant on the subtle `--color-border` instead of `--color-border-emphasized`, so a Card's outer frame matches its own LayoutHeader/LayoutFooter dividers and neighboring ClickableCards instead of rendering a heavier edge.
47
+ - CheckboxInput, RadioList, Switch: align control sizes. The visible checkbox and radio controls now fill their size exactly (20px at `sm`, 24px at `md`) instead of being inset 2px. The `sm` Switch track is now 32px wide with a 2px inset.
48
+ - Export the `BaseProps` type through the `@astryxdesign/core/BaseProps` subpath. Previously it was only reachable through the package barrel, so the `import type {BaseProps} from '@astryxdesign/core/BaseProps'` specifier that `astryx swizzle` generates failed to resolve (#4091).
49
+ - Guard DropdownMenu item hover styles with `@media (hover: hover)` to prevent sticky highlights on touch devices. Forward BaseProps pass-throughs to the menu element.
50
+ - FieldStatus renders a leading status icon on the `detached` message so status is not conveyed by color/position alone (WCAG 1.4.1). The icon is decorative for assistive tech; the message text and live-region announcement carry the status. The `attached` variant is unchanged.
51
+ - FileInput no longer nests interactive controls (the clear and status buttons) inside a role="button" trigger. The trigger is now a visually hidden button alongside them in a non-interactive container, resolving the nested-interactive a11y violation (WCAG 4.1.2) while keeping click, keyboard, and drag-and-drop behavior. (#4522)
52
+ - Inputs no longer show the hover ring while disabled. The shared input wrapper's disabled state now suppresses both the base and status hover shadows, so TextInput, TextArea, NumberInput, DateInput, TimeInput, Selector, MultiSelector, Typeahead, and Tokenizer stay visually inert on hover when disabled.
53
+ - HoverCard: move themeProps className to the layer container (where bg/radius/shadow live) so themes can target the visual surface. Forward consumer xstyle/className/style to that same layer container so surface customization lands next to the theme class, instead of silently dropping them.
54
+ - With `statusVariant="detached"`, bordered inputs no longer render a status icon inside the control (this also covers DateTimeInput, which is fixed to the detached presentation) — the detached message box already carries a leading icon, so the on-field glyph was a duplicate. Also centers the detached message's icon on the first line of text.
55
+ - DropdownMenu/ContextMenu: mouse hover now moves the highlight instead of adding a second one, so keyboard focus and pointer hover share a single highlighted item (#4493)
56
+ - utils: clamp plainDateAddMonths to the target month's last day
57
+ Adding a month to Jan 31 landed on Mar 3 (Date#setMonth overflow) instead of Feb 28, so month arithmetic from end-of-month dates skipped February entirely. The helper now uses pure month arithmetic and clamps the day, matching Temporal.PlainDate.add and date-fns.
58
+ - Calendar RTL: month-navigation chevrons now mirror correctly under RTL (via the shared `rtlStyles.mirror` transform on the nav-icon wrapper), and the range-selection / hover-preview fill pills use logical CSS (`insetInline*`, `border*Start/EndRadius`) so their rounded start/end caps follow the reading direction instead of the physical left/right. LTR rendering is unchanged.
59
+ - Carousel now supports RTL: the directional scroll-button chevrons mirror under RTL, the scroll buttons respect RTL scroll semantics (previously the button was a no-op under RTL), and the button pills sit on the correct edges.
60
+ - RTL: migrate physical `left`/`right` CSS properties to their logical equivalents so components mirror correctly under `dir="rtl"`. This is the Phase 2 mechanical, one-to-one follow-up to the RTL direction API — a no-op in the default LTR direction with no visual change.
61
+ - RTL Phase 4 (behavioral): mirror directional behavior that logical-CSS and icon name-swaps alone couldn't fix. SideNavCollapseButton and TreeListItem now compose `rtlStyles.mirror` on the icon wrapper outside the state rotation, so the chevrons point toward the correct edge in every collapsed/expanded × LTR/RTL combination. TreeList connector/guide lines position via logical `inset-inline-start`/`inset-inline-end` so they mirror to the inline-start (right) edge under RTL alongside the chevron and row indent. Slider positions its thumb, fill, and marks via logical `inset-inline-start` and flips the physical centering transform under RTL, and its pointer/click math measures the value fraction from the inline-start (right) edge under RTL — so a click at 25% of the track maps to 75 instead of 25.
62
+ - RTL Phase 4b behavioral fixes: ChatMessageBubble grouped-bubble tail corners now use logical border radii so the tail follows reading direction (mirrors under RTL, text unaffected); Table sticky-column shadows make their `translateX` and gradient direction-aware so the shadow fades from the pinned edge toward scrolled content in both LTR and RTL instead of rendering inside-out, and gate shadow visibility on `Math.abs(scrollLeft)` so the start/end shadows still appear under RTL (where spec-compliant browsers report a negative `scrollLeft`); ResizeHandle's hit-area bias is now direction-aware (mirrors about center under RTL) and the pointer-drag delta reads the handle's computed direction so dragging resizes intuitively in RTL.
63
+ - Markdown honors the `components.image` override for standalone (block) images, matching the inline image path. A standalone `![alt](src)` line parses as a block image, whose render path previously hardcoded a bare `<img>` and ignored a supplied `components.image`; it now uses the override just like an inline image does.
64
+ - Selector & MultiSelector: keep group headers visible while searching; hide groups with no matching items. Previously, typing a query flattened grouped options into a single ungrouped list; now each group header stays above its matching items and a group is hidden only when none of its items match.
65
+ - SideNav: remove the top border above the footer region so the `footer` slot no longer renders a divider line.
66
+ - Slider: round snapped values to the min/step decimal precision
67
+ With fractional steps, `min + steps * step` accumulated binary floating-point error, so a keyboard nudge on a `step={0.1}` slider emitted `0.30000000000000004` through `onChange`/`onChangeEnd` (and into `aria-valuenow`/the value tooltip once the consumer echoed it back). Snapped values are now rounded to the combined decimal precision of `min` and `step`, which removes only the error — exact steps are unaffected.
68
+ - Tooltip: dismiss the tooltip when its trigger is pressed. Previously the tooltip stayed open through a click (e.g. a "Copy link" button's tooltip lingered after activation); now pressing the trigger hides its own tooltip. Applies to uncontrolled tooltips only.
69
+ - Typeahead: omit aria-activedescendant when search results are empty or index is out of bounds (#4059)
70
+
71
+ #### Documentation
72
+
73
+ - document `width` prop across 17 input component doc files (#4163)
74
+
75
+ #### Other Changes
76
+
77
+ - Add `@astryx/no-physical-properties` ESLint rule that flags physical left/right CSS properties inside `stylex.create()` and suggests the CSS logical equivalent for RTL support.
78
+ - KEY-BASED: `marginLeft`/`marginRight`, `paddingLeft`/`paddingRight`, `borderLeft`/`borderRight` (+ their `Width`/`Style`/`Color` longhands), `left`/`right` → `insetInlineStart`/`insetInlineEnd`, and the four physical corner radii → their diagonal-aware logical names (`borderTopLeftRadius` → `borderStartStartRadius`, etc.).
79
+ - VALUE-BASED: `textAlign: 'left'|'right'`, `float: 'left'|'right'`, and `clear: 'left'|'right'` (the key stays, only the physical value is flagged).
80
+ - Scoped strictly to `stylex.create()` — physical identifiers used elsewhere are ignored.
81
+ - `useDirection()` returns `'ltr' | 'rtl'` for the current provider context (falls back to `'ltr'` when called outside a provider).
82
+ - `getLocaleDirection(locale)` computes direction from a BCP 47 locale via `Intl.Locale.getTextInfo()` — safe to call from React Server Components and Next.js layouts to set `<html dir>`.
83
+ - `<InternationalizationProvider locale="ar">` auto-derives `dir="rtl"`. Pass an explicit `dir` prop to override (useful for RTL testing under an English catalog, or to force LTR).
84
+ - Pagination is the first component to consume the hook: prev/next chevron icons flip under RTL while the aria-labels stay semantic.
85
+ - Storybook gains a global `Direction` toolbar for toggling every story between LTR and RTL.
86
+ - Component-level CSS migrations (borders, chevrons, sliders, calendar range pills, etc.) land in follow-up PRs.
87
+ - `textAlign: 'left' | 'right'` → `'start' | 'end'` (Selector, Typeahead, Chat trigger menu, DropdownMenu, CommandPalette, NavMenu items).
88
+ - `borderLeft*`/`borderRight*` → `borderInlineStart*`/`borderInlineEnd*`, kept as separate start/end declarations (Banner, Table cell/header dividers, DateRangeInput preset sidebar).
89
+ - Static `left`/`right` positioning → `insetInlineStart`/`insetInlineEnd` for full-bleed overlays and single-side offsets (Button spinner overlay, Chat dock/blur/placeholder, Field sr-only label, Lightbox close/nav/counter buttons, TabList indicators, Thumbnail remove slot, CodeBlock copy button).
90
+ - Inline `marginLeft` indentation → `marginInlineStart` (TreeList rows).
91
+
92
+ #### Contributors
93
+
94
+ Thanks to everyone who contributed to this release:
95
+
96
+ - @AKnassa
97
+ - @arham766
98
+ - @bhamodi
99
+ - @cixzhang
100
+ - @ernestt
101
+ - @freddymeta
102
+ - @HelloOjasMutreja
103
+ - @humbertovirtudes
104
+ - @kentonquatman
105
+ - @lexs
106
+ - @nynexman4464
107
+
108
+ ---
109
+
3
110
  # 0.1.9
4
111
 
5
112
  #### New Features
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file Avatar.tsx
3
3
  * @input Uses React, HTMLAttributes, ReactNode, useState; useTooltip
4
- * (Tooltip hook) for the optional name-on-hover tooltip
4
+ * (Tooltip hook) for the optional name-on-hover tooltip; useTranslator (i18n)
5
5
  * @output Exports Avatar component, AvatarProps, AvatarSize types
6
6
  * @position Core implementation; consumed by index.ts
7
7
  *
@@ -72,6 +72,11 @@ export interface AvatarProps extends BaseProps<HTMLDivElement> {
72
72
  /**
73
73
  * Content displayed in the corner of the avatar.
74
74
  * Typically used for status indicators or badges.
75
+ *
76
+ * When the element carries a string `label` prop (as `AvatarStatusDot`
77
+ * does), the label is composed into the avatar's accessible name
78
+ * (e.g. "Jane Doe, Online") so assistive tech can reach the status —
79
+ * the `role="img"` root prunes descendant semantics (WCAG 4.1.2).
75
80
  */
76
81
  status?: ReactNode;
77
82
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/Avatar/Avatar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACxD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAc5C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AA2BrD;;;;;;GAMG;AACH,KAAK,eAAe,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzD;;GAEG;AACH,KAAK,iBAAiB,GACpB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAgBpD;AAiJD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CAChD;AAsCD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,EACrB,GAAG,EACH,aAAa,EAAE,MAAM,EACrB,WAAW,EACX,IAAI,EACJ,IAAW,EACX,GAAG,EACH,MAAM,EACN,OAAc,EACd,IAAI,EACJ,EAAE,EACF,MAAM,EACN,GAAG,EACH,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAsOb;yBAzPe,MAAM"}
1
+ {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../src/Avatar/Avatar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAoC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACxE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAc5C,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AA4BrD;;;;;;GAMG;AACH,KAAK,eAAe,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzD;;GAEG;AACH,KAAK,iBAAiB,GACpB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAEzE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,iBAAiB,CAAC;AAE7D;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAgBpD;AAiJD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CAChD;AAwDD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,EACrB,GAAG,EACH,aAAa,EAAE,MAAM,EACrB,WAAW,EACX,IAAI,EACJ,IAAW,EACX,GAAG,EACH,MAAM,EACN,OAAc,EACd,IAAI,EACJ,EAAE,EACF,MAAM,EACN,GAAG,EACH,OAAO,EACP,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAoPb;yBAvQe,MAAM"}
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @file Avatar.tsx
7
7
  * @input Uses React, HTMLAttributes, ReactNode, useState; useTooltip
8
- * (Tooltip hook) for the optional name-on-hover tooltip
8
+ * (Tooltip hook) for the optional name-on-hover tooltip; useTranslator (i18n)
9
9
  * @output Exports Avatar component, AvatarProps, AvatarSize types
10
10
  * @position Core implementation; consumed by index.ts
11
11
  *
@@ -17,7 +17,7 @@
17
17
  *
18
18
  * Last synced props: alt, fallbackSrc, name, size, src, status, href, as, target, rel, onClick
19
19
  */
20
- import { useMemo, useState } from 'react';
20
+ import { isValidElement, useMemo, useState } from 'react';
21
21
  import * as stylex from '@stylexjs/stylex';
22
22
  import "../theme/tokens.stylex.js";
23
23
  import { colorVars, typographyVars, fontWeightVars, radiusVars } from "../theme/tokens.stylex.js";
@@ -27,7 +27,8 @@ import { mergeProps, mergeRefs } from "../utils/index.js";
27
27
  import { themeProps } from "../utils/themeProps.js";
28
28
  import { useTooltip } from "../Tooltip/useTooltip.js";
29
29
  import { useLinkComponent } from "../Link/useLinkComponent.js";
30
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
30
+ import { useTranslator } from "../i18n/index.js";
31
+
31
32
  /**
32
33
  * The offset ratio for positioning elements on a circle's edge at 45°.
33
34
  *
@@ -40,6 +41,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
40
41
  *
41
42
  * This constant represents that ratio: (1 - 1/√2) / 2 ≈ 0.146
42
43
  */
44
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
43
45
  const CIRCLE_EDGE_OFFSET_RATIO = (1 - 1 / Math.SQRT2) / 2;
44
46
 
45
47
  /**
@@ -228,6 +230,26 @@ function getInitials(name) {
228
230
  return (words[0].charAt(0) + words[words.length - 1].charAt(0)).toUpperCase();
229
231
  }
230
232
 
233
+ /**
234
+ * Reads the accessible status label off the `status` element, when it
235
+ * exposes one. `AvatarStatusDot`'s `label` prop is the canonical source,
236
+ * but any custom status element with a string `label` prop participates.
237
+ *
238
+ * The avatar root is `role="img"`, which prunes ALL descendant semantics
239
+ * from the accessibility tree — a label inside the status subtree is never
240
+ * announced on its own. Composing it into the avatar's own accessible name
241
+ * is the only way the status reaches assistive tech (WCAG 4.1.2).
242
+ */
243
+ function getStatusLabel(status) {
244
+ if (! /*#__PURE__*/isValidElement(status)) {
245
+ return undefined;
246
+ }
247
+ const {
248
+ label
249
+ } = status.props;
250
+ return typeof label === 'string' && label !== '' ? label : undefined;
251
+ }
252
+
231
253
  /**
232
254
  * Default person icon SVG for when no image or name is provided
233
255
  */
@@ -292,10 +314,21 @@ export function Avatar({
292
314
  const showInitials = !showImage && !showFallbackImage && name;
293
315
  const showIcon = !showImage && !showFallbackImage && !name;
294
316
 
295
- // A meaningful accessible name comes from `alt` or `name`. With neither, the
296
- // avatar is decorative — expose it as `presentation`/`aria-hidden` rather than
297
- // announcing a meaningless generic "Avatar" (obs-9).
298
- const accessibleName = alt || name;
317
+ // A meaningful accessible name comes from `alt`/`name`, composed with the
318
+ // status element's `label` when one is present ("Jane Doe, Online") — the
319
+ // `role="img"` root prunes descendant semantics, so surfacing the label in
320
+ // the avatar's own name is the only way assistive tech can reach the
321
+ // status (WCAG 4.1.2). A labelled status alone is also meaningful. With
322
+ // neither a name nor a labelled status, the avatar is decorative — expose
323
+ // it as `presentation`/`aria-hidden` rather than announcing a meaningless
324
+ // generic "Avatar" (obs-9).
325
+ const t = useTranslator();
326
+ const nameLabel = alt || name;
327
+ const statusLabel = getStatusLabel(status);
328
+ const accessibleName = nameLabel && statusLabel ? t('@astryx.avatar.nameWithStatus', {
329
+ name: nameLabel,
330
+ status: statusLabel
331
+ }) : nameLabel || statusLabel;
299
332
  const isDecorative = !accessibleName;
300
333
  const avatarGroup = useAvatarGroup();
301
334
  const resolvedSize = avatarGroup?.size ?? size;
@@ -60,10 +60,12 @@ export interface AvatarStatusDotProps extends BaseProps<HTMLDivElement> {
60
60
  * Describes the meaning of the indicator for screen readers
61
61
  * (e.g. "Online", "Accepted", "John Doe is busy").
62
62
  *
63
- * Note: inside an Avatar the label is currently not announced — the
64
- * Avatar root is `role="img"`, which prunes descendant semantics.
65
- * Pass it anyway; composing status into the avatar's accessible name
66
- * is a planned Avatar-level fix.
63
+ * Note: inside an Avatar the dot sits in the avatar's `role="img"`
64
+ * subtree, where descendant semantics are pruned — the dot is never its
65
+ * own stop there. Instead, Avatar reads this `label` and composes it into
66
+ * its own accessible name (e.g. "Jane Doe, Online"), which is how the
67
+ * status reaches assistive tech (WCAG 4.1.2). Standalone dots (outside an
68
+ * Avatar) expose `role="img"` with this label directly.
67
69
  */
68
70
  label?: string;
69
71
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarStatusDot.d.ts","sourceRoot":"","sources":["../../src/Avatar/AvatarStatusDot.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAAM,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAiD5C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;CACb;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,yBAAyB,CAAC;AAErE,MAAM,WAAW,oBAAqB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACrE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AA2JD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,OAAmB,EACnB,KAAK,EACL,IAAI,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,oBAAoB,qBAyCtB;yBAlDe,eAAe"}
1
+ {"version":3,"file":"AvatarStatusDot.d.ts","sourceRoot":"","sources":["../../src/Avatar/AvatarStatusDot.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAAM,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACjD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAiD5C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;CACb;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,MAAM,yBAAyB,CAAC;AAErE,MAAM,WAAW,oBAAqB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACrE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AA2JD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,OAAmB,EACnB,KAAK,EACL,IAAI,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,oBAAoB,qBAyCtB;yBAlDe,eAAe"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file AvatarGroupOverflow.tsx
3
- * @input Uses React, StyleX, AvatarGroupContext
3
+ * @input Uses React, StyleX, AvatarGroupContext, i18n (useTranslator)
4
4
  * @output Exports AvatarGroupOverflow for overflow indicator
5
5
  * @position Slot component used inside AvatarGroup
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarGroupOverflow.d.ts","sourceRoot":"","sources":["../../src/AvatarGroup/AvatarGroupOverflow.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAW5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAM5C,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,SAAS,CAAC,WAAW,CAAC,EACtB,SAAS,CACV;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA4ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,GAAG,EACH,KAAK,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,wBAAwB,GAAG,SAAS,CAyDtC;yBAlEe,mBAAmB"}
1
+ {"version":3,"file":"AvatarGroupOverflow.d.ts","sourceRoot":"","sources":["../../src/AvatarGroup/AvatarGroupOverflow.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAW5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAO5C,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CACpD,SAAS,CAAC,WAAW,CAAC,EACtB,SAAS,CACV;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC7B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA4ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,GAAG,EACH,KAAK,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,wBAAwB,GAAG,SAAS,CA0DtC;yBAnEe,mBAAmB"}
@@ -3,7 +3,7 @@
3
3
 
4
4
  /**
5
5
  * @file AvatarGroupOverflow.tsx
6
- * @input Uses React, StyleX, AvatarGroupContext
6
+ * @input Uses React, StyleX, AvatarGroupContext, i18n (useTranslator)
7
7
  * @output Exports AvatarGroupOverflow for overflow indicator
8
8
  * @position Slot component used inside AvatarGroup
9
9
  *
@@ -19,6 +19,7 @@ import { colorVars, typographyVars, fontWeightVars, radiusVars, spacingVars } fr
19
19
  import { mergeProps } from "../utils/index.js";
20
20
  import { useAvatarGroup } from "./AvatarGroupContext.js";
21
21
  import { themeProps } from "../utils/themeProps.js";
22
+ import { useTranslator } from "../i18n/index.js";
22
23
  import { jsx as _jsx } from "react/jsx-runtime";
23
24
  const BORDER_WIDTH = 2;
24
25
  const OVERFLOW_FONT_RATIO = 0.35;
@@ -105,10 +106,13 @@ export function AvatarGroupOverflow({
105
106
  style,
106
107
  ...rest
107
108
  }) {
109
+ const t = useTranslator();
108
110
  const group = useAvatarGroup();
109
111
  const numericSize = group?.numericSize ?? 36;
110
112
  const overlap = group?.overlap ?? 0;
111
- const label = `${count} more`;
113
+ const label = t('@astryx.avatarGroup.overflow', {
114
+ count
115
+ });
112
116
  const content = children ?? `+${count}`;
113
117
  if (onClick) {
114
118
  return /*#__PURE__*/_jsx("button", {
@@ -1 +1 @@
1
- {"version":3,"file":"BreadcrumbItem.d.ts","sourceRoot":"","sources":["../../src/Breadcrumbs/BreadcrumbItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAQ5C,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,qCAAqC,CAAC;AAK7C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAMrE,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,SAAS,CAAC,aAAa,CAAC,EACxB,SAAS,CACV;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC/C;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AA8GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAC7B,GAAG,EACH,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,SAAS,EAAE,aAAa,EACxB,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,IAAI,EACR,EAAE,mBAAmB,qBAoMrB;yBAnNe,cAAc"}
1
+ {"version":3,"file":"BreadcrumbItem.d.ts","sourceRoot":"","sources":["../../src/Breadcrumbs/BreadcrumbItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,EAOZ,KAAK,SAAS,EACd,KAAK,UAAU,EAChB,MAAM,OAAO,CAAC;AAUf,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC;AAErD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAQ5C,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,qCAAqC,CAAC;AAM7C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAC;AAMrE,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,SAAS,CAAC,aAAa,CAAC,EACxB,SAAS,CACV;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;OAIG;IACH,EAAE,CAAC,EAAE,iBAAiB,CAAC;IACvB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC/C;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AA8GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAC7B,GAAG,EACH,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,SAAS,EAAE,aAAa,EACxB,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,IAAI,EACR,EAAE,mBAAmB,qBAoMrB;yBAnNe,cAAc"}
@@ -36,7 +36,7 @@ import { useTypeahead } from "../hooks/useTypeahead.js";
36
36
  import { layerAnimations } from "../Layer/layerAnimations.stylex.js";
37
37
  import { renderDropdownItems } from "../DropdownMenu/renderDropdownItems.js";
38
38
  import { DropdownMenuContext } from "../DropdownMenu/DropdownMenuContext.js";
39
- import { MENU_ITEM_ROLES, MENU_ITEM_SELECTOR } from "../DropdownMenu/menuItemRoles.js";
39
+ import { MENU_ITEM_ROLES, MENU_ITEM_SELECTOR, MENU_BOUNDARY_SELECTOR } from "../DropdownMenu/menuItemRoles.js";
40
40
 
41
41
  // =============================================================================
42
42
  // Props
@@ -319,19 +319,26 @@ function BreadcrumbMenuTrigger({
319
319
  listRef,
320
320
  handleKeyDown: listNavKeyDown,
321
321
  focusFirst,
322
- focusItem
322
+ focusItem,
323
+ ownsEvent,
324
+ getItems: getMenuItems
323
325
  } = useListFocus({
324
326
  itemSelector: MENU_ITEM_SELECTOR,
327
+ boundarySelector: MENU_BOUNDARY_SELECTOR,
325
328
  wrap: false,
326
329
  onEscape: closeMenu
327
330
  });
328
- const getMenuItems = useCallback(() => listRef.current ? Array.from(listRef.current.querySelectorAll(MENU_ITEM_SELECTOR)) : [], [listRef]);
329
331
  const typeahead = useTypeahead({
330
332
  getItemLabels: () => getMenuItems().map(el => el.textContent),
331
333
  onMatch: focusItem,
332
334
  getCurrentIndex: () => getMenuItems().findIndex(el => el === document.activeElement || el.contains(document.activeElement))
333
335
  });
334
336
  const listKeyDown = useCallback(e => {
337
+ // A submenu flyout renders inline inside this menu; its key events bubble
338
+ // up here. Let that level own them — only handle events from this level.
339
+ if (!ownsEvent(e)) {
340
+ return;
341
+ }
335
342
  if (e.key === 'Enter' || e.key === ' ') {
336
343
  e.preventDefault();
337
344
  const focused = document.activeElement;
@@ -350,7 +357,7 @@ function BreadcrumbMenuTrigger({
350
357
  return;
351
358
  }
352
359
  listNavKeyDown(e);
353
- }, [listNavKeyDown, closeMenu, typeahead]);
360
+ }, [listNavKeyDown, closeMenu, typeahead, ownsEvent]);
354
361
  const openAndFocus = useCallback(() => {
355
362
  popover.show();
356
363
  requestAnimationFrame(() => focusFirst());
@@ -9,5 +9,6 @@ export { DropdownMenuItem as BreadcrumbMenuItem, type DropdownMenuItemProps as B
9
9
  export { DropdownMenuCheckboxItem as BreadcrumbMenuCheckboxItem, type DropdownMenuCheckboxItemProps as BreadcrumbMenuCheckboxItemProps, } from '../DropdownMenu/DropdownMenuCheckboxItem';
10
10
  export { DropdownMenuRadioGroup as BreadcrumbMenuRadioGroup, type DropdownMenuRadioGroupProps as BreadcrumbMenuRadioGroupProps, } from '../DropdownMenu/DropdownMenuRadioGroup';
11
11
  export { DropdownMenuRadioItem as BreadcrumbMenuRadioItem, type DropdownMenuRadioItemProps as BreadcrumbMenuRadioItemProps, } from '../DropdownMenu/DropdownMenuRadioItem';
12
+ export { DropdownMenuSubMenu as BreadcrumbMenuSubMenu, type DropdownMenuSubMenuProps as BreadcrumbMenuSubMenuProps, } from '../DropdownMenu/DropdownMenuSubMenu';
12
13
  export type { DropdownMenuOption as BreadcrumbMenuOption, DropdownMenuItemData as BreadcrumbMenuItemData, DropdownMenuDivider as BreadcrumbMenuDivider, DropdownMenuSection as BreadcrumbMenuSection, } from '../DropdownMenu/DropdownMenu';
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Breadcrumbs/index.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AAM1D,OAAO,EACL,gBAAgB,IAAI,kBAAkB,EACtC,KAAK,qBAAqB,IAAI,uBAAuB,GACtD,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,wBAAwB,IAAI,0BAA0B,EACtD,KAAK,6BAA6B,IAAI,+BAA+B,GACtE,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,sBAAsB,IAAI,wBAAwB,EAClD,KAAK,2BAA2B,IAAI,6BAA6B,GAClE,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,qBAAqB,IAAI,uBAAuB,EAChD,KAAK,0BAA0B,IAAI,4BAA4B,GAChE,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EACV,kBAAkB,IAAI,oBAAoB,EAC1C,oBAAoB,IAAI,sBAAsB,EAC9C,mBAAmB,IAAI,qBAAqB,EAC5C,mBAAmB,IAAI,qBAAqB,GAC7C,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Breadcrumbs/index.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AAM1D,OAAO,EACL,gBAAgB,IAAI,kBAAkB,EACtC,KAAK,qBAAqB,IAAI,uBAAuB,GACtD,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,wBAAwB,IAAI,0BAA0B,EACtD,KAAK,6BAA6B,IAAI,+BAA+B,GACtE,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,sBAAsB,IAAI,wBAAwB,EAClD,KAAK,2BAA2B,IAAI,6BAA6B,GAClE,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,qBAAqB,IAAI,uBAAuB,EAChD,KAAK,0BAA0B,IAAI,4BAA4B,GAChE,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,mBAAmB,IAAI,qBAAqB,EAC5C,KAAK,wBAAwB,IAAI,0BAA0B,GAC5D,MAAM,qCAAqC,CAAC;AAC7C,YAAY,EACV,kBAAkB,IAAI,oBAAoB,EAC1C,oBAAoB,IAAI,sBAAsB,EAC9C,mBAAmB,IAAI,qBAAqB,EAC5C,mBAAmB,IAAI,qBAAqB,GAC7C,MAAM,8BAA8B,CAAC"}
@@ -14,4 +14,5 @@ export { BreadcrumbItem } from "./BreadcrumbItem.js";
14
14
  export { DropdownMenuItem as BreadcrumbMenuItem } from "../DropdownMenu/DropdownMenuItem.js";
15
15
  export { DropdownMenuCheckboxItem as BreadcrumbMenuCheckboxItem } from "../DropdownMenu/DropdownMenuCheckboxItem.js";
16
16
  export { DropdownMenuRadioGroup as BreadcrumbMenuRadioGroup } from "../DropdownMenu/DropdownMenuRadioGroup.js";
17
- export { DropdownMenuRadioItem as BreadcrumbMenuRadioItem } from "../DropdownMenu/DropdownMenuRadioItem.js";
17
+ export { DropdownMenuRadioItem as BreadcrumbMenuRadioItem } from "../DropdownMenu/DropdownMenuRadioItem.js";
18
+ export { DropdownMenuSubMenu as BreadcrumbMenuSubMenu } from "../DropdownMenu/DropdownMenuSubMenu.js";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @file Button.tsx
3
- * @input Uses React, ButtonHTMLAttributes, ReactNode
3
+ * @input Uses React, ButtonHTMLAttributes, ReactNode, i18n (useTranslator)
4
4
  * @output Exports Button component, ButtonProps, ButtonVariant types
5
5
  * @position Core implementation; consumed by index.ts, tested by Button.test.tsx
6
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/Button/Button.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../src/Button/Button.tsx"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file Button.tsx
7
- * @input Uses React, ButtonHTMLAttributes, ReactNode
7
+ * @input Uses React, ButtonHTMLAttributes, ReactNode, i18n (useTranslator)
8
8
  * @output Exports Button component, ButtonProps, ButtonVariant types
9
9
  * @position Core implementation; consumed by index.ts, tested by Button.test.tsx
10
10
  *
@@ -30,6 +30,7 @@ import { useButtonGroup } from "../ButtonGroup/ButtonGroupContext.js";
30
30
  import { mergeProps, mergeRefs } from "../utils/index.js";
31
31
  import { useLinkComponent } from "../Link/useLinkComponent.js";
32
32
  import { themeProps } from "../utils/themeProps.js";
33
+ import { useTranslator } from "../i18n/index.js";
33
34
 
34
35
  /**
35
36
  * Base button styles
@@ -376,6 +377,7 @@ export function Button({
376
377
  ref,
377
378
  ...props
378
379
  }) {
380
+ const t = useTranslator();
379
381
  const size = useSize(sizeProp, 'md');
380
382
  const buttonGroup = useButtonGroup();
381
383
  const [isPending, startTransition] = useTransition();
@@ -498,7 +500,7 @@ export function Button({
498
500
  }), /*#__PURE__*/_jsx(VisuallyHidden, {
499
501
  role: "status",
500
502
  "aria-live": "polite",
501
- children: isLoadingState ? 'Loading' : ''
503
+ children: isLoadingState ? t('@astryx.button.loading') : ''
502
504
  })]
503
505
  });
504
506
 
@@ -1 +1 @@
1
- {"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../src/Calendar/Calendar.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA8C5C,YAAY,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,SAAS,EACV,MAAM,oBAAoB,CAAC;AAK5B,+CAA+C;AAE/C,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,UAAU,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CAC3C;AAID,UAAU,iBAAkB,SAAQ,IAAI,CACtC,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,GAAG,cAAc,CAC5B;IACC,kDAAkD;IAClD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qDAAqD;IACrD,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACtC,+CAA+C;IAC/C,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAEvB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC;IAEpB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC;IAEpB;;;OAGG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC;IAEzD;;;OAGG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI,CAAC;IAEvD;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;CAC1C;AAID,UAAU,mBAAoB,SAAQ,iBAAiB;IACrD,qBAAqB;IACrB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAEhB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,aAAa,CAAC;IAE7B,qCAAqC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,KAAK,IAAI,CAAC;CAC9D;AAED,UAAU,kBAAmB,SAAQ,iBAAiB;IACpD,qBAAqB;IACrB,IAAI,EAAE,OAAO,CAAC;IAEd,0BAA0B;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,SAAS,CAAC;IAEzB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AAMrE;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,EAAE,aAAa,+BAyUtD;yBAzUe,QAAQ"}
1
+ {"version":3,"file":"Calendar.d.ts","sourceRoot":"","sources":["../../src/Calendar/Calendar.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA8C5C,YAAY,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,SAAS,EACV,MAAM,oBAAoB,CAAC;AAK5B,+CAA+C;AAE/C,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,UAAU,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;CAC3C;AAID,UAAU,iBAAkB,SAAQ,IAAI,CACtC,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,GAAG,cAAc,CAC5B;IACC,kDAAkD;IAClD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qDAAqD;IACrD,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACtC,+CAA+C;IAC/C,cAAc,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAEvB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC;IAEpB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC;IAEpB;;;OAGG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC;IAEzD;;;OAGG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAE1B,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI,CAAC;IAEvD;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,GAAG,aAAa,CAAC;CAC1C;AAID,UAAU,mBAAoB,SAAQ,iBAAiB;IACrD,qBAAqB;IACrB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAEhB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,aAAa,CAAC;IAE7B,qCAAqC;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,KAAK,IAAI,CAAC;CAC9D;AAED,UAAU,kBAAmB,SAAQ,iBAAiB;IACpD,qBAAqB;IACrB,IAAI,EAAE,OAAO,CAAC;IAEd,0BAA0B;IAC1B,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,SAAS,CAAC;IAEzB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AAMrE;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,EAAE,aAAa,+BA+VtD;yBA/Ve,QAAQ"}
@@ -235,8 +235,14 @@ export function Calendar({
235
235
  } else {
236
236
  // Range mode
237
237
  if (rangeSelectionStart === null) {
238
- // First click - start the range
238
+ // First click - start the range. Nothing else about this pick is
239
+ // perceivable non-visually (WCAG 1.3.1) — the grid doesn't move, so
240
+ // the month-change announcement stays silent — so speak the range
241
+ // progress through the same polite live region.
239
242
  setRangeSelectionStart(iso);
243
+ announce(t('@astryx.calendar.rangeStartAnnounce', {
244
+ date: plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY)
245
+ }));
240
246
  } else {
241
247
  // Second click - complete the range
242
248
  const startPd = plainDateFromISO(rangeSelectionStart);
@@ -258,9 +264,15 @@ export function Calendar({
258
264
  setInternalValue(range);
259
265
  setRangeSelectionStart(null);
260
266
  onChange?.(range);
267
+ // Completed-range announcement, in chronological order (matches the
268
+ // swapped {start, end} above even for a reverse pick).
269
+ announce(t('@astryx.calendar.rangeCompleteAnnounce', {
270
+ start: plainDateFormat(plainDateFromISO(start), DATE_FORMAT_WITH_WEEKDAY),
271
+ end: plainDateFormat(plainDateFromISO(end), DATE_FORMAT_WITH_WEEKDAY)
272
+ }));
261
273
  }
262
274
  }
263
- }, [mode, onChange, rangeSelectionStart]);
275
+ }, [mode, onChange, rangeSelectionStart, announce, t]);
264
276
  return /*#__PURE__*/_jsxs("div", {
265
277
  ref: ref,
266
278
  ...rest,
@@ -559,7 +571,11 @@ function MonthGrid({
559
571
  children: /*#__PURE__*/_jsxs("div", {
560
572
  ref: gridRef,
561
573
  role: "grid",
562
- "aria-label": monthLabel,
574
+ "aria-label": monthLabel
575
+ // APG grid pattern: a range selection holds multiple selected cells,
576
+ // so the grid must advertise multi-selectability.
577
+ ,
578
+ "aria-multiselectable": mode === 'range' ? true : undefined,
563
579
  onKeyDown: handleGridKeyDown,
564
580
  onFocus: handleGridFocus,
565
581
  ...stylex.props(monthGridStyles.daysGrid, hasWeekNumbers && monthGridStyles.daysGridWithNumbers),
@@ -612,6 +628,7 @@ function MonthGrid({
612
628
  isDisabled: isDateDisabled(day.date),
613
629
  neighbors: neighbors,
614
630
  isTabbable: day.iso === seedTabbableIso,
631
+ isRangeSelectionInProgress: rangeSelectionStart !== null,
615
632
  onDayClick: onDayClick,
616
633
  onDayHover: onDayHover
617
634
  }, day.iso);
@@ -640,9 +657,11 @@ function DayCell({
640
657
  isDisabled,
641
658
  neighbors,
642
659
  isTabbable: isTabbableDay,
660
+ isRangeSelectionInProgress,
643
661
  onDayClick,
644
662
  onDayHover
645
663
  }) {
664
+ const t = useTranslator();
646
665
  const {
647
666
  date,
648
667
  isOutside,
@@ -679,6 +698,28 @@ function DayCell({
679
698
  const showsTodayRing = state.isToday && !state.isSelected && !state.isInRange;
680
699
  const showsTodayInRangeRing = state.isToday && !state.isSelected && state.isInRange;
681
700
  const markerState = showsTodayRing ? 'today-only' : showsTodayInRangeRing ? 'today-in-range' : null;
701
+
702
+ // Accessible name for the day button. Roving focus lands on the <button>,
703
+ // not the role="gridcell" wrapper that carries aria-selected — and
704
+ // aria-selected is invalid on role="button" — so the selection/range state
705
+ // must be encoded into the button's name (WCAG 4.1.2). Localized via ICU
706
+ // params rather than string concatenation. A mid-flight first pick (where
707
+ // rangeStart === rangeEnd) reads as "range start" only; a completed one-day
708
+ // range reads as both start and end.
709
+ const dateLabel = plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY);
710
+ const dayLabel = state.isSelected ? t('@astryx.calendar.daySelected', {
711
+ date: dateLabel
712
+ }) : state.isRangeStart && state.isRangeEnd ? isRangeSelectionInProgress ? t('@astryx.calendar.dayRangeStart', {
713
+ date: dateLabel
714
+ }) : t('@astryx.calendar.dayRangeStartAndEnd', {
715
+ date: dateLabel
716
+ }) : state.isRangeStart ? t('@astryx.calendar.dayRangeStart', {
717
+ date: dateLabel
718
+ }) : state.isRangeEnd ? t('@astryx.calendar.dayRangeEnd', {
719
+ date: dateLabel
720
+ }) : state.isInRange ? t('@astryx.calendar.dayInRange', {
721
+ date: dateLabel
722
+ }) : dateLabel;
682
723
  const rangeRounding = computeRangeRounding(state, {
683
724
  prevInRange: neighbors.prevInRange,
684
725
  nextInRange: neighbors.nextInRange
@@ -698,7 +739,7 @@ function DayCell({
698
739
  }), /*#__PURE__*/_jsx("button", {
699
740
  type: "button",
700
741
  "data-date": day.iso,
701
- "aria-label": plainDateFormat(date, DATE_FORMAT_WITH_WEEKDAY),
742
+ "aria-label": dayLabel,
702
743
  "aria-disabled": state.effectivelyDisabled || undefined
703
744
  // Mark today's cell programmatically (APG date-picker pattern), not just
704
745
  // visually, so screen-reader users can identify the current date.
package/dist/Card/Card.js CHANGED
@@ -55,7 +55,7 @@ const styles = {
55
55
  withBorder: {
56
56
  kMzoRj: "x1litavf",
57
57
  ksu8eU: "x1y0btm7",
58
- kVAM5u: "xvy26l8",
58
+ kVAM5u: "x14i3s5s",
59
59
  kZCmMZ: "xs19ii7",
60
60
  kwRFfy: "x12frdag",
61
61
  kLKAdn: "x1nex4ik",
@@ -1 +1 @@
1
- {"version":3,"file":"ChatMessageBubble.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessageBubble.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAWrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1D,MAAM,WAAW,sBAAuB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACvE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,wBAAwB,CAAC;IAEnC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACrC;AAyGD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,OAAkB,EAClB,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,sBAAsB,+BAyFxB;yBArGe,iBAAiB"}
1
+ {"version":3,"file":"ChatMessageBubble.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessageBubble.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAWrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAG5C,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1D,MAAM,WAAW,sBAAuB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACvE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,wBAAwB,CAAC;IAEnC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;CACrC;AA8GD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,QAAQ,EACR,OAAkB,EAClB,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EAAE,SAAS,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,sBAAsB,+BAyFxB;yBArGe,iBAAiB"}