@astryxdesign/core 0.1.6 → 0.1.7-canary.04cd8f7

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 (571) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +25 -14
  3. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  4. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  5. package/dist/AlertDialog/AlertDialog.js +4 -1
  6. package/dist/AppShell/AppShell.d.ts.map +1 -1
  7. package/dist/AppShell/AppShell.js +3 -1
  8. package/dist/AvatarGroup/AvatarGroup.d.ts +1 -1
  9. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  10. package/dist/AvatarGroup/AvatarGroup.js +4 -1
  11. package/dist/Banner/Banner.d.ts.map +1 -1
  12. package/dist/Banner/Banner.js +8 -6
  13. package/dist/Breadcrumbs/Breadcrumbs.d.ts +1 -1
  14. package/dist/Breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  15. package/dist/Breadcrumbs/Breadcrumbs.js +4 -1
  16. package/dist/Button/Button.d.ts +10 -2
  17. package/dist/Button/Button.d.ts.map +1 -1
  18. package/dist/Button/Button.js +49 -6
  19. package/dist/ButtonGroup/ButtonGroup.d.ts +20 -5
  20. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  21. package/dist/ButtonGroup/ButtonGroup.js +27 -11
  22. package/dist/Calendar/Calendar.d.ts.map +1 -1
  23. package/dist/Calendar/Calendar.js +29 -7
  24. package/dist/Carousel/Carousel.d.ts +1 -1
  25. package/dist/Carousel/Carousel.d.ts.map +1 -1
  26. package/dist/Carousel/Carousel.js +8 -5
  27. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  28. package/dist/Chat/ChatComposer.js +4 -1
  29. package/dist/Chat/ChatComposerDrawer.d.ts +1 -1
  30. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  31. package/dist/Chat/ChatComposerDrawer.js +9 -2
  32. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  33. package/dist/Chat/ChatComposerInput.js +6 -2
  34. package/dist/Chat/ChatLayout.d.ts +1 -11
  35. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  36. package/dist/Chat/ChatLayout.js +6 -4
  37. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  38. package/dist/Chat/ChatLayoutScrollButton.js +4 -2
  39. package/dist/Chat/ChatMessage.d.ts +1 -1
  40. package/dist/Chat/ChatMessage.d.ts.map +1 -1
  41. package/dist/Chat/ChatMessage.js +8 -2
  42. package/dist/Chat/ChatMessageBubble.d.ts +1 -1
  43. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  44. package/dist/Chat/ChatMessageBubble.js +3 -1
  45. package/dist/Chat/ChatMessageList.d.ts +1 -1
  46. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  47. package/dist/Chat/ChatMessageList.js +3 -1
  48. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  49. package/dist/Chat/ChatMessageMetadata.js +13 -8
  50. package/dist/Chat/ChatPastedTextToken.d.ts.map +1 -1
  51. package/dist/Chat/ChatPastedTextToken.js +3 -1
  52. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  53. package/dist/Chat/ChatSendButton.js +3 -1
  54. package/dist/Chat/index.d.ts +1 -1
  55. package/dist/Chat/index.d.ts.map +1 -1
  56. package/dist/Chat/useChatStreamScroll.d.ts +12 -1
  57. package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
  58. package/dist/Chat/useChatStreamScroll.js +43 -6
  59. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  60. package/dist/Chat/useSpeechRecognition.js +4 -2
  61. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  62. package/dist/Chat/useTriggerMenu.js +4 -2
  63. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  64. package/dist/CheckboxInput/CheckboxInput.js +4 -2
  65. package/dist/CheckboxList/CheckboxList.d.ts +1 -1
  66. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  67. package/dist/CheckboxList/CheckboxList.js +3 -1
  68. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  69. package/dist/CheckboxList/CheckboxListItem.js +3 -1
  70. package/dist/Citation/Citation.d.ts.map +1 -1
  71. package/dist/Citation/Citation.js +10 -2
  72. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  73. package/dist/CodeBlock/CodeBlock.js +71 -53
  74. package/dist/Collapsible/Collapsible.d.ts +11 -1
  75. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  76. package/dist/Collapsible/Collapsible.js +36 -4
  77. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  78. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  79. package/dist/CommandPalette/CommandPalette.js +8 -3
  80. package/dist/CommandPalette/CommandPaletteInput.d.ts +1 -1
  81. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  82. package/dist/CommandPalette/CommandPaletteInput.js +4 -1
  83. package/dist/CommandPalette/CommandPaletteList.d.ts +1 -1
  84. package/dist/CommandPalette/CommandPaletteList.d.ts.map +1 -1
  85. package/dist/CommandPalette/CommandPaletteList.js +4 -1
  86. package/dist/ContextMenu/ContextMenu.d.ts +1 -1
  87. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  88. package/dist/ContextMenu/ContextMenu.js +8 -4
  89. package/dist/ContextMenu/index.d.ts +3 -0
  90. package/dist/ContextMenu/index.d.ts.map +1 -1
  91. package/dist/ContextMenu/index.js +7 -1
  92. package/dist/DateInput/DateInput.d.ts +1 -1
  93. package/dist/DateInput/DateInput.d.ts.map +1 -1
  94. package/dist/DateInput/DateInput.js +10 -5
  95. package/dist/DateRangeInput/DateRangeInput.d.ts +1 -1
  96. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  97. package/dist/DateRangeInput/DateRangeInput.js +11 -6
  98. package/dist/DateTimeInput/DateTimeInput.d.ts +1 -1
  99. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  100. package/dist/DateTimeInput/DateTimeInput.js +15 -7
  101. package/dist/Dialog/Dialog.d.ts.map +1 -1
  102. package/dist/Dialog/Dialog.js +15 -12
  103. package/dist/Dialog/DialogHeader.d.ts +1 -1
  104. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  105. package/dist/Dialog/DialogHeader.js +7 -3
  106. package/dist/DropdownMenu/DropdownMenu.d.ts +1 -1
  107. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  108. package/dist/DropdownMenu/DropdownMenu.js +19 -9
  109. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +89 -0
  110. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -0
  111. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +170 -0
  112. package/dist/DropdownMenu/DropdownMenuContext.d.ts +17 -1
  113. package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
  114. package/dist/DropdownMenu/DropdownMenuContext.js +18 -0
  115. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +69 -0
  116. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -0
  117. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +70 -0
  118. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +69 -0
  119. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -0
  120. package/dist/DropdownMenu/DropdownMenuRadioItem.js +178 -0
  121. package/dist/DropdownMenu/index.d.ts +5 -1
  122. package/dist/DropdownMenu/index.d.ts.map +1 -1
  123. package/dist/DropdownMenu/index.js +10 -1
  124. package/dist/DropdownMenu/menuItemRoles.d.ts +13 -0
  125. package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -0
  126. package/dist/DropdownMenu/menuItemRoles.js +15 -0
  127. package/dist/EmptyState/EmptyState.d.ts +4 -1
  128. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  129. package/dist/FileInput/FileInput.d.ts.map +1 -1
  130. package/dist/FileInput/FileInput.js +11 -1
  131. package/dist/Icon/Icon.d.ts +17 -12
  132. package/dist/Icon/Icon.d.ts.map +1 -1
  133. package/dist/Icon/Icon.js +28 -20
  134. package/dist/Kbd/Kbd.js +1 -1
  135. package/dist/Layer/useLayer.d.ts +10 -0
  136. package/dist/Layer/useLayer.d.ts.map +1 -1
  137. package/dist/Layer/useLayer.js +23 -1
  138. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  139. package/dist/Lightbox/Lightbox.js +6 -4
  140. package/dist/Link/Link.d.ts +5 -1
  141. package/dist/Link/Link.d.ts.map +1 -1
  142. package/dist/Link/Link.js +32 -1
  143. package/dist/Markdown/Markdown.d.ts.map +1 -1
  144. package/dist/Markdown/Markdown.js +10 -8
  145. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  146. package/dist/MobileNav/MobileNav.js +4 -2
  147. package/dist/MobileNav/MobileNavToggle.d.ts +1 -1
  148. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  149. package/dist/MobileNav/MobileNavToggle.js +4 -1
  150. package/dist/MoreMenu/MoreMenu.d.ts +1 -1
  151. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  152. package/dist/MoreMenu/MoreMenu.js +4 -1
  153. package/dist/MultiSelector/MultiSelector.d.ts +1 -1
  154. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  155. package/dist/MultiSelector/MultiSelector.js +13 -6
  156. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  157. package/dist/NumberInput/NumberInput.js +5 -1
  158. package/dist/Outline/Outline.d.ts +1 -1
  159. package/dist/Outline/Outline.d.ts.map +1 -1
  160. package/dist/Outline/Outline.js +4 -1
  161. package/dist/Pagination/Pagination.d.ts +1 -1
  162. package/dist/Pagination/Pagination.d.ts.map +1 -1
  163. package/dist/Pagination/Pagination.js +38 -11
  164. package/dist/Popover/usePopover.d.ts.map +1 -1
  165. package/dist/Popover/usePopover.js +4 -1
  166. package/dist/PowerSearch/PowerSearch.d.ts +1 -1
  167. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearch.js +22 -12
  169. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +1 -1
  170. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  171. package/dist/PowerSearch/PowerSearchEditPopover.js +26 -20
  172. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  173. package/dist/PowerSearch/PowerSearchToken.js +7 -3
  174. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  175. package/dist/PowerSearch/PowerSearchValueEditor.js +34 -21
  176. package/dist/PowerSearch/formatFilterValue.d.ts +2 -1
  177. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  178. package/dist/PowerSearch/formatFilterValue.js +19 -9
  179. package/dist/PowerSearch/index.d.ts +2 -1
  180. package/dist/PowerSearch/index.d.ts.map +1 -1
  181. package/dist/PowerSearch/index.js +1 -0
  182. package/dist/PowerSearch/resolveOperatorLabel.d.ts +23 -0
  183. package/dist/PowerSearch/resolveOperatorLabel.d.ts.map +1 -0
  184. package/dist/PowerSearch/resolveOperatorLabel.js +28 -0
  185. package/dist/PowerSearch/types.d.ts +28 -2
  186. package/dist/PowerSearch/types.d.ts.map +1 -1
  187. package/dist/PowerSearch/usePowerSearchConfig.d.ts.map +1 -1
  188. package/dist/PowerSearch/usePowerSearchConfig.js +27 -27
  189. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  190. package/dist/PowerSearch/usePowerSearchSource.js +15 -8
  191. package/dist/Resizable/ResizeHandle.d.ts +1 -1
  192. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  193. package/dist/Resizable/ResizeHandle.js +4 -1
  194. package/dist/Selector/Selector.d.ts.map +1 -1
  195. package/dist/Selector/Selector.js +52 -14
  196. package/dist/SideNav/SideNav.d.ts.map +1 -1
  197. package/dist/SideNav/SideNav.js +4 -2
  198. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  199. package/dist/SideNav/SideNavCollapseButton.js +3 -1
  200. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  201. package/dist/SideNav/SideNavHeading.js +5 -3
  202. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  203. package/dist/SideNav/SideNavItem.js +7 -1
  204. package/dist/Switch/Switch.d.ts.map +1 -1
  205. package/dist/Switch/Switch.js +4 -2
  206. package/dist/TabList/Tab.d.ts.map +1 -1
  207. package/dist/TabList/Tab.js +2 -2
  208. package/dist/TabList/TabList.d.ts +1 -1
  209. package/dist/TabList/TabList.d.ts.map +1 -1
  210. package/dist/TabList/TabList.js +6 -1
  211. package/dist/TabList/TabMenu.d.ts.map +1 -1
  212. package/dist/TabList/TabMenu.js +1 -1
  213. package/dist/Table/BaseTable.d.ts.map +1 -1
  214. package/dist/Table/BaseTable.js +29 -16
  215. package/dist/Table/Table.d.ts.map +1 -1
  216. package/dist/Table/Table.js +5 -3
  217. package/dist/Table/index.d.ts +2 -0
  218. package/dist/Table/index.d.ts.map +1 -1
  219. package/dist/Table/index.js +1 -0
  220. package/dist/Table/plugins/columnResize/useTableColumnResize.js +1 -1
  221. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  222. package/dist/Table/plugins/filtering/useTableFiltering.js +56 -19
  223. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +1 -1
  224. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  225. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +12 -5
  226. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  227. package/dist/Table/plugins/pagination/useTablePagination.js +6 -3
  228. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  229. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +8 -6
  230. package/dist/Table/plugins/rowIndex/useTableRowIndex.d.ts +1 -1
  231. package/dist/Table/plugins/rowIndex/useTableRowIndex.js +1 -1
  232. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  233. package/dist/Table/plugins/selection/useTableSelection.js +5 -2
  234. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  235. package/dist/Table/plugins/sortable/useTableSortable.js +6 -4
  236. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +2 -2
  237. package/dist/Table/plugins/tree/index.d.ts +5 -0
  238. package/dist/Table/plugins/tree/index.d.ts.map +1 -0
  239. package/dist/Table/plugins/tree/index.js +4 -0
  240. package/dist/Table/plugins/tree/useTableTreeData.d.ts +38 -0
  241. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -0
  242. package/dist/Table/plugins/tree/useTableTreeData.js +358 -0
  243. package/dist/Table/plugins/tree/useTableTreeState.d.ts +51 -0
  244. package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -0
  245. package/dist/Table/plugins/tree/useTableTreeState.js +175 -0
  246. package/dist/Table/types.d.ts +17 -10
  247. package/dist/Table/types.d.ts.map +1 -1
  248. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  249. package/dist/Table/useBaseTablePlugins.js +6 -3
  250. package/dist/TextInput/TextInput.d.ts.map +1 -1
  251. package/dist/TextInput/TextInput.js +5 -1
  252. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  253. package/dist/Thumbnail/Thumbnail.js +8 -2
  254. package/dist/TimeInput/TimeInput.d.ts +1 -1
  255. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  256. package/dist/TimeInput/TimeInput.js +7 -2
  257. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  258. package/dist/Timestamp/Timestamp.js +18 -3
  259. package/dist/Toast/Toast.d.ts.map +1 -1
  260. package/dist/Toast/Toast.js +3 -1
  261. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  262. package/dist/Toast/ToastViewport.js +3 -1
  263. package/dist/Token/Token.d.ts.map +1 -1
  264. package/dist/Token/Token.js +8 -2
  265. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  266. package/dist/Tokenizer/Tokenizer.js +3 -1
  267. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  268. package/dist/Toolbar/Toolbar.js +8 -1
  269. package/dist/TopNav/TopNav.d.ts +2 -1
  270. package/dist/TopNav/TopNav.d.ts.map +1 -1
  271. package/dist/TopNav/TopNav.js +4 -1
  272. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  273. package/dist/TopNav/TopNavHeading.js +5 -3
  274. package/dist/TreeList/TreeList.d.ts.map +1 -1
  275. package/dist/TreeList/TreeList.js +5 -1
  276. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  277. package/dist/TreeList/TreeListItem.js +7 -1
  278. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  279. package/dist/Typeahead/BaseTypeahead.js +8 -4
  280. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  281. package/dist/Typeahead/Typeahead.js +3 -1
  282. package/dist/VisuallyHidden/VisuallyHidden.d.ts +1 -0
  283. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -1
  284. package/dist/VisuallyHidden/VisuallyHidden.js +1 -0
  285. package/dist/astryx.css +38 -4
  286. package/dist/astryx.umd.js +62 -60
  287. package/dist/astryx.umd.js.map +4 -4
  288. package/dist/authoring/doc.d.ts +145 -0
  289. package/dist/authoring/doc.d.ts.map +1 -0
  290. package/dist/authoring/doc.js +100 -0
  291. package/dist/authoring/index.d.ts +29 -0
  292. package/dist/authoring/index.d.ts.map +1 -0
  293. package/dist/authoring/index.js +28 -0
  294. package/dist/authoring/integration.d.ts +35 -0
  295. package/dist/authoring/integration.d.ts.map +1 -0
  296. package/dist/authoring/integration.js +30 -0
  297. package/dist/authoring/template.d.ts +66 -0
  298. package/dist/authoring/template.d.ts.map +1 -0
  299. package/dist/authoring/template.js +55 -0
  300. package/dist/config.d.ts +80 -0
  301. package/dist/config.d.ts.map +1 -0
  302. package/dist/config.js +40 -0
  303. package/dist/docs-types.d.ts +13 -4
  304. package/dist/docs-types.d.ts.map +1 -1
  305. package/dist/i18n/InternationalizationContext.d.ts +12 -0
  306. package/dist/i18n/InternationalizationContext.d.ts.map +1 -0
  307. package/dist/i18n/InternationalizationContext.js +29 -0
  308. package/dist/i18n/InternationalizationProvider.d.ts +61 -0
  309. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -0
  310. package/dist/i18n/InternationalizationProvider.js +44 -0
  311. package/dist/i18n/index.d.ts +24 -0
  312. package/dist/i18n/index.d.ts.map +1 -0
  313. package/dist/i18n/index.js +21 -0
  314. package/dist/i18n/resolve.d.ts +22 -0
  315. package/dist/i18n/resolve.d.ts.map +1 -0
  316. package/dist/i18n/resolve.js +141 -0
  317. package/dist/i18n/translator.d.ts +25 -0
  318. package/dist/i18n/translator.d.ts.map +1 -0
  319. package/dist/i18n/translator.js +1 -0
  320. package/dist/i18n/types.d.ts +47 -0
  321. package/dist/i18n/types.d.ts.map +1 -0
  322. package/dist/i18n/types.js +1 -0
  323. package/dist/i18n/useTranslator.d.ts +15 -0
  324. package/dist/i18n/useTranslator.d.ts.map +1 -0
  325. package/dist/i18n/useTranslator.js +39 -0
  326. package/dist/index.d.ts +1 -0
  327. package/dist/index.d.ts.map +1 -1
  328. package/dist/index.js +3 -0
  329. package/dist/theme/Theme.js +1 -1
  330. package/dist/theme/defineTheme.d.ts +1 -1
  331. package/dist/theme/defineTheme.js +1 -1
  332. package/dist/theme/hct.d.ts +0 -1
  333. package/dist/theme/hct.d.ts.map +1 -1
  334. package/dist/theme/hct.js +0 -3
  335. package/dist/utils/color.d.ts +13 -1
  336. package/dist/utils/color.d.ts.map +1 -1
  337. package/dist/utils/color.js +23 -1
  338. package/dist/utils/index.d.ts +1 -1
  339. package/dist/utils/index.d.ts.map +1 -1
  340. package/dist/utils/index.js +1 -1
  341. package/locales/en.json +754 -0
  342. package/locales/pseudo.json +566 -0
  343. package/package.json +23 -2
  344. package/src/AlertDialog/AlertDialog.doc.mjs +5 -0
  345. package/src/AlertDialog/AlertDialog.tsx +4 -1
  346. package/src/AppShell/AppShell.doc.mjs +8 -2
  347. package/src/AppShell/AppShell.tsx +3 -1
  348. package/src/AvatarGroup/AvatarGroup.tsx +4 -1
  349. package/src/Banner/Banner.tsx +10 -5
  350. package/src/Breadcrumbs/Breadcrumbs.tsx +4 -1
  351. package/src/Button/Button.doc.mjs +8 -0
  352. package/src/Button/Button.test.tsx +27 -0
  353. package/src/Button/Button.tsx +51 -5
  354. package/src/ButtonGroup/ButtonGroup.test.tsx +386 -2
  355. package/src/ButtonGroup/ButtonGroup.tsx +27 -11
  356. package/src/Calendar/Calendar.test.tsx +103 -2
  357. package/src/Calendar/Calendar.tsx +29 -6
  358. package/src/Card/Card.doc.mjs +3 -3
  359. package/src/Carousel/Carousel.tsx +10 -7
  360. package/src/Chat/ChatComposer.tsx +5 -1
  361. package/src/Chat/ChatComposerDrawer.tsx +9 -2
  362. package/src/Chat/ChatComposerInput.tsx +10 -4
  363. package/src/Chat/ChatLayout.test.tsx +127 -2
  364. package/src/Chat/ChatLayout.tsx +5 -12
  365. package/src/Chat/ChatLayoutScrollButton.tsx +4 -2
  366. package/src/Chat/ChatMessage.tsx +5 -1
  367. package/src/Chat/ChatMessageBubble.tsx +2 -0
  368. package/src/Chat/ChatMessageList.doc.mjs +1 -1
  369. package/src/Chat/ChatMessageList.tsx +2 -0
  370. package/src/Chat/ChatMessageMetadata.tsx +15 -9
  371. package/src/Chat/ChatPastedTextToken.tsx +3 -1
  372. package/src/Chat/ChatSendButton.tsx +3 -1
  373. package/src/Chat/ChatToolCalls.doc.mjs +1 -1
  374. package/src/Chat/index.ts +1 -0
  375. package/src/Chat/useChatStreamScroll.test.tsx +168 -0
  376. package/src/Chat/useChatStreamScroll.ts +67 -11
  377. package/src/Chat/useSpeechRecognition.ts +11 -2
  378. package/src/Chat/useTriggerMenu.tsx +4 -2
  379. package/src/CheckboxInput/CheckboxInput.doc.mjs +1 -1
  380. package/src/CheckboxInput/CheckboxInput.test.tsx +16 -0
  381. package/src/CheckboxInput/CheckboxInput.tsx +4 -2
  382. package/src/CheckboxList/CheckboxList.doc.mjs +6 -1
  383. package/src/CheckboxList/CheckboxList.tsx +2 -0
  384. package/src/CheckboxList/CheckboxListItem.tsx +7 -1
  385. package/src/Citation/Citation.tsx +4 -2
  386. package/src/ClickableCard/ClickableCard.doc.mjs +1 -1
  387. package/src/CodeBlock/CodeBlock.tsx +91 -40
  388. package/src/Collapsible/Collapsible.doc.mjs +7 -0
  389. package/src/Collapsible/Collapsible.test.tsx +80 -0
  390. package/src/Collapsible/Collapsible.tsx +58 -5
  391. package/src/CommandPalette/CommandPalette.tsx +10 -3
  392. package/src/CommandPalette/CommandPaletteInput.test.tsx +1 -1
  393. package/src/CommandPalette/CommandPaletteInput.tsx +5 -1
  394. package/src/CommandPalette/CommandPaletteList.tsx +4 -1
  395. package/src/ContextMenu/ContextMenu.test.tsx +75 -1
  396. package/src/ContextMenu/ContextMenu.tsx +14 -6
  397. package/src/ContextMenu/index.ts +15 -0
  398. package/src/DateInput/DateInput.doc.mjs +2 -2
  399. package/src/DateInput/DateInput.test.tsx +17 -5
  400. package/src/DateInput/DateInput.tsx +13 -5
  401. package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
  402. package/src/DateRangeInput/DateRangeInput.tsx +14 -6
  403. package/src/DateTimeInput/DateTimeInput.doc.mjs +2 -2
  404. package/src/DateTimeInput/DateTimeInput.tsx +17 -7
  405. package/src/Dialog/Dialog.tsx +11 -15
  406. package/src/Dialog/DialogHeader.tsx +7 -3
  407. package/src/DropdownMenu/DropdownMenu.doc.mjs +23 -0
  408. package/src/DropdownMenu/DropdownMenu.tsx +23 -14
  409. package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +95 -0
  410. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +237 -0
  411. package/src/DropdownMenu/DropdownMenuContext.tsx +29 -1
  412. package/src/DropdownMenu/DropdownMenuItem.doc.mjs +7 -1
  413. package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +80 -0
  414. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +119 -0
  415. package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +80 -0
  416. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +232 -0
  417. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +163 -0
  418. package/src/DropdownMenu/index.ts +23 -3
  419. package/src/DropdownMenu/menuItemRoles.ts +22 -0
  420. package/src/EmptyState/EmptyState.doc.mjs +3 -3
  421. package/src/EmptyState/EmptyState.tsx +4 -1
  422. package/src/Field/Field.doc.mjs +3 -3
  423. package/src/Field/FieldLabel.doc.mjs +1 -1
  424. package/src/FileInput/FileInput.test.tsx +40 -1
  425. package/src/FileInput/FileInput.tsx +12 -1
  426. package/src/Grid/Grid.doc.mjs +5 -5
  427. package/src/Icon/Icon.test.tsx +46 -0
  428. package/src/Icon/Icon.tsx +37 -24
  429. package/src/InputGroup/InputGroup.doc.mjs +1 -1
  430. package/src/Kbd/Kbd.test.tsx +26 -0
  431. package/src/Kbd/Kbd.tsx +1 -1
  432. package/src/Layer/useLayer.doc.mjs +8 -5
  433. package/src/Layer/useLayer.test.tsx +136 -1
  434. package/src/Layer/useLayer.tsx +34 -2
  435. package/src/Lightbox/Lightbox.doc.mjs +7 -2
  436. package/src/Lightbox/Lightbox.tsx +6 -4
  437. package/src/Link/Link.test.tsx +74 -2
  438. package/src/Link/Link.tsx +48 -1
  439. package/src/Markdown/Markdown.tsx +12 -4
  440. package/src/MobileNav/MobileNav.tsx +4 -2
  441. package/src/MobileNav/MobileNavToggle.tsx +5 -3
  442. package/src/MoreMenu/MoreMenu.tsx +4 -1
  443. package/src/MultiSelector/MultiSelector.tsx +14 -5
  444. package/src/NumberInput/NumberInput.doc.mjs +2 -2
  445. package/src/NumberInput/NumberInput.tsx +3 -1
  446. package/src/Outline/Outline.tsx +4 -1
  447. package/src/OverflowList/OverflowList.doc.mjs +2 -2
  448. package/src/Pagination/Pagination.tsx +35 -12
  449. package/src/Popover/usePopover.tsx +6 -1
  450. package/src/PowerSearch/PowerSearch.doc.mjs +9 -4
  451. package/src/PowerSearch/PowerSearch.tsx +22 -10
  452. package/src/PowerSearch/PowerSearchEditPopover.tsx +27 -20
  453. package/src/PowerSearch/PowerSearchToken.tsx +17 -6
  454. package/src/PowerSearch/PowerSearchValueEditor.tsx +34 -21
  455. package/src/PowerSearch/formatFilterValue.test.ts +282 -0
  456. package/src/PowerSearch/formatFilterValue.ts +21 -8
  457. package/src/PowerSearch/index.ts +5 -0
  458. package/src/PowerSearch/resolveOperatorLabel.ts +34 -0
  459. package/src/PowerSearch/types.ts +33 -9
  460. package/src/PowerSearch/usePowerSearchConfig.ts +59 -27
  461. package/src/PowerSearch/usePowerSearchSource.ts +17 -8
  462. package/src/RadioList/RadioList.doc.mjs +1 -1
  463. package/src/Resizable/ResizeHandle.tsx +4 -1
  464. package/src/Section/Section.doc.mjs +4 -4
  465. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  466. package/src/Selector/Selector.doc.mjs +6 -3
  467. package/src/Selector/Selector.test.tsx +114 -6
  468. package/src/Selector/Selector.tsx +68 -17
  469. package/src/Selector/SelectorOption.doc.mjs +1 -1
  470. package/src/SideNav/SideNav.tsx +4 -2
  471. package/src/SideNav/SideNavCollapseButton.tsx +3 -1
  472. package/src/SideNav/SideNavHeading.tsx +5 -3
  473. package/src/SideNav/SideNavItem.doc.mjs +2 -2
  474. package/src/SideNav/SideNavItem.tsx +3 -1
  475. package/src/Slider/Slider.doc.mjs +2 -2
  476. package/src/Stack/Stack.doc.mjs +10 -10
  477. package/src/Switch/Switch.doc.mjs +3 -3
  478. package/src/Switch/Switch.test.tsx +16 -0
  479. package/src/Switch/Switch.tsx +4 -2
  480. package/src/TabList/Tab.tsx +5 -1
  481. package/src/TabList/TabList.doc.mjs +3 -3
  482. package/src/TabList/TabList.test.tsx +66 -0
  483. package/src/TabList/TabList.tsx +12 -1
  484. package/src/TabList/TabMenu.tsx +4 -1
  485. package/src/Table/BaseTable.tsx +36 -19
  486. package/src/Table/Table.doc.mjs +2 -0
  487. package/src/Table/Table.test.tsx +132 -1
  488. package/src/Table/Table.tsx +6 -4
  489. package/src/Table/index.ts +7 -0
  490. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +1 -1
  491. package/src/Table/plugins/filtering/useTableFiltering.tsx +31 -30
  492. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +7 -5
  493. package/src/Table/plugins/pagination/useTablePagination.tsx +4 -1
  494. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -8
  495. package/src/Table/plugins/rowIndex/useTableRowIndex.tsx +1 -1
  496. package/src/Table/plugins/selection/useTableSelection.tsx +6 -7
  497. package/src/Table/plugins/sortable/useTableSortable.tsx +8 -5
  498. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +4 -4
  499. package/src/Table/plugins/tree/index.ts +12 -0
  500. package/src/Table/plugins/tree/useTableTreeData-perf.test.tsx +163 -0
  501. package/src/Table/plugins/tree/useTableTreeData.test.tsx +594 -0
  502. package/src/Table/plugins/tree/useTableTreeData.tsx +495 -0
  503. package/src/Table/plugins/tree/useTableTreeState.test.tsx +636 -0
  504. package/src/Table/plugins/tree/useTableTreeState.tsx +253 -0
  505. package/src/Table/types.ts +18 -12
  506. package/src/Table/useBaseTablePlugins.ts +6 -2
  507. package/src/Table/useTableFiltering.doc.mjs +2 -2
  508. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  509. package/src/Table/useTableSortable.doc.mjs +11 -11
  510. package/src/Table/useTableTreeData.doc.mjs +75 -0
  511. package/src/Table/useTableTreeState.doc.mjs +98 -0
  512. package/src/Text/Text.doc.mjs +2 -2
  513. package/src/TextArea/TextArea.doc.mjs +1 -1
  514. package/src/TextInput/TextInput.doc.mjs +1 -1
  515. package/src/TextInput/TextInput.tsx +3 -1
  516. package/src/Thumbnail/Thumbnail.tsx +4 -2
  517. package/src/TimeInput/TimeInput.doc.mjs +2 -2
  518. package/src/TimeInput/TimeInput.tsx +6 -2
  519. package/src/Timestamp/Timestamp.doc.mjs +4 -4
  520. package/src/Timestamp/Timestamp.test.tsx +120 -7
  521. package/src/Timestamp/Timestamp.tsx +21 -1
  522. package/src/Toast/Toast.tsx +3 -1
  523. package/src/Toast/ToastViewport.tsx +3 -1
  524. package/src/Token/Token.tsx +4 -2
  525. package/src/Tokenizer/Tokenizer.doc.mjs +2 -2
  526. package/src/Tokenizer/Tokenizer.tsx +4 -4
  527. package/src/Toolbar/Toolbar.doc.mjs +1 -1
  528. package/src/Toolbar/Toolbar.tsx +10 -3
  529. package/src/TopNav/TopNav.doc.mjs +1 -0
  530. package/src/TopNav/TopNav.test.tsx +30 -0
  531. package/src/TopNav/TopNav.tsx +6 -4
  532. package/src/TopNav/TopNavHeading.tsx +5 -3
  533. package/src/TreeList/TreeList.tsx +5 -1
  534. package/src/TreeList/TreeListItem.tsx +6 -1
  535. package/src/Typeahead/BaseTypeahead.tsx +11 -4
  536. package/src/Typeahead/Typeahead.doc.mjs +1 -1
  537. package/src/Typeahead/Typeahead.tsx +3 -1
  538. package/src/VisuallyHidden/VisuallyHidden.tsx +1 -0
  539. package/src/authoring/doc.ts +166 -0
  540. package/src/authoring/index.test.ts +52 -0
  541. package/src/authoring/index.ts +50 -0
  542. package/src/authoring/integration.ts +42 -0
  543. package/src/authoring/template.ts +74 -0
  544. package/src/config.test.ts +16 -0
  545. package/src/config.ts +92 -0
  546. package/src/docPropLiterals.test.ts +938 -0
  547. package/src/docs-types.ts +15 -10
  548. package/src/i18n/InternationalizationContext.ts +39 -0
  549. package/src/i18n/InternationalizationProvider.doc.mjs +72 -0
  550. package/src/i18n/InternationalizationProvider.tsx +82 -0
  551. package/src/i18n/__tests__/e2e-pagination.test.tsx +172 -0
  552. package/src/i18n/__tests__/e2e-powersearch.test.tsx +130 -0
  553. package/src/i18n/__tests__/resolve.test.ts +284 -0
  554. package/src/i18n/index.ts +32 -0
  555. package/src/i18n/resolve.ts +165 -0
  556. package/src/i18n/translator.ts +31 -0
  557. package/src/i18n/types.ts +53 -0
  558. package/src/i18n/useTranslator.doc.mjs +46 -0
  559. package/src/i18n/useTranslator.ts +50 -0
  560. package/src/index.ts +3 -0
  561. package/src/theme/Theme.doc.mjs +4 -4
  562. package/src/theme/Theme.tsx +1 -1
  563. package/src/theme/defineTheme.ts +1 -1
  564. package/src/theme/hct.ts +0 -4
  565. package/src/utils/color.test.ts +101 -1
  566. package/src/utils/color.ts +23 -1
  567. package/src/utils/index.ts +8 -1
  568. package/dist/NavItem/index.d.ts +0 -9
  569. package/dist/NavItem/index.d.ts.map +0 -1
  570. package/dist/NavItem/index.js +0 -10
  571. package/src/NavItem/index.ts +0 -11
@@ -95,7 +95,7 @@ export const docs = {
95
95
  {
96
96
  name: 'labelIcon',
97
97
  type: 'IconType',
98
- description: 'Icon to display before the label text. See `npx astryx docs icons` for valid semantic names.',
98
+ description: 'Icon to display before the label text. See `astryx docs icons` for valid semantic names.',
99
99
  },
100
100
  {
101
101
  name: 'labelTooltip',
@@ -104,8 +104,8 @@ export const docs = {
104
104
  },
105
105
  {
106
106
  name: 'status',
107
- type: 'FieldStatus',
108
- description: 'Status indicator with type and optional message. When message is set, displays a colored status box.',
107
+ type: "{type: 'warning' | 'error' | 'success', message?: string, messageID?: string}",
108
+ description: 'Status indicator with type and optional message. When message is set, displays a colored status box. messageID is for wiring aria-describedby on the input.',
109
109
  },
110
110
  {
111
111
  name: 'statusVariant',
@@ -48,7 +48,7 @@ export const docs = {
48
48
  {
49
49
  name: 'labelIcon',
50
50
  type: 'IconType',
51
- description: 'Icon before the label text. See `npx astryx docs icons` for valid semantic names.',
51
+ description: 'Icon before the label text. See `astryx docs icons` for valid semantic names.',
52
52
  },
53
53
  {
54
54
  name: 'labelTooltip',
@@ -10,7 +10,13 @@
10
10
  */
11
11
 
12
12
  import {describe, it, expect, vi, afterEach, beforeEach} from 'vitest';
13
- import {render, screen, fireEvent, waitFor} from '@testing-library/react';
13
+ import {
14
+ render,
15
+ screen,
16
+ fireEvent,
17
+ createEvent,
18
+ waitFor,
19
+ } from '@testing-library/react';
14
20
  import userEvent from '@testing-library/user-event';
15
21
  import {FileInput} from './FileInput';
16
22
  import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
@@ -588,6 +594,39 @@ describe('FileInput', () => {
588
594
  expect(screen.getByText('Choose file')).toBeInTheDocument();
589
595
  });
590
596
 
597
+ it('keeps the drag-over state while dragging over the dropzone children', () => {
598
+ render(
599
+ <FileInput
600
+ label="Upload"
601
+ value={null}
602
+ onChange={() => {}}
603
+ mode="dropzone"
604
+ />,
605
+ );
606
+ const dropzone = screen.getByRole('button', {name: 'Upload'});
607
+ fireEvent.dragEnter(dropzone);
608
+ expect(screen.getByText('Drop files here')).toBeInTheDocument();
609
+
610
+ // Moving from the container onto one of its own children fires a
611
+ // dragleave on the container with the child as relatedTarget — the
612
+ // highlight must not flicker off while still inside the dropzone.
613
+ // (jsdom's DragEvent init drops relatedTarget, so set it directly.)
614
+ const child = screen.getByText('Drop files here');
615
+ const leaveToChild = createEvent.dragLeave(dropzone);
616
+ Object.defineProperty(leaveToChild, 'relatedTarget', {value: child});
617
+ fireEvent(dropzone, leaveToChild);
618
+ expect(screen.getByText('Drop files here')).toBeInTheDocument();
619
+
620
+ // Actually leaving the dropzone ends the drag-over state.
621
+ const leaveToOutside = createEvent.dragLeave(dropzone);
622
+ Object.defineProperty(leaveToOutside, 'relatedTarget', {
623
+ value: document.body,
624
+ });
625
+ fireEvent(dropzone, leaveToOutside);
626
+ expect(screen.queryByText('Drop files here')).not.toBeInTheDocument();
627
+ expect(screen.getByText('Choose file')).toBeInTheDocument();
628
+ });
629
+
591
630
  it('displays file name in dropzone mode', () => {
592
631
  const file = createFile('doc.pdf', 100, 'application/pdf');
593
632
  render(
@@ -55,6 +55,7 @@ import {mergeProps, mergeRefs} from '../utils';
55
55
  import type {BaseProps} from '../BaseProps';
56
56
  import type {SizeValue} from '../utils/types';
57
57
  import {themeProps} from '../utils/themeProps';
58
+ import {useTranslator} from '../i18n';
58
59
 
59
60
  function formatFileSize(bytes: number): string {
60
61
  if (bytes < 1024) {
@@ -425,6 +426,7 @@ export function FileInput({
425
426
  ref,
426
427
  ...rest
427
428
  }: FileInputProps) {
429
+ const t = useTranslator();
428
430
  const id = useId();
429
431
  const descriptionID = useId();
430
432
  const statusMessageID = useId();
@@ -607,6 +609,15 @@ export function FileInput({
607
609
  const handleDragLeave = useCallback((e: DragEvent) => {
608
610
  e.preventDefault();
609
611
  e.stopPropagation();
612
+ // Moving over the dropzone's own children (icon, text) fires dragleave on
613
+ // the container too — only a leave that actually exits the dropzone ends
614
+ // the drag-over state, otherwise the highlight flickers mid-drag.
615
+ if (
616
+ e.relatedTarget instanceof Node &&
617
+ e.currentTarget.contains(e.relatedTarget)
618
+ ) {
619
+ return;
620
+ }
610
621
  setIsDragOver(false);
611
622
  }, []);
612
623
 
@@ -774,7 +785,7 @@ export function FileInput({
774
785
  />
775
786
  {isDropzone ? renderDropzoneContent() : renderCompactContent()}
776
787
  {hasFiles && !isDisabled && !isLoading && (
777
- <InputClearButton label={`Clear ${label}`} onClick={handleClear} />
788
+ <InputClearButton label={t('@astryx.fileInput.clearLabel', {label})} onClick={handleClear} />
778
789
  )}
779
790
  </div>
780
791
  <div
@@ -60,28 +60,28 @@ export const docs = {
60
60
  },
61
61
  {
62
62
  name: 'gap',
63
- type: 'SpacingStep',
63
+ type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10',
64
64
  description: 'Spacing between all items.',
65
65
  },
66
66
  {
67
67
  name: 'rowGap',
68
- type: 'SpacingStep',
68
+ type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10',
69
69
  description: 'Row spacing; overrides `gap` for the row axis.',
70
70
  },
71
71
  {
72
72
  name: 'columnGap',
73
- type: 'SpacingStep',
73
+ type: '0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10',
74
74
  description: 'Column spacing; overrides `gap` for the column axis.',
75
75
  },
76
76
  {
77
77
  name: 'align',
78
- type: 'GridAlignment',
78
+ type: "'start' | 'center' | 'end' | 'stretch'",
79
79
  description: 'Vertical alignment of items.',
80
80
  default: "'stretch'",
81
81
  },
82
82
  {
83
83
  name: 'justify',
84
- type: 'GridAlignment',
84
+ type: "'start' | 'center' | 'end' | 'stretch'",
85
85
  description: 'Horizontal alignment of items.',
86
86
  default: "'stretch'",
87
87
  },
@@ -96,6 +96,52 @@ describe('Icon', () => {
96
96
  expect(screen.getByTestId('icon')).toBeInTheDocument();
97
97
  });
98
98
 
99
+ it('sizes component-mode icons in rem so they scale with root font-size', () => {
100
+ const sizes = {
101
+ xsm: '0.75rem',
102
+ sm: '1rem',
103
+ md: '1.25rem',
104
+ lg: '1.5rem',
105
+ } as const;
106
+ for (const [size, expected] of Object.entries(sizes)) {
107
+ const {unmount} = render(
108
+ <Icon
109
+ icon={TestIcon}
110
+ size={size as keyof typeof sizes}
111
+ data-testid="icon"
112
+ />,
113
+ );
114
+ const style = getComputedStyle(screen.getByTestId('icon'));
115
+ expect(style.width).toBe(expected);
116
+ expect(style.height).toBe(expected);
117
+ unmount();
118
+ }
119
+ });
120
+
121
+ it('sizes registry (string-mode) icons in rem, including fontSize', () => {
122
+ const sizes = {
123
+ xsm: '0.75rem',
124
+ sm: '1rem',
125
+ md: '1.25rem',
126
+ lg: '1.5rem',
127
+ } as const;
128
+ for (const [size, expected] of Object.entries(sizes)) {
129
+ const {unmount} = render(
130
+ <Icon
131
+ icon="check"
132
+ size={size as keyof typeof sizes}
133
+ data-testid="icon"
134
+ />,
135
+ );
136
+ const style = getComputedStyle(screen.getByTestId('icon'));
137
+ expect(style.width).toBe(expected);
138
+ expect(style.height).toBe(expected);
139
+ // fontSize is expressed in rem so 1em-based registry icons scale too.
140
+ expect(style.fontSize).toBe(expected);
141
+ unmount();
142
+ }
143
+ });
144
+
99
145
  it('forwards ref correctly', () => {
100
146
  const ref = vi.fn();
101
147
  render(<Icon icon={TestIcon} ref={ref} />);
package/src/Icon/Icon.tsx CHANGED
@@ -111,51 +111,64 @@ const colorStyles = stylex.create({
111
111
  /**
112
112
  * Size styles for direct SVG icon components.
113
113
  * Uses width/height only — SVG components handle their own viewBox scaling.
114
+ *
115
+ * Sizes are expressed in `rem` (relative to the root font-size) so icons scale
116
+ * in step with text when the document font-size changes, matching the rest of
117
+ * the design system's rem-based type scale. Values are the px-equivalents at a
118
+ * 16px root: 12px → 0.75rem, 16px → 1rem, 20px → 1.25rem, 24px → 1.5rem.
114
119
  */
115
120
  const sizeStyles = stylex.create({
116
121
  xsm: {
117
- width: 12,
118
- height: 12,
122
+ width: '0.75rem',
123
+ height: '0.75rem',
119
124
  },
120
125
  sm: {
121
- width: 16,
122
- height: 16,
126
+ width: '1rem',
127
+ height: '1rem',
123
128
  },
124
129
  md: {
125
- width: 20,
126
- height: 20,
130
+ width: '1.25rem',
131
+ height: '1.25rem',
127
132
  },
128
133
  lg: {
129
- width: 24,
130
- height: 24,
134
+ width: '1.5rem',
135
+ height: '1.5rem',
131
136
  },
132
137
  });
133
138
 
134
139
  /**
135
140
  * Size styles for string-based (registry) icons.
136
141
  * Includes fontSize so that 1em-based icons from the registry scale correctly.
142
+ *
143
+ * Expressed in `rem` for the same reason as {@link sizeStyles} — icons track the
144
+ * root font-size instead of being locked to absolute pixels.
137
145
  */
138
146
  const spanSizeStyles = stylex.create({
147
+ /* eslint-disable @astryx/no-hardcoded-styles -- fontSize here sizes 1em-based
148
+ registry SVGs to the icon box; icons use their own 12/16/20/24 scale, not
149
+ the 14px-anchored textSizeVars type scale. Values are rem so icons track
150
+ the root font-size. */
139
151
  xsm: {
140
- width: 12,
141
- height: 12,
142
- fontSize: 12,
152
+ width: '0.75rem',
153
+ height: '0.75rem',
154
+ fontSize: '0.75rem',
143
155
  },
144
156
  sm: {
145
- width: 16,
146
- height: 16,
147
- fontSize: 16,
157
+ width: '1rem',
158
+ height: '1rem',
159
+ fontSize: '1rem',
148
160
  },
149
161
  md: {
150
- width: 20,
151
- height: 20,
152
- fontSize: 20,
162
+ width: '1.25rem',
163
+ height: '1.25rem',
164
+ fontSize: '1.25rem',
153
165
  },
154
166
  lg: {
155
- width: 24,
156
- height: 24,
157
- fontSize: 24,
167
+ width: '1.5rem',
168
+ height: '1.5rem',
169
+ fontSize: '1.5rem',
158
170
  },
171
+ /* eslint-enable @astryx/no-hardcoded-styles */
159
172
  });
160
173
 
161
174
  // =============================================================================
@@ -194,10 +207,10 @@ export interface IconProps extends Omit<
194
207
  color?: IconColor;
195
208
  /**
196
209
  * The size of the icon.
197
- * - 'xsm': 12px
198
- * - 'sm': 16px
199
- * - 'md': 20px
200
- * - 'lg': 24px
210
+ * - 'xsm': 0.75rem (12px at a 16px root)
211
+ * - 'sm': 1rem (16px at a 16px root)
212
+ * - 'md': 1.25rem (20px at a 16px root)
213
+ * - 'lg': 1.5rem (24px at a 16px root)
201
214
  * @default 'md'
202
215
  */
203
216
  size?: IconSize;
@@ -76,7 +76,7 @@ export const docs = {
76
76
  },
77
77
  {
78
78
  name: 'status',
79
- type: 'InputStatus',
79
+ type: "{type: 'warning' | 'error' | 'success', message?: string}",
80
80
  description: 'Status indicator applied to the group border.',
81
81
  },
82
82
  {
@@ -119,4 +119,30 @@ describe('Kbd', () => {
119
119
  expect(screen.getByText('⇧')).toBeInTheDocument();
120
120
  expect(screen.getByText('+')).toBeInTheDocument();
121
121
  });
122
+
123
+ it('keeps the computed role and aria-label when unrelated rest props are spread', () => {
124
+ render(<Kbd keys="mod+k" data-testid="kbd" id="shortcut" />);
125
+ const el = screen.getByTestId('kbd');
126
+ // Pass-through attributes land on the wrapper...
127
+ expect(el).toHaveAttribute('id', 'shortcut');
128
+ // ...without disturbing the computed accessibility contract.
129
+ expect(el).toHaveAttribute('role', 'img');
130
+ expect(el).toHaveAttribute('aria-label', 'Control + K');
131
+ });
132
+
133
+ it('computed role and aria-label win over consumer-passed overrides', () => {
134
+ // Contract props the component computes must not be clobbered by
135
+ // pass-through attributes: {...rest} is spread before role/aria-label.
136
+ render(
137
+ <Kbd
138
+ keys="mod+k"
139
+ role="presentation"
140
+ aria-label="custom"
141
+ data-testid="kbd"
142
+ />,
143
+ );
144
+ const el = screen.getByTestId('kbd');
145
+ expect(el).toHaveAttribute('role', 'img');
146
+ expect(el).toHaveAttribute('aria-label', 'Control + K');
147
+ });
122
148
  });
package/src/Kbd/Kbd.tsx CHANGED
@@ -188,10 +188,10 @@ export function Kbd({keys, ref, xstyle, className, style, ...rest}: KbdProps) {
188
188
 
189
189
  return (
190
190
  <span
191
+ {...rest}
191
192
  ref={ref}
192
193
  role="img"
193
194
  aria-label={accessibleName}
194
- {...rest}
195
195
  {...mergeProps(
196
196
  themeProps('kbd'),
197
197
  stylex.props(styles.wrapper, xstyle),
@@ -72,13 +72,14 @@ export const docs = {
72
72
  {
73
73
  name: 'id',
74
74
  type: 'string',
75
- description: 'Unique ID for aria-describedby or other ARIA relationships.',
75
+ description:
76
+ 'Unique ID for aria-describedby or other ARIA relationships.',
76
77
  },
77
78
  {
78
79
  name: 'render',
79
80
  type: '(children: ReactNode, props: ContextRenderProps | FixedRenderProps) => ReactNode',
80
81
  description:
81
- 'Render function for the popover element. Pass placement/alignment in context mode or x/y in fixed mode. Placement/alignment are logical: they map to the self-* position-area keyword family, which resolves against the popover\'s own inherited direction, so RTL contexts mirror automatically in pure CSS. Pass `positioning: "custom"` in context mode to author position styles yourself via `style` (e.g. explicit anchor() insets or an anchor-size() cover): the hook keeps the popover behavior and position-anchor wiring but derives no position styles — including the automatic RTL mirroring, which becomes your responsibility. In context mode, pass `as: "span"` to render an inline-safe layer (e.g. inside a paragraph). The layer renders inline in the React tree; the Popover API promotes it to the top layer when shown, so it escapes ancestor clipping and stacking without a portal.',
82
+ 'Render function for the popover element. Pass placement/alignment in context mode or x/y in fixed mode. Placement/alignment are logical: they map to the self-* position-area keyword family, which resolves against the popover\'s own inherited direction, so RTL contexts mirror automatically in pure CSS. Pass `positioning: "custom"` in context mode to author position styles yourself via `style` (e.g. explicit anchor() insets or an anchor-size() cover): the hook keeps the popover behavior and position-anchor wiring but derives no position styles, including the automatic RTL mirroring, which becomes your responsibility. In context mode, pass `as: "span"` to render an inline-safe layer (e.g. inside a paragraph). The layer renders inline in the React tree; the Popover API promotes it to the top layer when shown, so it escapes ancestor clipping and stacking without a portal. When the layer would overflow the viewport, position-try fallbacks flip it to the opposite side; centered layers additionally slide along the alignment axis (span fallbacks) so they stay on-screen near viewport edges.',
82
83
  },
83
84
  ],
84
85
  usage: {
@@ -130,7 +131,7 @@ export const docsDense = {
130
131
  hide: 'hide layer.',
131
132
  isOpen: 'whether layer is open.',
132
133
  id: 'unique ARIA id.',
133
- render: 'renders popover element; pass placement/alignment or x/y. Placement/alignment logical: mapped to self-* position-area keywords resolved against the popover\'s inherited direction (RTL mirrors in pure CSS). `positioning: "custom"` (context mode) = author position styles yourself via `style`; keeps popover behavior + position-anchor wiring, derives nothing (incl. RTL mirroring — yours). Context mode accepts `as: "span"` for inline-safe layers. Renders inline; the Popover API top layer escapes clipping/stacking without a portal.',
134
+ render: 'renders popover element; pass placement/alignment or x/y. Placement/alignment logical: mapped to self-* position-area keywords resolved against the popover\'s inherited direction (RTL mirrors in pure CSS). `positioning: "custom"` (context mode) = author position styles yourself via `style`; keeps popover behavior + position-anchor wiring, derives nothing (incl. RTL mirroring, which becomes yours). Context mode accepts `as: "span"` for inline-safe layers. Renders inline; the Popover API top layer escapes clipping/stacking without a portal. Viewport overflow: flips to opposite side; centered layers also slide along the alignment axis (span fallbacks).',
134
135
  },
135
136
  usage: {
136
137
  description:
@@ -138,11 +139,13 @@ export const docsDense = {
138
139
  bestPractices: [
139
140
  {
140
141
  guidance: true,
141
- description: 'Use context mode for trigger-anchored overlays; fixed mode for explicit coordinates.',
142
+ description:
143
+ 'Use context mode for trigger-anchored overlays; fixed mode for explicit coordinates.',
142
144
  },
143
145
  {
144
146
  guidance: true,
145
- description: 'Build on Popover/HoverCard/Tooltip for common overlay patterns.',
147
+ description:
148
+ 'Build on Popover/HoverCard/Tooltip for common overlay patterns.',
146
149
  },
147
150
  {
148
151
  guidance: true,
@@ -12,7 +12,7 @@
12
12
  import {describe, it, expect, vi, afterEach} from 'vitest';
13
13
  import {render, act} from '@testing-library/react';
14
14
  import userEvent from '@testing-library/user-event';
15
- import {useLayer} from './useLayer';
15
+ import {useLayer, getPositionTryFallbacks} from './useLayer';
16
16
  import type {
17
17
  LayerPlacement,
18
18
  LayerAlignment,
@@ -33,6 +33,141 @@ function LayerHarness({
33
33
  return <>{layer.render(<span>Layer content</span>, {x: 0, y: 0})}</>;
34
34
  }
35
35
 
36
+ /**
37
+ * Context-mode harness: renders a trigger plus the layer so tests can assert
38
+ * on the anchor-positioning styles applied to the popover element.
39
+ */
40
+ function ContextLayerHarness({
41
+ placement,
42
+ alignment,
43
+ }: {
44
+ placement?: LayerPlacement;
45
+ alignment?: LayerAlignment;
46
+ }) {
47
+ const layer = useLayer({mode: 'context'});
48
+ return (
49
+ <>
50
+ <button type="button" ref={layer.ref}>
51
+ Trigger
52
+ </button>
53
+ {layer.render(<span>Layer content</span>, {placement, alignment})}
54
+ </>
55
+ );
56
+ }
57
+
58
+ describe('getPositionTryFallbacks (issue #3671)', () => {
59
+ const FLIPS = 'flip-block, flip-inline, flip-block flip-inline';
60
+
61
+ it('appends inline span fallbacks for centered above/below layers so inline overflow can resolve (flip-inline is a no-op on center)', () => {
62
+ expect(getPositionTryFallbacks('above', 'center')).toBe(
63
+ `${FLIPS}, top span-left, top span-right, bottom span-left, bottom span-right`,
64
+ );
65
+ expect(getPositionTryFallbacks('below', 'center')).toBe(
66
+ `${FLIPS}, bottom span-left, bottom span-right, top span-left, top span-right`,
67
+ );
68
+ });
69
+
70
+ it('appends block span fallbacks for centered start/end layers so block overflow can resolve (flip-block is a no-op on center)', () => {
71
+ expect(getPositionTryFallbacks('start', 'center')).toBe(
72
+ `${FLIPS}, left span-top, left span-bottom, right span-top, right span-bottom`,
73
+ );
74
+ expect(getPositionTryFallbacks('end', 'center')).toBe(
75
+ `${FLIPS}, right span-top, right span-bottom, left span-top, left span-bottom`,
76
+ );
77
+ });
78
+
79
+ it('keeps flip-only fallbacks for non-centered alignments (flips already resolve overflow there)', () => {
80
+ const nonCentered: [LayerPlacement, LayerAlignment][] = [
81
+ ['above', 'start'],
82
+ ['above', 'end'],
83
+ ['below', 'start'],
84
+ ['below', 'end'],
85
+ ['start', 'start'],
86
+ ['start', 'end'],
87
+ ['end', 'start'],
88
+ ['end', 'end'],
89
+ ];
90
+ for (const [placement, alignment] of nonCentered) {
91
+ expect(getPositionTryFallbacks(placement, alignment)).toBe(FLIPS);
92
+ }
93
+ });
94
+
95
+ it('defaults to above/center when called without arguments (matches renderContext defaults)', () => {
96
+ expect(getPositionTryFallbacks()).toBe(
97
+ getPositionTryFallbacks('above', 'center'),
98
+ );
99
+ expect(getPositionTryFallbacks(undefined, undefined)).toBe(
100
+ `${FLIPS}, top span-left, top span-right, bottom span-left, bottom span-right`,
101
+ );
102
+ });
103
+
104
+ it('produces well-formed, duplicate-free lists with flips first and axis-correct spans for every placement/alignment combo', () => {
105
+ const placements: LayerPlacement[] = ['above', 'below', 'start', 'end'];
106
+ const alignments: LayerAlignment[] = ['start', 'center', 'end'];
107
+ const spanPattern: Record<LayerPlacement, RegExp> = {
108
+ above: /^(top|bottom) span-(left|right)$/,
109
+ below: /^(top|bottom) span-(left|right)$/,
110
+ start: /^(left|right) span-(top|bottom)$/,
111
+ end: /^(left|right) span-(top|bottom)$/,
112
+ };
113
+
114
+ for (const placement of placements) {
115
+ for (const alignment of alignments) {
116
+ const list = getPositionTryFallbacks(placement, alignment);
117
+ const items = list.split(', ');
118
+
119
+ expect(items.slice(0, 3)).toEqual([
120
+ 'flip-block',
121
+ 'flip-inline',
122
+ 'flip-block flip-inline',
123
+ ]);
124
+ expect(new Set(items).size).toBe(items.length);
125
+ for (const item of items.slice(3)) {
126
+ expect(item).toMatch(spanPattern[placement]);
127
+ }
128
+ expect(items.length).toBe(alignment === 'center' ? 7 : 3);
129
+ }
130
+ }
131
+ });
132
+
133
+ it('updates the fallback list when placement/alignment props change on re-render', () => {
134
+ const {container, rerender} = render(
135
+ <ContextLayerHarness placement="above" alignment="center" />,
136
+ );
137
+ const layerEl = container.querySelector('[popover]') as HTMLElement;
138
+ expect(layerEl.style.positionTryFallbacks).toContain('top span-left');
139
+
140
+ rerender(<ContextLayerHarness placement="above" alignment="start" />);
141
+ expect(layerEl.style.positionTryFallbacks).toBe(FLIPS);
142
+
143
+ rerender(<ContextLayerHarness placement="start" alignment="center" />);
144
+ expect(layerEl.style.positionTryFallbacks).toBe(
145
+ `${FLIPS}, left span-top, left span-bottom, right span-top, right span-bottom`,
146
+ );
147
+ });
148
+
149
+ it('does not apply anchor fallbacks in fixed mode (manual coordinates)', () => {
150
+ function FixedHarness() {
151
+ const layer = useLayer({mode: 'fixed'});
152
+ return <>{layer.render(<span>Fixed content</span>, {x: 10, y: 20})}</>;
153
+ }
154
+ const {container} = render(<FixedHarness />);
155
+ const layerEl = container.querySelector('[popover]') as HTMLElement;
156
+ expect(layerEl.style.positionTryFallbacks ?? '').toBeFalsy();
157
+ expect(layerEl.style.left).toBe('10px');
158
+ expect(layerEl.style.top).toBe('20px');
159
+ });
160
+
161
+ it('applies span fallbacks to the rendered popover for the default (above/center) layer', () => {
162
+ const {container} = render(<ContextLayerHarness />);
163
+ const layerEl = container.querySelector('[popover]') as HTMLElement;
164
+ expect(layerEl).not.toBeNull();
165
+ expect(layerEl.style.positionTryFallbacks).toBe(
166
+ `${FLIPS}, top span-left, top span-right, bottom span-left, bottom span-right`,
167
+ );
168
+ });
169
+ });
170
+
36
171
  describe('useLayer', () => {
37
172
  const originalShowPopover = HTMLElement.prototype.showPopover;
38
173
  const originalHidePopover = HTMLElement.prototype.hidePopover;
@@ -320,6 +320,36 @@ function getPositionArea(
320
320
  return inline; // center
321
321
  }
322
322
 
323
+ /**
324
+ * Compute the `position-try-fallbacks` list for a placement/alignment pair.
325
+ *
326
+ * Flips alone cannot rescue a centered layer — flipping along the alignment
327
+ * axis maps center → center, so overflow on that axis renders clipped
328
+ * (#3671). Centered alignments therefore append span-based fallbacks letting
329
+ * the browser slide the layer along the alignment axis as a last resort
330
+ * (same-side spans first). Flips already resolve non-centered alignments.
331
+ */
332
+ export function getPositionTryFallbacks(
333
+ placement: LayerPlacement = 'above',
334
+ alignment: LayerAlignment = 'center',
335
+ ): string {
336
+ const flips = 'flip-block, flip-inline, flip-block flip-inline';
337
+
338
+ if (alignment !== 'center') {
339
+ return flips;
340
+ }
341
+
342
+ if (placement === 'above' || placement === 'below') {
343
+ const [same, opposite] =
344
+ placement === 'above' ? ['top', 'bottom'] : ['bottom', 'top'];
345
+ return `${flips}, ${same} span-left, ${same} span-right, ${opposite} span-left, ${opposite} span-right`;
346
+ }
347
+
348
+ const [same, opposite] =
349
+ placement === 'start' ? ['left', 'right'] : ['right', 'left'];
350
+ return `${flips}, ${same} span-top, ${same} span-bottom, ${opposite} span-top, ${opposite} span-bottom`;
351
+ }
352
+
323
353
  /**
324
354
  * Core layer hook that handles popover behavior and positioning.
325
355
  *
@@ -512,8 +542,10 @@ export function useLayer(
512
542
  : {
513
543
  positionAnchor: anchorId,
514
544
  positionArea: getPositionArea(placement, alignment),
515
- positionTryFallbacks:
516
- 'flip-block, flip-inline, flip-block flip-inline',
545
+ positionTryFallbacks: getPositionTryFallbacks(
546
+ placement,
547
+ alignment,
548
+ ),
517
549
  };
518
550
 
519
551
  const stylexResult = stylex.props(styles.base, xstyle);
@@ -22,8 +22,13 @@ export const docs = {
22
22
  },
23
23
  {
24
24
  name: 'media',
25
+ // Left as the named type on purpose: the shape carries `caption?:
26
+ // ReactNode`, so spelling it out makes the docsite playground parse the
27
+ // whole prop as an editable *string*, which would feed the preview text
28
+ // where a media object belongs. The shape and its legal values live in
29
+ // the description instead (#1645).
25
30
  type: 'LightboxMedia | LightboxMedia[]',
26
- description: 'Media to display. Pass a single object for one item, or an array for gallery mode with prev/next navigation. Each item has src, alt, optional caption and type.',
31
+ description: "Media to display. Pass a single object for one item, or an array for gallery mode with prev/next navigation. Each item is {src: string, alt: string, caption?: ReactNode, type?: 'image' | 'video'}; type defaults to 'image', and zoom/pan is disabled for 'video'.",
27
32
  required: true,
28
33
  },
29
34
  {
@@ -100,7 +105,7 @@ export const docsZh = {
100
105
  {
101
106
  name: 'media',
102
107
  type: 'LightboxMedia | LightboxMedia[]',
103
- description: '要显示的媒体。传入单个对象或数组(用于画廊模式的上一张/下一张导航)。',
108
+ description: "要显示的媒体。传入单个对象或数组(用于画廊模式的上一张/下一张导航)。每项为 {src, alt, caption?, type?: 'image' | 'video'};type 默认为 'image','video' 禁用缩放/平移。",
104
109
  required: true,
105
110
  },
106
111
  {