@astryxdesign/core 0.1.9 → 0.2.0-canary.136a00f

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 (560) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/dist/Avatar/Avatar.d.ts +42 -3
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +190 -59
  5. package/dist/Avatar/AvatarStatusDot.d.ts +6 -4
  6. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  7. package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
  8. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  9. package/dist/AvatarGroup/AvatarGroup.js +58 -6
  10. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  11. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  12. package/dist/AvatarGroup/AvatarGroupOverflow.js +7 -2
  13. package/dist/Banner/Banner.js +2 -2
  14. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  15. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -4
  16. package/dist/Breadcrumbs/index.d.ts +1 -0
  17. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  18. package/dist/Breadcrumbs/index.js +2 -1
  19. package/dist/Button/Button.d.ts +1 -1
  20. package/dist/Button/Button.d.ts.map +1 -1
  21. package/dist/Button/Button.js +6 -4
  22. package/dist/Calendar/Calendar.d.ts.map +1 -1
  23. package/dist/Calendar/Calendar.js +50 -9
  24. package/dist/Calendar/dayCellUtils.d.ts +4 -4
  25. package/dist/Calendar/dayCellUtils.js +2 -2
  26. package/dist/Calendar/styles.d.ts +30 -31
  27. package/dist/Calendar/styles.d.ts.map +1 -1
  28. package/dist/Calendar/styles.js +30 -31
  29. package/dist/Card/Card.js +1 -1
  30. package/dist/Carousel/Carousel.d.ts.map +1 -1
  31. package/dist/Carousel/Carousel.js +22 -12
  32. package/dist/Chat/ChatComposerInput.js +1 -1
  33. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  34. package/dist/Chat/ChatDictationButton.js +3 -1
  35. package/dist/Chat/ChatLayout.js +4 -4
  36. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  37. package/dist/Chat/ChatMessageBubble.js +8 -8
  38. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  39. package/dist/Chat/ChatToolCalls.js +10 -3
  40. package/dist/Chat/useTriggerMenu.js +2 -2
  41. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  42. package/dist/CheckboxInput/CheckboxInput.js +6 -6
  43. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  44. package/dist/CheckboxList/CheckboxListItem.js +19 -4
  45. package/dist/Citation/Citation.d.ts +22 -1
  46. package/dist/Citation/Citation.d.ts.map +1 -1
  47. package/dist/Citation/Citation.js +20 -6
  48. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  49. package/dist/CodeBlock/CodeBlock.js +16 -10
  50. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  51. package/dist/Collapsible/Collapsible.js +3 -1
  52. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  53. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  54. package/dist/CommandPalette/CommandPalette.js +42 -3
  55. package/dist/CommandPalette/CommandPaletteItem.js +1 -1
  56. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  57. package/dist/ContextMenu/ContextMenu.js +23 -5
  58. package/dist/ContextMenu/index.d.ts +1 -0
  59. package/dist/ContextMenu/index.d.ts.map +1 -1
  60. package/dist/ContextMenu/index.js +3 -1
  61. package/dist/DateInput/DateInput.d.ts +10 -2
  62. package/dist/DateInput/DateInput.d.ts.map +1 -1
  63. package/dist/DateInput/DateInput.js +33 -19
  64. package/dist/DateRangeInput/DateRangeInput.d.ts +10 -2
  65. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  66. package/dist/DateRangeInput/DateRangeInput.js +23 -20
  67. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  68. package/dist/DateTimeInput/DateTimeInput.js +23 -18
  69. package/dist/Divider/Divider.d.ts +2 -2
  70. package/dist/Divider/Divider.d.ts.map +1 -1
  71. package/dist/Divider/Divider.js +13 -0
  72. package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
  73. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  74. package/dist/DropdownMenu/DropdownMenu.js +22 -5
  75. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  76. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +4 -1
  77. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  78. package/dist/DropdownMenu/DropdownMenuItem.js +5 -2
  79. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +8 -11
  80. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  81. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +3 -1
  82. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +1 -1
  83. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  84. package/dist/DropdownMenu/DropdownMenuRadioItem.js +5 -2
  85. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
  86. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
  87. package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
  88. package/dist/DropdownMenu/index.d.ts +10 -0
  89. package/dist/DropdownMenu/index.d.ts.map +1 -1
  90. package/dist/DropdownMenu/index.js +13 -0
  91. package/dist/DropdownMenu/menuItemHover.d.ts +23 -0
  92. package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
  93. package/dist/DropdownMenu/menuItemHover.js +33 -0
  94. package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
  95. package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
  96. package/dist/DropdownMenu/menuItemRoles.js +10 -1
  97. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  98. package/dist/DropdownMenu/renderDropdownItems.js +21 -6
  99. package/dist/Field/Field.d.ts +3 -1
  100. package/dist/Field/Field.d.ts.map +1 -1
  101. package/dist/Field/Field.js +4 -1
  102. package/dist/Field/FieldLabel.d.ts +2 -1
  103. package/dist/Field/FieldLabel.d.ts.map +1 -1
  104. package/dist/Field/FieldLabel.js +9 -5
  105. package/dist/Field/inputStyles.stylex.d.ts +1 -0
  106. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  107. package/dist/Field/inputStyles.stylex.js +1 -0
  108. package/dist/FieldStatus/FieldStatus.d.ts +10 -0
  109. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  110. package/dist/FieldStatus/FieldStatus.js +39 -3
  111. package/dist/FileInput/FileInput.d.ts +10 -2
  112. package/dist/FileInput/FileInput.d.ts.map +1 -1
  113. package/dist/FileInput/FileInput.js +93 -65
  114. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  115. package/dist/HoverCard/useHoverCard.js +10 -4
  116. package/dist/Icon/Icon.d.ts +15 -1
  117. package/dist/Icon/Icon.d.ts.map +1 -1
  118. package/dist/Icon/Icon.js +19 -3
  119. package/dist/Item/Item.d.ts +16 -3
  120. package/dist/Item/Item.d.ts.map +1 -1
  121. package/dist/Item/Item.js +31 -6
  122. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  123. package/dist/Layer/layerAnimations.stylex.js +10 -2
  124. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  125. package/dist/Lightbox/Lightbox.js +19 -13
  126. package/dist/List/List.d.ts.map +1 -1
  127. package/dist/List/List.js +6 -3
  128. package/dist/List/ListItem.d.ts +11 -1
  129. package/dist/List/ListItem.d.ts.map +1 -1
  130. package/dist/List/ListItem.js +2 -0
  131. package/dist/Markdown/Markdown.d.ts.map +1 -1
  132. package/dist/Markdown/Markdown.js +7 -0
  133. package/dist/MetadataList/MetadataList.d.ts +1 -1
  134. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  135. package/dist/MetadataList/MetadataList.js +4 -2
  136. package/dist/MultiSelector/MultiSelector.d.ts +9 -1
  137. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  138. package/dist/MultiSelector/MultiSelector.js +80 -42
  139. package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
  140. package/dist/NumberInput/NumberInput.d.ts +10 -2
  141. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  142. package/dist/NumberInput/NumberInput.js +22 -17
  143. package/dist/Outline/Outline.js +2 -2
  144. package/dist/Pagination/Pagination.d.ts.map +1 -1
  145. package/dist/Pagination/Pagination.js +11 -3
  146. package/dist/PowerSearch/PowerSearch.d.ts +9 -2
  147. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  148. package/dist/PowerSearch/PowerSearch.js +2 -0
  149. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  150. package/dist/ProgressBar/ProgressBar.js +6 -1
  151. package/dist/RadioList/RadioList.d.ts +2 -2
  152. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  153. package/dist/RadioList/RadioListItem.js +5 -5
  154. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  155. package/dist/Resizable/ResizeHandle.js +49 -19
  156. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  157. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  158. package/dist/SegmentedControl/SegmentedControlItem.js +5 -3
  159. package/dist/Selector/Selector.d.ts +8 -0
  160. package/dist/Selector/Selector.d.ts.map +1 -1
  161. package/dist/Selector/Selector.js +66 -17
  162. package/dist/SideNav/SideNav.d.ts.map +1 -1
  163. package/dist/SideNav/SideNav.js +5 -5
  164. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  165. package/dist/SideNav/SideNavCollapseButton.js +13 -10
  166. package/dist/SideNav/SideNavItem.d.ts +1 -1
  167. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  168. package/dist/SideNav/SideNavItem.js +12 -10
  169. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  170. package/dist/Skeleton/Skeleton.js +2 -2
  171. package/dist/Slider/Slider.d.ts.map +1 -1
  172. package/dist/Slider/Slider.js +87 -34
  173. package/dist/Spinner/Spinner.d.ts +3 -2
  174. package/dist/Spinner/Spinner.d.ts.map +1 -1
  175. package/dist/Spinner/Spinner.js +11 -2
  176. package/dist/Switch/Switch.d.ts +8 -1
  177. package/dist/Switch/Switch.d.ts.map +1 -1
  178. package/dist/Switch/Switch.js +171 -91
  179. package/dist/TabList/Tab.js +2 -2
  180. package/dist/TabList/TabList.d.ts +2 -11
  181. package/dist/TabList/TabList.d.ts.map +1 -1
  182. package/dist/TabList/TabList.js +5 -9
  183. package/dist/TabList/TabListContext.d.ts +0 -5
  184. package/dist/TabList/TabListContext.d.ts.map +1 -1
  185. package/dist/TabList/TabListContext.js +0 -5
  186. package/dist/TabList/TabMenu.js +1 -1
  187. package/dist/Table/BaseTable.d.ts.map +1 -1
  188. package/dist/Table/BaseTable.js +30 -4
  189. package/dist/Table/TableCell.js +3 -3
  190. package/dist/Table/TableHeaderCell.js +3 -3
  191. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  192. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
  193. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  194. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +37 -27
  195. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  196. package/dist/Table/plugins/selection/useTableSelection.js +3 -0
  197. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  198. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +15 -7
  199. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  200. package/dist/Table/plugins/tree/useTableTreeData.js +29 -23
  201. package/dist/Table/types.d.ts +32 -0
  202. package/dist/Table/types.d.ts.map +1 -1
  203. package/dist/TextArea/TextArea.d.ts +10 -1
  204. package/dist/TextArea/TextArea.d.ts.map +1 -1
  205. package/dist/TextArea/TextArea.js +18 -19
  206. package/dist/TextInput/TextInput.d.ts +10 -2
  207. package/dist/TextInput/TextInput.d.ts.map +1 -1
  208. package/dist/TextInput/TextInput.js +20 -17
  209. package/dist/Thumbnail/Thumbnail.js +2 -2
  210. package/dist/TimeInput/TimeInput.d.ts +10 -2
  211. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  212. package/dist/TimeInput/TimeInput.js +17 -17
  213. package/dist/Timestamp/Timestamp.d.ts +31 -3
  214. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  215. package/dist/Timestamp/Timestamp.js +47 -76
  216. package/dist/Timestamp/formatInstant.d.ts +41 -0
  217. package/dist/Timestamp/formatInstant.d.ts.map +1 -0
  218. package/dist/Timestamp/formatInstant.js +177 -0
  219. package/dist/Timestamp/index.d.ts +1 -0
  220. package/dist/Timestamp/index.d.ts.map +1 -1
  221. package/dist/Timestamp/tooltipEntries.d.ts +56 -0
  222. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -0
  223. package/dist/Timestamp/tooltipEntries.js +163 -0
  224. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  225. package/dist/Toast/ToastViewport.js +61 -9
  226. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  227. package/dist/ToggleButton/ToggleButton.js +3 -1
  228. package/dist/Token/Token.d.ts +34 -4
  229. package/dist/Token/Token.d.ts.map +1 -1
  230. package/dist/Token/Token.js +85 -45
  231. package/dist/Token/TokenLink.d.ts +62 -0
  232. package/dist/Token/TokenLink.d.ts.map +1 -0
  233. package/dist/Token/TokenLink.js +76 -0
  234. package/dist/Token/index.d.ts +1 -1
  235. package/dist/Token/index.d.ts.map +1 -1
  236. package/dist/Tokenizer/Tokenizer.d.ts +9 -2
  237. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  238. package/dist/Tokenizer/Tokenizer.js +4 -2
  239. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  240. package/dist/Tooltip/useTooltip.js +17 -1
  241. package/dist/TopNav/TopNavItem.d.ts +3 -1
  242. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  243. package/dist/TopNav/TopNavItem.js +30 -3
  244. package/dist/TreeList/TreeList.d.ts.map +1 -1
  245. package/dist/TreeList/TreeList.js +1 -0
  246. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  247. package/dist/TreeList/TreeListBranches.js +8 -6
  248. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  249. package/dist/TreeList/TreeListItem.js +32 -14
  250. package/dist/Typeahead/BaseTypeahead.d.ts +9 -0
  251. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  252. package/dist/Typeahead/BaseTypeahead.js +22 -11
  253. package/dist/Typeahead/Typeahead.d.ts +9 -2
  254. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  255. package/dist/Typeahead/Typeahead.js +11 -2
  256. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  257. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  258. package/dist/Typeahead/TypeaheadItem.js +20 -10
  259. package/dist/astryx.css +70 -30
  260. package/dist/astryx.umd.js +51 -51
  261. package/dist/astryx.umd.js.map +4 -4
  262. package/dist/hooks/index.d.ts +2 -0
  263. package/dist/hooks/index.d.ts.map +1 -1
  264. package/dist/hooks/index.js +1 -0
  265. package/dist/hooks/isRtlElement.d.ts +18 -0
  266. package/dist/hooks/isRtlElement.d.ts.map +1 -0
  267. package/dist/hooks/isRtlElement.js +27 -0
  268. package/dist/hooks/useAnnounce.d.ts +3 -0
  269. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  270. package/dist/hooks/useAnnounce.js +39 -1
  271. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  272. package/dist/hooks/useFocusTrap.js +52 -11
  273. package/dist/hooks/useGridFocus.d.ts +6 -1
  274. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  275. package/dist/hooks/useGridFocus.js +12 -9
  276. package/dist/hooks/useHotkeys.d.ts +9 -0
  277. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  278. package/dist/hooks/useHotkeys.js +9 -0
  279. package/dist/hooks/useInputStatusIcon.d.ts +38 -0
  280. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
  281. package/dist/hooks/useInputStatusIcon.js +158 -0
  282. package/dist/hooks/useKeyboardHint.d.ts +1 -1
  283. package/dist/hooks/useKeyboardHint.d.ts.map +1 -1
  284. package/dist/hooks/useKeyboardHint.js +4 -2
  285. package/dist/hooks/useListFocus.d.ts +39 -1
  286. package/dist/hooks/useListFocus.d.ts.map +1 -1
  287. package/dist/hooks/useListFocus.js +54 -9
  288. package/dist/i18n/InternationalizationContext.d.ts +1 -0
  289. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  290. package/dist/i18n/InternationalizationContext.js +3 -0
  291. package/dist/i18n/InternationalizationProvider.d.ts +8 -1
  292. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  293. package/dist/i18n/InternationalizationProvider.js +5 -1
  294. package/dist/i18n/getLocaleDirection.d.ts +18 -0
  295. package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
  296. package/dist/i18n/getLocaleDirection.js +29 -0
  297. package/dist/i18n/index.d.ts +6 -0
  298. package/dist/i18n/index.d.ts.map +1 -1
  299. package/dist/i18n/index.js +7 -1
  300. package/dist/i18n/useDirection.d.ts +2 -0
  301. package/dist/i18n/useDirection.d.ts.map +1 -0
  302. package/dist/i18n/useDirection.js +27 -0
  303. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  304. package/dist/theme/derivedVarRegistry.js +13 -0
  305. package/dist/utils/index.d.ts +1 -0
  306. package/dist/utils/index.d.ts.map +1 -1
  307. package/dist/utils/index.js +2 -1
  308. package/dist/utils/plainDate.d.ts +17 -0
  309. package/dist/utils/plainDate.d.ts.map +1 -1
  310. package/dist/utils/plainDate.js +23 -4
  311. package/dist/utils/rtlStyles.d.ts +24 -0
  312. package/dist/utils/rtlStyles.d.ts.map +1 -0
  313. package/dist/utils/rtlStyles.js +27 -0
  314. package/locales/en.json +112 -0
  315. package/locales/pseudo.json +84 -0
  316. package/package.json +6 -1
  317. package/src/Avatar/Avatar.doc.mjs +50 -3
  318. package/src/Avatar/Avatar.test.tsx +218 -0
  319. package/src/Avatar/Avatar.tsx +285 -79
  320. package/src/Avatar/AvatarStatusDot.doc.mjs +4 -4
  321. package/src/Avatar/AvatarStatusDot.tsx +6 -4
  322. package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
  323. package/src/AvatarGroup/AvatarGroup.test.tsx +162 -2
  324. package/src/AvatarGroup/AvatarGroup.tsx +58 -3
  325. package/src/AvatarGroup/AvatarGroupOverflow.tsx +5 -2
  326. package/src/Banner/Banner.tsx +6 -6
  327. package/src/Breadcrumbs/BreadcrumbItem.tsx +10 -10
  328. package/src/Breadcrumbs/Breadcrumbs.test.tsx +52 -1
  329. package/src/Breadcrumbs/index.ts +4 -0
  330. package/src/Button/Button.doc.mjs +0 -4
  331. package/src/Button/Button.test.tsx +16 -0
  332. package/src/Button/Button.tsx +6 -4
  333. package/src/Calendar/Calendar.test.tsx +170 -20
  334. package/src/Calendar/Calendar.tsx +73 -16
  335. package/src/Calendar/dayCellUtils.test.ts +18 -18
  336. package/src/Calendar/dayCellUtils.ts +2 -2
  337. package/src/Calendar/styles.ts +33 -39
  338. package/src/Card/Card.tsx +1 -1
  339. package/src/Carousel/Carousel.tsx +25 -6
  340. package/src/Chat/ChatComposer.doc.mjs +2 -2
  341. package/src/Chat/ChatComposerInput.doc.mjs +1 -1
  342. package/src/Chat/ChatComposerInput.tsx +2 -2
  343. package/src/Chat/ChatDictationButton.tsx +7 -1
  344. package/src/Chat/ChatLayout.tsx +4 -4
  345. package/src/Chat/ChatMessageBubble.tsx +15 -10
  346. package/src/Chat/ChatSystemMessage.test.tsx +5 -0
  347. package/src/Chat/ChatToolCalls.tsx +9 -2
  348. package/src/Chat/useTriggerMenu.tsx +1 -1
  349. package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
  350. package/src/CheckboxInput/CheckboxInput.test.tsx +23 -0
  351. package/src/CheckboxInput/CheckboxInput.tsx +21 -6
  352. package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
  353. package/src/CheckboxList/CheckboxList.test.tsx +94 -3
  354. package/src/CheckboxList/CheckboxListItem.tsx +17 -10
  355. package/src/Citation/Citation.doc.mjs +4 -3
  356. package/src/Citation/Citation.test.tsx +97 -0
  357. package/src/Citation/Citation.tsx +43 -11
  358. package/src/CodeBlock/CodeBlock.test.tsx +17 -0
  359. package/src/CodeBlock/CodeBlock.tsx +38 -11
  360. package/src/Collapsible/Collapsible.doc.mjs +1 -0
  361. package/src/Collapsible/Collapsible.test.tsx +7 -0
  362. package/src/Collapsible/Collapsible.tsx +16 -6
  363. package/src/CommandPalette/CommandPalette.test.tsx +95 -1
  364. package/src/CommandPalette/CommandPalette.tsx +41 -2
  365. package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
  366. package/src/ContextMenu/ContextMenu.test.tsx +59 -2
  367. package/src/ContextMenu/ContextMenu.tsx +22 -11
  368. package/src/ContextMenu/index.ts +5 -0
  369. package/src/DateInput/DateInput.doc.mjs +25 -0
  370. package/src/DateInput/DateInput.test.tsx +230 -0
  371. package/src/DateInput/DateInput.tsx +51 -29
  372. package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
  373. package/src/DateRangeInput/DateRangeInput.test.tsx +140 -0
  374. package/src/DateRangeInput/DateRangeInput.tsx +42 -30
  375. package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
  376. package/src/DateTimeInput/DateTimeInput.test.tsx +112 -0
  377. package/src/DateTimeInput/DateTimeInput.tsx +44 -39
  378. package/src/Divider/Divider.test.tsx +32 -8
  379. package/src/Divider/Divider.tsx +14 -1
  380. package/src/DropdownMenu/DropdownMenu.test.tsx +60 -0
  381. package/src/DropdownMenu/DropdownMenu.tsx +31 -12
  382. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +8 -2
  383. package/src/DropdownMenu/DropdownMenuItem.tsx +9 -3
  384. package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +4 -12
  385. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +9 -10
  386. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +9 -3
  387. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +20 -2
  388. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
  389. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
  390. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
  391. package/src/DropdownMenu/index.ts +16 -0
  392. package/src/DropdownMenu/menuItemHover.ts +39 -0
  393. package/src/DropdownMenu/menuItemRoles.ts +9 -0
  394. package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
  395. package/src/Field/Field.tsx +14 -9
  396. package/src/Field/FieldLabel.test.tsx +25 -0
  397. package/src/Field/FieldLabel.tsx +12 -3
  398. package/src/Field/inputStyles.stylex.ts +2 -0
  399. package/src/FieldStatus/FieldStatus.test.tsx +72 -0
  400. package/src/FieldStatus/FieldStatus.tsx +48 -2
  401. package/src/FileInput/FileInput.doc.mjs +23 -2
  402. package/src/FileInput/FileInput.test.tsx +104 -13
  403. package/src/FileInput/FileInput.tsx +106 -79
  404. package/src/HoverCard/useHoverCard.tsx +15 -3
  405. package/src/Icon/Icon.doc.mjs +13 -0
  406. package/src/Icon/Icon.test.tsx +89 -0
  407. package/src/Icon/Icon.tsx +51 -3
  408. package/src/Item/Item.doc.mjs +5 -0
  409. package/src/Item/Item.test.tsx +88 -0
  410. package/src/Item/Item.tsx +57 -11
  411. package/src/Layer/layerAnimations.stylex.ts +23 -0
  412. package/src/Lightbox/Lightbox.tsx +15 -7
  413. package/src/List/List.test.tsx +17 -29
  414. package/src/List/List.tsx +6 -1
  415. package/src/List/ListItem.doc.mjs +12 -0
  416. package/src/List/ListItem.tsx +13 -0
  417. package/src/Markdown/Markdown.test.tsx +21 -0
  418. package/src/Markdown/Markdown.tsx +4 -0
  419. package/src/MetadataList/MetadataList.test.tsx +24 -0
  420. package/src/MetadataList/MetadataList.tsx +6 -2
  421. package/src/MultiSelector/MultiSelector.doc.mjs +20 -0
  422. package/src/MultiSelector/MultiSelector.test.tsx +402 -0
  423. package/src/MultiSelector/MultiSelector.tsx +120 -59
  424. package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
  425. package/src/NumberInput/NumberInput.doc.mjs +21 -0
  426. package/src/NumberInput/NumberInput.test.tsx +71 -0
  427. package/src/NumberInput/NumberInput.tsx +35 -26
  428. package/src/Outline/Outline.test.tsx +12 -12
  429. package/src/Outline/Outline.tsx +2 -2
  430. package/src/Pagination/Pagination.tsx +11 -3
  431. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  432. package/src/PowerSearch/PowerSearch.test.tsx +23 -0
  433. package/src/PowerSearch/PowerSearch.tsx +10 -1
  434. package/src/ProgressBar/ProgressBar.test.tsx +34 -0
  435. package/src/ProgressBar/ProgressBar.tsx +16 -1
  436. package/src/RadioList/RadioList.doc.mjs +6 -0
  437. package/src/RadioList/RadioList.test.tsx +26 -4
  438. package/src/RadioList/RadioList.tsx +2 -2
  439. package/src/RadioList/RadioListItem.tsx +12 -5
  440. package/src/Resizable/ResizeHandle.test.tsx +94 -0
  441. package/src/Resizable/ResizeHandle.tsx +70 -20
  442. package/src/SegmentedControl/SegmentedControl.test.tsx +28 -0
  443. package/src/SegmentedControl/SegmentedControlItem.tsx +22 -2
  444. package/src/Selector/Selector.doc.mjs +15 -0
  445. package/src/Selector/Selector.test.tsx +370 -0
  446. package/src/Selector/Selector.tsx +88 -20
  447. package/src/SideNav/SideNav.tsx +1 -8
  448. package/src/SideNav/SideNavCollapseButton.tsx +9 -7
  449. package/src/SideNav/SideNavItem.tsx +5 -3
  450. package/src/Skeleton/Skeleton.test.tsx +16 -0
  451. package/src/Skeleton/Skeleton.tsx +13 -1
  452. package/src/Slider/Slider.doc.mjs +6 -0
  453. package/src/Slider/Slider.test.tsx +240 -12
  454. package/src/Slider/Slider.tsx +96 -23
  455. package/src/Spinner/Spinner.test.tsx +10 -8
  456. package/src/Spinner/Spinner.tsx +15 -5
  457. package/src/Switch/Switch.doc.mjs +142 -42
  458. package/src/Switch/Switch.test.tsx +111 -0
  459. package/src/Switch/Switch.tsx +149 -32
  460. package/src/TabList/Tab.tsx +2 -2
  461. package/src/TabList/TabList.doc.mjs +0 -6
  462. package/src/TabList/TabList.test.tsx +3 -15
  463. package/src/TabList/TabList.tsx +6 -17
  464. package/src/TabList/TabListContext.ts +0 -6
  465. package/src/TabList/TabMenu.tsx +2 -2
  466. package/src/Table/BaseTable.tsx +34 -2
  467. package/src/Table/Table.doc.mjs +11 -0
  468. package/src/Table/Table.test.tsx +85 -0
  469. package/src/Table/TableCell.tsx +3 -3
  470. package/src/Table/TableHeaderCell.tsx +3 -3
  471. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +9 -6
  472. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +19 -0
  473. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +27 -18
  474. package/src/Table/plugins/selection/useTableSelection.test.tsx +61 -3
  475. package/src/Table/plugins/selection/useTableSelection.tsx +3 -0
  476. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +38 -9
  477. package/src/Table/plugins/tree/useTableTreeData.tsx +17 -13
  478. package/src/Table/types.ts +33 -0
  479. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  480. package/src/TextArea/TextArea.doc.mjs +21 -0
  481. package/src/TextArea/TextArea.test.tsx +23 -0
  482. package/src/TextArea/TextArea.tsx +27 -26
  483. package/src/TextInput/TextInput.doc.mjs +21 -0
  484. package/src/TextInput/TextInput.test.tsx +150 -0
  485. package/src/TextInput/TextInput.tsx +28 -25
  486. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  487. package/src/Thumbnail/Thumbnail.tsx +1 -1
  488. package/src/TimeInput/TimeInput.doc.mjs +21 -0
  489. package/src/TimeInput/TimeInput.test.tsx +23 -0
  490. package/src/TimeInput/TimeInput.tsx +24 -25
  491. package/src/Timestamp/Timestamp.doc.mjs +32 -6
  492. package/src/Timestamp/Timestamp.test.tsx +371 -0
  493. package/src/Timestamp/Timestamp.tsx +96 -93
  494. package/src/Timestamp/formatInstant.ts +218 -0
  495. package/src/Timestamp/index.ts +4 -0
  496. package/src/Timestamp/tooltipEntries.test.ts +552 -0
  497. package/src/Timestamp/tooltipEntries.ts +210 -0
  498. package/src/Toast/ToastViewport.test.tsx +218 -8
  499. package/src/Toast/ToastViewport.tsx +71 -12
  500. package/src/ToggleButton/ToggleButton.test.tsx +24 -0
  501. package/src/ToggleButton/ToggleButton.tsx +19 -1
  502. package/src/Token/Token.test.tsx +166 -15
  503. package/src/Token/Token.tsx +104 -47
  504. package/src/Token/TokenLink.tsx +107 -0
  505. package/src/Token/index.ts +1 -1
  506. package/src/Tokenizer/Tokenizer.doc.mjs +23 -1
  507. package/src/Tokenizer/Tokenizer.test.tsx +23 -0
  508. package/src/Tokenizer/Tokenizer.tsx +14 -2
  509. package/src/Tooltip/Tooltip.test.tsx +46 -0
  510. package/src/Tooltip/useTooltip.tsx +20 -0
  511. package/src/TopNav/TopNav.test.tsx +93 -2
  512. package/src/TopNav/TopNavItem.doc.mjs +3 -3
  513. package/src/TopNav/TopNavItem.tsx +35 -6
  514. package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +1 -1
  515. package/src/TreeList/TreeList.doc.mjs +6 -0
  516. package/src/TreeList/TreeList.test.tsx +50 -10
  517. package/src/TreeList/TreeList.tsx +5 -0
  518. package/src/TreeList/TreeListBranches.tsx +8 -6
  519. package/src/TreeList/TreeListItem.tsx +33 -11
  520. package/src/Typeahead/BaseTypeahead.tsx +42 -15
  521. package/src/Typeahead/Typeahead.doc.mjs +13 -0
  522. package/src/Typeahead/Typeahead.test.tsx +112 -0
  523. package/src/Typeahead/Typeahead.tsx +17 -1
  524. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  525. package/src/__tests__/forcedColors.ts +60 -0
  526. package/src/__tests__/inputWidthContract.test.tsx +62 -0
  527. package/src/doc-mjs.d.ts +19 -0
  528. package/src/hooks/index.ts +6 -0
  529. package/src/hooks/isRtlElement.ts +27 -0
  530. package/src/hooks/useAnnounce.test.tsx +75 -2
  531. package/src/hooks/useAnnounce.ts +47 -1
  532. package/src/hooks/useFocusTrap.test.tsx +104 -0
  533. package/src/hooks/useFocusTrap.ts +61 -12
  534. package/src/hooks/useGridFocus.doc.mjs +3 -3
  535. package/src/hooks/useGridFocus.test.tsx +41 -0
  536. package/src/hooks/useGridFocus.ts +21 -10
  537. package/src/hooks/useHotkeys.ts +9 -0
  538. package/src/hooks/useInputStatusIcon.test.tsx +162 -0
  539. package/src/hooks/useInputStatusIcon.tsx +224 -0
  540. package/src/hooks/useKeyboardHint.test.tsx +22 -0
  541. package/src/hooks/useKeyboardHint.tsx +6 -2
  542. package/src/hooks/useListFocus.doc.mjs +25 -3
  543. package/src/hooks/useListFocus.test.tsx +153 -1
  544. package/src/hooks/useListFocus.ts +102 -9
  545. package/src/i18n/InternationalizationContext.ts +4 -0
  546. package/src/i18n/InternationalizationProvider.tsx +12 -2
  547. package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
  548. package/src/i18n/__tests__/useDirection.test.tsx +66 -0
  549. package/src/i18n/getLocaleDirection.ts +29 -0
  550. package/src/i18n/index.ts +6 -0
  551. package/src/i18n/useDirection.ts +29 -0
  552. package/src/reset.css +0 -26
  553. package/src/reset.test.ts +60 -0
  554. package/src/theme/derivedVarRegistry.test.ts +1 -0
  555. package/src/theme/derivedVarRegistry.ts +6 -0
  556. package/src/theme/generateThemeRules.test.ts +42 -0
  557. package/src/utils/index.ts +2 -0
  558. package/src/utils/plainDate.test.ts +24 -6
  559. package/src/utils/plainDate.ts +18 -4
  560. package/src/utils/rtlStyles.ts +27 -0
@@ -41,8 +41,9 @@ import {Button} from '../Button';
41
41
  import {Icon} from '../Icon';
42
42
  import {useLayer} from '../Layer';
43
43
  import {useScrollOverflow} from '../hooks/useScrollOverflow';
44
+ import {isRtlElement} from '../hooks/isRtlElement';
44
45
  import type {BaseProps} from '../BaseProps';
45
- import {mergeProps, mergeRefs} from '../utils';
46
+ import {mergeProps, mergeRefs, rtlStyles} from '../utils';
46
47
  import type {SpacingStep} from '../utils/types';
47
48
  import {themeProps} from '../utils/themeProps';
48
49
  import {useTranslator} from '../i18n';
@@ -166,10 +167,16 @@ const styles = stylex.create({
166
167
  transitionTimingFunction: easeVars['--ease-standard'],
167
168
  },
168
169
  buttonPillStart: {
169
- transform: 'translateX(-50%)',
170
+ transform: {
171
+ default: 'translateX(-50%)',
172
+ ':is([dir="rtl"] *)': 'translateX(50%)',
173
+ },
170
174
  },
171
175
  buttonPillEnd: {
172
- transform: 'translateX(50%)',
176
+ transform: {
177
+ default: 'translateX(50%)',
178
+ ':is([dir="rtl"] *)': 'translateX(-50%)',
179
+ },
173
180
  },
174
181
  buttonHidden: {
175
182
  opacity: 0,
@@ -347,7 +354,11 @@ export function Carousel({
347
354
  typeof window.matchMedia === 'function' &&
348
355
  window.matchMedia('(prefers-reduced-motion: reduce)').matches;
349
356
  el.scrollBy({
350
- left: direction * Math.max(amount, itemWidth),
357
+ // `direction` is the logical intent (-1 = toward content start, +1 =
358
+ // toward content end). Under RTL the scroll axis is inverted (start is
359
+ // scrollLeft 0, the end is negative), so flip the physical delta sign.
360
+ left:
361
+ (isRtlElement(el) ? -1 : 1) * direction * Math.max(amount, itemWidth),
351
362
  behavior: prefersReducedMotion ? 'auto' : 'smooth',
352
363
  });
353
364
  }, []);
@@ -425,7 +436,11 @@ export function Carousel({
425
436
  !overflowStart && styles.buttonHidden,
426
437
  )}>
427
438
  <Button
428
- icon={<Icon icon="chevronLeft" size="xsm" />}
439
+ icon={
440
+ <span {...stylex.props(rtlStyles.mirror)}>
441
+ <Icon icon="chevronLeft" size="xsm" />
442
+ </span>
443
+ }
429
444
  label={t('@astryx.carousel.scrollLeft')}
430
445
  variant="ghost"
431
446
  size="sm"
@@ -446,7 +461,11 @@ export function Carousel({
446
461
  !overflowEnd && styles.buttonHidden,
447
462
  )}>
448
463
  <Button
449
- icon={<Icon icon="chevronRight" size="xsm" />}
464
+ icon={
465
+ <span {...stylex.props(rtlStyles.mirror)}>
466
+ <Icon icon="chevronRight" size="xsm" />
467
+ </span>
468
+ }
450
469
  label={t('@astryx.carousel.scrollRight')}
451
470
  variant="ghost"
452
471
  size="sm"
@@ -60,7 +60,7 @@ export const docs = {
60
60
  name: 'elevation',
61
61
  type: "'none' | 'low'",
62
62
  description:
63
- "Resting elevation of the composer body. `low` (the default) keeps today's raised look — low at rest, bumping to med on hover / focus. `none` flattens it and draws a border with the same rest / hover / focus treatment as a text input (emphasized border → accent on focus, matching inset rings).",
63
+ "Resting elevation of the composer body. `low` (the default) keeps today's raised look: low at rest, bumping to med on hover / focus. `none` flattens it and draws a border with the same rest / hover / focus treatment as a text input (emphasized border → accent on focus, matching inset rings).",
64
64
  default: "'low'",
65
65
  },
66
66
  {
@@ -109,7 +109,7 @@ export const docs = {
109
109
  {
110
110
  name: 'input',
111
111
  type: 'ReactNode',
112
- description: 'Slot: custom input element. Replaces the default input. Use ChatComposerInput for trigger menus/tokens, or wire any input (plain textarea, rich editor) to the composition contract via useChatComposerContext() — read value/onChange/onSubmit/canSend and register a focus control on inputControlRef so body-click-to-focus works.',
112
+ description: 'Slot: custom input element. Replaces the default input. Use ChatComposerInput for trigger menus/tokens, or wire any input (plain textarea, rich editor) to the composition contract via useChatComposerContext(): read value/onChange/onSubmit/canSend and register a focus control on inputControlRef so body-click-to-focus works.',
113
113
  slotElements: [
114
114
  {
115
115
  __element: 'TextInput',
@@ -83,7 +83,7 @@ export const docs = {
83
83
  {
84
84
  name: 'onKeyDown',
85
85
  type: '(event) => void',
86
- description: 'Key-down handler invoked before the built-in Enter/history behavior (after any open trigger menu). The seam for platform-specific keys: call event.preventDefault() to suppress the default submit (e.g. newline on a touch keyboard), or act on the event yourself to add behavior (e.g. submit on Cmd/Ctrl+Enter). IME composition is always respected — Enter never submits mid-composition.',
86
+ description: 'Key-down handler invoked before the built-in Enter/history behavior (after any open trigger menu). The seam for platform-specific keys: call event.preventDefault() to suppress the default submit (e.g. newline on a touch keyboard), or act on the event yourself to add behavior (e.g. submit on Cmd/Ctrl+Enter). IME composition is always respected; Enter never submits mid-composition.',
87
87
  },
88
88
  ],
89
89
  };
@@ -238,8 +238,8 @@ const styles = stylex.create({
238
238
  placeholder: {
239
239
  position: 'absolute',
240
240
  top: 0,
241
- left: 0,
242
- right: 0,
241
+ insetInlineStart: 0,
242
+ insetInlineEnd: 0,
243
243
  pointerEvents: 'none',
244
244
  color: colorVars['--color-text-secondary'],
245
245
  fontSize: {
@@ -26,6 +26,7 @@ import {Button} from '../Button';
26
26
  import {Icon} from '../Icon';
27
27
  import {mergeProps} from '../utils';
28
28
  import type {BaseProps} from '../BaseProps';
29
+ import {useTranslator} from '../i18n';
29
30
 
30
31
  // =============================================================================
31
32
  // Types
@@ -110,13 +111,18 @@ export function ChatDictationButton({
110
111
  style,
111
112
  ...rest
112
113
  }: ChatDictationButtonProps) {
114
+ const t = useTranslator();
115
+
113
116
  if (isHiddenWhenUnsupported && !dictation.isSupported) {
114
117
  return null;
115
118
  }
116
119
 
117
120
  const {isListening, bands, volume: rawVolume} = dictation;
118
121
  const accessibleLabel =
119
- label ?? (isListening ? 'Stop dictation' : 'Start dictation');
122
+ label ??
123
+ (isListening
124
+ ? t('@astryx.chatDictationButton.stopDictation')
125
+ : t('@astryx.chatDictationButton.startDictation'));
120
126
 
121
127
  // Boost each band for visibility — quiet speech (0-10%) maps to full visual range
122
128
  const boostedBands = bands.map(b => Math.min(Math.pow(b / 0.2, 0.5), 1));
@@ -134,8 +134,8 @@ const styles = stylex.create({
134
134
  // --- Dock container ---
135
135
  dockContainer: {
136
136
  bottom: 0,
137
- left: 0,
138
- right: 0,
137
+ insetInlineStart: 0,
138
+ insetInlineEnd: 0,
139
139
  zIndex: 0,
140
140
  isolation: 'isolate',
141
141
  pointerEvents: 'none',
@@ -150,8 +150,8 @@ const styles = stylex.create({
150
150
  blurLayer: {
151
151
  position: 'absolute',
152
152
  bottom: 0,
153
- left: 0,
154
- right: 0,
153
+ insetInlineStart: 0,
154
+ insetInlineEnd: 0,
155
155
  pointerEvents: 'none',
156
156
  backdropFilter: 'blur(12px)',
157
157
  WebkitBackdropFilter: 'blur(12px)',
@@ -160,27 +160,32 @@ const styles = stylex.create({
160
160
  backgroundColor: 'transparent',
161
161
  color: colorVars['--color-text-primary'],
162
162
  },
163
- // Grouped bubble corners — assistant (left side tight)
163
+ // Grouped bubble corners — assistant (inline-start side tight).
164
+ // Logical radii so the tail follows reading direction: inline-start is the
165
+ // left edge under LTR and the right edge under RTL (assistant tucks toward
166
+ // the start of the line in both directions).
164
167
  groupFirstAssistant: {
165
- borderBottomLeftRadius: radiusVars['--radius-inner'],
168
+ borderEndStartRadius: radiusVars['--radius-inner'],
166
169
  },
167
170
  groupMiddleAssistant: {
168
- borderTopLeftRadius: radiusVars['--radius-inner'],
169
- borderBottomLeftRadius: radiusVars['--radius-inner'],
171
+ borderStartStartRadius: radiusVars['--radius-inner'],
172
+ borderEndStartRadius: radiusVars['--radius-inner'],
170
173
  },
171
174
  groupLastAssistant: {
172
- borderTopLeftRadius: radiusVars['--radius-inner'],
175
+ borderStartStartRadius: radiusVars['--radius-inner'],
173
176
  },
174
- // Grouped bubble corners — user (right side tight)
177
+ // Grouped bubble corners — user (inline-end side tight).
178
+ // Logical radii: inline-end is the right edge under LTR and the left edge
179
+ // under RTL (user tucks toward the end of the line in both directions).
175
180
  groupFirstUser: {
176
- borderBottomRightRadius: radiusVars['--radius-inner'],
181
+ borderEndEndRadius: radiusVars['--radius-inner'],
177
182
  },
178
183
  groupMiddleUser: {
179
- borderTopRightRadius: radiusVars['--radius-inner'],
180
- borderBottomRightRadius: radiusVars['--radius-inner'],
184
+ borderStartEndRadius: radiusVars['--radius-inner'],
185
+ borderEndEndRadius: radiusVars['--radius-inner'],
181
186
  },
182
187
  groupLastUser: {
183
- borderTopRightRadius: radiusVars['--radius-inner'],
188
+ borderStartEndRadius: radiusVars['--radius-inner'],
184
189
  },
185
190
  });
186
191
 
@@ -28,6 +28,11 @@ describe('ChatSystemMessage', () => {
28
28
  expect(screen.getByText('Today')).toBeTruthy();
29
29
  });
30
30
 
31
+ it('exposes the divider variant label as the separator accessible name', () => {
32
+ render(<ChatSystemMessage variant="divider">Today</ChatSystemMessage>);
33
+ expect(screen.getByRole('separator')).toHaveAccessibleName('Today');
34
+ });
35
+
31
36
  it('renders icon', () => {
32
37
  render(
33
38
  <ChatSystemMessage icon={<span data-testid="icon">*</span>}>
@@ -37,6 +37,7 @@ import {Icon, type IconName} from '../Icon';
37
37
  import {Spinner} from '../Spinner';
38
38
  import {VisuallyHidden} from '../VisuallyHidden';
39
39
  import {themeProps} from '../utils/themeProps';
40
+ import {useTranslator} from '../i18n';
40
41
 
41
42
  // =============================================================================
42
43
  // Types
@@ -363,6 +364,7 @@ function getToolCallKey(call: ChatToolCallItem): string {
363
364
  // =============================================================================
364
365
 
365
366
  function CallRow({call}: {call: ChatToolCallItem}) {
367
+ const t = useTranslator();
366
368
  const status = call.status ?? 'complete';
367
369
  const hasDetail = call.resultDetail != null;
368
370
  const [isDetailOpen, setIsDetailOpen] = useState(false);
@@ -414,7 +416,11 @@ function CallRow({call}: {call: ChatToolCallItem}) {
414
416
  // as real text so it reaches screen readers, keyboard, and touch
415
417
  // users. Rendering it inside the row also folds it into the
416
418
  // accessible name of expandable (role="button") rows.
417
- <VisuallyHidden>{`Error: ${call.errorMessage}`}</VisuallyHidden>
419
+ <VisuallyHidden>
420
+ {t('@astryx.chatToolCalls.error', {
421
+ message: call.errorMessage ?? '',
422
+ })}
423
+ </VisuallyHidden>
418
424
  )}
419
425
  </span>
420
426
  <span {...stylex.props(styles.callName)}>{call.name}</span>
@@ -498,6 +504,7 @@ function CallRow({call}: {call: ChatToolCallItem}) {
498
504
  * ```
499
505
  */
500
506
  export function ChatToolCalls(props: ChatToolCallsProps) {
507
+ const t = useTranslator();
501
508
  const {
502
509
  calls,
503
510
  label: _customLabel,
@@ -580,7 +587,7 @@ export function ChatToolCalls(props: ChatToolCallsProps) {
580
587
  <Icon icon="wrench" size="sm" color="inherit" />
581
588
  </span>
582
589
  <span {...stylex.props(styles.groupLabel)}>
583
- {calls.length} tool calls
590
+ {t('@astryx.chatToolCalls.groupLabel', {count: calls.length})}
584
591
  </span>
585
592
  </>
586
593
  ) : (
@@ -125,7 +125,7 @@ const styles = stylex.create({
125
125
  outline: 'none',
126
126
  backgroundColor: 'transparent',
127
127
  border: 'none',
128
- textAlign: 'left' as const,
128
+ textAlign: 'start' as const,
129
129
  fontFamily: typographyVars['--font-family-body'],
130
130
  fontSize: typeScaleVars['--text-body-size'],
131
131
  lineHeight: typeScaleVars['--text-body-leading'],
@@ -121,6 +121,12 @@ export const docs = {
121
121
  description:
122
122
  'Status indicator. Displays a colored message box below the checkbox and sets aria-invalid for errors.',
123
123
  },
124
+ {
125
+ name: 'width',
126
+ type: 'SizeValue',
127
+ description:
128
+ 'Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.',
129
+ },
124
130
  ],
125
131
  theming: {
126
132
  targets: [
@@ -13,6 +13,7 @@ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
13
13
  import {render, screen, fireEvent, waitFor} from '@testing-library/react';
14
14
  import userEvent from '@testing-library/user-event';
15
15
  import {CheckboxInput} from './CheckboxInput';
16
+ import {getForcedColorsRules} from '../__tests__/forcedColors';
16
17
  import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
17
18
 
18
19
  afterEach(() => {
@@ -543,3 +544,25 @@ describe('CheckboxInput', () => {
543
544
  });
544
545
  });
545
546
  });
547
+
548
+ // jsdom cannot emulate forced-colors rendering, so this asserts that the
549
+ // compiled output includes the forced-colors rule; visual behavior needs
550
+ // manual verification under Windows High Contrast.
551
+ describe('forced colors (WCAG 1.4.11)', () => {
552
+ it('compiles a forced-colors fill so the indeterminate mark survives Windows High Contrast', () => {
553
+ render(
554
+ <CheckboxInput label="All" value="indeterminate" onChange={() => {}} />,
555
+ );
556
+ // The painted indeterminate bar would be stripped to Canvas (invisible);
557
+ // CanvasText keeps it perceivable.
558
+ expect(getForcedColorsRules()).toContain('background-color: canvastext;');
559
+ });
560
+
561
+ it('compiles a forced-colors color so the checkmark survives Windows High Contrast', () => {
562
+ render(<CheckboxInput label="Accept" value={true} onChange={() => {}} />);
563
+ // The check strokes with currentColor; forced colors leaves it the same
564
+ // white as the flattened box, so it needs its own CanvasText color to stay
565
+ // perceivable on the Canvas box.
566
+ expect(getForcedColorsRules()).toContain('color: canvastext;');
567
+ });
568
+ });
@@ -158,14 +158,29 @@ const styles = stylex.create({
158
158
  },
159
159
  checkmark: {
160
160
  display: 'none',
161
- color: colorVars['--color-on-accent'],
161
+ color: {
162
+ default: colorVars['--color-on-accent'],
163
+ // Forced colors (Windows High Contrast) does not reliably force an SVG
164
+ // stroke painted with currentColor, so the check stays the same white as
165
+ // the flattened (Canvas) box fill — a white check on a white box.
166
+ // CanvasText keeps it perceivable on the Canvas box, matching the
167
+ // indeterminate mark (WCAG 1.4.11).
168
+ '@media (forced-colors: active)': 'CanvasText',
169
+ },
162
170
  },
163
171
  checkmarkVisible: {
164
172
  display: 'block',
165
173
  },
166
174
  indeterminateMark: {
167
175
  display: 'none',
168
- backgroundColor: colorVars['--color-on-accent'],
176
+ backgroundColor: {
177
+ default: colorVars['--color-on-accent'],
178
+ // Forced colors (Windows High Contrast) strips painted backgrounds,
179
+ // which would make the indeterminate bar invisible; CanvasText keeps it
180
+ // perceivable on the Canvas box fill (WCAG 1.4.11). The checkmark carries
181
+ // the matching CanvasText treatment on its own style.
182
+ '@media (forced-colors: active)': 'CanvasText',
183
+ },
169
184
  borderRadius: radiusVars['--radius-full'],
170
185
  },
171
186
  indeterminateMarkVisible: {
@@ -198,12 +213,12 @@ const wrapperSizeStyles = stylex.create({
198
213
 
199
214
  const checkboxSizeStyles = stylex.create({
200
215
  sm: {
201
- width: 18,
202
- height: 18,
216
+ width: 20,
217
+ height: 20,
203
218
  },
204
219
  md: {
205
- width: 22,
206
- height: 22,
220
+ width: 24,
221
+ height: 24,
207
222
  },
208
223
  });
209
224
 
@@ -88,6 +88,12 @@ export const docs = {
88
88
  type: "{type: 'warning' | 'error' | 'success', message?: string}",
89
89
  description: 'Status indicator ({ type, message }).',
90
90
  },
91
+ {
92
+ name: 'width',
93
+ type: 'SizeValue',
94
+ description:
95
+ 'Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.',
96
+ },
91
97
  {
92
98
  name: 'xstyle',
93
99
  type: 'StyleXStyles',
@@ -154,14 +154,105 @@ describe('CheckboxList', () => {
154
154
  </CheckboxList>,
155
155
  );
156
156
 
157
- // Click the interactive row (invisible-button pattern), which is where the
158
- // composed onClick lives — not the inner checkbox.
159
- await user.click(screen.getByRole('button', {name: 'Option B'}));
157
+ // The row is a pointer-only click surface (no invisible row button — the
158
+ // checkbox is the option's only tab stop). Click the row's label area,
159
+ // where the composed onClick fires — not the inner checkbox.
160
+ expect(
161
+ screen.queryByRole('button', {name: 'Option B'}),
162
+ ).not.toBeInTheDocument();
163
+ // The text also exists in the checkbox's visually hidden <label>; target
164
+ // the row's label <span> to click the row surface.
165
+ await user.click(screen.getByText('Option B', {selector: 'span'}));
160
166
 
161
167
  expect(handleClick).toHaveBeenCalledTimes(1);
162
168
  expect(handleChange).toHaveBeenCalledWith(['a', 'b']);
163
169
  });
164
170
 
171
+ describe('single tab stop per option (WCAG 4.1.2 / APG checkbox pattern)', () => {
172
+ it('renders exactly one focusable control per option — the checkbox, no row button', () => {
173
+ render(
174
+ <CheckboxList label="Preferences" value={['a']} onChange={() => {}}>
175
+ <CheckboxListItem label="Option A" value="a" />
176
+ <CheckboxListItem label="Option B" value="b" />
177
+ </CheckboxList>,
178
+ );
179
+ // No invisible whole-row button duplicating the checkbox's action.
180
+ expect(screen.queryByRole('button')).not.toBeInTheDocument();
181
+ for (const item of screen.getAllByRole('listitem')) {
182
+ const focusables = item.querySelectorAll(
183
+ 'button, a[href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
184
+ );
185
+ expect(focusables).toHaveLength(1);
186
+ expect(focusables[0]).toBe(within(item).getByRole('checkbox'));
187
+ }
188
+ });
189
+
190
+ it('Tab moves directly from one option checkbox to the next', async () => {
191
+ const user = userEvent.setup();
192
+ render(
193
+ <CheckboxList label="Preferences" value={[]} onChange={() => {}}>
194
+ <CheckboxListItem label="Option A" value="a" />
195
+ <CheckboxListItem label="Option B" value="b" />
196
+ </CheckboxList>,
197
+ );
198
+ await user.tab();
199
+ expect(screen.getByRole('checkbox', {name: 'Option A'})).toHaveFocus();
200
+ await user.tab();
201
+ expect(screen.getByRole('checkbox', {name: 'Option B'})).toHaveFocus();
202
+ // No further tab stop inside the list (the row itself is not focusable).
203
+ await user.tab();
204
+ expect(document.body).toHaveFocus();
205
+ });
206
+
207
+ it('clicking the row surface (outside the checkbox) still toggles', async () => {
208
+ const user = userEvent.setup();
209
+ const handleChange = vi.fn();
210
+ render(
211
+ <CheckboxList label="Preferences" value={['a']} onChange={handleChange}>
212
+ <CheckboxListItem label="Option A" value="a" />
213
+ <CheckboxListItem label="Option B" value="b" />
214
+ </CheckboxList>,
215
+ );
216
+ // The text also exists in the checkbox's visually hidden <label>;
217
+ // target the row's label <span> to click the row surface.
218
+ await user.click(screen.getByText('Option B', {selector: 'span'}));
219
+ expect(handleChange).toHaveBeenCalledTimes(1);
220
+ expect(handleChange).toHaveBeenCalledWith(['a', 'b']);
221
+ });
222
+
223
+ it('toggles with Space on the focused checkbox, which reports checked state', async () => {
224
+ const user = userEvent.setup();
225
+ const handleChange = vi.fn();
226
+ render(
227
+ <CheckboxList label="Preferences" value={['a']} onChange={handleChange}>
228
+ <CheckboxListItem label="Option A" value="a" />
229
+ <CheckboxListItem label="Option B" value="b" />
230
+ </CheckboxList>,
231
+ );
232
+ await user.tab();
233
+ // The focused control is the checkbox itself, so its accessible name
234
+ // and checked state are what assistive tech announces on focus.
235
+ const checkboxA = screen.getByRole('checkbox', {name: 'Option A'});
236
+ expect(checkboxA).toHaveFocus();
237
+ expect(checkboxA).toBeChecked();
238
+ await user.keyboard(' ');
239
+ expect(handleChange).toHaveBeenCalledTimes(1);
240
+ expect(handleChange).toHaveBeenCalledWith([]);
241
+ });
242
+
243
+ it('the row itself is not focusable', () => {
244
+ render(
245
+ <CheckboxList label="Preferences" value={[]} onChange={() => {}}>
246
+ <CheckboxListItem label="Option A" value="a" />
247
+ </CheckboxList>,
248
+ );
249
+ const item = screen.getByRole('listitem');
250
+ expect(item).not.toHaveAttribute('tabindex');
251
+ item.focus();
252
+ expect(item).not.toHaveFocus();
253
+ });
254
+ });
255
+
165
256
  it('disables all checkboxes when group isDisabled is true', () => {
166
257
  render(
167
258
  <CheckboxList
@@ -16,12 +16,11 @@
16
16
  * - /packages/cli/templates/blocks/components/CheckboxList/ (showcase blocks)
17
17
  */
18
18
 
19
- import {use, type MouseEvent, type ReactNode} from 'react';
19
+ import {use, useRef, type ReactNode} from 'react';
20
20
  import * as stylex from '@stylexjs/stylex';
21
21
  import type {StyleXStyles} from '@stylexjs/stylex';
22
22
  import {colorVars} from '../theme/tokens.stylex';
23
23
  import type {BaseProps} from '../BaseProps';
24
- import {composeEventHandlers} from '../utils';
25
24
  import {useDevWarning} from '../hooks/useDevWarning';
26
25
  import {CheckboxInput} from '../CheckboxInput/CheckboxInput';
27
26
  import {ListItem} from '../List/ListItem';
@@ -212,6 +211,14 @@ export function CheckboxListItem({
212
211
  // Whether this item is interactive (has a toggle handler)
213
212
  const isInteractive = !effectiveReadOnly && (ctx != null || onCheck != null);
214
213
 
214
+ // The checkbox is the row's single keyboard control and action. The row is
215
+ // an enlarged click/tap target that delegates surface clicks to it via
216
+ // ListItem's `interactiveRef` (useClickableContainer), so each option is
217
+ // exactly one tab stop. Delegate whenever the row should respond to clicks:
218
+ // a toggleable item, or one carrying a consumer `onClick`.
219
+ const checkboxRef = useRef<HTMLInputElement | null>(null);
220
+ const hasRowInteraction = isInteractive || onClickProp != null;
221
+
215
222
  const handleToggle = () => {
216
223
  if (effectiveDisabled || effectiveReadOnly || isBusy) {
217
224
  return;
@@ -244,14 +251,12 @@ export function CheckboxListItem({
244
251
  description={description}
245
252
  endContent={endContent}
246
253
  isDisabled={effectiveDisabled}
247
- onClick={
248
- isInteractive || onClickProp
249
- ? composeEventHandlers<MouseEvent>(
250
- onClickProp as ((event: MouseEvent) => void) | undefined,
251
- isInteractive ? handleToggle : undefined,
252
- )
253
- : undefined
254
- }
254
+ // Delegate row clicks to the checkbox instead of wiring onClick (which
255
+ // would add an invisible row button = a second tab stop). The checkbox
256
+ // stays the option's sole focusable control (WCAG 4.1.2 / APG checkbox
257
+ // pattern). A consumer onClick rides on the checkbox itself (below), so
258
+ // it still fires for both direct and delegated (row-surface) clicks.
259
+ interactiveRef={hasRowInteraction ? checkboxRef : undefined}
255
260
  aria-busy={isBusy || undefined}
256
261
  xstyle={
257
262
  [
@@ -266,10 +271,12 @@ export function CheckboxListItem({
266
271
  style={style}
267
272
  startContent={
268
273
  <CheckboxInput
274
+ ref={checkboxRef}
269
275
  label={checkboxLabel}
270
276
  isLabelHidden
271
277
  value={resolvedChecked}
272
278
  onChange={() => handleToggle()}
279
+ onClick={onClickProp}
273
280
  isDisabled={effectiveDisabled}
274
281
  isReadOnly={effectiveReadOnly}
275
282
  isLoading={isBusy}
@@ -39,7 +39,7 @@ export const docs = {
39
39
  name: 'Icon',
40
40
  required: false,
41
41
  description:
42
- 'An optional favicon or source icon displayed before the label text. Only available in the label variant.',
42
+ 'An optional source icon shown before the label text. Accepts a favicon/logo image URL (via source.src) or a React node such as an Astryx <Icon>. Only available in the label variant.',
43
43
  },
44
44
  {
45
45
  name: 'Label text',
@@ -71,7 +71,7 @@ export const docs = {
71
71
  name: 'source',
72
72
  type: 'CitationSource',
73
73
  description:
74
- 'The citation source object containing title, url, and optional icon.',
74
+ 'The citation source object containing title, url, an optional image src, and an optional icon node.',
75
75
  required: true,
76
76
  },
77
77
  {
@@ -121,7 +121,8 @@ export const docsDense = {
121
121
  ],
122
122
  },
123
123
  propDescriptions: {
124
- source: 'citation source object with title, url, optional icon.',
124
+ source:
125
+ 'citation source object with title, url, optional image src, and optional icon node.',
125
126
  number: 'display index for this citation.',
126
127
  variant: 'display style: label chip with source title or compact numbered badge.',
127
128
  },