@astryxdesign/core 0.1.9 → 0.2.0-canary.0e01213

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 (625) 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/Center/Center.d.ts +20 -3
  33. package/dist/Center/Center.d.ts.map +1 -1
  34. package/dist/Center/Center.js +10 -2
  35. package/dist/Chat/ChatComposerInput.js +1 -1
  36. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  37. package/dist/Chat/ChatDictationButton.js +3 -1
  38. package/dist/Chat/ChatLayout.d.ts +7 -0
  39. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  40. package/dist/Chat/ChatLayout.js +16 -5
  41. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  42. package/dist/Chat/ChatMessageBubble.js +8 -8
  43. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  44. package/dist/Chat/ChatToolCalls.js +10 -3
  45. package/dist/Chat/useTriggerMenu.js +2 -2
  46. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  47. package/dist/CheckboxInput/CheckboxInput.js +6 -6
  48. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  49. package/dist/CheckboxList/CheckboxListItem.js +19 -4
  50. package/dist/Citation/Citation.d.ts +22 -1
  51. package/dist/Citation/Citation.d.ts.map +1 -1
  52. package/dist/Citation/Citation.js +20 -6
  53. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  54. package/dist/CodeBlock/CodeBlock.js +16 -10
  55. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  56. package/dist/Collapsible/Collapsible.js +3 -1
  57. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  58. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  59. package/dist/CommandPalette/CommandPalette.js +42 -3
  60. package/dist/CommandPalette/CommandPaletteItem.js +1 -1
  61. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  62. package/dist/ContextMenu/ContextMenu.js +23 -5
  63. package/dist/ContextMenu/index.d.ts +1 -0
  64. package/dist/ContextMenu/index.d.ts.map +1 -1
  65. package/dist/ContextMenu/index.js +3 -1
  66. package/dist/DateInput/DateInput.d.ts +10 -2
  67. package/dist/DateInput/DateInput.d.ts.map +1 -1
  68. package/dist/DateInput/DateInput.js +33 -19
  69. package/dist/DateRangeInput/DateRangeInput.d.ts +10 -2
  70. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  71. package/dist/DateRangeInput/DateRangeInput.js +23 -20
  72. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  73. package/dist/DateTimeInput/DateTimeInput.js +23 -18
  74. package/dist/Divider/Divider.d.ts +2 -2
  75. package/dist/Divider/Divider.d.ts.map +1 -1
  76. package/dist/Divider/Divider.js +13 -0
  77. package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
  78. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  79. package/dist/DropdownMenu/DropdownMenu.js +22 -5
  80. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +18 -12
  81. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  82. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +42 -64
  83. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  84. package/dist/DropdownMenu/DropdownMenuItem.js +5 -2
  85. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +8 -11
  86. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  87. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +3 -1
  88. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +1 -1
  89. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  90. package/dist/DropdownMenu/DropdownMenuRadioItem.js +10 -3
  91. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
  92. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
  93. package/dist/DropdownMenu/DropdownMenuSubMenu.js +435 -0
  94. package/dist/DropdownMenu/index.d.ts +10 -0
  95. package/dist/DropdownMenu/index.d.ts.map +1 -1
  96. package/dist/DropdownMenu/index.js +13 -0
  97. package/dist/DropdownMenu/menuItemHover.d.ts +24 -0
  98. package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
  99. package/dist/DropdownMenu/menuItemHover.js +34 -0
  100. package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
  101. package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
  102. package/dist/DropdownMenu/menuItemRoles.js +10 -1
  103. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  104. package/dist/DropdownMenu/renderDropdownItems.js +27 -10
  105. package/dist/Field/Field.d.ts +3 -1
  106. package/dist/Field/Field.d.ts.map +1 -1
  107. package/dist/Field/Field.js +4 -1
  108. package/dist/Field/FieldLabel.d.ts +2 -1
  109. package/dist/Field/FieldLabel.d.ts.map +1 -1
  110. package/dist/Field/FieldLabel.js +9 -5
  111. package/dist/Field/inputStyles.stylex.d.ts +1 -0
  112. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  113. package/dist/Field/inputStyles.stylex.js +1 -0
  114. package/dist/FieldStatus/FieldStatus.d.ts +10 -0
  115. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  116. package/dist/FieldStatus/FieldStatus.js +51 -5
  117. package/dist/FileInput/FileInput.d.ts +10 -2
  118. package/dist/FileInput/FileInput.d.ts.map +1 -1
  119. package/dist/FileInput/FileInput.js +93 -65
  120. package/dist/Heading/Heading.d.ts.map +1 -1
  121. package/dist/Heading/Heading.js +3 -2
  122. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  123. package/dist/HoverCard/useHoverCard.js +10 -4
  124. package/dist/Icon/Icon.d.ts +15 -1
  125. package/dist/Icon/Icon.d.ts.map +1 -1
  126. package/dist/Icon/Icon.js +19 -3
  127. package/dist/Item/Item.d.ts +16 -3
  128. package/dist/Item/Item.d.ts.map +1 -1
  129. package/dist/Item/Item.js +31 -6
  130. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  131. package/dist/Layer/layerAnimations.stylex.js +10 -2
  132. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  133. package/dist/Lightbox/Lightbox.js +34 -15
  134. package/dist/List/List.d.ts.map +1 -1
  135. package/dist/List/List.js +6 -3
  136. package/dist/List/ListItem.d.ts +11 -1
  137. package/dist/List/ListItem.d.ts.map +1 -1
  138. package/dist/List/ListItem.js +2 -0
  139. package/dist/Markdown/Markdown.d.ts.map +1 -1
  140. package/dist/Markdown/Markdown.js +7 -0
  141. package/dist/MetadataList/MetadataList.d.ts +1 -1
  142. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  143. package/dist/MetadataList/MetadataList.js +4 -2
  144. package/dist/MultiSelector/MultiSelector.d.ts +9 -1
  145. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  146. package/dist/MultiSelector/MultiSelector.js +87 -45
  147. package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
  148. package/dist/NumberInput/NumberInput.d.ts +10 -2
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +22 -17
  151. package/dist/Outline/Outline.js +2 -2
  152. package/dist/Pagination/Pagination.d.ts.map +1 -1
  153. package/dist/Pagination/Pagination.js +11 -3
  154. package/dist/PowerSearch/PowerSearch.d.ts +9 -2
  155. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  156. package/dist/PowerSearch/PowerSearch.js +2 -0
  157. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  158. package/dist/ProgressBar/ProgressBar.js +6 -1
  159. package/dist/RadioList/RadioList.d.ts +2 -2
  160. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  161. package/dist/RadioList/RadioListItem.js +5 -5
  162. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  163. package/dist/Resizable/ResizeHandle.js +49 -19
  164. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  165. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  166. package/dist/SegmentedControl/SegmentedControlItem.js +5 -3
  167. package/dist/Selector/Selector.d.ts +8 -0
  168. package/dist/Selector/Selector.d.ts.map +1 -1
  169. package/dist/Selector/Selector.js +72 -19
  170. package/dist/SideNav/SideNav.d.ts.map +1 -1
  171. package/dist/SideNav/SideNav.js +5 -5
  172. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  173. package/dist/SideNav/SideNavCollapseButton.js +13 -10
  174. package/dist/SideNav/SideNavItem.d.ts +1 -1
  175. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  176. package/dist/SideNav/SideNavItem.js +12 -10
  177. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  178. package/dist/Skeleton/Skeleton.js +2 -2
  179. package/dist/Slider/Slider.d.ts.map +1 -1
  180. package/dist/Slider/Slider.js +87 -34
  181. package/dist/Spinner/Spinner.d.ts +3 -2
  182. package/dist/Spinner/Spinner.d.ts.map +1 -1
  183. package/dist/Spinner/Spinner.js +11 -2
  184. package/dist/Switch/Switch.d.ts +8 -1
  185. package/dist/Switch/Switch.d.ts.map +1 -1
  186. package/dist/Switch/Switch.js +171 -91
  187. package/dist/TabList/Tab.js +2 -2
  188. package/dist/TabList/TabList.d.ts +2 -11
  189. package/dist/TabList/TabList.d.ts.map +1 -1
  190. package/dist/TabList/TabList.js +5 -9
  191. package/dist/TabList/TabListContext.d.ts +0 -5
  192. package/dist/TabList/TabListContext.d.ts.map +1 -1
  193. package/dist/TabList/TabListContext.js +0 -5
  194. package/dist/TabList/TabMenu.js +1 -1
  195. package/dist/Table/BaseTable.d.ts.map +1 -1
  196. package/dist/Table/BaseTable.js +30 -4
  197. package/dist/Table/TableCell.js +3 -3
  198. package/dist/Table/TableHeaderCell.js +3 -3
  199. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  200. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
  201. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +18 -3
  202. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  203. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +58 -30
  204. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  205. package/dist/Table/plugins/selection/useTableSelection.js +3 -0
  206. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  207. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +15 -7
  208. package/dist/Table/plugins/tree/useTableTreeData.d.ts +11 -0
  209. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  210. package/dist/Table/plugins/tree/useTableTreeData.js +65 -25
  211. package/dist/Table/types.d.ts +32 -0
  212. package/dist/Table/types.d.ts.map +1 -1
  213. package/dist/Text/Text.d.ts +10 -1
  214. package/dist/Text/Text.d.ts.map +1 -1
  215. package/dist/Text/Text.js +25 -2
  216. package/dist/Text/index.d.ts +2 -2
  217. package/dist/Text/index.d.ts.map +1 -1
  218. package/dist/TextArea/TextArea.d.ts +10 -1
  219. package/dist/TextArea/TextArea.d.ts.map +1 -1
  220. package/dist/TextArea/TextArea.js +119 -52
  221. package/dist/TextInput/TextInput.d.ts +10 -2
  222. package/dist/TextInput/TextInput.d.ts.map +1 -1
  223. package/dist/TextInput/TextInput.js +20 -17
  224. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  225. package/dist/Thumbnail/Thumbnail.js +51 -45
  226. package/dist/TimeInput/TimeInput.d.ts +10 -2
  227. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  228. package/dist/TimeInput/TimeInput.js +17 -17
  229. package/dist/Timestamp/Timestamp.d.ts +31 -3
  230. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  231. package/dist/Timestamp/Timestamp.js +48 -77
  232. package/dist/Timestamp/formatInstant.d.ts +41 -0
  233. package/dist/Timestamp/formatInstant.d.ts.map +1 -0
  234. package/dist/Timestamp/formatInstant.js +177 -0
  235. package/dist/Timestamp/index.d.ts +1 -0
  236. package/dist/Timestamp/index.d.ts.map +1 -1
  237. package/dist/Timestamp/tooltipEntries.d.ts +56 -0
  238. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -0
  239. package/dist/Timestamp/tooltipEntries.js +163 -0
  240. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  241. package/dist/Toast/ToastViewport.js +61 -9
  242. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  243. package/dist/ToggleButton/ToggleButton.js +3 -1
  244. package/dist/Token/Token.d.ts +34 -4
  245. package/dist/Token/Token.d.ts.map +1 -1
  246. package/dist/Token/Token.js +85 -45
  247. package/dist/Token/TokenLink.d.ts +62 -0
  248. package/dist/Token/TokenLink.d.ts.map +1 -0
  249. package/dist/Token/TokenLink.js +76 -0
  250. package/dist/Token/index.d.ts +1 -1
  251. package/dist/Token/index.d.ts.map +1 -1
  252. package/dist/Tokenizer/Tokenizer.d.ts +9 -2
  253. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  254. package/dist/Tokenizer/Tokenizer.js +4 -2
  255. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  256. package/dist/Tooltip/useTooltip.js +17 -1
  257. package/dist/TopNav/TopNavItem.d.ts +3 -1
  258. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  259. package/dist/TopNav/TopNavItem.js +30 -3
  260. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  261. package/dist/TopNav/TopNavMegaMenu.js +9 -3
  262. package/dist/TreeList/TreeList.d.ts.map +1 -1
  263. package/dist/TreeList/TreeList.js +1 -0
  264. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  265. package/dist/TreeList/TreeListBranches.js +8 -6
  266. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  267. package/dist/TreeList/TreeListItem.js +32 -14
  268. package/dist/Typeahead/BaseTypeahead.d.ts +9 -0
  269. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  270. package/dist/Typeahead/BaseTypeahead.js +22 -11
  271. package/dist/Typeahead/Typeahead.d.ts +9 -2
  272. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  273. package/dist/Typeahead/Typeahead.js +11 -2
  274. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  275. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  276. package/dist/Typeahead/TypeaheadItem.js +20 -10
  277. package/dist/astryx.css +115 -35
  278. package/dist/astryx.umd.js +51 -51
  279. package/dist/astryx.umd.js.map +4 -4
  280. package/dist/hooks/containerReveal.pool.stylex.d.ts +281 -0
  281. package/dist/hooks/containerReveal.pool.stylex.d.ts.map +1 -0
  282. package/dist/hooks/containerReveal.pool.stylex.js +281 -0
  283. package/dist/hooks/index.d.ts +4 -0
  284. package/dist/hooks/index.d.ts.map +1 -1
  285. package/dist/hooks/index.js +3 -1
  286. package/dist/hooks/isRtlElement.d.ts +18 -0
  287. package/dist/hooks/isRtlElement.d.ts.map +1 -0
  288. package/dist/hooks/isRtlElement.js +27 -0
  289. package/dist/hooks/useAnnounce.d.ts +3 -0
  290. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  291. package/dist/hooks/useAnnounce.js +39 -1
  292. package/dist/hooks/useContainerReveal.d.ts +83 -0
  293. package/dist/hooks/useContainerReveal.d.ts.map +1 -0
  294. package/dist/hooks/useContainerReveal.js +123 -0
  295. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  296. package/dist/hooks/useFocusTrap.js +52 -11
  297. package/dist/hooks/useGridFocus.d.ts +6 -1
  298. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  299. package/dist/hooks/useGridFocus.js +12 -9
  300. package/dist/hooks/useHotkeys.d.ts +9 -0
  301. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  302. package/dist/hooks/useHotkeys.js +9 -0
  303. package/dist/hooks/useInputStatusIcon.d.ts +38 -0
  304. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
  305. package/dist/hooks/useInputStatusIcon.js +169 -0
  306. package/dist/hooks/useKeyboardHint.d.ts +1 -1
  307. package/dist/hooks/useKeyboardHint.d.ts.map +1 -1
  308. package/dist/hooks/useKeyboardHint.js +4 -2
  309. package/dist/hooks/useListFocus.d.ts +39 -1
  310. package/dist/hooks/useListFocus.d.ts.map +1 -1
  311. package/dist/hooks/useListFocus.js +54 -9
  312. package/dist/i18n/InternationalizationContext.d.ts +1 -0
  313. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  314. package/dist/i18n/InternationalizationContext.js +3 -0
  315. package/dist/i18n/InternationalizationProvider.d.ts +8 -1
  316. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  317. package/dist/i18n/InternationalizationProvider.js +5 -1
  318. package/dist/i18n/getLocaleDirection.d.ts +18 -0
  319. package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
  320. package/dist/i18n/getLocaleDirection.js +29 -0
  321. package/dist/i18n/index.d.ts +6 -0
  322. package/dist/i18n/index.d.ts.map +1 -1
  323. package/dist/i18n/index.js +7 -1
  324. package/dist/i18n/useDirection.d.ts +2 -0
  325. package/dist/i18n/useDirection.d.ts.map +1 -0
  326. package/dist/i18n/useDirection.js +27 -0
  327. package/dist/theme/defineTheme.d.ts +6 -0
  328. package/dist/theme/defineTheme.d.ts.map +1 -1
  329. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  330. package/dist/theme/derivedVarRegistry.js +13 -0
  331. package/dist/theme/expandColorScale.d.ts +19 -2
  332. package/dist/theme/expandColorScale.d.ts.map +1 -1
  333. package/dist/theme/expandColorScale.js +38 -10
  334. package/dist/theme/index.d.ts +3 -3
  335. package/dist/theme/index.d.ts.map +1 -1
  336. package/dist/theme/types.d.ts +39 -2
  337. package/dist/theme/types.d.ts.map +1 -1
  338. package/dist/utils/index.d.ts +1 -0
  339. package/dist/utils/index.d.ts.map +1 -1
  340. package/dist/utils/index.js +2 -1
  341. package/dist/utils/plainDate.d.ts +17 -0
  342. package/dist/utils/plainDate.d.ts.map +1 -1
  343. package/dist/utils/plainDate.js +23 -4
  344. package/dist/utils/rtlStyles.d.ts +24 -0
  345. package/dist/utils/rtlStyles.d.ts.map +1 -0
  346. package/dist/utils/rtlStyles.js +27 -0
  347. package/locales/en.json +120 -0
  348. package/locales/pseudo.json +90 -0
  349. package/package.json +8 -3
  350. package/src/Avatar/Avatar.doc.mjs +50 -3
  351. package/src/Avatar/Avatar.test.tsx +218 -0
  352. package/src/Avatar/Avatar.tsx +285 -79
  353. package/src/Avatar/AvatarStatusDot.doc.mjs +4 -4
  354. package/src/Avatar/AvatarStatusDot.tsx +6 -4
  355. package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
  356. package/src/AvatarGroup/AvatarGroup.test.tsx +162 -2
  357. package/src/AvatarGroup/AvatarGroup.tsx +58 -3
  358. package/src/AvatarGroup/AvatarGroupOverflow.tsx +5 -2
  359. package/src/Banner/Banner.tsx +6 -6
  360. package/src/Breadcrumbs/BreadcrumbItem.tsx +10 -10
  361. package/src/Breadcrumbs/Breadcrumbs.test.tsx +52 -1
  362. package/src/Breadcrumbs/index.ts +4 -0
  363. package/src/Button/Button.doc.mjs +0 -4
  364. package/src/Button/Button.test.tsx +16 -0
  365. package/src/Button/Button.tsx +6 -4
  366. package/src/Calendar/Calendar.test.tsx +170 -20
  367. package/src/Calendar/Calendar.tsx +73 -16
  368. package/src/Calendar/dayCellUtils.test.ts +18 -18
  369. package/src/Calendar/dayCellUtils.ts +2 -2
  370. package/src/Calendar/styles.ts +33 -39
  371. package/src/Card/Card.tsx +1 -1
  372. package/src/Carousel/Carousel.tsx +25 -6
  373. package/src/Center/Center.doc.mjs +38 -0
  374. package/src/Center/Center.test.tsx +75 -0
  375. package/src/Center/Center.tsx +37 -2
  376. package/src/Chat/ChatComposer.doc.mjs +2 -2
  377. package/src/Chat/ChatComposerInput.doc.mjs +1 -1
  378. package/src/Chat/ChatComposerInput.tsx +2 -2
  379. package/src/Chat/ChatDictationButton.tsx +7 -1
  380. package/src/Chat/ChatLayout.test.tsx +57 -0
  381. package/src/Chat/ChatLayout.tsx +26 -5
  382. package/src/Chat/ChatMessageBubble.tsx +15 -10
  383. package/src/Chat/ChatSystemMessage.test.tsx +5 -0
  384. package/src/Chat/ChatToolCalls.tsx +9 -2
  385. package/src/Chat/useTriggerMenu.tsx +1 -1
  386. package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
  387. package/src/CheckboxInput/CheckboxInput.test.tsx +23 -0
  388. package/src/CheckboxInput/CheckboxInput.tsx +21 -6
  389. package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
  390. package/src/CheckboxList/CheckboxList.test.tsx +94 -3
  391. package/src/CheckboxList/CheckboxListItem.tsx +17 -10
  392. package/src/Citation/Citation.doc.mjs +4 -3
  393. package/src/Citation/Citation.test.tsx +97 -0
  394. package/src/Citation/Citation.tsx +43 -11
  395. package/src/CodeBlock/CodeBlock.test.tsx +17 -0
  396. package/src/CodeBlock/CodeBlock.tsx +38 -11
  397. package/src/Collapsible/Collapsible.doc.mjs +1 -0
  398. package/src/Collapsible/Collapsible.test.tsx +7 -0
  399. package/src/Collapsible/Collapsible.tsx +16 -6
  400. package/src/CommandPalette/CommandPalette.test.tsx +95 -1
  401. package/src/CommandPalette/CommandPalette.tsx +41 -2
  402. package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
  403. package/src/ContextMenu/ContextMenu.test.tsx +59 -2
  404. package/src/ContextMenu/ContextMenu.tsx +22 -11
  405. package/src/ContextMenu/index.ts +5 -0
  406. package/src/DateInput/DateInput.doc.mjs +25 -0
  407. package/src/DateInput/DateInput.test.tsx +230 -0
  408. package/src/DateInput/DateInput.tsx +51 -29
  409. package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
  410. package/src/DateRangeInput/DateRangeInput.test.tsx +140 -0
  411. package/src/DateRangeInput/DateRangeInput.tsx +42 -30
  412. package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
  413. package/src/DateTimeInput/DateTimeInput.test.tsx +112 -0
  414. package/src/DateTimeInput/DateTimeInput.tsx +44 -39
  415. package/src/Divider/Divider.test.tsx +32 -8
  416. package/src/Divider/Divider.tsx +14 -1
  417. package/src/DropdownMenu/DropdownMenu.doc.mjs +5 -2
  418. package/src/DropdownMenu/DropdownMenu.test.tsx +95 -0
  419. package/src/DropdownMenu/DropdownMenu.tsx +31 -12
  420. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +49 -66
  421. package/src/DropdownMenu/DropdownMenuItem.tsx +9 -3
  422. package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +4 -12
  423. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +9 -10
  424. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +19 -4
  425. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +84 -2
  426. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
  427. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +680 -0
  428. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +569 -0
  429. package/src/DropdownMenu/index.ts +16 -0
  430. package/src/DropdownMenu/menuItemHover.ts +40 -0
  431. package/src/DropdownMenu/menuItemRoles.ts +9 -0
  432. package/src/DropdownMenu/renderDropdownItems.tsx +40 -14
  433. package/src/Field/Field.doc.mjs +4 -0
  434. package/src/Field/Field.tsx +14 -9
  435. package/src/Field/FieldLabel.test.tsx +25 -0
  436. package/src/Field/FieldLabel.tsx +12 -3
  437. package/src/Field/inputStyles.stylex.ts +2 -0
  438. package/src/FieldStatus/FieldStatus.doc.mjs +1 -0
  439. package/src/FieldStatus/FieldStatus.test.tsx +133 -0
  440. package/src/FieldStatus/FieldStatus.tsx +61 -4
  441. package/src/FileInput/FileInput.doc.mjs +23 -2
  442. package/src/FileInput/FileInput.test.tsx +104 -13
  443. package/src/FileInput/FileInput.tsx +106 -79
  444. package/src/Heading/Heading.tsx +2 -1
  445. package/src/HoverCard/useHoverCard.tsx +15 -3
  446. package/src/Icon/Icon.doc.mjs +13 -0
  447. package/src/Icon/Icon.test.tsx +89 -0
  448. package/src/Icon/Icon.tsx +51 -3
  449. package/src/Item/Item.doc.mjs +5 -0
  450. package/src/Item/Item.test.tsx +88 -0
  451. package/src/Item/Item.tsx +57 -11
  452. package/src/Layer/layerAnimations.stylex.ts +23 -0
  453. package/src/Lightbox/Lightbox.test.tsx +33 -0
  454. package/src/Lightbox/Lightbox.tsx +30 -10
  455. package/src/List/List.test.tsx +17 -29
  456. package/src/List/List.tsx +6 -1
  457. package/src/List/ListItem.doc.mjs +12 -0
  458. package/src/List/ListItem.tsx +13 -0
  459. package/src/Markdown/Markdown.test.tsx +21 -0
  460. package/src/Markdown/Markdown.tsx +4 -0
  461. package/src/MetadataList/MetadataList.test.tsx +24 -0
  462. package/src/MetadataList/MetadataList.tsx +6 -2
  463. package/src/MultiSelector/MultiSelector.doc.mjs +20 -0
  464. package/src/MultiSelector/MultiSelector.test.tsx +436 -0
  465. package/src/MultiSelector/MultiSelector.tsx +133 -67
  466. package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
  467. package/src/NumberInput/NumberInput.doc.mjs +21 -0
  468. package/src/NumberInput/NumberInput.test.tsx +71 -0
  469. package/src/NumberInput/NumberInput.tsx +35 -26
  470. package/src/Outline/Outline.test.tsx +12 -12
  471. package/src/Outline/Outline.tsx +2 -2
  472. package/src/Pagination/Pagination.tsx +11 -3
  473. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  474. package/src/PowerSearch/PowerSearch.test.tsx +23 -0
  475. package/src/PowerSearch/PowerSearch.tsx +10 -1
  476. package/src/ProgressBar/ProgressBar.test.tsx +34 -0
  477. package/src/ProgressBar/ProgressBar.tsx +16 -1
  478. package/src/RadioList/RadioList.doc.mjs +6 -0
  479. package/src/RadioList/RadioList.test.tsx +26 -4
  480. package/src/RadioList/RadioList.tsx +2 -2
  481. package/src/RadioList/RadioListItem.tsx +12 -5
  482. package/src/Resizable/ResizeHandle.test.tsx +94 -0
  483. package/src/Resizable/ResizeHandle.tsx +70 -20
  484. package/src/SegmentedControl/SegmentedControl.test.tsx +28 -0
  485. package/src/SegmentedControl/SegmentedControlItem.tsx +22 -2
  486. package/src/Selector/Selector.doc.mjs +15 -0
  487. package/src/Selector/Selector.test.tsx +400 -0
  488. package/src/Selector/Selector.tsx +95 -23
  489. package/src/SideNav/SideNav.tsx +1 -8
  490. package/src/SideNav/SideNavCollapseButton.tsx +9 -7
  491. package/src/SideNav/SideNavItem.tsx +5 -3
  492. package/src/Skeleton/Skeleton.test.tsx +16 -0
  493. package/src/Skeleton/Skeleton.tsx +13 -1
  494. package/src/Slider/Slider.doc.mjs +6 -0
  495. package/src/Slider/Slider.test.tsx +240 -12
  496. package/src/Slider/Slider.tsx +96 -23
  497. package/src/Spinner/Spinner.test.tsx +10 -8
  498. package/src/Spinner/Spinner.tsx +15 -5
  499. package/src/Switch/Switch.doc.mjs +142 -42
  500. package/src/Switch/Switch.test.tsx +111 -0
  501. package/src/Switch/Switch.tsx +149 -32
  502. package/src/TabList/Tab.tsx +2 -2
  503. package/src/TabList/TabList.doc.mjs +0 -6
  504. package/src/TabList/TabList.test.tsx +3 -15
  505. package/src/TabList/TabList.tsx +6 -17
  506. package/src/TabList/TabListContext.ts +0 -6
  507. package/src/TabList/TabMenu.tsx +2 -2
  508. package/src/Table/BaseTable.tsx +34 -2
  509. package/src/Table/Table.doc.mjs +11 -0
  510. package/src/Table/Table.test.tsx +85 -0
  511. package/src/Table/TableCell.tsx +3 -3
  512. package/src/Table/TableHeaderCell.tsx +3 -3
  513. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +9 -6
  514. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +19 -0
  515. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +48 -21
  516. package/src/Table/plugins/selection/useTableSelection.test.tsx +61 -3
  517. package/src/Table/plugins/selection/useTableSelection.tsx +3 -0
  518. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +38 -9
  519. package/src/Table/plugins/tree/useTableTreeData.test.tsx +161 -2
  520. package/src/Table/plugins/tree/useTableTreeData.tsx +71 -14
  521. package/src/Table/types.ts +33 -0
  522. package/src/Table/useTableRowExpansion.doc.mjs +55 -2
  523. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  524. package/src/Table/useTableTreeData.doc.mjs +9 -0
  525. package/src/Text/Heading.doc.mjs +3 -3
  526. package/src/Text/Text.doc.mjs +1 -1
  527. package/src/Text/Text.test.tsx +42 -0
  528. package/src/Text/Text.tsx +25 -1
  529. package/src/Text/index.ts +2 -6
  530. package/src/TextArea/TextArea.doc.mjs +23 -2
  531. package/src/TextArea/TextArea.test.tsx +132 -4
  532. package/src/TextArea/TextArea.tsx +161 -67
  533. package/src/TextInput/TextInput.doc.mjs +21 -0
  534. package/src/TextInput/TextInput.test.tsx +150 -0
  535. package/src/TextInput/TextInput.tsx +28 -25
  536. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  537. package/src/Thumbnail/Thumbnail.test.tsx +24 -1
  538. package/src/Thumbnail/Thumbnail.tsx +28 -35
  539. package/src/TimeInput/TimeInput.doc.mjs +21 -0
  540. package/src/TimeInput/TimeInput.test.tsx +23 -0
  541. package/src/TimeInput/TimeInput.tsx +24 -25
  542. package/src/Timestamp/Timestamp.doc.mjs +32 -6
  543. package/src/Timestamp/Timestamp.test.tsx +371 -0
  544. package/src/Timestamp/Timestamp.tsx +96 -93
  545. package/src/Timestamp/formatInstant.ts +218 -0
  546. package/src/Timestamp/index.ts +4 -0
  547. package/src/Timestamp/tooltipEntries.test.ts +552 -0
  548. package/src/Timestamp/tooltipEntries.ts +210 -0
  549. package/src/Toast/ToastViewport.test.tsx +218 -8
  550. package/src/Toast/ToastViewport.tsx +71 -12
  551. package/src/ToggleButton/ToggleButton.test.tsx +24 -0
  552. package/src/ToggleButton/ToggleButton.tsx +19 -1
  553. package/src/Token/Token.test.tsx +166 -15
  554. package/src/Token/Token.tsx +104 -47
  555. package/src/Token/TokenLink.tsx +107 -0
  556. package/src/Token/index.ts +1 -1
  557. package/src/Tokenizer/Tokenizer.doc.mjs +23 -1
  558. package/src/Tokenizer/Tokenizer.test.tsx +23 -0
  559. package/src/Tokenizer/Tokenizer.tsx +14 -2
  560. package/src/Tooltip/Tooltip.test.tsx +46 -0
  561. package/src/Tooltip/useTooltip.tsx +20 -0
  562. package/src/TopNav/TopNav.test.tsx +93 -2
  563. package/src/TopNav/TopNavItem.doc.mjs +3 -3
  564. package/src/TopNav/TopNavItem.tsx +35 -6
  565. package/src/TopNav/TopNavMegaMenu.tsx +26 -2
  566. package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +1 -1
  567. package/src/TreeList/TreeList.doc.mjs +6 -0
  568. package/src/TreeList/TreeList.test.tsx +50 -10
  569. package/src/TreeList/TreeList.tsx +5 -0
  570. package/src/TreeList/TreeListBranches.tsx +8 -6
  571. package/src/TreeList/TreeListItem.tsx +33 -11
  572. package/src/Typeahead/BaseTypeahead.tsx +42 -15
  573. package/src/Typeahead/Typeahead.doc.mjs +13 -0
  574. package/src/Typeahead/Typeahead.test.tsx +112 -0
  575. package/src/Typeahead/Typeahead.tsx +17 -1
  576. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  577. package/src/__tests__/babelPluginAddExtensions.test.ts +190 -0
  578. package/src/__tests__/forcedColors.ts +60 -0
  579. package/src/__tests__/inputWidthContract.test.tsx +62 -0
  580. package/src/doc-mjs.d.ts +19 -0
  581. package/src/hooks/containerReveal.pool.stylex.ts +464 -0
  582. package/src/hooks/index.ts +13 -0
  583. package/src/hooks/isRtlElement.ts +27 -0
  584. package/src/hooks/useAnnounce.test.tsx +75 -2
  585. package/src/hooks/useAnnounce.ts +47 -1
  586. package/src/hooks/useContainerReveal.test.tsx +116 -0
  587. package/src/hooks/useContainerReveal.ts +180 -0
  588. package/src/hooks/useFocusTrap.test.tsx +104 -0
  589. package/src/hooks/useFocusTrap.ts +61 -12
  590. package/src/hooks/useGridFocus.doc.mjs +3 -3
  591. package/src/hooks/useGridFocus.test.tsx +41 -0
  592. package/src/hooks/useGridFocus.ts +21 -10
  593. package/src/hooks/useHotkeys.ts +9 -0
  594. package/src/hooks/useInputStatusIcon.test.tsx +221 -0
  595. package/src/hooks/useInputStatusIcon.tsx +235 -0
  596. package/src/hooks/useKeyboardHint.test.tsx +22 -0
  597. package/src/hooks/useKeyboardHint.tsx +6 -2
  598. package/src/hooks/useListFocus.doc.mjs +25 -3
  599. package/src/hooks/useListFocus.test.tsx +153 -1
  600. package/src/hooks/useListFocus.ts +102 -9
  601. package/src/i18n/InternationalizationContext.ts +4 -0
  602. package/src/i18n/InternationalizationProvider.tsx +12 -2
  603. package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
  604. package/src/i18n/__tests__/useDirection.test.tsx +66 -0
  605. package/src/i18n/getLocaleDirection.ts +29 -0
  606. package/src/i18n/index.ts +6 -0
  607. package/src/i18n/useDirection.ts +29 -0
  608. package/src/reset.css +0 -26
  609. package/src/reset.test.ts +60 -0
  610. package/src/theme/defineTheme.ts +6 -0
  611. package/src/theme/derivedVarRegistry.test.ts +1 -0
  612. package/src/theme/derivedVarRegistry.ts +6 -0
  613. package/src/theme/expandColorScale.test.ts +144 -0
  614. package/src/theme/expandColorScale.ts +53 -15
  615. package/src/theme/generateThemeRules.test.ts +42 -0
  616. package/src/theme/index.ts +4 -8
  617. package/src/theme/types.ts +43 -13
  618. package/src/utils/index.ts +2 -0
  619. package/src/utils/plainDate.test.ts +24 -6
  620. package/src/utils/plainDate.ts +18 -4
  621. package/src/utils/rtlStyles.ts +27 -0
  622. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +0 -9
  623. package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +0 -1
  624. package/dist/Thumbnail/thumbnail.markers.stylex.js +0 -14
  625. package/src/Thumbnail/thumbnail.markers.stylex.ts +0 -12
@@ -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"
@@ -36,6 +36,24 @@ export const docs = {
36
36
  type: 'SizeValue',
37
37
  description: 'Minimum container height (px or CSS value).',
38
38
  },
39
+ {
40
+ name: 'padding',
41
+ type: 'SpacingStep',
42
+ description:
43
+ 'Inner padding on all sides, using the spacing scale (0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10). Matches the padding prop on Stack, Card, LayoutContent, and LayoutPanel. Pass as a JSX number expression e.g. padding={3}.',
44
+ },
45
+ {
46
+ name: 'paddingInline',
47
+ type: 'SpacingStep',
48
+ description:
49
+ 'Inline (horizontal) padding, using the spacing scale. Overrides padding on the inline axis when both are set.',
50
+ },
51
+ {
52
+ name: 'paddingBlock',
53
+ type: 'SpacingStep',
54
+ description:
55
+ 'Block (vertical) padding, using the spacing scale. Overrides padding on the block axis when both are set.',
56
+ },
39
57
  {
40
58
  name: 'isInline',
41
59
  type: 'boolean',
@@ -95,6 +113,22 @@ export const docsZh = {
95
113
  {name: 'axis', type: "'both' | 'horizontal' | 'vertical'", description: '居中的方向。', default: "'both'"},
96
114
  {name: 'width', type: 'number | string', description: '容器宽度(px 或 CSS 值)。'},
97
115
  {name: 'height', type: 'number | string', description: '容器高度(px 或 CSS 值)。'},
116
+ {
117
+ name: 'padding',
118
+ type: 'SpacingStep',
119
+ description:
120
+ '所有方向的内边距,使用间距刻度(0、0.5、1、1.5、2、3、4、5、6、8、10)。与 Stack、Card、LayoutContent 和 LayoutPanel 的 padding 属性一致。在 JSX 中使用数字表达式 e.g. padding={3}。',
121
+ },
122
+ {
123
+ name: 'paddingInline',
124
+ type: 'SpacingStep',
125
+ description: '行内(水平)内边距,使用间距刻度。两者同时设置时在行内轴上覆盖 padding。',
126
+ },
127
+ {
128
+ name: 'paddingBlock',
129
+ type: 'SpacingStep',
130
+ description: '块(垂直)内边距,使用间距刻度。两者同时设置时在块轴上覆盖 padding。',
131
+ },
98
132
  {name: 'isInline', type: 'boolean', description: '使用 inline-flex(适用于文本/图标)。', default: 'false'},
99
133
  {name: 'children', type: 'ReactNode', description: '要居中的内容。'},
100
134
  {
@@ -134,6 +168,10 @@ export const docsDense = {
134
168
  axis: 'centering direction(s)',
135
169
  width: 'container width (px or CSS)',
136
170
  height: 'container height (px or CSS)',
171
+ padding:
172
+ 'inner padding on all sides (spacing step: 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10)',
173
+ paddingInline: 'inline (horizontal) padding; overrides padding on that axis',
174
+ paddingBlock: 'block (vertical) padding; overrides padding on that axis',
137
175
  isInline: 'use inline-flex for text/icons',
138
176
  children: 'content to center',
139
177
  xstyle: 'StyleX styles for layout (margins, positioning, sizing); must be stylex.create() value',
@@ -82,6 +82,81 @@ describe('Center', () => {
82
82
  expect(element).toBeInTheDocument();
83
83
  });
84
84
 
85
+ it('applies a class when padding is set', () => {
86
+ const {rerender} = render(
87
+ <Center data-testid="center">
88
+ <div>Content</div>
89
+ </Center>,
90
+ );
91
+ const baseline = screen.getByTestId('center').className;
92
+ rerender(
93
+ <Center padding={3} data-testid="center">
94
+ <div>Content</div>
95
+ </Center>,
96
+ );
97
+ const withPadding = screen.getByTestId('center').className;
98
+ expect(withPadding).not.toBe('');
99
+ expect(withPadding).not.toBe(baseline);
100
+ });
101
+
102
+ it('accepts paddingInline and paddingBlock without error', () => {
103
+ render(
104
+ <Center paddingInline={4} paddingBlock={2} data-testid="center">
105
+ <div>Content</div>
106
+ </Center>,
107
+ );
108
+ expect(screen.getByTestId('center')).toBeInTheDocument();
109
+ });
110
+
111
+ it('lets paddingInline/paddingBlock override padding on their axis', () => {
112
+ // padding sets both axes; paddingInline overrides the inline axis. The
113
+ // component should render without conflict and carry a class.
114
+ render(
115
+ <Center padding={2} paddingInline={5} data-testid="center">
116
+ <div>Content</div>
117
+ </Center>,
118
+ );
119
+ expect(screen.getByTestId('center').className).not.toBe('');
120
+ });
121
+
122
+ it('applies a class for explicit padding={0} (zero is a valid spacing step)', () => {
123
+ const {rerender} = render(
124
+ <Center data-testid="center">
125
+ <div>Content</div>
126
+ </Center>,
127
+ );
128
+ const baseline = screen.getByTestId('center').className;
129
+ rerender(
130
+ <Center padding={0} data-testid="center">
131
+ <div>Content</div>
132
+ </Center>,
133
+ );
134
+ expect(screen.getByTestId('center').className).not.toBe(baseline);
135
+ });
136
+
137
+ it('leaves the default className unchanged when no padding props are set', () => {
138
+ const {rerender} = render(
139
+ <Center data-testid="center">
140
+ <div>Content</div>
141
+ </Center>,
142
+ );
143
+ const baseline = screen.getByTestId('center').className;
144
+ // Opting in changes the className...
145
+ rerender(
146
+ <Center padding={3} data-testid="center">
147
+ <div>Content</div>
148
+ </Center>,
149
+ );
150
+ expect(screen.getByTestId('center').className).not.toBe(baseline);
151
+ // ...and dropping the prop restores the exact default output.
152
+ rerender(
153
+ <Center data-testid="center">
154
+ <div>Content</div>
155
+ </Center>,
156
+ );
157
+ expect(screen.getByTestId('center').className).toBe(baseline);
158
+ });
159
+
85
160
  it('renders as inline-flex when isInline is true', () => {
86
161
  render(
87
162
  <Center isInline data-testid="center">
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file Center.tsx
7
- * @input Uses React, StyleX for centering styles
7
+ * @input Uses React, StyleX for centering styles, Layout padding.stylex for spacing-scale padding
8
8
  * @output Exports Center component and CenterProps
9
9
  * @position Center component for centering children horizontally/vertically
10
10
  *
@@ -18,7 +18,11 @@
18
18
  import type {ReactNode} from 'react';
19
19
  import type {BaseProps} from '../BaseProps';
20
20
  import * as stylex from '@stylexjs/stylex';
21
- import type {SizeValue} from '../utils/types';
21
+ import type {SizeValue, SpacingStep} from '../utils/types';
22
+ import {
23
+ paddingInlineStyles,
24
+ paddingBlockStyles,
25
+ } from '../Layout/padding.stylex';
22
26
  import {mergeProps} from '../utils';
23
27
  import {themeProps} from '../utils/themeProps';
24
28
 
@@ -90,6 +94,26 @@ export interface CenterProps extends BaseProps<HTMLDivElement> {
90
94
  */
91
95
  minHeight?: SizeValue;
92
96
 
97
+ /**
98
+ * Inner padding on all sides, using the spacing scale.
99
+ * Accepts numeric spacing steps: 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10.
100
+ *
101
+ * Matches the `padding` prop on `Stack`, `Card`, `LayoutContent`, and `LayoutPanel`.
102
+ */
103
+ padding?: SpacingStep;
104
+
105
+ /**
106
+ * Inline (horizontal) padding, using the spacing scale.
107
+ * Overrides `padding` on the inline axis when both are set.
108
+ */
109
+ paddingInline?: SpacingStep;
110
+
111
+ /**
112
+ * Block (vertical) padding, using the spacing scale.
113
+ * Overrides `padding` on the block axis when both are set.
114
+ */
115
+ paddingBlock?: SpacingStep;
116
+
93
117
  /**
94
118
  * Whether to make the container inline-flex (useful for text/icons).
95
119
  * @default false
@@ -121,6 +145,9 @@ export function Center({
121
145
  height,
122
146
  maxWidth,
123
147
  minHeight,
148
+ padding,
149
+ paddingInline,
150
+ paddingBlock,
124
151
  isInline = false,
125
152
  children,
126
153
  xstyle,
@@ -129,6 +156,11 @@ export function Center({
129
156
  ref,
130
157
  ...props
131
158
  }: CenterProps) {
159
+ // Resolve padding to per-axis values: `padding` sets both axes; `paddingInline`
160
+ // / `paddingBlock` take precedence on their own axis when provided.
161
+ const resolvedPaddingInline = paddingInline ?? padding;
162
+ const resolvedPaddingBlock = paddingBlock ?? padding;
163
+
132
164
  const stylexProps = mergeProps(
133
165
  themeProps('center', {axis}),
134
166
  stylex.props(
@@ -141,6 +173,9 @@ export function Center({
141
173
  maxWidth ?? null,
142
174
  minHeight ?? null,
143
175
  ),
176
+ resolvedPaddingInline != null &&
177
+ paddingInlineStyles[resolvedPaddingInline],
178
+ resolvedPaddingBlock != null && paddingBlockStyles[resolvedPaddingBlock],
144
179
  xstyle,
145
180
  ),
146
181
  className,
@@ -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));
@@ -103,6 +103,63 @@ describe('ChatLayout', () => {
103
103
  });
104
104
  });
105
105
 
106
+ // ---------------------------------------------------------------------------
107
+ // Self-scroll layout contract (#2573)
108
+ //
109
+ // jsdom has no layout, so these assert the class-level CSS intent: the root
110
+ // must be a flex column whose message area flexes (grow, no shrink) instead
111
+ // of forcing minHeight: 100%. With minHeight: 100% the in-flow sticky dock
112
+ // added its full height on top of the message area, so the root always
113
+ // overflowed by exactly the dock height (phantom scrollbar). Real-layout
114
+ // geometry was verified in a browser; see the PR for measurements.
115
+ // ---------------------------------------------------------------------------
116
+
117
+ describe('ChatLayout — self-scroll layout contract (#2573)', () => {
118
+ it('root is a flex column so the dock height is part of the 100%', () => {
119
+ render(
120
+ <ChatLayout composer={<div>composer</div>} data-testid="layout">
121
+ <div>msg</div>
122
+ </ChatLayout>,
123
+ );
124
+ const root = screen.getByTestId('layout');
125
+ expect(root).toHaveStyle({display: 'flex', flexDirection: 'column'});
126
+ });
127
+
128
+ it('message area flexes to fill leftover space instead of minHeight: 100%', () => {
129
+ render(
130
+ <ChatLayout composer={<div>composer</div>} data-testid="layout">
131
+ <div>msg</div>
132
+ </ChatLayout>,
133
+ );
134
+ const messageArea = screen.getByTestId('layout')
135
+ .firstElementChild as HTMLElement;
136
+ expect(messageArea).toHaveStyle({flexGrow: '1', flexShrink: '0'});
137
+ // minHeight: 100% is the phantom-scrollbar bug — it must not come back.
138
+ expect(getComputedStyle(messageArea).minHeight).not.toBe('100%');
139
+ });
140
+
141
+ it('dock is sticky in self-scroll mode and fixed with an external scrollRef', () => {
142
+ const {rerender} = render(
143
+ <ChatLayout composer={<div>composer</div>} data-testid="layout">
144
+ <div>msg</div>
145
+ </ChatLayout>,
146
+ );
147
+ const dock = screen.getByTestId('layout').lastElementChild as HTMLElement;
148
+ expect(dock).toHaveStyle({position: 'sticky'});
149
+
150
+ const scrollRef = {current: document.documentElement};
151
+ rerender(
152
+ <ChatLayout
153
+ composer={<div>composer</div>}
154
+ data-testid="layout"
155
+ scrollRef={scrollRef}>
156
+ <div>msg</div>
157
+ </ChatLayout>,
158
+ );
159
+ expect(dock).toHaveStyle({position: 'fixed'});
160
+ });
161
+ });
162
+
106
163
  // ---------------------------------------------------------------------------
107
164
  // First-fill scroll positioning
108
165
  //
@@ -12,6 +12,13 @@
12
12
  * Provides the scroll container ref and content ref, renders the
13
13
  * scroll-to-bottom button, frosted glass dock, and message area.
14
14
  *
15
+ * Layout contract: the root is a flex column. The message area flexes
16
+ * (grow 1, shrink 0) to fill the space the dock doesn't need; the sticky
17
+ * dock keeps its natural height in flow. Short content therefore fills
18
+ * exactly 100% with no overflow, and long content grows past the root so
19
+ * self-scroll mode scrolls (#2573). In external-scrollRef mode the dock
20
+ * is position: fixed (out of flow) and the message area fills the root.
21
+ *
15
22
  * Density (compact/balanced/spacious) is controlled via a prop with
16
23
  * 'balanced' as the default. No JS measurement or ResizeObserver needed.
17
24
  * The container-type on root enables container queries in child components.
@@ -100,6 +107,13 @@ const styles = stylex.create({
100
107
  containerType: 'inline-size',
101
108
  minHeight: 0,
102
109
  flex: 1,
110
+ // Flex column so the sticky dock's natural height is part of the 100%:
111
+ // messageArea flexes to fill the leftover space instead of forcing
112
+ // minHeight: 100% on its own. Without this, the in-flow sticky dock
113
+ // adds its full height on top of the 100% message area and the root
114
+ // always overflows by exactly the dock height (#2573).
115
+ display: 'flex',
116
+ flexDirection: 'column',
103
117
  },
104
118
  rootScrollable: {
105
119
  overflowY: 'auto',
@@ -116,7 +130,11 @@ const styles = stylex.create({
116
130
  display: 'flex',
117
131
  flexDirection: 'column',
118
132
  marginInline: 'auto',
119
- minHeight: '100%',
133
+ // Fill the space the dock doesn't need (grow), but never shrink below
134
+ // content height — long content must overflow the root so it scrolls.
135
+ flexGrow: 1,
136
+ flexShrink: 0,
137
+ flexBasis: 'auto',
120
138
  paddingBlockEnd: spacingVars['--spacing-6'],
121
139
  width: '100%',
122
140
  maxWidth: '100%',
@@ -134,11 +152,14 @@ const styles = stylex.create({
134
152
  // --- Dock container ---
135
153
  dockContainer: {
136
154
  bottom: 0,
137
- left: 0,
138
- right: 0,
155
+ insetInlineStart: 0,
156
+ insetInlineEnd: 0,
139
157
  zIndex: 0,
140
158
  isolation: 'isolate',
141
159
  pointerEvents: 'none',
160
+ // Keep the sticky dock at its natural height as a flex item.
161
+ // (Inert in fixed mode — position: fixed takes it out of flex layout.)
162
+ flexShrink: 0,
142
163
  },
143
164
  dockContainerFixed: {
144
165
  position: 'fixed',
@@ -150,8 +171,8 @@ const styles = stylex.create({
150
171
  blurLayer: {
151
172
  position: 'absolute',
152
173
  bottom: 0,
153
- left: 0,
154
- right: 0,
174
+ insetInlineStart: 0,
175
+ insetInlineEnd: 0,
155
176
  pointerEvents: 'none',
156
177
  backdropFilter: 'blur(12px)',
157
178
  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
+ });