@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
@@ -4,7 +4,8 @@
4
4
 
5
5
  /**
6
6
  * @file Selector.tsx
7
- * @input Uses React, StyleX, usePopover, useTooltip, Icon, InputGroupContext
7
+ * @input Uses React, StyleX, usePopover, useTooltip, Icon, InputGroupContext,
8
+ * and Selector positioning hooks
8
9
  * @output Exports Selector component
9
10
  * @position Core implementation; consumed by index.ts
10
11
  *
@@ -31,9 +32,11 @@ import * as stylex from '@stylexjs/stylex';
31
32
  import {usePopover} from '../Popover/usePopover';
32
33
  import {useTooltip} from '../Tooltip';
33
34
  import {Icon, renderIconSlot, type IconType} from '../Icon';
35
+ import {useIndicator} from '../Indicator';
34
36
  import type {IconName} from '../Icon';
35
37
  import {
36
38
  Field,
39
+ InputClearButton,
37
40
  inputStatusBorderStyles,
38
41
  inputStatusHoverShadowStyles,
39
42
  inputWrapperStyles,
@@ -66,12 +69,14 @@ import {
66
69
  getSelectableOptions,
67
70
  } from './utils';
68
71
  import {useCombobox, useSelectedItemOffset} from './hooks';
72
+ import {useTypeahead} from '../hooks/useTypeahead';
69
73
  import {SelectorOption} from './SelectorOption';
70
74
  import {getInputARIA, mergeProps} from '../utils';
71
75
  import {useSize} from '../SizeContext/SizeContext';
72
76
  import type {BaseProps} from '../BaseProps';
73
77
  import type {SizeValue} from '../utils/types';
74
78
  import {themeProps} from '../utils/themeProps';
79
+ import {stableClassName} from '../naming';
75
80
  import {groupStyles} from '../InputGroup/groupStyles';
76
81
  import {useInputGroup} from '../InputGroup/InputGroupContext';
77
82
  import {VisuallyHidden} from '../VisuallyHidden';
@@ -134,26 +139,27 @@ const styles = stylex.create({
134
139
  whiteSpace: 'nowrap',
135
140
  textAlign: 'start',
136
141
  },
142
+ // Only what Icon does not already provide: `size="sm"` gives the 16px box
143
+ // and `color` the token, but the glyph still must not shrink inside the flex
144
+ // trigger.
137
145
  triggerIcon: {
138
146
  flexShrink: 0,
139
- display: 'flex',
140
- alignItems: 'center',
141
- justifyContent: 'center',
142
- width: 16,
143
- height: 16,
147
+ },
148
+ // Rotation lives on the chevron glyph itself (passed through `xstyle`), not
149
+ // on the layout wrapper above, so the icon's `selector-indicator-icon` theme
150
+ // target and the open/closed transform sit on one element — a theme can
151
+ // restyle the mark and its rotation through a single selector. The wrapper
152
+ // keeps only layout. The status branch renders a different icon, so it never
153
+ // picks these up and needs no transition opt-out.
154
+ triggerIconRotation: {
144
155
  transitionProperty: 'transform',
145
156
  transitionDuration: durationVars['--duration-fast'],
146
157
  transitionTimingFunction: easeVars['--ease-standard'],
147
158
  transformOrigin: 'center',
148
- color: colorVars['--color-icon-secondary'],
149
159
  },
150
160
  triggerIconOpen: {
151
161
  transform: 'rotate(180deg)',
152
162
  },
153
- triggerIconStatus: {
154
- // Disable rotation transition for status icons
155
- transition: 'none',
156
- },
157
163
  triggerGhost: {
158
164
  width: 'auto',
159
165
  borderWidth: 0,
@@ -197,23 +203,6 @@ const styles = stylex.create({
197
203
  },
198
204
 
199
205
  // Clear button
200
- clearButton: {
201
- display: 'flex',
202
- alignItems: 'center',
203
- justifyContent: 'center',
204
- padding: 0,
205
- margin: 0,
206
- borderWidth: 0,
207
- borderStyle: 'none',
208
- backgroundColor: 'transparent',
209
- cursor: 'pointer',
210
- borderRadius: radiusVars['--radius-element'],
211
- outline: {
212
- default: 'none',
213
- ':focus-visible': `${borderVars['--border-width']} solid ${colorVars['--color-accent']}`,
214
- },
215
- outlineOffset: 1,
216
- },
217
206
  statusButton: {
218
207
  display: 'flex',
219
208
  alignItems: 'center',
@@ -238,10 +227,16 @@ const styles = stylex.create({
238
227
  boxSizing: 'border-box',
239
228
  maxHeight: '300px',
240
229
  overflowY: 'auto',
241
- padding: spacingVars['--spacing-1'],
230
+ paddingBlock: spacingVars['--spacing-1'],
231
+ paddingInline: spacingVars['--spacing-1'],
242
232
  opacity: 1,
243
233
  transition: `opacity ${durationVars['--duration-fast']}`,
244
234
  },
235
+ dropdownInput: {
236
+ // The input trigger's text inset includes its border. Mirror that extra
237
+ // pixel in the menu; the borderless ghost variant needs no correction.
238
+ paddingInline: `calc(${spacingVars['--spacing-1']} + ${borderVars['--border-width']})`,
239
+ },
245
240
  dropdownHidden: {
246
241
  opacity: 0,
247
242
  transition: 'none',
@@ -703,6 +698,9 @@ export function Selector<T extends SelectorOptionType>(
703
698
  const statusMessageId = useId();
704
699
  const inputLabelId = useId();
705
700
  const searchId = useId();
701
+ // Measure from the same outer control that usePopover anchors to; using the
702
+ // shorter inner button makes every size's selected row land too low.
703
+ const anchorRef = useRef<HTMLDivElement>(null);
706
704
  const triggerRef = useRef<HTMLButtonElement>(null);
707
705
  const searchRef = useRef<HTMLInputElement>(null);
708
706
  const inputGroup = useInputGroup();
@@ -715,6 +713,7 @@ export function Selector<T extends SelectorOptionType>(
715
713
  const [, startTransition] = useTransition();
716
714
  const [optimisticValue, setOptimisticValue] = useOptimistic(normalizedValue);
717
715
  const isBusy = isLoading || optimisticValue !== normalizedValue;
716
+ const announce = useAnnounce();
718
717
 
719
718
  // Disabled-reason tooltip. Disabled controls swallow pointer events, so the
720
719
  // tooltip listeners attach to the trigger container (which already exists)
@@ -775,15 +774,15 @@ export function Selector<T extends SelectorOptionType>(
775
774
  // Ref for listbox to measure selected item position
776
775
  const listboxRef = useRef<HTMLDivElement>(null);
777
776
 
778
- // Announce match counts / "No results found" politely as the user types, so
779
- // screen-reader users hear how many options remain. Filtering was previously
780
- // silent (comboboxes-7). Mirrors BaseTypeahead, which announces from its
781
- // query-change callback (not a reactive effect) via the same useAnnounce hook.
782
- const announce = useAnnounce();
777
+ // Typeahead is defined below (it needs the popover), but closing and clearing
778
+ // must drop its pending buffer otherwise a stale prefix survives the reset
779
+ // window and poisons the next keystroke ("Dog" then "c" would search "dc").
780
+ const resetTypeaheadRef = useRef<() => void>(() => {});
783
781
 
784
782
  // Layer for dropdown positioning
785
783
  const handleLayerHide = useCallback(() => {
786
784
  setSearchQuery('');
785
+ resetTypeaheadRef.current();
787
786
  // Clear any lingering result count when the popover closes so stale status
788
787
  // text does not linger in the a11y tree.
789
788
  announce('');
@@ -840,7 +839,7 @@ export function Selector<T extends SelectorOptionType>(
840
839
  selectedItemIndex,
841
840
  listboxId,
842
841
  listboxRef,
843
- triggerRef,
842
+ anchorRef,
844
843
  });
845
844
 
846
845
  const selectedItemOffset = shouldOverlaySelectedItem ? rawOffset : 0;
@@ -854,6 +853,7 @@ export function Selector<T extends SelectorOptionType>(
854
853
  // Clear the current value. Shared by the clear button and the keyboard
855
854
  // Delete/Backspace path so clearing is reachable without a mouse.
856
855
  const clearValue = useCallback(() => {
856
+ resetTypeaheadRef.current();
857
857
  onChange?.(null);
858
858
  if (changeAction) {
859
859
  startTransition(async () => {
@@ -863,10 +863,29 @@ export function Selector<T extends SelectorOptionType>(
863
863
  }
864
864
  }, [onChange, changeAction, startTransition, setOptimisticValue]);
865
865
 
866
- // Selector behavior (keyboard nav, typeahead, selection)
866
+ // Type-to-find appends to the query rather than replacing it: characters
867
+ // typed before focus reaches the search input must not be dropped.
868
+ const appendSearchQuery = useCallback((char: string) => {
869
+ setSearchQuery(query => query + char);
870
+ }, []);
871
+
872
+ const commitValue = useCallback(
873
+ (newValue: string) => {
874
+ onChange?.(newValue);
875
+ if (changeAction) {
876
+ startTransition(async () => {
877
+ setOptimisticValue(newValue);
878
+ await changeAction(newValue);
879
+ });
880
+ }
881
+ },
882
+ [onChange, changeAction, startTransition, setOptimisticValue],
883
+ );
884
+
885
+ // Selector behavior (keyboard nav, selection)
867
886
  const {
868
887
  highlightedIndex,
869
- setHighlightedIndex: _setHighlightedIndex,
888
+ setHighlightedIndex,
870
889
  getItemId,
871
890
  onTriggerClick,
872
891
  onKeyDown,
@@ -874,7 +893,11 @@ export function Selector<T extends SelectorOptionType>(
874
893
  onItemMouseEnter,
875
894
  } = useCombobox({
876
895
  selectableItems: filteredItems,
877
- value: normalizedValue,
896
+ // The optimistic value, not the raw prop: with a pending changeAction the
897
+ // prop still holds the old selection, so the popup would open with the
898
+ // highlight on it and Delete/Backspace could clear a value the action has
899
+ // already replaced.
900
+ value: optimisticValue,
878
901
  isDisabled,
879
902
  isOpen: popover.isOpen,
880
903
  hasSearch,
@@ -882,27 +905,61 @@ export function Selector<T extends SelectorOptionType>(
882
905
  popover.show();
883
906
  if (hasSearch) {
884
907
  requestAnimationFrame(() => {
885
- searchRef.current?.focus();
908
+ const input = searchRef.current;
909
+ if (input) {
910
+ input.focus();
911
+ // When typing seeded the query, place the caret after it so the
912
+ // user keeps typing where they left off.
913
+ input.setSelectionRange(input.value.length, input.value.length);
914
+ }
886
915
  });
887
916
  }
888
917
  }, [popover, hasSearch]),
889
918
  onClose: popover.hide,
890
- onSelect: useCallback(
891
- (newValue: string) => {
892
- onChange?.(newValue);
893
- if (changeAction) {
894
- startTransition(async () => {
895
- setOptimisticValue(newValue);
896
- await changeAction(newValue);
897
- });
898
- }
899
- },
900
- [onChange, changeAction, startTransition, setOptimisticValue],
901
- ),
919
+ onSelect: commitValue,
902
920
  onClear: hasClear ? clearValue : undefined,
921
+ onSearchSeed: appendSearchQuery,
903
922
  listboxId,
904
923
  });
905
924
 
925
+ // Type-to-select, shared with the other collections (menus, listboxes).
926
+ // Open, it walks the highlight — aria-activedescendant announces each match.
927
+ // Closed, it commits the match like a native select, which changes the value
928
+ // without opening the popup or moving focus, so nothing else would prompt
929
+ // assistive tech to re-read the trigger: announce it explicitly.
930
+ const typeahead = useTypeahead({
931
+ getItemLabels: () => selectableItems.map(item => item.label ?? item.value),
932
+ isDisabled: index => selectableItems[index]?.disabled === true,
933
+ // Cycle onward from the highlight when open, from the committed selection
934
+ // when closed — the optimistic one, so a pending changeAction cannot strand
935
+ // cycling on the first match. -1 means nothing is selected or highlighted,
936
+ // which the hook reads as "search from the top".
937
+ getCurrentIndex: () =>
938
+ popover.isOpen ? highlightedIndex : selectedItemIndex,
939
+ onMatch: index => {
940
+ const item = selectableItems[index];
941
+ if (popover.isOpen) {
942
+ setHighlightedIndex(index);
943
+ } else if (item.value !== optimisticValue) {
944
+ commitValue(item.value);
945
+ announce(item.label ?? item.value);
946
+ }
947
+ },
948
+ });
949
+ resetTypeaheadRef.current = typeahead.reset;
950
+
951
+ const handleTriggerKeyDown = useCallback(
952
+ (e: React.KeyboardEvent) => {
953
+ // With hasSearch the query input owns typing, so type-to-select is off.
954
+ if (!isDisabled && !hasSearch && typeahead.onKeyDown(e)) {
955
+ e.preventDefault();
956
+ return;
957
+ }
958
+ onKeyDown(e);
959
+ },
960
+ [isDisabled, hasSearch, typeahead, onKeyDown],
961
+ );
962
+
906
963
  // Keep the highlighted option visible during keyboard navigation. The
907
964
  // listbox is a fixed-height scroll container, so without this the virtual
908
965
  // cursor walks off-screen once navigation passes the visible window. Mirrors
@@ -1020,6 +1077,11 @@ export function Selector<T extends SelectorOptionType>(
1020
1077
  t,
1021
1078
  ]);
1022
1079
 
1080
+ // The single-selection mark, resolved from the theme once per render. A
1081
+ // theme that maps `check` to another indicator (a radio, say) changes every
1082
+ // selected-option mark in the app through this one lookup.
1083
+ const SelectionMark = useIndicator('check');
1084
+
1023
1085
  // Render an individual item
1024
1086
  const renderItem = useCallback(
1025
1087
  (item: SelectorOptionData, flatIndex: number) => {
@@ -1049,7 +1111,21 @@ export function Selector<T extends SelectorOptionType>(
1049
1111
  <DefaultOption option={item} />
1050
1112
  )}
1051
1113
  </span>
1052
- {isSelected && <Icon icon="check" size="sm" color="accent" />}
1114
+ {/*
1115
+ * Rendered UNCONDITIONALLY, with the state passed down: the default
1116
+ * check draws nothing when unchecked, but a theme that replaces the
1117
+ * `check` indicator with a radio needs the unselected state to draw
1118
+ * its empty circle. `{isSelected && …}` would make that impossible.
1119
+ *
1120
+ * `selector-check` stays the stable target for the mark's position
1121
+ * in the row; the indicator owns what the mark looks like.
1122
+ */}
1123
+ <SelectionMark
1124
+ state={isSelected ? 'checked' : 'unchecked'}
1125
+ size="sm"
1126
+ isDisabled={item.disabled ?? false}
1127
+ {...themeProps('selector-check')}
1128
+ />
1053
1129
  </div>
1054
1130
  );
1055
1131
  },
@@ -1061,6 +1137,7 @@ export function Selector<T extends SelectorOptionType>(
1061
1137
  getItemId,
1062
1138
  onItemSelect,
1063
1139
  onItemMouseEnter,
1140
+ SelectionMark,
1064
1141
  ],
1065
1142
  );
1066
1143
 
@@ -1078,7 +1155,10 @@ export function Selector<T extends SelectorOptionType>(
1078
1155
  <div
1079
1156
  key="empty"
1080
1157
  role="presentation"
1081
- {...stylex.props(styles.emptyState)}>
1158
+ {...mergeProps(
1159
+ themeProps('selector-empty-state'),
1160
+ stylex.props(styles.emptyState),
1161
+ )}>
1082
1162
  No results found
1083
1163
  </div>,
1084
1164
  ];
@@ -1150,6 +1230,7 @@ export function Selector<T extends SelectorOptionType>(
1150
1230
  <>
1151
1231
  <div
1152
1232
  ref={el => {
1233
+ anchorRef.current = el;
1153
1234
  popover.triggerRef(el);
1154
1235
  // Anchor + hover/focus listeners for the disabled-message tooltip.
1155
1236
  // Handlers are gated internally by isEnabled, and anchor names
@@ -1163,6 +1244,7 @@ export function Selector<T extends SelectorOptionType>(
1163
1244
  variant,
1164
1245
  size,
1165
1246
  status: status?.type ?? null,
1247
+ disabled: isDisabled ? 'disabled' : null,
1166
1248
  }),
1167
1249
  stylex.props(
1168
1250
  inputWrapperStyles.base,
@@ -1217,7 +1299,7 @@ export function Selector<T extends SelectorOptionType>(
1217
1299
  // still blocked by the isDisabled guards in useCombobox.
1218
1300
  disabled={isDisabled && !showsDisabledMessage}
1219
1301
  aria-disabled={showsDisabledMessage ? 'true' : undefined}
1220
- onKeyDown={onKeyDown}
1302
+ onKeyDown={handleTriggerKeyDown}
1221
1303
  tabIndex={isDisabled && !showsDisabledMessage ? -1 : 0}
1222
1304
  {...stylex.props(styles.trigger)}>
1223
1305
  <span {...stylex.props(styles.triggerLabel)}>
@@ -1236,68 +1318,65 @@ export function Selector<T extends SelectorOptionType>(
1236
1318
  )}
1237
1319
  {isBusy && <Spinner size="sm" />}
1238
1320
  {hasClear && value != null && !isDisabled && (
1239
- <button
1240
- type="button"
1321
+ <InputClearButton
1322
+ label={t('@astryx.selector.clearLabel', {label})}
1241
1323
  onClick={handleClear}
1242
- aria-label={t('@astryx.selector.clearLabel', {label})}
1243
- {...stylex.props(styles.clearButton)}>
1244
- <Icon
1245
- icon="close"
1246
- size="sm"
1247
- color="secondary"
1248
- // Stable theme target on the clear glyph itself, so a theme can
1249
- // restyle just this icon (color, size, hover) via `defineTheme`.
1250
- // Same-element rules in @layer astryx-theme win over the icon's
1251
- // own base color/size, which a button-level target could not
1252
- // reach.
1253
- {...themeProps('selector-clear-icon')}
1254
- />
1255
- </button>
1324
+ iconClassName={stableClassName('selector-clear-icon')}
1325
+ />
1256
1326
  )}
1257
- <span
1258
- {...stylex.props(
1259
- styles.triggerIcon,
1260
- !showStatusIcon && popover.isOpen && styles.triggerIconOpen,
1261
- showStatusIcon && styles.triggerIconStatus,
1262
- )}>
1263
- {showStatusIcon ? (
1264
- showStatusTooltip ? (
1265
- <button
1266
- ref={statusTooltip.ref}
1267
- type="button"
1268
- aria-label={t(STATUS_BUTTON_LABEL_KEY[status.type])}
1269
- aria-describedby={statusTooltip.describedBy}
1270
- onClick={e => e.stopPropagation()}
1271
- {...stylex.props(styles.statusButton)}>
1272
- <Icon
1273
- icon={STATUS_ICON_MAP[status.type]}
1274
- size="sm"
1275
- color={STATUS_ICON_COLOR_MAP[status.type]}
1276
- />
1277
- </button>
1278
- ) : (
1327
+ {/*
1328
+ No wrapper span: Icon's own span already provides the 16px box (`sm`)
1329
+ and the icon color, so the status glyph and the chevron are each
1330
+ directly targetable instead of sharing one untargetable parent — and
1331
+ the two affordances stop sharing a node.
1332
+ */}
1333
+ {showStatusIcon ? (
1334
+ showStatusTooltip ? (
1335
+ <button
1336
+ ref={statusTooltip.ref}
1337
+ type="button"
1338
+ aria-label={t(STATUS_BUTTON_LABEL_KEY[status.type])}
1339
+ aria-describedby={statusTooltip.describedBy}
1340
+ onClick={e => e.stopPropagation()}
1341
+ {...stylex.props(styles.statusButton)}>
1279
1342
  <Icon
1280
1343
  icon={STATUS_ICON_MAP[status.type]}
1281
1344
  size="sm"
1282
1345
  color={STATUS_ICON_COLOR_MAP[status.type]}
1346
+ xstyle={styles.triggerIcon}
1283
1347
  />
1284
- )
1348
+ </button>
1285
1349
  ) : (
1286
1350
  <Icon
1287
- icon="chevronDown"
1351
+ icon={STATUS_ICON_MAP[status.type]}
1288
1352
  size="sm"
1289
- color="inherit"
1290
- // Stable theme target on the chevron glyph itself, so a theme can
1291
- // restyle just this icon (color, size, hover) — and its
1292
- // open/closed state — via `defineTheme`. Same-element rules in
1293
- // @layer astryx-theme win over the icon's own base color/size,
1294
- // which a button-level target could not reach.
1295
- {...themeProps('selector-indicator-icon', {
1296
- state: popover.isOpen ? 'expanded' : 'collapsed',
1297
- })}
1353
+ color={STATUS_ICON_COLOR_MAP[status.type]}
1354
+ xstyle={styles.triggerIcon}
1298
1355
  />
1299
- )}
1300
- </span>
1356
+ )
1357
+ ) : (
1358
+ <Icon
1359
+ icon="chevronDown"
1360
+ size="sm"
1361
+ color="secondary"
1362
+ // The rotation rides on the glyph, alongside the box and color
1363
+ // the wrapper used to provide, so one element carries the mark,
1364
+ // its open/closed transform, and the theme target.
1365
+ xstyle={[
1366
+ styles.triggerIcon,
1367
+ styles.triggerIconRotation,
1368
+ popover.isOpen && styles.triggerIconOpen,
1369
+ ]}
1370
+ // Stable theme target on the chevron glyph itself, so a theme can
1371
+ // restyle just this icon (color, size, hover) — and its
1372
+ // open/closed state — via `defineTheme`. Same-element rules in
1373
+ // @layer astryx-theme win over the icon's own base color/size,
1374
+ // which a button-level target could not reach.
1375
+ {...themeProps('selector-indicator-icon', {
1376
+ state: popover.isOpen ? 'expanded' : 'collapsed',
1377
+ })}
1378
+ />
1379
+ )}
1301
1380
  </div>
1302
1381
 
1303
1382
  {popover.render(
@@ -1309,7 +1388,10 @@ export function Selector<T extends SelectorOptionType>(
1309
1388
  id={listboxId}
1310
1389
  role="listbox"
1311
1390
  aria-labelledby={triggerId}
1312
- {...stylex.props(styles.dropdown)}>
1391
+ {...stylex.props(
1392
+ styles.dropdown,
1393
+ variant !== 'ghost' && styles.dropdownInput,
1394
+ )}>
1313
1395
  {renderOptions()}
1314
1396
  </div>
1315
1397
  </div>
@@ -1321,6 +1403,7 @@ export function Selector<T extends SelectorOptionType>(
1321
1403
  aria-labelledby={triggerId}
1322
1404
  {...stylex.props(
1323
1405
  styles.dropdown,
1406
+ variant !== 'ghost' && styles.dropdownInput,
1324
1407
  !isPositioned && styles.dropdownHidden,
1325
1408
  )}>
1326
1409
  {renderOptions()}