@astryxdesign/core 0.3.0 → 0.4.0

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 (551) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/dist/AlertDialog/AlertDialog.d.ts +10 -2
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +22 -3
  5. package/dist/AppShell/AppShell.d.ts +2 -2
  6. package/dist/AppShell/AppShell.d.ts.map +1 -1
  7. package/dist/AppShell/AppShell.js +40 -9
  8. package/dist/AspectRatio/AspectRatio.d.ts +13 -0
  9. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  10. package/dist/AspectRatio/AspectRatio.js +9 -0
  11. package/dist/Avatar/Avatar.d.ts.map +1 -1
  12. package/dist/Avatar/Avatar.js +33 -20
  13. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroupOverflow.js +2 -3
  15. package/dist/Banner/Banner.d.ts.map +1 -1
  16. package/dist/Banner/Banner.js +15 -14
  17. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  18. package/dist/Breadcrumbs/BreadcrumbItem.js +21 -8
  19. package/dist/Breadcrumbs/index.d.ts +2 -1
  20. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  21. package/dist/Breadcrumbs/index.js +1 -0
  22. package/dist/Button/Button.d.ts.map +1 -1
  23. package/dist/Button/Button.js +11 -15
  24. package/dist/Calendar/Calendar.d.ts.map +1 -1
  25. package/dist/Calendar/Calendar.js +2 -1
  26. package/dist/Calendar/styles.d.ts +0 -2
  27. package/dist/Calendar/styles.d.ts.map +1 -1
  28. package/dist/Calendar/styles.js +0 -2
  29. package/dist/Carousel/Carousel.d.ts.map +1 -1
  30. package/dist/Carousel/Carousel.js +8 -12
  31. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  32. package/dist/Chat/ChatDictationButton.js +2 -1
  33. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  34. package/dist/Chat/ChatLayoutScrollButton.js +3 -1
  35. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  36. package/dist/Chat/ChatSendButton.js +4 -3
  37. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  38. package/dist/Chat/ChatToolCalls.js +17 -17
  39. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  40. package/dist/Chat/useTriggerMenu.js +2 -6
  41. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  42. package/dist/CheckboxInput/CheckboxInput.js +36 -125
  43. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  44. package/dist/ClickableCard/ClickableCard.js +3 -11
  45. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  46. package/dist/CodeBlock/CodeBlock.js +84 -67
  47. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  48. package/dist/Collapsible/Collapsible.js +35 -15
  49. package/dist/CommandPalette/CommandPaletteItem.d.ts +1 -1
  50. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  51. package/dist/CommandPalette/CommandPaletteItem.js +6 -3
  52. package/dist/CommandPalette/CommandPaletteList.js +1 -1
  53. package/dist/ComplexSelector/ComplexSelector.d.ts +1 -1
  54. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  55. package/dist/ComplexSelector/ComplexSelector.js +35 -33
  56. package/dist/ContextMenu/ContextMenu.d.ts +2 -2
  57. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  58. package/dist/ContextMenu/ContextMenu.js +1 -1
  59. package/dist/ContextMenu/index.d.ts +2 -1
  60. package/dist/ContextMenu/index.d.ts.map +1 -1
  61. package/dist/ContextMenu/index.js +1 -0
  62. package/dist/DateInput/DateInput.d.ts +9 -2
  63. package/dist/DateInput/DateInput.d.ts.map +1 -1
  64. package/dist/DateInput/DateInput.js +24 -23
  65. package/dist/DateRangeInput/DateRangeInput.d.ts +9 -2
  66. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  67. package/dist/DateRangeInput/DateRangeInput.js +11 -16
  68. package/dist/DateTimeInput/DateTimeInput.d.ts +9 -1
  69. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  70. package/dist/DateTimeInput/DateTimeInput.js +22 -17
  71. package/dist/Dialog/Dialog.d.ts.map +1 -1
  72. package/dist/Dialog/Dialog.js +4 -4
  73. package/dist/DropdownMenu/DropdownMenu.d.ts +33 -8
  74. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  75. package/dist/DropdownMenu/DropdownMenu.js +62 -20
  76. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +8 -11
  77. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  78. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +32 -31
  79. package/dist/DropdownMenu/DropdownMenuDivider.d.ts +25 -0
  80. package/dist/DropdownMenu/DropdownMenuDivider.d.ts.map +1 -0
  81. package/dist/DropdownMenu/DropdownMenuDivider.js +66 -0
  82. package/dist/DropdownMenu/DropdownMenuItem.d.ts +15 -2
  83. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  84. package/dist/DropdownMenu/DropdownMenuItem.js +20 -8
  85. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +5 -5
  86. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  87. package/dist/DropdownMenu/DropdownMenuRadioItem.js +24 -67
  88. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  89. package/dist/DropdownMenu/DropdownMenuSubMenu.js +2 -8
  90. package/dist/DropdownMenu/index.d.ts +2 -1
  91. package/dist/DropdownMenu/index.d.ts.map +1 -1
  92. package/dist/DropdownMenu/index.js +4 -0
  93. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  94. package/dist/DropdownMenu/renderDropdownItems.js +35 -27
  95. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  96. package/dist/EmptyState/EmptyState.js +9 -5
  97. package/dist/Field/InputClearButton.d.ts +16 -3
  98. package/dist/Field/InputClearButton.d.ts.map +1 -1
  99. package/dist/Field/InputClearButton.js +15 -4
  100. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  101. package/dist/HoverCard/useHoverCard.js +3 -19
  102. package/dist/Indicator/CheckIndicator.d.ts +25 -0
  103. package/dist/Indicator/CheckIndicator.d.ts.map +1 -0
  104. package/dist/Indicator/CheckIndicator.js +155 -0
  105. package/dist/Indicator/CheckboxIndicator.d.ts +22 -0
  106. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -0
  107. package/dist/Indicator/CheckboxIndicator.js +173 -0
  108. package/dist/Indicator/RadioIndicator.d.ts +23 -0
  109. package/dist/Indicator/RadioIndicator.d.ts.map +1 -0
  110. package/dist/Indicator/RadioIndicator.js +137 -0
  111. package/dist/Indicator/index.d.ts +24 -0
  112. package/dist/Indicator/index.d.ts.map +1 -0
  113. package/dist/Indicator/index.js +26 -0
  114. package/dist/Indicator/indicator.markers.stylex.d.ts +16 -0
  115. package/dist/Indicator/indicator.markers.stylex.d.ts.map +1 -0
  116. package/dist/Indicator/indicator.markers.stylex.js +21 -0
  117. package/dist/Indicator/indicatorRegistry.d.ts +71 -0
  118. package/dist/Indicator/indicatorRegistry.d.ts.map +1 -0
  119. package/dist/Indicator/indicatorRegistry.js +93 -0
  120. package/dist/Indicator/types.d.ts +167 -0
  121. package/dist/Indicator/types.d.ts.map +1 -0
  122. package/dist/Indicator/types.js +1 -0
  123. package/dist/Indicator/useIndicator.d.ts +18 -0
  124. package/dist/Indicator/useIndicator.d.ts.map +1 -0
  125. package/dist/Indicator/useIndicator.js +30 -0
  126. package/dist/Item/Item.d.ts.map +1 -1
  127. package/dist/Item/Item.js +4 -8
  128. package/dist/Layer/useLayer.d.ts +14 -0
  129. package/dist/Layer/useLayer.d.ts.map +1 -1
  130. package/dist/Layer/useLayer.js +25 -2
  131. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  132. package/dist/Lightbox/Lightbox.js +56 -53
  133. package/dist/Link/Link.d.ts.map +1 -1
  134. package/dist/Link/Link.js +4 -5
  135. package/dist/MobileNav/MobileNav.js +8 -8
  136. package/dist/MoreMenu/MoreMenu.d.ts +14 -1
  137. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  138. package/dist/MoreMenu/MoreMenu.js +4 -0
  139. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  140. package/dist/MultiSelector/MultiSelector.js +78 -75
  141. package/dist/NumberInput/NumberInput.d.ts +27 -1
  142. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  143. package/dist/NumberInput/NumberInput.js +230 -42
  144. package/dist/Outline/Outline.d.ts.map +1 -1
  145. package/dist/Outline/Outline.js +2 -3
  146. package/dist/Pagination/Pagination.d.ts.map +1 -1
  147. package/dist/Pagination/Pagination.js +61 -63
  148. package/dist/Popover/Popover.d.ts.map +1 -1
  149. package/dist/Popover/Popover.js +6 -8
  150. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  151. package/dist/PowerSearch/PowerSearch.js +1 -1
  152. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  153. package/dist/PowerSearch/PowerSearchEditPopover.js +7 -0
  154. package/dist/ProgressBar/ProgressBar.d.ts +11 -4
  155. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  156. package/dist/ProgressBar/ProgressBar.js +96 -6
  157. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  158. package/dist/RadioList/RadioListItem.js +29 -84
  159. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  160. package/dist/Resizable/ResizeHandle.js +2 -3
  161. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  162. package/dist/SegmentedControl/SegmentedControlItem.js +2 -3
  163. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  164. package/dist/SelectableCard/SelectableCard.js +3 -11
  165. package/dist/Selector/Selector.d.ts +2 -1
  166. package/dist/Selector/Selector.d.ts.map +1 -1
  167. package/dist/Selector/Selector.js +164 -94
  168. package/dist/Selector/hooks.d.ts +18 -6
  169. package/dist/Selector/hooks.d.ts.map +1 -1
  170. package/dist/Selector/hooks.js +57 -40
  171. package/dist/SideNav/SideNav.d.ts.map +1 -1
  172. package/dist/SideNav/SideNav.js +1 -1
  173. package/dist/SideNav/SideNavCollapseButton.d.ts +1 -1
  174. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  175. package/dist/SideNav/SideNavCollapseButton.js +29 -14
  176. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  177. package/dist/SideNav/SideNavHeading.js +56 -20
  178. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  179. package/dist/SideNav/SideNavItem.js +28 -22
  180. package/dist/Stack/stack.stylex.d.ts +3 -3
  181. package/dist/Switch/Switch.js +11 -10
  182. package/dist/TabList/Tab.d.ts.map +1 -1
  183. package/dist/TabList/Tab.js +2 -3
  184. package/dist/TabList/TabMenu.d.ts.map +1 -1
  185. package/dist/TabList/TabMenu.js +41 -19
  186. package/dist/Table/BaseTable.d.ts.map +1 -1
  187. package/dist/Table/BaseTable.js +8 -0
  188. package/dist/Table/index.d.ts +1 -1
  189. package/dist/Table/index.d.ts.map +1 -1
  190. package/dist/Table/index.js +1 -1
  191. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +1 -1
  192. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  193. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +22 -18
  194. package/dist/Table/plugins/rowExpansion/index.d.ts +1 -1
  195. package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -1
  196. package/dist/Table/plugins/rowExpansion/index.js +1 -1
  197. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +41 -76
  198. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  199. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +94 -345
  200. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  201. package/dist/Table/plugins/sortable/useTableSortable.js +23 -4
  202. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  203. package/dist/Table/plugins/tree/useTableTreeData.js +29 -33
  204. package/dist/Table/tableContextMenu.d.ts.map +1 -1
  205. package/dist/Table/tableContextMenu.js +2 -1
  206. package/dist/Table/types.d.ts +11 -0
  207. package/dist/Table/types.d.ts.map +1 -1
  208. package/dist/TextArea/TextArea.d.ts +10 -1
  209. package/dist/TextArea/TextArea.d.ts.map +1 -1
  210. package/dist/TextArea/TextArea.js +16 -6
  211. package/dist/TextInput/TextInput.d.ts +10 -1
  212. package/dist/TextInput/TextInput.d.ts.map +1 -1
  213. package/dist/TextInput/TextInput.js +13 -19
  214. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  215. package/dist/Thumbnail/Thumbnail.js +32 -26
  216. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  217. package/dist/TimeInput/TimeInput.js +7 -15
  218. package/dist/Timestamp/TimestampHoverCard.d.ts.map +1 -1
  219. package/dist/Timestamp/TimestampHoverCard.js +16 -34
  220. package/dist/Token/Token.d.ts.map +1 -1
  221. package/dist/Token/Token.js +20 -11
  222. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  223. package/dist/Tokenizer/Tokenizer.js +4 -2
  224. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  225. package/dist/Tooltip/useTooltip.js +3 -19
  226. package/dist/TopNav/TopNav.d.ts.map +1 -1
  227. package/dist/TopNav/TopNav.js +6 -5
  228. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  229. package/dist/TopNav/TopNavHeading.js +54 -16
  230. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  231. package/dist/TopNav/TopNavItem.js +3 -9
  232. package/dist/TopNav/TopNavMegaMenu.d.ts +7 -0
  233. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  234. package/dist/TopNav/TopNavMegaMenu.js +146 -60
  235. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  236. package/dist/TopNav/TopNavMegaMenuItem.js +22 -3
  237. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  238. package/dist/TopNav/TopNavMenu.js +83 -38
  239. package/dist/TreeList/TreeList.d.ts.map +1 -1
  240. package/dist/TreeList/TreeList.js +13 -0
  241. package/dist/TreeList/TreeListBranches.d.ts +1 -1
  242. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  243. package/dist/TreeList/TreeListBranches.js +14 -4
  244. package/dist/TreeList/TreeListItem.d.ts +11 -1
  245. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  246. package/dist/TreeList/TreeListItem.js +57 -30
  247. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  248. package/dist/Typeahead/BaseTypeahead.js +16 -8
  249. package/dist/astryx.css +74 -85
  250. package/dist/astryx.umd.js +56 -56
  251. package/dist/astryx.umd.js.map +4 -4
  252. package/dist/hooks/containerReveal.stylex.d.ts +61 -0
  253. package/dist/hooks/containerReveal.stylex.d.ts.map +1 -0
  254. package/dist/hooks/containerReveal.stylex.js +63 -0
  255. package/dist/hooks/index.d.ts +3 -0
  256. package/dist/hooks/index.d.ts.map +1 -1
  257. package/dist/hooks/index.js +2 -0
  258. package/dist/hooks/useClipboard.d.ts +59 -0
  259. package/dist/hooks/useClipboard.d.ts.map +1 -0
  260. package/dist/hooks/useClipboard.js +106 -0
  261. package/dist/hooks/useContainerReveal.d.ts +14 -8
  262. package/dist/hooks/useContainerReveal.d.ts.map +1 -1
  263. package/dist/hooks/useContainerReveal.js +28 -69
  264. package/dist/hooks/useIndicatorFocusRing.d.ts +28 -0
  265. package/dist/hooks/useIndicatorFocusRing.d.ts.map +1 -0
  266. package/dist/hooks/useIndicatorFocusRing.js +96 -0
  267. package/dist/hooks/useLongPress.d.ts.map +1 -1
  268. package/dist/hooks/useLongPress.js +12 -2
  269. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  270. package/dist/hooks/useScrollLock.js +33 -18
  271. package/dist/hooks/useStreamingText.d.ts +18 -3
  272. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  273. package/dist/hooks/useStreamingText.js +47 -7
  274. package/dist/hooks/useTreeFocus.d.ts.map +1 -1
  275. package/dist/hooks/useTreeFocus.js +9 -3
  276. package/dist/hooks/useTypeahead.d.ts +3 -2
  277. package/dist/hooks/useTypeahead.d.ts.map +1 -1
  278. package/dist/hooks/useTypeahead.js +19 -7
  279. package/dist/index.d.ts +1 -0
  280. package/dist/index.d.ts.map +1 -1
  281. package/dist/index.js +1 -0
  282. package/dist/theme/defineTheme.d.ts +16 -0
  283. package/dist/theme/defineTheme.d.ts.map +1 -1
  284. package/dist/theme/defineTheme.js +8 -0
  285. package/dist/theme/derivedVarRegistry.d.ts +8 -0
  286. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  287. package/dist/theme/derivedVarRegistry.js +14 -13
  288. package/dist/theme/expandColorScale.d.ts +3 -1
  289. package/dist/theme/expandColorScale.d.ts.map +1 -1
  290. package/dist/theme/expandColorScale.js +17 -7
  291. package/dist/theme/expandTypeScale.d.ts.map +1 -1
  292. package/dist/theme/expandTypeScale.js +17 -0
  293. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  294. package/dist/theme/generateThemeRules.js +11 -0
  295. package/dist/theme/index.d.ts +1 -0
  296. package/dist/theme/index.d.ts.map +1 -1
  297. package/dist/utils/focusOutline.stylex.d.ts +107 -0
  298. package/dist/utils/focusOutline.stylex.d.ts.map +1 -0
  299. package/dist/utils/focusOutline.stylex.js +130 -0
  300. package/dist/utils/focusReturn.d.ts +24 -0
  301. package/dist/utils/focusReturn.d.ts.map +1 -0
  302. package/dist/utils/focusReturn.js +29 -0
  303. package/dist/utils/index.d.ts +1 -0
  304. package/dist/utils/index.d.ts.map +1 -1
  305. package/dist/utils/index.js +1 -0
  306. package/dist/utils/mergeRefs.d.ts.map +1 -1
  307. package/dist/utils/mergeRefs.js +7 -5
  308. package/dist/utils/rtlStyles.d.ts +2 -2
  309. package/dist/utils/rtlStyles.js +2 -2
  310. package/dist/utils/themeProps.d.ts +20 -1
  311. package/dist/utils/themeProps.d.ts.map +1 -1
  312. package/dist/utils/themeProps.js +8 -2
  313. package/locales/en.json +12 -0
  314. package/locales/pseudo.json +9 -0
  315. package/package.json +7 -2
  316. package/src/AlertDialog/AlertDialog.doc.mjs +16 -3
  317. package/src/AlertDialog/AlertDialog.test.tsx +208 -1
  318. package/src/AlertDialog/AlertDialog.tsx +21 -3
  319. package/src/AppShell/AppShell.doc.mjs +11 -0
  320. package/src/AppShell/AppShell.test.tsx +139 -0
  321. package/src/AppShell/AppShell.tsx +32 -22
  322. package/src/AspectRatio/AspectRatio.doc.mjs +27 -3
  323. package/src/AspectRatio/AspectRatio.test.tsx +30 -0
  324. package/src/AspectRatio/AspectRatio.tsx +13 -0
  325. package/src/Avatar/Avatar.doc.mjs +2 -13
  326. package/src/Avatar/Avatar.test.tsx +33 -8
  327. package/src/Avatar/Avatar.tsx +52 -50
  328. package/src/AvatarGroup/AvatarGroupOverflow.tsx +2 -9
  329. package/src/Banner/Banner.tsx +9 -6
  330. package/src/Breadcrumbs/BreadcrumbItem.tsx +16 -6
  331. package/src/Breadcrumbs/index.ts +5 -1
  332. package/src/Button/Button.tsx +21 -41
  333. package/src/Calendar/Calendar.tsx +2 -1
  334. package/src/Calendar/styles.ts +0 -8
  335. package/src/Carousel/Carousel.doc.mjs +3 -0
  336. package/src/Carousel/Carousel.tsx +10 -6
  337. package/src/Chat/Chat.doc.mjs +2 -0
  338. package/src/Chat/ChatDictationButton.tsx +7 -1
  339. package/src/Chat/ChatLayoutScrollButton.test.tsx +22 -0
  340. package/src/Chat/ChatLayoutScrollButton.tsx +8 -1
  341. package/src/Chat/ChatSendButton.tsx +2 -3
  342. package/src/Chat/ChatToolCalls.test.tsx +35 -0
  343. package/src/Chat/ChatToolCalls.tsx +36 -16
  344. package/src/Chat/useTriggerMenu.tsx +2 -5
  345. package/src/CheckboxInput/CheckboxInput.doc.mjs +4 -2
  346. package/src/CheckboxInput/CheckboxInput.test.tsx +115 -0
  347. package/src/CheckboxInput/CheckboxInput.tsx +45 -202
  348. package/src/ClickableCard/ClickableCard.tsx +6 -11
  349. package/src/CodeBlock/CodeBlock.doc.mjs +3 -0
  350. package/src/CodeBlock/CodeBlock.test.tsx +91 -0
  351. package/src/CodeBlock/CodeBlock.tsx +57 -80
  352. package/src/Collapsible/Collapsible.tsx +22 -18
  353. package/src/CommandPalette/CommandPalette.test.tsx +29 -0
  354. package/src/CommandPalette/CommandPaletteItem.tsx +7 -4
  355. package/src/CommandPalette/CommandPaletteList.tsx +2 -2
  356. package/src/ComplexSelector/ComplexSelector.doc.mjs +42 -0
  357. package/src/ComplexSelector/ComplexSelector.test.tsx +64 -0
  358. package/src/ComplexSelector/ComplexSelector.tsx +46 -29
  359. package/src/ContextMenu/ContextMenu.doc.mjs +1 -1
  360. package/src/ContextMenu/ContextMenu.test.tsx +41 -0
  361. package/src/ContextMenu/ContextMenu.tsx +3 -3
  362. package/src/ContextMenu/index.ts +5 -1
  363. package/src/DateInput/DateInput.doc.mjs +18 -3
  364. package/src/DateInput/DateInput.test.tsx +93 -11
  365. package/src/DateInput/DateInput.tsx +41 -19
  366. package/src/DateRangeInput/DateRangeInput.doc.mjs +10 -2
  367. package/src/DateRangeInput/DateRangeInput.test.tsx +110 -14
  368. package/src/DateRangeInput/DateRangeInput.tsx +24 -12
  369. package/src/DateTimeInput/DateTimeInput.doc.mjs +16 -2
  370. package/src/DateTimeInput/DateTimeInput.test.tsx +75 -0
  371. package/src/DateTimeInput/DateTimeInput.tsx +35 -8
  372. package/src/Dialog/Dialog.tsx +2 -9
  373. package/src/DropdownMenu/DropdownMenu.doc.mjs +5 -9
  374. package/src/DropdownMenu/DropdownMenu.test.tsx +534 -4
  375. package/src/DropdownMenu/DropdownMenu.tsx +113 -52
  376. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +27 -30
  377. package/src/DropdownMenu/DropdownMenuDivider.doc.mjs +34 -0
  378. package/src/DropdownMenu/DropdownMenuDivider.tsx +81 -0
  379. package/src/DropdownMenu/DropdownMenuItem.doc.mjs +39 -4
  380. package/src/DropdownMenu/DropdownMenuItem.tsx +48 -10
  381. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +30 -76
  382. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +25 -19
  383. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +44 -14
  384. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +1 -5
  385. package/src/DropdownMenu/index.ts +8 -1
  386. package/src/DropdownMenu/renderDropdownItems.tsx +33 -34
  387. package/src/EmptyState/EmptyState.doc.mjs +4 -0
  388. package/src/EmptyState/EmptyState.test.tsx +62 -0
  389. package/src/EmptyState/EmptyState.tsx +16 -6
  390. package/src/Field/Field.doc.mjs +1 -0
  391. package/src/Field/InputClearButton.test.tsx +117 -0
  392. package/src/Field/InputClearButton.tsx +30 -3
  393. package/src/HoverCard/useHoverCard.tsx +2 -23
  394. package/src/Icon/Icon.doc.mjs +2 -1
  395. package/src/Indicator/CheckIndicator.tsx +174 -0
  396. package/src/Indicator/CheckboxIndicator.tsx +257 -0
  397. package/src/Indicator/Indicator.doc.mjs +344 -0
  398. package/src/Indicator/Indicator.test.tsx +393 -0
  399. package/src/Indicator/RadioIndicator.tsx +206 -0
  400. package/src/Indicator/index.ts +45 -0
  401. package/src/Indicator/indicator.markers.stylex.ts +19 -0
  402. package/src/Indicator/indicatorRegistry.test.tsx +106 -0
  403. package/src/Indicator/indicatorRegistry.ts +120 -0
  404. package/src/Indicator/types.ts +186 -0
  405. package/src/Indicator/useIndicator.ts +39 -0
  406. package/src/Item/Item.doc.mjs +1 -1
  407. package/src/Item/Item.tsx +7 -14
  408. package/src/Layer/useLayer.doc.mjs +2 -2
  409. package/src/Layer/useLayer.test.tsx +85 -0
  410. package/src/Layer/useLayer.tsx +39 -1
  411. package/src/Lightbox/Lightbox.doc.mjs +1 -1
  412. package/src/Lightbox/Lightbox.tsx +43 -38
  413. package/src/Link/Link.tsx +4 -11
  414. package/src/MobileNav/MobileNav.tsx +3 -3
  415. package/src/MoreMenu/MoreMenu.doc.mjs +31 -0
  416. package/src/MoreMenu/MoreMenu.test.tsx +68 -1
  417. package/src/MoreMenu/MoreMenu.tsx +19 -0
  418. package/src/MultiSelector/MultiSelector.doc.mjs +9 -1
  419. package/src/MultiSelector/MultiSelector.test.tsx +255 -16
  420. package/src/MultiSelector/MultiSelector.tsx +103 -99
  421. package/src/NumberInput/NumberInput.doc.mjs +265 -50
  422. package/src/NumberInput/NumberInput.test.tsx +726 -21
  423. package/src/NumberInput/NumberInput.tsx +353 -59
  424. package/src/Outline/Outline.tsx +2 -5
  425. package/src/Pagination/Pagination.doc.mjs +1 -1
  426. package/src/Pagination/Pagination.test.tsx +22 -7
  427. package/src/Pagination/Pagination.tsx +38 -35
  428. package/src/Popover/Popover.tsx +6 -7
  429. package/src/PowerSearch/PowerSearch.tsx +1 -1
  430. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +42 -0
  431. package/src/PowerSearch/PowerSearchEditPopover.tsx +7 -0
  432. package/src/ProgressBar/ProgressBar.doc.mjs +27 -5
  433. package/src/ProgressBar/ProgressBar.test.tsx +224 -1
  434. package/src/ProgressBar/ProgressBar.tsx +124 -22
  435. package/src/RadioList/RadioList.doc.mjs +4 -2
  436. package/src/RadioList/RadioListItem.tsx +31 -130
  437. package/src/Resizable/ResizeHandle.tsx +2 -9
  438. package/src/SegmentedControl/SegmentedControlItem.tsx +2 -9
  439. package/src/SelectableCard/SelectableCard.tsx +4 -9
  440. package/src/Selector/Selector.doc.mjs +7 -4
  441. package/src/Selector/Selector.test.tsx +935 -25
  442. package/src/Selector/Selector.tsx +189 -106
  443. package/src/Selector/hooks.ts +77 -50
  444. package/src/SideNav/SideNav.test.tsx +46 -0
  445. package/src/SideNav/SideNav.tsx +1 -0
  446. package/src/SideNav/SideNavCollapseButton.tsx +15 -10
  447. package/src/SideNav/SideNavHeading.tsx +48 -10
  448. package/src/SideNav/SideNavItem.tsx +20 -12
  449. package/src/Stack/Stack.doc.mjs +110 -0
  450. package/src/StatusDot/StatusDot.doc.mjs +12 -3
  451. package/src/Switch/Switch.test.tsx +32 -0
  452. package/src/Switch/Switch.tsx +8 -8
  453. package/src/TabList/Tab.tsx +2 -9
  454. package/src/TabList/TabMenu.tsx +14 -21
  455. package/src/Table/BaseTable.tsx +11 -0
  456. package/src/Table/index.ts +1 -4
  457. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +30 -14
  458. package/src/Table/plugins/rowExpansion/index.ts +1 -4
  459. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +125 -175
  460. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +115 -458
  461. package/src/Table/plugins/sortable/useTableSortable.tsx +2 -6
  462. package/src/Table/plugins/tree/useTableTreeData.tsx +43 -24
  463. package/src/Table/tableContextMenu.test.tsx +27 -0
  464. package/src/Table/tableContextMenu.tsx +1 -0
  465. package/src/Table/types.ts +11 -0
  466. package/src/Table/useTableGroupedRows.doc.mjs +1 -1
  467. package/src/Table/useTableRowExpansion.doc.mjs +43 -66
  468. package/src/TextArea/TextArea.doc.mjs +42 -2
  469. package/src/TextArea/TextArea.test.tsx +219 -0
  470. package/src/TextArea/TextArea.tsx +34 -7
  471. package/src/TextInput/TextInput.doc.mjs +18 -2
  472. package/src/TextInput/TextInput.test.tsx +189 -0
  473. package/src/TextInput/TextInput.tsx +25 -31
  474. package/src/Thumbnail/Thumbnail.tsx +2 -9
  475. package/src/TimeInput/TimeInput.doc.mjs +2 -2
  476. package/src/TimeInput/TimeInput.test.tsx +30 -3
  477. package/src/TimeInput/TimeInput.tsx +9 -26
  478. package/src/Timestamp/Timestamp.doc.mjs +4 -3
  479. package/src/Timestamp/TimestampHoverCard.tsx +13 -35
  480. package/src/Token/Token.tsx +5 -28
  481. package/src/Tokenizer/Tokenizer.doc.mjs +2 -2
  482. package/src/Tokenizer/Tokenizer.test.tsx +45 -3
  483. package/src/Tokenizer/Tokenizer.tsx +10 -2
  484. package/src/Tooltip/useTooltip.tsx +2 -23
  485. package/src/TopNav/TopNav.tsx +1 -3
  486. package/src/TopNav/TopNavHeading.tsx +42 -13
  487. package/src/TopNav/TopNavItem.tsx +3 -21
  488. package/src/TopNav/TopNavMegaMenu.test.tsx +433 -33
  489. package/src/TopNav/TopNavMegaMenu.tsx +118 -53
  490. package/src/TopNav/TopNavMegaMenuItem.tsx +2 -9
  491. package/src/TopNav/TopNavMenu.tsx +34 -37
  492. package/src/TreeList/TreeList.doc.mjs +5 -0
  493. package/src/TreeList/TreeList.test.tsx +206 -7
  494. package/src/TreeList/TreeList.tsx +22 -0
  495. package/src/TreeList/TreeListBranches.tsx +25 -2
  496. package/src/TreeList/TreeListItem.tsx +89 -52
  497. package/src/Typeahead/BaseTypeahead.tsx +19 -6
  498. package/src/Typeahead/Typeahead.doc.mjs +1 -0
  499. package/src/Typeahead/Typeahead.test.tsx +76 -3
  500. package/src/hooks/containerReveal.stylex.ts +102 -0
  501. package/src/hooks/index.ts +4 -0
  502. package/src/hooks/useClipboard.doc.mjs +87 -0
  503. package/src/hooks/useClipboard.test.tsx +151 -0
  504. package/src/hooks/useClipboard.ts +135 -0
  505. package/src/hooks/useContainerReveal.doc.mjs +7 -7
  506. package/src/hooks/useContainerReveal.test.tsx +42 -62
  507. package/src/hooks/useContainerReveal.ts +36 -91
  508. package/src/hooks/useImageMode.test.ts +1 -1
  509. package/src/hooks/useIndicatorFocusRing.tsx +120 -0
  510. package/src/hooks/useLongPress.test.tsx +18 -0
  511. package/src/hooks/useLongPress.ts +12 -2
  512. package/src/hooks/useScrollLock.test.ts +72 -0
  513. package/src/hooks/useScrollLock.ts +51 -19
  514. package/src/hooks/useStreamingText.test.ts +46 -1
  515. package/src/hooks/useStreamingText.ts +49 -7
  516. package/src/hooks/useTreeFocus.test.tsx +50 -0
  517. package/src/hooks/useTreeFocus.ts +14 -3
  518. package/src/hooks/useTypeahead.test.tsx +150 -0
  519. package/src/hooks/useTypeahead.ts +24 -9
  520. package/src/i18n/InternationalizationProvider.doc.mjs +7 -2
  521. package/src/index.ts +1 -0
  522. package/src/theme/defineTheme.ts +24 -0
  523. package/src/theme/derivedVarRegistry.test.ts +21 -1
  524. package/src/theme/derivedVarRegistry.ts +19 -6
  525. package/src/theme/expandColorScale.test.ts +14 -0
  526. package/src/theme/expandColorScale.ts +24 -9
  527. package/src/theme/expandTypeScale.test.ts +43 -0
  528. package/src/theme/expandTypeScale.ts +17 -0
  529. package/src/theme/generateThemeRules.test.ts +61 -20
  530. package/src/theme/generateThemeRules.ts +11 -0
  531. package/src/theme/index.ts +13 -0
  532. package/src/utils/focusOutline.stylex.ts +163 -0
  533. package/src/utils/focusReturn.test.ts +42 -0
  534. package/src/utils/focusReturn.ts +31 -0
  535. package/src/utils/index.ts +1 -0
  536. package/src/utils/mergeRefs.test.ts +48 -0
  537. package/src/utils/mergeRefs.ts +12 -6
  538. package/src/utils/rtlStyles.ts +2 -2
  539. package/src/utils/themeProps.ts +26 -4
  540. package/dist/CheckboxInput/checkbox.markers.stylex.d.ts +0 -9
  541. package/dist/CheckboxInput/checkbox.markers.stylex.d.ts.map +0 -1
  542. package/dist/CheckboxInput/checkbox.markers.stylex.js +0 -14
  543. package/dist/RadioList/radio.markers.stylex.d.ts +0 -7
  544. package/dist/RadioList/radio.markers.stylex.d.ts.map +0 -1
  545. package/dist/RadioList/radio.markers.stylex.js +0 -12
  546. package/dist/hooks/containerReveal.pool.stylex.d.ts +0 -303
  547. package/dist/hooks/containerReveal.pool.stylex.d.ts.map +0 -1
  548. package/dist/hooks/containerReveal.pool.stylex.js +0 -292
  549. package/src/CheckboxInput/checkbox.markers.stylex.ts +0 -12
  550. package/src/RadioList/radio.markers.stylex.ts +0 -10
  551. package/src/hooks/containerReveal.pool.stylex.ts +0 -571
@@ -33,8 +33,9 @@ import {
33
33
  easeVars,
34
34
  } from '../theme/tokens.stylex';
35
35
  import {mergeProps} from '../utils';
36
- import {useAnnounce} from '../hooks/useAnnounce';
36
+ import {useClipboard} from '../hooks/useClipboard';
37
37
  import {Icon} from '../Icon';
38
+ import {IconButton} from '../IconButton';
38
39
  import {
39
40
  tokenize,
40
41
  tokenizeAsync,
@@ -45,6 +46,7 @@ import type {SyntaxToken, TokenLine} from './tokenizer';
45
46
  import {ensureHighlightStyles} from './highlightStyles';
46
47
  import {applyHighlightRangesChunked} from './highlightRanges';
47
48
  import {themeProps} from '../utils/themeProps';
49
+ import {focusOutlineProps} from '../utils/focusOutline.stylex';
48
50
  import {useTranslator} from '../i18n';
49
51
  import {SyntaxTheme, type SyntaxThemeDefinition} from '../theme/syntax';
50
52
 
@@ -198,6 +200,10 @@ const styles = stylex.create({
198
200
  },
199
201
  animationDuration: durationVars['--duration-medium'],
200
202
  animationTimingFunction: easeVars['--ease-standard'],
203
+ },
204
+ // Applied to the chevron <Icon> (via `xstyle`): the glyph is the element that
205
+ // rotates and the element a theme targets, so one selector reaches both.
206
+ collapseChevronIcon: {
201
207
  transitionProperty: 'transform',
202
208
  transitionDuration: durationVars['--duration-fast'],
203
209
  transitionTimingFunction: easeVars['--ease-standard'],
@@ -214,14 +220,6 @@ const styles = stylex.create({
214
220
  // Restore a keyboard-only focus ring with the standard token/offset so this
215
221
  // disclosure control matches the rest of the system (Collapsible, TabMenu);
216
222
  // otherwise it falls back to the inconsistent UA default outline.
217
- outline: {
218
- default: null,
219
- ':focus-visible': `2px solid ${colorVars['--color-accent']}`,
220
- },
221
- outlineOffset: {
222
- default: '0',
223
- ':focus-visible': '2px',
224
- },
225
223
  },
226
224
  code: {
227
225
  display: 'block',
@@ -303,22 +301,11 @@ const styles = stylex.create({
303
301
  fontSize: typeScaleVars['--text-code-size'],
304
302
  },
305
303
  copyButton: {
306
- display: 'inline-flex',
307
- alignItems: 'center',
308
- justifyContent: 'center',
309
- padding: spacingVars['--spacing-1'],
310
- marginInlineEnd: `calc(-1 * ${spacingVars['--spacing-2']})`,
311
- border: 'none',
312
- borderRadius: radiusVars['--radius-inner'],
313
- backgroundColor: {
314
- default: 'transparent',
315
- '@media (hover: hover)': {
316
- ':hover': colorVars['--color-overlay-hover'],
317
- },
318
- },
304
+ // The copy control is a ghost IconButton (Button owns its own padding,
305
+ // radius, and hover surface); this only tints the resting glyph to the
306
+ // muted syntax-comment colour so it blends into the header/corner. A theme
307
+ // reaches it via the `codeblock-copy-button` target on the Button.
319
308
  color: 'var(--color-syntax-comment)',
320
- cursor: 'pointer',
321
- lineHeight: 0,
322
309
  },
323
310
  copyButtonAbsolute: {
324
311
  position: 'absolute',
@@ -747,18 +734,12 @@ export function CodeBlock({
747
734
  ...props
748
735
  }: CodeBlockProps) {
749
736
  const t = useTranslator();
750
- const [copied, setCopied] = useState(false);
751
- const copyResetTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
752
- const announce = useAnnounce();
753
-
754
- // Clear a pending "copied" reset when the block unmounts.
755
- useEffect(() => {
756
- return () => {
757
- if (copyResetTimerRef.current != null) {
758
- clearTimeout(copyResetTimerRef.current);
759
- }
760
- };
761
- }, []);
737
+ // Owns the clipboard write, the transient copied flag, its reset timer, and
738
+ // the polite copy announcement (a swapped aria-label alone is not reliably
739
+ // announced) shared with Timestamp via the same hook.
740
+ const {copy, isCopied: copied} = useClipboard({
741
+ announce: t('@astryx.codeBlock.copied'),
742
+ });
762
743
 
763
744
  const useSpans =
764
745
  highlightMode === 'spans' ||
@@ -781,26 +762,11 @@ export function CodeBlock({
781
762
  );
782
763
 
783
764
  const handleCopy = useCallback(async () => {
784
- try {
785
- await navigator.clipboard.writeText(code);
786
- setCopied(true);
787
- // Swapping the button's aria-label alone isn't reliably announced by
788
- // screen readers, so confirm the copy via a polite live region.
789
- announce(t('@astryx.codeBlock.copied'));
765
+ const didCopy = await copy(code);
766
+ if (didCopy) {
790
767
  onCopy?.();
791
- // Restart the reset timer on every copy — otherwise a rapid re-copy
792
- // is reverted early by the previous click's timer.
793
- if (copyResetTimerRef.current != null) {
794
- clearTimeout(copyResetTimerRef.current);
795
- }
796
- copyResetTimerRef.current = setTimeout(() => {
797
- copyResetTimerRef.current = null;
798
- setCopied(false);
799
- }, 2000);
800
- } catch {
801
- // Clipboard failures leave the copied state unchanged.
802
768
  }
803
- }, [code, onCopy, announce, t]);
769
+ }, [code, copy, onCopy]);
804
770
 
805
771
  const sizeStyle = size === 'sm' ? styles.sizeSm : styles.sizeMd;
806
772
  // Digits in the largest line number — sizes the gutter column width.
@@ -822,34 +788,37 @@ export function CodeBlock({
822
788
  ? {maxHeight: typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight}
823
789
  : undefined;
824
790
 
825
- const copyIcon = (
826
- <Icon icon={copied ? 'check' : 'copy'} size="sm" color="inherit" />
827
- );
828
-
829
791
  const copyButtonEl = hasCopyButton ? (
830
- <button
831
- type="button"
792
+ <IconButton
793
+ variant="ghost"
794
+ size="sm"
795
+ icon={<Icon icon={copied ? 'check' : 'copy'} size="sm" color="inherit" />}
796
+ // A visible "Copy" hover/focus hint via Button's built-in tooltip. It
797
+ // stays "Copy" after copying — the copy → check icon flip is the
798
+ // confirmation, not a tooltip change. The aria-label still swaps to the
799
+ // localized "Copied" for assistive tech, backed by the announcement.
800
+ tooltip={t('@astryx.codeBlock.copyCode')}
801
+ label={
802
+ copied ? t('@astryx.codeBlock.copied') : t('@astryx.codeBlock.copyCode')
803
+ }
832
804
  onClick={e => {
833
805
  // Stop propagation so copying does not toggle the collapsible header.
834
806
  e.stopPropagation();
835
807
  void handleCopy();
836
808
  }}
837
- aria-label={
838
- copied ? t('@astryx.codeBlock.copied') : t('@astryx.codeBlock.copyCode')
839
- }
840
- {...stylex.props(
841
- styles.copyButton,
842
- !showHeader && styles.copyButtonAbsolute,
843
- )}>
844
- {copyIcon}
845
- </button>
809
+ xstyle={[styles.copyButton, !showHeader && styles.copyButtonAbsolute]}
810
+ {...themeProps('codeblock-copy-button')}
811
+ />
846
812
  ) : null;
847
813
 
848
814
  const headerEl = showHeader ? (
849
815
  <div
850
- {...stylex.props(
851
- styles.headerRow,
852
- hasLineNumbers ? styles.headerWithDivider : styles.headerCompact,
816
+ {...mergeProps(
817
+ themeProps('codeblock-header', {size, language, container}),
818
+ stylex.props(
819
+ styles.headerRow,
820
+ hasLineNumbers ? styles.headerWithDivider : styles.headerCompact,
821
+ ),
853
822
  )}>
854
823
  <div
855
824
  role={canCollapse ? 'button' : undefined}
@@ -867,18 +836,26 @@ export function CodeBlock({
867
836
  }
868
837
  : undefined
869
838
  }
870
- {...stylex.props(
839
+ {...focusOutlineProps.focusVisible(
871
840
  styles.header,
872
841
  canCollapse && styles.headerCollapsible,
873
842
  )}>
874
- <span {...stylex.props(styles.headerTitle)}>
843
+ <span
844
+ {...mergeProps(
845
+ themeProps('codeblock-title', {size, language}),
846
+ stylex.props(styles.headerTitle),
847
+ )}>
875
848
  {canCollapse && (
876
- <span
877
- {...stylex.props(
878
- styles.collapseChevron,
879
- !isCollapsed && styles.collapseChevronExpanded,
880
- )}>
881
- <Icon icon="chevronRight" size="xsm" color="inherit" />
849
+ <span {...stylex.props(styles.collapseChevron)}>
850
+ <Icon
851
+ icon="chevronRight"
852
+ size="xsm"
853
+ color="inherit"
854
+ xstyle={[
855
+ styles.collapseChevronIcon,
856
+ !isCollapsed && styles.collapseChevronExpanded,
857
+ ]}
858
+ />
882
859
  </span>
883
860
  )}
884
861
  {title}
@@ -42,10 +42,11 @@ import {
42
42
 
43
43
  import {useCollapsible} from './useCollapsible';
44
44
  import {CollapsibleGroupPresentationContext} from './CollapsibleGroupContext';
45
- import {useIcon} from '../Icon';
45
+ import {Icon} from '../Icon';
46
46
  import {mergeProps} from '../utils';
47
47
  import type {BaseProps} from '../BaseProps';
48
48
  import {themeProps} from '../utils/themeProps';
49
+ import {focusOutlineProps} from '../utils/focusOutline.stylex';
49
50
 
50
51
  const styles = stylex.create({
51
52
  root: {
@@ -73,14 +74,6 @@ const styles = stylex.create({
73
74
  paddingBlock: 0,
74
75
  // `all: unset` above wipes the UA focus outline; restore a keyboard-only
75
76
  // focus ring using the standard token/offset (WCAG 2.4.7).
76
- outline: {
77
- default: null,
78
- ':focus-visible': `2px solid ${colorVars['--color-accent']}`,
79
- },
80
- outlineOffset: {
81
- default: '0',
82
- ':focus-visible': '2px',
83
- },
84
77
  },
85
78
  // Capsize: trim leading from text triggers
86
79
  triggerLabel: {
@@ -100,10 +93,17 @@ const styles = stylex.create({
100
93
  alignItems: 'center',
101
94
  justifyContent: 'center',
102
95
  flexShrink: 0,
96
+ // The chevron is sized off the trigger's own type size (--text-large-size,
97
+ // 17px), which sits between Icon's `sm` (16px) and `md` (20px) boxes.
98
+ // Pinning the box to the token keeps the glyph exactly the size it was
99
+ // when it was a bare 1em SVG inheriting the trigger's font-size, and keeps
100
+ // it tracking the trigger if a theme retunes that step.
101
+ width: typeScaleVars['--text-large-size'],
102
+ height: typeScaleVars['--text-large-size'],
103
+ fontSize: typeScaleVars['--text-large-size'],
103
104
  transitionProperty: 'transform',
104
105
  transitionDuration: durationVars['--duration-fast'],
105
106
  transitionTimingFunction: easeVars['--ease-standard'],
106
- color: colorVars['--color-icon-secondary'],
107
107
  },
108
108
  chevronOpen: {
109
109
  transform: 'rotate(180deg)',
@@ -293,8 +293,6 @@ export function Collapsible({
293
293
  const isDivided = presentation?.hasDividers ?? false;
294
294
  const density = presentation?.density ?? null;
295
295
 
296
- const chevronIcon = useIcon('chevronDown');
297
-
298
296
  // Links the trigger to the region it shows/hides so assistive tech can move
299
297
  // from the button to its controlled content (disclosure pattern).
300
298
  const contentId = useId();
@@ -327,20 +325,26 @@ export function Collapsible({
327
325
  themeProps('collapsible-trigger', {
328
326
  density: density ?? undefined,
329
327
  }),
330
- stylex.props(
328
+ focusOutlineProps.focusVisible(
331
329
  styles.trigger,
332
330
  density != null && triggerDensity[density],
333
331
  isDisabled && styles.triggerDisabled,
334
332
  ),
335
333
  )}>
336
334
  <span {...stylex.props(styles.triggerLabel)}>{trigger}</span>
337
- <span
338
- {...stylex.props(
335
+ <Icon
336
+ icon="chevronDown"
337
+ // Nearest size to the trigger's 17px type step; `chevron` re-pins the
338
+ // exact box (see the style) so the glyph does not resize.
339
+ size="sm"
340
+ // Was `--color-icon-secondary` on the old wrapper span; `secondary`
341
+ // is the same token, expressed as an Icon color.
342
+ color="secondary"
343
+ xstyle={[
339
344
  styles.chevron,
340
345
  isOpen ? styles.chevronOpen : styles.chevronClosed,
341
- )}>
342
- {chevronIcon}
343
- </span>
346
+ ]}
347
+ />
344
348
  </button>
345
349
  <div
346
350
  id={contentId}
@@ -274,6 +274,35 @@ describe('CommandPalette', () => {
274
274
  );
275
275
  });
276
276
 
277
+ it('does not move the highlight while typing in the search input', async () => {
278
+ // The palette's input already filters; letting the shared combobox
279
+ // typeahead also chase prefixes would drag the highlight — and Enter —
280
+ // onto a command the user never picked.
281
+ const gitSource = createStaticSource([
282
+ {id: 'git-add', label: 'git add'},
283
+ {id: 'git-commit', label: 'git commit'},
284
+ {id: 'git-push', label: 'git push'},
285
+ ]);
286
+ render(
287
+ <CommandPalette
288
+ isOpen={true}
289
+ onOpenChange={() => {}}
290
+ searchSource={gitSource}
291
+ />,
292
+ );
293
+
294
+ const input = screen.getByRole('combobox');
295
+ await waitFor(() =>
296
+ expect(screen.getByText('git add')).toBeInTheDocument(),
297
+ );
298
+
299
+ fireEvent.keyDown(input, {key: 'g'});
300
+ fireEvent.keyDown(input, {key: 'i'});
301
+ fireEvent.keyDown(input, {key: 't'});
302
+
303
+ expect(input).not.toHaveAttribute('aria-activedescendant');
304
+ });
305
+
277
306
  describe('screen reader announcements', () => {
278
307
  const politeRegion = () =>
279
308
  document.querySelector('[data-astryx-live-region="polite"]');
@@ -15,6 +15,7 @@ import {useCallback, useEffect, useMemo, useRef, type ReactNode} from 'react';
15
15
  import * as stylex from '@stylexjs/stylex';
16
16
  import type {BaseProps} from '../BaseProps';
17
17
  import {mergeProps, mergeRefs} from '../utils';
18
+ import {composeEventHandlers} from '../utils/composeEventHandlers';
18
19
  import {
19
20
  colorVars,
20
21
  spacingVars,
@@ -127,6 +128,8 @@ export function CommandPaletteItem({
127
128
  xstyle,
128
129
  className,
129
130
  style,
131
+ onClick: onClickProp,
132
+ onMouseEnter: onMouseEnterProp,
130
133
  ...props
131
134
  }: CommandPaletteItemProps) {
132
135
  const ctx = useCommandPaletteContext();
@@ -186,13 +189,14 @@ export function CommandPaletteItem({
186
189
  return (
187
190
  <div
188
191
  ref={mergeRefs(ref, itemRef)}
192
+ {...props}
189
193
  id={ctx && itemIndex >= 0 ? ctx.getItemId(itemIndex) : undefined}
190
194
  role="option"
191
195
  aria-selected={isSelected}
192
196
  aria-disabled={isDisabled || undefined}
193
197
  data-value={value}
194
- onClick={handleClick}
195
- onMouseEnter={handleMouseEnter}
198
+ onClick={composeEventHandlers(onClickProp, handleClick)}
199
+ onMouseEnter={composeEventHandlers(onMouseEnterProp, handleMouseEnter)}
196
200
  {...mergeProps(
197
201
  themeProps('command-palette-item'),
198
202
  stylex.props(
@@ -205,8 +209,7 @@ export function CommandPaletteItem({
205
209
  ),
206
210
  className,
207
211
  style,
208
- )}
209
- {...props}>
212
+ )}>
210
213
  {children}
211
214
  </div>
212
215
  );
@@ -87,6 +87,7 @@ export function CommandPaletteList({
87
87
  return (
88
88
  <div
89
89
  ref={ref}
90
+ {...props}
90
91
  id={ctx?.listId}
91
92
  role="listbox"
92
93
  aria-label={label}
@@ -95,8 +96,7 @@ export function CommandPaletteList({
95
96
  stylex.props(styles.list, xstyle),
96
97
  className,
97
98
  style,
98
- )}
99
- {...props}>
99
+ )}>
100
100
  {children}
101
101
  </div>
102
102
  );
@@ -24,6 +24,7 @@ export const docs = {
24
24
  className: 'astryx-complex-selector-indicator-icon',
25
25
  states: ['state'],
26
26
  },
27
+ {className: 'astryx-complex-selector-popup'},
27
28
  ],
28
29
  },
29
30
  components: [
@@ -164,6 +165,47 @@ export const docsDense = {
164
165
  category: 'Data Input',
165
166
  description:
166
167
  'Field+dialog-popover shell for rich custom selectors. Content gets value/onChange/close/state; content owns semantics. Use focus hooks and evaluate custom content against WCAG 2.2.',
168
+ usage: {
169
+ description:
170
+ 'Use when a selection needs richer custom content than a Selector row. One component: it owns field, trigger, popover, focus restore, and changeAction; the render prop owns the selector-specific accessible structure.',
171
+ bestPractices: [
172
+ {
173
+ guidance: true,
174
+ description:
175
+ 'Compose content from the right accessible structure: RadioList for a simple choice, Calendar/date inputs for dates, TreeList or a searchable list for hierarchy, a custom grid for 2D arrow navigation.',
176
+ },
177
+ {
178
+ guidance: true,
179
+ description:
180
+ 'Use the onChange helper from children; it calls both onChange and changeAction and updates optimistic busy state.',
181
+ },
182
+ {
183
+ guidance: true,
184
+ description:
185
+ 'Call close() from custom content when a selection should dismiss the popup. Keep it open for multi-step or freeform flows.',
186
+ },
187
+ {
188
+ guidance: true,
189
+ description:
190
+ 'Use Astryx focus hooks: useGridFocus for 2D grids, useTreeFocus via TreeList for hierarchies, useListFocus for custom linear collections.',
191
+ },
192
+ {
193
+ guidance: true,
194
+ description:
195
+ 'Evaluate custom content against WCAG 2.2: keyboard operation, focus visible/not obscured, names and roles, labels/instructions, target size, and contrast.',
196
+ },
197
+ {
198
+ guidance: false,
199
+ description:
200
+ 'Do not rebuild trigger ARIA, popover focus management, or changeAction handling in product code.',
201
+ },
202
+ {
203
+ guidance: false,
204
+ description:
205
+ 'Do not use ComplexSelector for a plain single-column text list; use Selector instead.',
206
+ },
207
+ ],
208
+ },
167
209
  propDescriptions: {
168
210
  label: 'Accessible field label.',
169
211
  value: 'Controlled value.',
@@ -106,6 +106,27 @@ describe('ComplexSelector', () => {
106
106
  );
107
107
  });
108
108
 
109
+ it('gives the popup clearance on both block edges, not just the leading one (#4803)', async () => {
110
+ const user = userEvent.setup();
111
+ render(
112
+ <FruitComplexSelector
113
+ value={{fruit: 'Apple', ripeness: 'Ripe'}}
114
+ onChange={() => {}}
115
+ />,
116
+ );
117
+ await user.click(screen.getByRole('button', {name: 'Fruit blend'}));
118
+ const popup = document.querySelector('[popover]') as HTMLElement;
119
+ expect(popup).not.toBeNull();
120
+ // Both edges, not just the leading one: the trailing edge is what faces
121
+ // the trigger when the same popup opens upward (placement="above") or is
122
+ // flipped by position-try-fallbacks. useLayer's `offset` sets both from
123
+ // the resolved placement; jsdom resolves neither the var indirection nor
124
+ // logical margins, so read the debug-mode declarations it emits.
125
+ const blockStart = popup.style.getPropertyValue('--x-marginBlockStart');
126
+ expect(blockStart).not.toBe('');
127
+ expect(popup.style.getPropertyValue('--x-marginBlockEnd')).toBe(blockStart);
128
+ });
129
+
109
130
  it('runs changeAction through the provided onChange helper', async () => {
110
131
  const user = userEvent.setup();
111
132
  const onChange = vi.fn();
@@ -154,3 +175,46 @@ describe('ComplexSelector', () => {
154
175
  expect(trigger).toHaveAttribute('aria-expanded', 'false');
155
176
  });
156
177
  });
178
+
179
+ describe('ComplexSelector popup theme target', () => {
180
+ it('puts astryx-complex-selector-popup on the content box inside the layer', async () => {
181
+ const user = userEvent.setup();
182
+ render(
183
+ <ComplexSelector label="Fruit blend" value="Apple" triggerLabel="Apple">
184
+ {() => <button type="button">Done</button>}
185
+ </ComplexSelector>,
186
+ );
187
+ await user.click(screen.getByRole('button', {name: 'Fruit blend'}));
188
+
189
+ const layer = document.querySelector('[popover]') as HTMLElement;
190
+ const popup = document.querySelector(
191
+ '.astryx-complex-selector-popup',
192
+ ) as HTMLElement;
193
+ expect(popup).not.toBeNull();
194
+ // The layer is a bare positioning box; the target must be the content box
195
+ // it contains, which is what actually paints.
196
+ expect(popup).not.toBe(layer);
197
+ expect(layer.contains(popup)).toBe(true);
198
+ expect(popup).toContainElement(
199
+ screen.getByRole('button', {name: 'Done', ...h}),
200
+ );
201
+ });
202
+
203
+ it('keeps the target when the consumer also passes contentXstyle', async () => {
204
+ const user = userEvent.setup();
205
+ render(
206
+ <ComplexSelector
207
+ label="Fruit blend"
208
+ value="Apple"
209
+ triggerLabel="Apple"
210
+ contentXstyle={{}}>
211
+ {() => <button type="button">Done</button>}
212
+ </ComplexSelector>,
213
+ );
214
+ await user.click(screen.getByRole('button', {name: 'Fruit blend'}));
215
+
216
+ expect(
217
+ document.querySelector('.astryx-complex-selector-popup'),
218
+ ).not.toBeNull();
219
+ });
220
+ });