@astryxdesign/core 0.3.0 → 0.4.0-canary.3112e99

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 (594) 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 +3 -0
  16. package/dist/Banner/Banner.d.ts.map +1 -1
  17. package/dist/Banner/Banner.js +32 -17
  18. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  19. package/dist/Breadcrumbs/BreadcrumbItem.js +21 -8
  20. package/dist/Breadcrumbs/index.d.ts +2 -1
  21. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  22. package/dist/Breadcrumbs/index.js +1 -0
  23. package/dist/Button/Button.d.ts.map +1 -1
  24. package/dist/Button/Button.js +12 -16
  25. package/dist/Calendar/Calendar.d.ts.map +1 -1
  26. package/dist/Calendar/Calendar.js +2 -1
  27. package/dist/Calendar/styles.d.ts +0 -2
  28. package/dist/Calendar/styles.d.ts.map +1 -1
  29. package/dist/Calendar/styles.js +0 -2
  30. package/dist/Carousel/Carousel.d.ts.map +1 -1
  31. package/dist/Carousel/Carousel.js +8 -12
  32. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  33. package/dist/Chat/ChatDictationButton.js +2 -1
  34. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  35. package/dist/Chat/ChatLayoutScrollButton.js +3 -1
  36. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  37. package/dist/Chat/ChatSendButton.js +4 -3
  38. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  39. package/dist/Chat/ChatToolCalls.js +17 -17
  40. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  41. package/dist/Chat/useTriggerMenu.js +2 -6
  42. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  43. package/dist/CheckboxInput/CheckboxInput.js +36 -125
  44. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  45. package/dist/ClickableCard/ClickableCard.js +3 -11
  46. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  47. package/dist/CodeBlock/CodeBlock.js +84 -67
  48. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  49. package/dist/Collapsible/Collapsible.js +35 -15
  50. package/dist/CommandPalette/CommandPaletteItem.d.ts +1 -1
  51. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  52. package/dist/CommandPalette/CommandPaletteItem.js +6 -3
  53. package/dist/CommandPalette/CommandPaletteList.js +1 -1
  54. package/dist/ComplexSelector/ComplexSelector.d.ts +1 -1
  55. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  56. package/dist/ComplexSelector/ComplexSelector.js +32 -31
  57. package/dist/ContextMenu/ContextMenu.d.ts +2 -2
  58. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  59. package/dist/ContextMenu/ContextMenu.js +1 -1
  60. package/dist/ContextMenu/index.d.ts +2 -1
  61. package/dist/ContextMenu/index.d.ts.map +1 -1
  62. package/dist/ContextMenu/index.js +1 -0
  63. package/dist/DateInput/DateInput.d.ts +9 -2
  64. package/dist/DateInput/DateInput.d.ts.map +1 -1
  65. package/dist/DateInput/DateInput.js +47 -33
  66. package/dist/DateRangeInput/DateRangeInput.d.ts +9 -2
  67. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  68. package/dist/DateRangeInput/DateRangeInput.js +55 -32
  69. package/dist/DateTimeInput/DateTimeInput.d.ts +9 -1
  70. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  71. package/dist/DateTimeInput/DateTimeInput.js +54 -30
  72. package/dist/Dialog/Dialog.d.ts.map +1 -1
  73. package/dist/Dialog/Dialog.js +4 -4
  74. package/dist/DropdownMenu/DropdownMenu.d.ts +33 -8
  75. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  76. package/dist/DropdownMenu/DropdownMenu.js +62 -20
  77. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +8 -11
  78. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  79. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +32 -31
  80. package/dist/DropdownMenu/DropdownMenuDivider.d.ts +25 -0
  81. package/dist/DropdownMenu/DropdownMenuDivider.d.ts.map +1 -0
  82. package/dist/DropdownMenu/DropdownMenuDivider.js +66 -0
  83. package/dist/DropdownMenu/DropdownMenuItem.d.ts +15 -2
  84. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  85. package/dist/DropdownMenu/DropdownMenuItem.js +20 -8
  86. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -1
  87. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  88. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +10 -3
  89. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +5 -5
  90. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  91. package/dist/DropdownMenu/DropdownMenuRadioItem.js +24 -67
  92. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  93. package/dist/DropdownMenu/DropdownMenuSubMenu.js +2 -8
  94. package/dist/DropdownMenu/index.d.ts +2 -1
  95. package/dist/DropdownMenu/index.d.ts.map +1 -1
  96. package/dist/DropdownMenu/index.js +4 -0
  97. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  98. package/dist/DropdownMenu/renderDropdownItems.js +35 -27
  99. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  100. package/dist/EmptyState/EmptyState.js +9 -5
  101. package/dist/Field/InputClearButton.d.ts +16 -3
  102. package/dist/Field/InputClearButton.d.ts.map +1 -1
  103. package/dist/Field/InputClearButton.js +15 -4
  104. package/dist/FileInput/FileInput.d.ts.map +1 -1
  105. package/dist/FileInput/FileInput.js +21 -10
  106. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  107. package/dist/HoverCard/useHoverCard.js +3 -19
  108. package/dist/Indicator/CheckIndicator.d.ts +25 -0
  109. package/dist/Indicator/CheckIndicator.d.ts.map +1 -0
  110. package/dist/Indicator/CheckIndicator.js +155 -0
  111. package/dist/Indicator/CheckboxIndicator.d.ts +22 -0
  112. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -0
  113. package/dist/Indicator/CheckboxIndicator.js +173 -0
  114. package/dist/Indicator/RadioIndicator.d.ts +23 -0
  115. package/dist/Indicator/RadioIndicator.d.ts.map +1 -0
  116. package/dist/Indicator/RadioIndicator.js +137 -0
  117. package/dist/Indicator/index.d.ts +24 -0
  118. package/dist/Indicator/index.d.ts.map +1 -0
  119. package/dist/Indicator/index.js +26 -0
  120. package/dist/Indicator/indicator.markers.stylex.d.ts +16 -0
  121. package/dist/Indicator/indicator.markers.stylex.d.ts.map +1 -0
  122. package/dist/Indicator/indicator.markers.stylex.js +21 -0
  123. package/dist/Indicator/indicatorRegistry.d.ts +71 -0
  124. package/dist/Indicator/indicatorRegistry.d.ts.map +1 -0
  125. package/dist/Indicator/indicatorRegistry.js +93 -0
  126. package/dist/Indicator/types.d.ts +177 -0
  127. package/dist/Indicator/types.d.ts.map +1 -0
  128. package/dist/Indicator/types.js +1 -0
  129. package/dist/Indicator/useIndicator.d.ts +18 -0
  130. package/dist/Indicator/useIndicator.d.ts.map +1 -0
  131. package/dist/Indicator/useIndicator.js +30 -0
  132. package/dist/Item/Item.d.ts.map +1 -1
  133. package/dist/Item/Item.js +4 -8
  134. package/dist/Layer/useLayer.d.ts +14 -0
  135. package/dist/Layer/useLayer.d.ts.map +1 -1
  136. package/dist/Layer/useLayer.js +25 -2
  137. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  138. package/dist/Lightbox/Lightbox.js +80 -103
  139. package/dist/Link/Link.d.ts.map +1 -1
  140. package/dist/Link/Link.js +4 -5
  141. package/dist/MobileNav/MobileNav.js +8 -8
  142. package/dist/MoreMenu/MoreMenu.d.ts +14 -1
  143. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  144. package/dist/MoreMenu/MoreMenu.js +4 -0
  145. package/dist/MultiSelector/MultiSelector.d.ts +8 -1
  146. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  147. package/dist/MultiSelector/MultiSelector.js +119 -95
  148. package/dist/NumberInput/NumberInput.d.ts +27 -1
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +230 -42
  151. package/dist/Outline/Outline.d.ts.map +1 -1
  152. package/dist/Outline/Outline.js +2 -3
  153. package/dist/Pagination/Pagination.d.ts.map +1 -1
  154. package/dist/Pagination/Pagination.js +61 -63
  155. package/dist/Popover/Popover.d.ts.map +1 -1
  156. package/dist/Popover/Popover.js +6 -8
  157. package/dist/Popover/usePopover.d.ts +15 -0
  158. package/dist/Popover/usePopover.d.ts.map +1 -1
  159. package/dist/Popover/usePopover.js +14 -2
  160. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  161. package/dist/PowerSearch/PowerSearch.js +1 -1
  162. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  163. package/dist/PowerSearch/PowerSearchEditPopover.js +7 -0
  164. package/dist/ProgressBar/ProgressBar.d.ts +11 -4
  165. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  166. package/dist/ProgressBar/ProgressBar.js +95 -6
  167. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  168. package/dist/RadioList/RadioListItem.js +29 -84
  169. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  170. package/dist/Resizable/ResizeHandle.js +2 -3
  171. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  172. package/dist/SegmentedControl/SegmentedControlItem.js +2 -3
  173. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  174. package/dist/SelectableCard/SelectableCard.js +3 -11
  175. package/dist/Selector/Selector.d.ts +12 -1
  176. package/dist/Selector/Selector.d.ts.map +1 -1
  177. package/dist/Selector/Selector.js +222 -111
  178. package/dist/Selector/hooks.d.ts +18 -6
  179. package/dist/Selector/hooks.d.ts.map +1 -1
  180. package/dist/Selector/hooks.js +57 -40
  181. package/dist/SideNav/SideNav.d.ts.map +1 -1
  182. package/dist/SideNav/SideNav.js +1 -1
  183. package/dist/SideNav/SideNavCollapseButton.d.ts +1 -1
  184. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  185. package/dist/SideNav/SideNavCollapseButton.js +29 -14
  186. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  187. package/dist/SideNav/SideNavHeading.js +56 -20
  188. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  189. package/dist/SideNav/SideNavItem.js +28 -22
  190. package/dist/Slider/Slider.d.ts.map +1 -1
  191. package/dist/Slider/Slider.js +2 -6
  192. package/dist/Stack/stack.stylex.d.ts +3 -3
  193. package/dist/Switch/Switch.d.ts.map +1 -1
  194. package/dist/Switch/Switch.js +14 -13
  195. package/dist/TabList/Tab.d.ts.map +1 -1
  196. package/dist/TabList/Tab.js +2 -3
  197. package/dist/TabList/TabMenu.d.ts.map +1 -1
  198. package/dist/TabList/TabMenu.js +41 -19
  199. package/dist/Table/BaseTable.d.ts.map +1 -1
  200. package/dist/Table/BaseTable.js +8 -0
  201. package/dist/Table/TableRow.d.ts +1 -1
  202. package/dist/Table/TableRow.d.ts.map +1 -1
  203. package/dist/Table/TableRow.js +4 -2
  204. package/dist/Table/index.d.ts +1 -1
  205. package/dist/Table/index.d.ts.map +1 -1
  206. package/dist/Table/index.js +1 -1
  207. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +1 -1
  208. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  209. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +22 -18
  210. package/dist/Table/plugins/rowExpansion/index.d.ts +1 -1
  211. package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -1
  212. package/dist/Table/plugins/rowExpansion/index.js +1 -1
  213. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +41 -76
  214. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  215. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +94 -345
  216. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  217. package/dist/Table/plugins/sortable/useTableSortable.js +23 -4
  218. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  219. package/dist/Table/plugins/tree/useTableTreeData.js +29 -33
  220. package/dist/Table/tableContextMenu.d.ts.map +1 -1
  221. package/dist/Table/tableContextMenu.js +2 -1
  222. package/dist/Table/types.d.ts +11 -0
  223. package/dist/Table/types.d.ts.map +1 -1
  224. package/dist/TextArea/TextArea.d.ts +10 -1
  225. package/dist/TextArea/TextArea.d.ts.map +1 -1
  226. package/dist/TextArea/TextArea.js +16 -6
  227. package/dist/TextInput/TextInput.d.ts +10 -1
  228. package/dist/TextInput/TextInput.d.ts.map +1 -1
  229. package/dist/TextInput/TextInput.js +13 -19
  230. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  231. package/dist/Thumbnail/Thumbnail.js +32 -26
  232. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  233. package/dist/TimeInput/TimeInput.js +14 -17
  234. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  235. package/dist/Timestamp/Timestamp.js +14 -3
  236. package/dist/Timestamp/TimestampHoverCard.d.ts.map +1 -1
  237. package/dist/Timestamp/TimestampHoverCard.js +16 -34
  238. package/dist/Timestamp/formatInstant.d.ts +11 -1
  239. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  240. package/dist/Timestamp/formatInstant.js +3 -1
  241. package/dist/Token/Token.d.ts.map +1 -1
  242. package/dist/Token/Token.js +20 -11
  243. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  244. package/dist/Tokenizer/Tokenizer.js +4 -2
  245. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  246. package/dist/Tooltip/useTooltip.js +3 -19
  247. package/dist/TopNav/TopNav.d.ts.map +1 -1
  248. package/dist/TopNav/TopNav.js +6 -5
  249. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  250. package/dist/TopNav/TopNavHeading.js +54 -16
  251. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  252. package/dist/TopNav/TopNavItem.js +3 -9
  253. package/dist/TopNav/TopNavMegaMenu.d.ts +7 -0
  254. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  255. package/dist/TopNav/TopNavMegaMenu.js +146 -60
  256. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMegaMenuItem.js +22 -3
  258. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  259. package/dist/TopNav/TopNavMenu.js +83 -38
  260. package/dist/TreeList/TreeList.d.ts.map +1 -1
  261. package/dist/TreeList/TreeList.js +13 -0
  262. package/dist/TreeList/TreeListBranches.d.ts +1 -1
  263. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  264. package/dist/TreeList/TreeListBranches.js +14 -4
  265. package/dist/TreeList/TreeListItem.d.ts +11 -1
  266. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  267. package/dist/TreeList/TreeListItem.js +57 -30
  268. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  269. package/dist/Typeahead/BaseTypeahead.js +16 -8
  270. package/dist/astryx.css +84 -96
  271. package/dist/astryx.umd.js +56 -56
  272. package/dist/astryx.umd.js.map +4 -4
  273. package/dist/hooks/containerReveal.stylex.d.ts +61 -0
  274. package/dist/hooks/containerReveal.stylex.d.ts.map +1 -0
  275. package/dist/hooks/containerReveal.stylex.js +63 -0
  276. package/dist/hooks/index.d.ts +3 -0
  277. package/dist/hooks/index.d.ts.map +1 -1
  278. package/dist/hooks/index.js +2 -0
  279. package/dist/hooks/useClipboard.d.ts +59 -0
  280. package/dist/hooks/useClipboard.d.ts.map +1 -0
  281. package/dist/hooks/useClipboard.js +106 -0
  282. package/dist/hooks/useContainerReveal.d.ts +14 -8
  283. package/dist/hooks/useContainerReveal.d.ts.map +1 -1
  284. package/dist/hooks/useContainerReveal.js +28 -69
  285. package/dist/hooks/useIndicatorFocusRing.d.ts +28 -0
  286. package/dist/hooks/useIndicatorFocusRing.d.ts.map +1 -0
  287. package/dist/hooks/useIndicatorFocusRing.js +96 -0
  288. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  289. package/dist/hooks/useInputStatusIcon.js +17 -4
  290. package/dist/hooks/useLongPress.d.ts.map +1 -1
  291. package/dist/hooks/useLongPress.js +12 -2
  292. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  293. package/dist/hooks/useScrollLock.js +33 -18
  294. package/dist/hooks/useStreamingText.d.ts +18 -3
  295. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  296. package/dist/hooks/useStreamingText.js +47 -7
  297. package/dist/hooks/useTreeFocus.d.ts.map +1 -1
  298. package/dist/hooks/useTreeFocus.js +9 -3
  299. package/dist/hooks/useTypeahead.d.ts +3 -2
  300. package/dist/hooks/useTypeahead.d.ts.map +1 -1
  301. package/dist/hooks/useTypeahead.js +19 -7
  302. package/dist/index.d.ts +1 -0
  303. package/dist/index.d.ts.map +1 -1
  304. package/dist/index.js +1 -0
  305. package/dist/theme/defineTheme.d.ts +18 -2
  306. package/dist/theme/defineTheme.d.ts.map +1 -1
  307. package/dist/theme/defineTheme.js +10 -1
  308. package/dist/theme/derivedVarRegistry.d.ts +8 -0
  309. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  310. package/dist/theme/derivedVarRegistry.js +14 -13
  311. package/dist/theme/expandColorScale.d.ts +3 -1
  312. package/dist/theme/expandColorScale.d.ts.map +1 -1
  313. package/dist/theme/expandColorScale.js +17 -7
  314. package/dist/theme/expandTypeScale.d.ts.map +1 -1
  315. package/dist/theme/expandTypeScale.js +17 -0
  316. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  317. package/dist/theme/generateThemeRules.js +11 -0
  318. package/dist/theme/index.d.ts +2 -1
  319. package/dist/theme/index.d.ts.map +1 -1
  320. package/dist/theme/index.js +1 -1
  321. package/dist/theme/tokens.stylex.d.ts +12 -0
  322. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  323. package/dist/theme/tokens.stylex.js +23 -0
  324. package/dist/utils/focusOutline.stylex.d.ts +122 -0
  325. package/dist/utils/focusOutline.stylex.d.ts.map +1 -0
  326. package/dist/utils/focusOutline.stylex.js +143 -0
  327. package/dist/utils/focusReturn.d.ts +24 -0
  328. package/dist/utils/focusReturn.d.ts.map +1 -0
  329. package/dist/utils/focusReturn.js +29 -0
  330. package/dist/utils/index.d.ts +2 -0
  331. package/dist/utils/index.d.ts.map +1 -1
  332. package/dist/utils/index.js +6 -1
  333. package/dist/utils/mergeRefs.d.ts.map +1 -1
  334. package/dist/utils/mergeRefs.js +7 -5
  335. package/dist/utils/rtlStyles.d.ts +2 -2
  336. package/dist/utils/rtlStyles.js +2 -2
  337. package/dist/utils/themeProps.d.ts +20 -1
  338. package/dist/utils/themeProps.d.ts.map +1 -1
  339. package/dist/utils/themeProps.js +8 -2
  340. package/locales/en.json +52 -0
  341. package/locales/pseudo.json +39 -0
  342. package/package.json +8 -3
  343. package/src/AlertDialog/AlertDialog.doc.mjs +16 -3
  344. package/src/AlertDialog/AlertDialog.test.tsx +208 -1
  345. package/src/AlertDialog/AlertDialog.tsx +21 -3
  346. package/src/AppShell/AppShell.doc.mjs +11 -0
  347. package/src/AppShell/AppShell.test.tsx +139 -0
  348. package/src/AppShell/AppShell.tsx +32 -22
  349. package/src/AspectRatio/AspectRatio.doc.mjs +27 -3
  350. package/src/AspectRatio/AspectRatio.test.tsx +30 -0
  351. package/src/AspectRatio/AspectRatio.tsx +13 -0
  352. package/src/Avatar/Avatar.doc.mjs +2 -13
  353. package/src/Avatar/Avatar.test.tsx +33 -8
  354. package/src/Avatar/Avatar.tsx +52 -50
  355. package/src/AvatarGroup/AvatarGroupOverflow.tsx +2 -9
  356. package/src/Banner/Banner.test.tsx +58 -1
  357. package/src/Banner/Banner.tsx +33 -11
  358. package/src/Breadcrumbs/BreadcrumbItem.tsx +16 -6
  359. package/src/Breadcrumbs/index.ts +5 -1
  360. package/src/Button/Button.doc.mjs +2 -2
  361. package/src/Button/Button.tsx +22 -41
  362. package/src/Calendar/Calendar.tsx +2 -1
  363. package/src/Calendar/styles.ts +0 -8
  364. package/src/Carousel/Carousel.doc.mjs +3 -0
  365. package/src/Carousel/Carousel.tsx +10 -6
  366. package/src/Chat/Chat.doc.mjs +2 -0
  367. package/src/Chat/ChatDictationButton.tsx +7 -1
  368. package/src/Chat/ChatLayoutScrollButton.test.tsx +22 -0
  369. package/src/Chat/ChatLayoutScrollButton.tsx +8 -1
  370. package/src/Chat/ChatSendButton.tsx +2 -3
  371. package/src/Chat/ChatToolCalls.test.tsx +35 -0
  372. package/src/Chat/ChatToolCalls.tsx +36 -16
  373. package/src/Chat/useTriggerMenu.tsx +2 -5
  374. package/src/CheckboxInput/CheckboxInput.doc.mjs +4 -2
  375. package/src/CheckboxInput/CheckboxInput.test.tsx +120 -0
  376. package/src/CheckboxInput/CheckboxInput.tsx +45 -202
  377. package/src/ClickableCard/ClickableCard.tsx +6 -11
  378. package/src/CodeBlock/CodeBlock.doc.mjs +3 -0
  379. package/src/CodeBlock/CodeBlock.test.tsx +91 -0
  380. package/src/CodeBlock/CodeBlock.tsx +57 -80
  381. package/src/Collapsible/Collapsible.tsx +22 -18
  382. package/src/CommandPalette/CommandPalette.test.tsx +29 -0
  383. package/src/CommandPalette/CommandPaletteItem.tsx +7 -4
  384. package/src/CommandPalette/CommandPaletteList.tsx +2 -2
  385. package/src/ComplexSelector/ComplexSelector.doc.mjs +42 -0
  386. package/src/ComplexSelector/ComplexSelector.test.tsx +73 -0
  387. package/src/ComplexSelector/ComplexSelector.tsx +41 -28
  388. package/src/ContextMenu/ContextMenu.doc.mjs +1 -1
  389. package/src/ContextMenu/ContextMenu.test.tsx +41 -0
  390. package/src/ContextMenu/ContextMenu.tsx +3 -3
  391. package/src/ContextMenu/index.ts +5 -1
  392. package/src/DateInput/DateInput.doc.mjs +18 -3
  393. package/src/DateInput/DateInput.test.tsx +112 -11
  394. package/src/DateInput/DateInput.tsx +44 -25
  395. package/src/DateRangeInput/DateRangeInput.doc.mjs +10 -2
  396. package/src/DateRangeInput/DateRangeInput.test.tsx +110 -14
  397. package/src/DateRangeInput/DateRangeInput.tsx +27 -21
  398. package/src/DateTimeInput/DateTimeInput.doc.mjs +16 -2
  399. package/src/DateTimeInput/DateTimeInput.test.tsx +154 -1
  400. package/src/DateTimeInput/DateTimeInput.tsx +58 -17
  401. package/src/Dialog/Dialog.tsx +2 -9
  402. package/src/DropdownMenu/DropdownMenu.doc.mjs +5 -9
  403. package/src/DropdownMenu/DropdownMenu.test.tsx +534 -4
  404. package/src/DropdownMenu/DropdownMenu.tsx +113 -52
  405. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +27 -30
  406. package/src/DropdownMenu/DropdownMenuDivider.doc.mjs +34 -0
  407. package/src/DropdownMenu/DropdownMenuDivider.tsx +81 -0
  408. package/src/DropdownMenu/DropdownMenuItem.doc.mjs +39 -4
  409. package/src/DropdownMenu/DropdownMenuItem.tsx +48 -10
  410. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +2 -1
  411. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +30 -76
  412. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +25 -19
  413. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +44 -14
  414. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +1 -5
  415. package/src/DropdownMenu/index.ts +8 -1
  416. package/src/DropdownMenu/renderDropdownItems.tsx +33 -34
  417. package/src/EmptyState/EmptyState.doc.mjs +4 -0
  418. package/src/EmptyState/EmptyState.test.tsx +62 -0
  419. package/src/EmptyState/EmptyState.tsx +16 -6
  420. package/src/Field/Field.doc.mjs +1 -0
  421. package/src/Field/InputClearButton.test.tsx +117 -0
  422. package/src/Field/InputClearButton.tsx +30 -3
  423. package/src/FileInput/FileInput.tsx +21 -8
  424. package/src/HoverCard/useHoverCard.tsx +2 -23
  425. package/src/Icon/Icon.doc.mjs +2 -1
  426. package/src/Indicator/CheckIndicator.tsx +174 -0
  427. package/src/Indicator/CheckboxIndicator.tsx +257 -0
  428. package/src/Indicator/Indicator.doc.mjs +344 -0
  429. package/src/Indicator/Indicator.test.tsx +393 -0
  430. package/src/Indicator/RadioIndicator.tsx +206 -0
  431. package/src/Indicator/index.ts +46 -0
  432. package/src/Indicator/indicator.markers.stylex.ts +19 -0
  433. package/src/Indicator/indicatorRegistry.test.tsx +106 -0
  434. package/src/Indicator/indicatorRegistry.ts +120 -0
  435. package/src/Indicator/types.ts +197 -0
  436. package/src/Indicator/useIndicator.ts +39 -0
  437. package/src/Item/Item.doc.mjs +1 -1
  438. package/src/Item/Item.tsx +7 -14
  439. package/src/Layer/useLayer.doc.mjs +2 -2
  440. package/src/Layer/useLayer.test.tsx +85 -0
  441. package/src/Layer/useLayer.tsx +39 -1
  442. package/src/Lightbox/Lightbox.doc.mjs +1 -1
  443. package/src/Lightbox/Lightbox.tsx +45 -49
  444. package/src/Link/Link.tsx +4 -11
  445. package/src/MobileNav/MobileNav.tsx +3 -3
  446. package/src/MoreMenu/MoreMenu.doc.mjs +31 -0
  447. package/src/MoreMenu/MoreMenu.test.tsx +68 -1
  448. package/src/MoreMenu/MoreMenu.tsx +19 -0
  449. package/src/MultiSelector/MultiSelector.doc.mjs +16 -1
  450. package/src/MultiSelector/MultiSelector.test.tsx +259 -16
  451. package/src/MultiSelector/MultiSelector.tsx +144 -121
  452. package/src/NumberInput/NumberInput.doc.mjs +265 -50
  453. package/src/NumberInput/NumberInput.test.tsx +726 -21
  454. package/src/NumberInput/NumberInput.tsx +353 -59
  455. package/src/Outline/Outline.tsx +2 -5
  456. package/src/Pagination/Pagination.doc.mjs +1 -1
  457. package/src/Pagination/Pagination.test.tsx +22 -7
  458. package/src/Pagination/Pagination.tsx +38 -35
  459. package/src/Popover/Popover.doc.mjs +2 -0
  460. package/src/Popover/Popover.tsx +6 -7
  461. package/src/Popover/usePopover.tsx +37 -4
  462. package/src/PowerSearch/PowerSearch.tsx +1 -1
  463. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +42 -0
  464. package/src/PowerSearch/PowerSearchEditPopover.tsx +7 -0
  465. package/src/ProgressBar/ProgressBar.doc.mjs +27 -5
  466. package/src/ProgressBar/ProgressBar.test.tsx +224 -1
  467. package/src/ProgressBar/ProgressBar.tsx +126 -30
  468. package/src/RadioList/RadioList.doc.mjs +4 -2
  469. package/src/RadioList/RadioListItem.tsx +31 -130
  470. package/src/Resizable/ResizeHandle.tsx +2 -9
  471. package/src/SegmentedControl/SegmentedControlItem.tsx +2 -9
  472. package/src/SelectableCard/SelectableCard.tsx +4 -9
  473. package/src/Selector/Selector.doc.mjs +15 -4
  474. package/src/Selector/Selector.test.tsx +1234 -98
  475. package/src/Selector/Selector.tsx +254 -126
  476. package/src/Selector/hooks.ts +77 -50
  477. package/src/SideNav/SideNav.test.tsx +46 -0
  478. package/src/SideNav/SideNav.tsx +1 -0
  479. package/src/SideNav/SideNavCollapseButton.tsx +15 -10
  480. package/src/SideNav/SideNavHeading.tsx +48 -10
  481. package/src/SideNav/SideNavItem.tsx +20 -12
  482. package/src/Slider/Slider.tsx +2 -11
  483. package/src/Stack/Stack.doc.mjs +110 -0
  484. package/src/StatusDot/StatusDot.doc.mjs +12 -3
  485. package/src/Switch/Switch.test.tsx +32 -0
  486. package/src/Switch/Switch.tsx +18 -10
  487. package/src/TabList/Tab.tsx +2 -9
  488. package/src/TabList/TabMenu.tsx +14 -21
  489. package/src/Table/BaseTable.tsx +11 -0
  490. package/src/Table/Table.test.tsx +31 -0
  491. package/src/Table/TableRow.tsx +6 -0
  492. package/src/Table/index.ts +1 -4
  493. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +30 -14
  494. package/src/Table/plugins/rowExpansion/index.ts +1 -4
  495. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +125 -175
  496. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +115 -458
  497. package/src/Table/plugins/sortable/useTableSortable.tsx +2 -6
  498. package/src/Table/plugins/tree/useTableTreeData.tsx +43 -24
  499. package/src/Table/tableContextMenu.test.tsx +27 -0
  500. package/src/Table/tableContextMenu.tsx +1 -0
  501. package/src/Table/types.ts +11 -0
  502. package/src/Table/useTableGroupedRows.doc.mjs +1 -1
  503. package/src/Table/useTableRowExpansion.doc.mjs +43 -66
  504. package/src/TextArea/TextArea.doc.mjs +42 -2
  505. package/src/TextArea/TextArea.test.tsx +219 -0
  506. package/src/TextArea/TextArea.tsx +34 -7
  507. package/src/TextInput/TextInput.doc.mjs +18 -2
  508. package/src/TextInput/TextInput.test.tsx +189 -0
  509. package/src/TextInput/TextInput.tsx +25 -31
  510. package/src/Thumbnail/Thumbnail.tsx +2 -9
  511. package/src/TimeInput/TimeInput.doc.mjs +2 -2
  512. package/src/TimeInput/TimeInput.test.tsx +84 -3
  513. package/src/TimeInput/TimeInput.tsx +26 -28
  514. package/src/Timestamp/Timestamp.doc.mjs +4 -3
  515. package/src/Timestamp/Timestamp.test.tsx +91 -14
  516. package/src/Timestamp/Timestamp.tsx +14 -2
  517. package/src/Timestamp/TimestampHoverCard.tsx +13 -35
  518. package/src/Timestamp/formatInstant.ts +16 -1
  519. package/src/Token/Token.tsx +5 -28
  520. package/src/Tokenizer/Tokenizer.doc.mjs +2 -2
  521. package/src/Tokenizer/Tokenizer.test.tsx +45 -3
  522. package/src/Tokenizer/Tokenizer.tsx +10 -2
  523. package/src/Tooltip/useTooltip.tsx +2 -23
  524. package/src/TopNav/TopNav.tsx +1 -3
  525. package/src/TopNav/TopNavHeading.tsx +42 -13
  526. package/src/TopNav/TopNavItem.tsx +3 -21
  527. package/src/TopNav/TopNavMegaMenu.doc.mjs +5 -0
  528. package/src/TopNav/TopNavMegaMenu.test.tsx +433 -33
  529. package/src/TopNav/TopNavMegaMenu.tsx +118 -53
  530. package/src/TopNav/TopNavMegaMenuItem.tsx +2 -9
  531. package/src/TopNav/TopNavMenu.tsx +34 -37
  532. package/src/TreeList/TreeList.doc.mjs +5 -0
  533. package/src/TreeList/TreeList.test.tsx +208 -8
  534. package/src/TreeList/TreeList.tsx +22 -0
  535. package/src/TreeList/TreeListBranches.tsx +25 -2
  536. package/src/TreeList/TreeListItem.tsx +89 -52
  537. package/src/Typeahead/BaseTypeahead.tsx +19 -6
  538. package/src/Typeahead/Typeahead.doc.mjs +1 -0
  539. package/src/Typeahead/Typeahead.test.tsx +76 -3
  540. package/src/hooks/containerReveal.stylex.ts +102 -0
  541. package/src/hooks/index.ts +4 -0
  542. package/src/hooks/useClipboard.doc.mjs +87 -0
  543. package/src/hooks/useClipboard.test.tsx +151 -0
  544. package/src/hooks/useClipboard.ts +135 -0
  545. package/src/hooks/useContainerReveal.doc.mjs +7 -7
  546. package/src/hooks/useContainerReveal.test.tsx +42 -62
  547. package/src/hooks/useContainerReveal.ts +36 -91
  548. package/src/hooks/useImageMode.test.ts +1 -1
  549. package/src/hooks/useIndicatorFocusRing.tsx +120 -0
  550. package/src/hooks/useInputStatusIcon.tsx +8 -8
  551. package/src/hooks/useLongPress.test.tsx +18 -0
  552. package/src/hooks/useLongPress.ts +12 -2
  553. package/src/hooks/useScrollLock.test.ts +72 -0
  554. package/src/hooks/useScrollLock.ts +51 -19
  555. package/src/hooks/useStreamingText.test.ts +46 -1
  556. package/src/hooks/useStreamingText.ts +49 -7
  557. package/src/hooks/useTreeFocus.test.tsx +50 -0
  558. package/src/hooks/useTreeFocus.ts +14 -3
  559. package/src/hooks/useTypeahead.test.tsx +150 -0
  560. package/src/hooks/useTypeahead.ts +24 -9
  561. package/src/i18n/InternationalizationProvider.doc.mjs +7 -2
  562. package/src/index.ts +1 -0
  563. package/src/theme/defineTheme.ts +27 -0
  564. package/src/theme/derivedVarRegistry.test.ts +21 -1
  565. package/src/theme/derivedVarRegistry.ts +19 -6
  566. package/src/theme/expandColorScale.test.ts +14 -0
  567. package/src/theme/expandColorScale.ts +24 -9
  568. package/src/theme/expandTypeScale.test.ts +43 -0
  569. package/src/theme/expandTypeScale.ts +17 -0
  570. package/src/theme/generateThemeRules.test.ts +78 -20
  571. package/src/theme/generateThemeRules.ts +11 -0
  572. package/src/theme/index.ts +15 -0
  573. package/src/theme/tokens.stylex.ts +18 -0
  574. package/src/theme/tokens.test.ts +37 -0
  575. package/src/utils/focusOutline.stylex.ts +177 -0
  576. package/src/utils/focusReturn.test.ts +42 -0
  577. package/src/utils/focusReturn.ts +31 -0
  578. package/src/utils/index.ts +5 -0
  579. package/src/utils/mergeRefs.test.ts +48 -0
  580. package/src/utils/mergeRefs.ts +12 -6
  581. package/src/utils/rtlStyles.ts +2 -2
  582. package/src/utils/themeProps.ts +26 -4
  583. package/dist/CheckboxInput/checkbox.markers.stylex.d.ts +0 -9
  584. package/dist/CheckboxInput/checkbox.markers.stylex.d.ts.map +0 -1
  585. package/dist/CheckboxInput/checkbox.markers.stylex.js +0 -14
  586. package/dist/RadioList/radio.markers.stylex.d.ts +0 -7
  587. package/dist/RadioList/radio.markers.stylex.d.ts.map +0 -1
  588. package/dist/RadioList/radio.markers.stylex.js +0 -12
  589. package/dist/hooks/containerReveal.pool.stylex.d.ts +0 -303
  590. package/dist/hooks/containerReveal.pool.stylex.d.ts.map +0 -1
  591. package/dist/hooks/containerReveal.pool.stylex.js +0 -292
  592. package/src/CheckboxInput/checkbox.markers.stylex.ts +0 -12
  593. package/src/RadioList/radio.markers.stylex.ts +0 -10
  594. 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,12 @@ 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';
36
+ import type {IndicatorPosition} from '../Indicator';
34
37
  import type {IconName} from '../Icon';
35
38
  import {
36
39
  Field,
40
+ InputClearButton,
37
41
  inputStatusBorderStyles,
38
42
  inputStatusHoverShadowStyles,
39
43
  inputWrapperStyles,
@@ -66,12 +70,15 @@ import {
66
70
  getSelectableOptions,
67
71
  } from './utils';
68
72
  import {useCombobox, useSelectedItemOffset} from './hooks';
73
+ import {useTypeahead} from '../hooks/useTypeahead';
69
74
  import {SelectorOption} from './SelectorOption';
70
75
  import {getInputARIA, mergeProps} from '../utils';
71
76
  import {useSize} from '../SizeContext/SizeContext';
72
77
  import type {BaseProps} from '../BaseProps';
73
78
  import type {SizeValue} from '../utils/types';
74
79
  import {themeProps} from '../utils/themeProps';
80
+ import {focusOutlineStyles} from '../utils/focusOutline.stylex';
81
+ import {stableClassName} from '../naming';
75
82
  import {groupStyles} from '../InputGroup/groupStyles';
76
83
  import {useInputGroup} from '../InputGroup/InputGroupContext';
77
84
  import {VisuallyHidden} from '../VisuallyHidden';
@@ -134,26 +141,27 @@ const styles = stylex.create({
134
141
  whiteSpace: 'nowrap',
135
142
  textAlign: 'start',
136
143
  },
144
+ // Only what Icon does not already provide: `size="sm"` gives the 16px box
145
+ // and `color` the token, but the glyph still must not shrink inside the flex
146
+ // trigger.
137
147
  triggerIcon: {
138
148
  flexShrink: 0,
139
- display: 'flex',
140
- alignItems: 'center',
141
- justifyContent: 'center',
142
- width: 16,
143
- height: 16,
149
+ },
150
+ // Rotation lives on the chevron glyph itself (passed through `xstyle`), not
151
+ // on the layout wrapper above, so the icon's `selector-indicator-icon` theme
152
+ // target and the open/closed transform sit on one element — a theme can
153
+ // restyle the mark and its rotation through a single selector. The wrapper
154
+ // keeps only layout. The status branch renders a different icon, so it never
155
+ // picks these up and needs no transition opt-out.
156
+ triggerIconRotation: {
144
157
  transitionProperty: 'transform',
145
158
  transitionDuration: durationVars['--duration-fast'],
146
159
  transitionTimingFunction: easeVars['--ease-standard'],
147
160
  transformOrigin: 'center',
148
- color: colorVars['--color-icon-secondary'],
149
161
  },
150
162
  triggerIconOpen: {
151
163
  transform: 'rotate(180deg)',
152
164
  },
153
- triggerIconStatus: {
154
- // Disable rotation transition for status icons
155
- transition: 'none',
156
- },
157
165
  triggerGhost: {
158
166
  width: 'auto',
159
167
  borderWidth: 0,
@@ -173,14 +181,6 @@ const styles = stylex.create({
173
181
  ':focus-within': 'none',
174
182
  },
175
183
  fontWeight: fontWeightVars['--font-weight-medium'],
176
- outline: {
177
- default: 'none',
178
- ':has(:focus-visible)': `2px solid ${colorVars['--color-accent']}`,
179
- },
180
- outlineOffset: {
181
- default: '0',
182
- ':has(:focus-visible)': '3px',
183
- },
184
184
  transitionProperty:
185
185
  'background-image, background-color, color, opacity, transform',
186
186
  transform: {
@@ -197,23 +197,6 @@ const styles = stylex.create({
197
197
  },
198
198
 
199
199
  // 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
200
  statusButton: {
218
201
  display: 'flex',
219
202
  alignItems: 'center',
@@ -226,11 +209,6 @@ const styles = stylex.create({
226
209
  color: 'inherit',
227
210
  cursor: 'pointer',
228
211
  borderRadius: radiusVars['--radius-element'],
229
- outline: {
230
- default: 'none',
231
- ':focus-visible': `${borderVars['--border-width']} solid ${colorVars['--color-accent']}`,
232
- },
233
- outlineOffset: 1,
234
212
  },
235
213
 
236
214
  // Dropdown container
@@ -238,10 +216,16 @@ const styles = stylex.create({
238
216
  boxSizing: 'border-box',
239
217
  maxHeight: '300px',
240
218
  overflowY: 'auto',
241
- padding: spacingVars['--spacing-1'],
219
+ paddingBlock: spacingVars['--spacing-1'],
220
+ paddingInline: spacingVars['--spacing-1'],
242
221
  opacity: 1,
243
222
  transition: `opacity ${durationVars['--duration-fast']}`,
244
223
  },
224
+ dropdownInput: {
225
+ // The input trigger's text inset includes its border. Mirror that extra
226
+ // pixel in the menu; the borderless ghost variant needs no correction.
227
+ paddingInline: `calc(${spacingVars['--spacing-1']} + ${borderVars['--border-width']})`,
228
+ },
245
229
  dropdownHidden: {
246
230
  opacity: 0,
247
231
  transition: 'none',
@@ -306,6 +290,19 @@ const styles = stylex.create({
306
290
  flex: 1,
307
291
  minWidth: 0,
308
292
  },
293
+ // The mark's column, reserved on every row and at either position, so a row
294
+ // occupies the same geometry whether or not it is the chosen one — the
295
+ // default check draws nothing when unchecked, and without the column a list
296
+ // would indent (or truncate) its chosen row differently from the rest.
297
+ // `minWidth` rather than `width`: a theme can replace `check` with a larger
298
+ // indicator (a radio is 20px at `sm`), and the column has to grow with it.
299
+ itemMarkColumn: {
300
+ display: 'inline-flex',
301
+ alignItems: 'center',
302
+ justifyContent: 'center',
303
+ flexShrink: 0,
304
+ minWidth: '1rem',
305
+ },
309
306
  itemCheckmark: {
310
307
  flexShrink: 0,
311
308
  width: 16,
@@ -523,6 +520,16 @@ interface SelectorPropsBase<
523
520
  */
524
521
  renderOption?: (option: SelectorOptionData) => ReactNode;
525
522
 
523
+ /**
524
+ * Which edge of the option row carries the selected mark. `start` reserves a
525
+ * mark column ahead of every label so they stay aligned, the way a native
526
+ * menu does; `end` is the house convention shared with Typeahead and
527
+ * CommandPalette.
528
+ *
529
+ * @default 'end'
530
+ */
531
+ indicatorPosition?: IndicatorPosition;
532
+
526
533
  /**
527
534
  * Whether to show a search input for filtering options.
528
535
  * @default false
@@ -673,6 +680,7 @@ export function Selector<T extends SelectorOptionType>(
673
680
  startIcon,
674
681
  htmlName,
675
682
  renderOption,
683
+ indicatorPosition = 'end',
676
684
  hasSearch = false,
677
685
  searchPlaceholder: searchPlaceholderFromProps,
678
686
  placement,
@@ -703,6 +711,9 @@ export function Selector<T extends SelectorOptionType>(
703
711
  const statusMessageId = useId();
704
712
  const inputLabelId = useId();
705
713
  const searchId = useId();
714
+ // Measure from the same outer control that usePopover anchors to; using the
715
+ // shorter inner button makes every size's selected row land too low.
716
+ const anchorRef = useRef<HTMLDivElement>(null);
706
717
  const triggerRef = useRef<HTMLButtonElement>(null);
707
718
  const searchRef = useRef<HTMLInputElement>(null);
708
719
  const inputGroup = useInputGroup();
@@ -715,6 +726,7 @@ export function Selector<T extends SelectorOptionType>(
715
726
  const [, startTransition] = useTransition();
716
727
  const [optimisticValue, setOptimisticValue] = useOptimistic(normalizedValue);
717
728
  const isBusy = isLoading || optimisticValue !== normalizedValue;
729
+ const announce = useAnnounce();
718
730
 
719
731
  // Disabled-reason tooltip. Disabled controls swallow pointer events, so the
720
732
  // tooltip listeners attach to the trigger container (which already exists)
@@ -775,15 +787,15 @@ export function Selector<T extends SelectorOptionType>(
775
787
  // Ref for listbox to measure selected item position
776
788
  const listboxRef = useRef<HTMLDivElement>(null);
777
789
 
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();
790
+ // Typeahead is defined below (it needs the popover), but closing and clearing
791
+ // must drop its pending buffer — otherwise a stale prefix survives the reset
792
+ // window and poisons the next keystroke ("Dog" then "c" would search "dc").
793
+ const resetTypeaheadRef = useRef<() => void>(() => {});
783
794
 
784
795
  // Layer for dropdown positioning
785
796
  const handleLayerHide = useCallback(() => {
786
797
  setSearchQuery('');
798
+ resetTypeaheadRef.current();
787
799
  // Clear any lingering result count when the popover closes so stale status
788
800
  // text does not linger in the a11y tree.
789
801
  announce('');
@@ -798,6 +810,9 @@ export function Selector<T extends SelectorOptionType>(
798
810
  // The popup's own role="listbox" is the exposed semantics; the trigger
799
811
  // keeps DOM focus, so wrapping it in a modal dialog would misrepresent it.
800
812
  role: 'none',
813
+ // The theme target belongs on the SURFACE that paints the popup, which
814
+ // `usePopover` owns — not on the scrolling list inside it.
815
+ surfaceTarget: 'selector-popup',
801
816
  });
802
817
 
803
818
  // Open dropdown on mount when isDefaultOpen is true
@@ -840,7 +855,7 @@ export function Selector<T extends SelectorOptionType>(
840
855
  selectedItemIndex,
841
856
  listboxId,
842
857
  listboxRef,
843
- triggerRef,
858
+ anchorRef,
844
859
  });
845
860
 
846
861
  const selectedItemOffset = shouldOverlaySelectedItem ? rawOffset : 0;
@@ -854,6 +869,7 @@ export function Selector<T extends SelectorOptionType>(
854
869
  // Clear the current value. Shared by the clear button and the keyboard
855
870
  // Delete/Backspace path so clearing is reachable without a mouse.
856
871
  const clearValue = useCallback(() => {
872
+ resetTypeaheadRef.current();
857
873
  onChange?.(null);
858
874
  if (changeAction) {
859
875
  startTransition(async () => {
@@ -863,10 +879,29 @@ export function Selector<T extends SelectorOptionType>(
863
879
  }
864
880
  }, [onChange, changeAction, startTransition, setOptimisticValue]);
865
881
 
866
- // Selector behavior (keyboard nav, typeahead, selection)
882
+ // Type-to-find appends to the query rather than replacing it: characters
883
+ // typed before focus reaches the search input must not be dropped.
884
+ const appendSearchQuery = useCallback((char: string) => {
885
+ setSearchQuery(query => query + char);
886
+ }, []);
887
+
888
+ const commitValue = useCallback(
889
+ (newValue: string) => {
890
+ onChange?.(newValue);
891
+ if (changeAction) {
892
+ startTransition(async () => {
893
+ setOptimisticValue(newValue);
894
+ await changeAction(newValue);
895
+ });
896
+ }
897
+ },
898
+ [onChange, changeAction, startTransition, setOptimisticValue],
899
+ );
900
+
901
+ // Selector behavior (keyboard nav, selection)
867
902
  const {
868
903
  highlightedIndex,
869
- setHighlightedIndex: _setHighlightedIndex,
904
+ setHighlightedIndex,
870
905
  getItemId,
871
906
  onTriggerClick,
872
907
  onKeyDown,
@@ -874,7 +909,11 @@ export function Selector<T extends SelectorOptionType>(
874
909
  onItemMouseEnter,
875
910
  } = useCombobox({
876
911
  selectableItems: filteredItems,
877
- value: normalizedValue,
912
+ // The optimistic value, not the raw prop: with a pending changeAction the
913
+ // prop still holds the old selection, so the popup would open with the
914
+ // highlight on it and Delete/Backspace could clear a value the action has
915
+ // already replaced.
916
+ value: optimisticValue,
878
917
  isDisabled,
879
918
  isOpen: popover.isOpen,
880
919
  hasSearch,
@@ -882,27 +921,61 @@ export function Selector<T extends SelectorOptionType>(
882
921
  popover.show();
883
922
  if (hasSearch) {
884
923
  requestAnimationFrame(() => {
885
- searchRef.current?.focus();
924
+ const input = searchRef.current;
925
+ if (input) {
926
+ input.focus();
927
+ // When typing seeded the query, place the caret after it so the
928
+ // user keeps typing where they left off.
929
+ input.setSelectionRange(input.value.length, input.value.length);
930
+ }
886
931
  });
887
932
  }
888
933
  }, [popover, hasSearch]),
889
934
  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
- ),
935
+ onSelect: commitValue,
902
936
  onClear: hasClear ? clearValue : undefined,
937
+ onSearchSeed: appendSearchQuery,
903
938
  listboxId,
904
939
  });
905
940
 
941
+ // Type-to-select, shared with the other collections (menus, listboxes).
942
+ // Open, it walks the highlight — aria-activedescendant announces each match.
943
+ // Closed, it commits the match like a native select, which changes the value
944
+ // without opening the popup or moving focus, so nothing else would prompt
945
+ // assistive tech to re-read the trigger: announce it explicitly.
946
+ const typeahead = useTypeahead({
947
+ getItemLabels: () => selectableItems.map(item => item.label ?? item.value),
948
+ isDisabled: index => selectableItems[index]?.disabled === true,
949
+ // Cycle onward from the highlight when open, from the committed selection
950
+ // when closed — the optimistic one, so a pending changeAction cannot strand
951
+ // cycling on the first match. -1 means nothing is selected or highlighted,
952
+ // which the hook reads as "search from the top".
953
+ getCurrentIndex: () =>
954
+ popover.isOpen ? highlightedIndex : selectedItemIndex,
955
+ onMatch: index => {
956
+ const item = selectableItems[index];
957
+ if (popover.isOpen) {
958
+ setHighlightedIndex(index);
959
+ } else if (item.value !== optimisticValue) {
960
+ commitValue(item.value);
961
+ announce(item.label ?? item.value);
962
+ }
963
+ },
964
+ });
965
+ resetTypeaheadRef.current = typeahead.reset;
966
+
967
+ const handleTriggerKeyDown = useCallback(
968
+ (e: React.KeyboardEvent) => {
969
+ // With hasSearch the query input owns typing, so type-to-select is off.
970
+ if (!isDisabled && !hasSearch && typeahead.onKeyDown(e)) {
971
+ e.preventDefault();
972
+ return;
973
+ }
974
+ onKeyDown(e);
975
+ },
976
+ [isDisabled, hasSearch, typeahead, onKeyDown],
977
+ );
978
+
906
979
  // Keep the highlighted option visible during keyboard navigation. The
907
980
  // listbox is a fixed-height scroll container, so without this the virtual
908
981
  // cursor walks off-screen once navigation passes the visible window. Mirrors
@@ -1020,12 +1093,56 @@ export function Selector<T extends SelectorOptionType>(
1020
1093
  t,
1021
1094
  ]);
1022
1095
 
1096
+ // The single-selection mark, resolved from the theme once per render. A
1097
+ // theme that maps `check` to another indicator (a radio, say) changes every
1098
+ // selected-option mark in the app through this one lookup.
1099
+ const SelectionMark = useIndicator('check');
1100
+
1023
1101
  // Render an individual item
1024
1102
  const renderItem = useCallback(
1025
1103
  (item: SelectorOptionData, flatIndex: number) => {
1026
1104
  const isHighlighted = flatIndex === highlightedIndex;
1027
1105
  const isSelected = item.value === normalizedValue;
1028
1106
 
1107
+ /*
1108
+ * Rendered UNCONDITIONALLY, with the state passed down: the default
1109
+ * check draws nothing when unchecked, but a theme that replaces the
1110
+ * `check` indicator with a radio needs the unselected state to draw
1111
+ * its empty circle. `{isSelected && …}` would make that impossible.
1112
+ *
1113
+ * `selector-check` stays the stable target for the mark's position
1114
+ * in the row; the indicator owns what the mark looks like.
1115
+ */
1116
+ const mark = (
1117
+ <span {...stylex.props(styles.itemMarkColumn)}>
1118
+ <SelectionMark
1119
+ state={isSelected ? 'checked' : 'unchecked'}
1120
+ size="sm"
1121
+ isDisabled={item.disabled ?? false}
1122
+ {...themeProps('selector-check')}
1123
+ />
1124
+ </span>
1125
+ );
1126
+
1127
+ const optionContent = (
1128
+ <span {...stylex.props(styles.itemContent)}>
1129
+ {renderOption ? renderOption(item) : <DefaultOption option={item} />}
1130
+ </span>
1131
+ );
1132
+
1133
+ const content =
1134
+ indicatorPosition === 'start' ? (
1135
+ <>
1136
+ {mark}
1137
+ {optionContent}
1138
+ </>
1139
+ ) : (
1140
+ <>
1141
+ {optionContent}
1142
+ {mark}
1143
+ </>
1144
+ );
1145
+
1029
1146
  return (
1030
1147
  <div
1031
1148
  key={item.value}
@@ -1042,25 +1159,20 @@ export function Selector<T extends SelectorOptionType>(
1042
1159
  isSelected && styles.itemSelected,
1043
1160
  item.disabled && styles.itemDisabled,
1044
1161
  )}>
1045
- <span {...stylex.props(styles.itemContent)}>
1046
- {renderOption ? (
1047
- renderOption(item)
1048
- ) : (
1049
- <DefaultOption option={item} />
1050
- )}
1051
- </span>
1052
- {isSelected && <Icon icon="check" size="sm" color="accent" />}
1162
+ {content}
1053
1163
  </div>
1054
1164
  );
1055
1165
  },
1056
1166
  [
1057
1167
  renderOption,
1168
+ indicatorPosition,
1058
1169
  highlightedIndex,
1059
1170
  size,
1060
1171
  normalizedValue,
1061
1172
  getItemId,
1062
1173
  onItemSelect,
1063
1174
  onItemMouseEnter,
1175
+ SelectionMark,
1064
1176
  ],
1065
1177
  );
1066
1178
 
@@ -1078,7 +1190,10 @@ export function Selector<T extends SelectorOptionType>(
1078
1190
  <div
1079
1191
  key="empty"
1080
1192
  role="presentation"
1081
- {...stylex.props(styles.emptyState)}>
1193
+ {...mergeProps(
1194
+ themeProps('selector-empty-state'),
1195
+ stylex.props(styles.emptyState),
1196
+ )}>
1082
1197
  No results found
1083
1198
  </div>,
1084
1199
  ];
@@ -1150,6 +1265,7 @@ export function Selector<T extends SelectorOptionType>(
1150
1265
  <>
1151
1266
  <div
1152
1267
  ref={el => {
1268
+ anchorRef.current = el;
1153
1269
  popover.triggerRef(el);
1154
1270
  // Anchor + hover/focus listeners for the disabled-message tooltip.
1155
1271
  // Handlers are gated internally by isEnabled, and anchor names
@@ -1163,12 +1279,14 @@ export function Selector<T extends SelectorOptionType>(
1163
1279
  variant,
1164
1280
  size,
1165
1281
  status: status?.type ?? null,
1282
+ disabled: isDisabled ? 'disabled' : null,
1166
1283
  }),
1167
1284
  stylex.props(
1168
1285
  inputWrapperStyles.base,
1169
1286
  styles.triggerContainer,
1170
1287
  sizeStyles[size],
1171
1288
  variant === 'ghost' && styles.triggerGhost,
1289
+ variant === 'ghost' && focusOutlineStyles.focusWithin,
1172
1290
  isDisabled && inputWrapperStyles.disabled,
1173
1291
  variant === 'ghost' && isDisabled && styles.triggerGhostDisabled,
1174
1292
  !selectedItem && styles.triggerPlaceholder,
@@ -1217,7 +1335,7 @@ export function Selector<T extends SelectorOptionType>(
1217
1335
  // still blocked by the isDisabled guards in useCombobox.
1218
1336
  disabled={isDisabled && !showsDisabledMessage}
1219
1337
  aria-disabled={showsDisabledMessage ? 'true' : undefined}
1220
- onKeyDown={onKeyDown}
1338
+ onKeyDown={handleTriggerKeyDown}
1221
1339
  tabIndex={isDisabled && !showsDisabledMessage ? -1 : 0}
1222
1340
  {...stylex.props(styles.trigger)}>
1223
1341
  <span {...stylex.props(styles.triggerLabel)}>
@@ -1236,68 +1354,68 @@ export function Selector<T extends SelectorOptionType>(
1236
1354
  )}
1237
1355
  {isBusy && <Spinner size="sm" />}
1238
1356
  {hasClear && value != null && !isDisabled && (
1239
- <button
1240
- type="button"
1357
+ <InputClearButton
1358
+ label={t('@astryx.selector.clearLabel', {label})}
1241
1359
  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>
1360
+ iconClassName={stableClassName('selector-clear-icon')}
1361
+ />
1256
1362
  )}
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
- ) : (
1363
+ {/*
1364
+ No wrapper span: Icon's own span already provides the 16px box (`sm`)
1365
+ and the icon color, so the status glyph and the chevron are each
1366
+ directly targetable instead of sharing one untargetable parent — and
1367
+ the two affordances stop sharing a node.
1368
+ */}
1369
+ {showStatusIcon ? (
1370
+ showStatusTooltip ? (
1371
+ <button
1372
+ ref={statusTooltip.ref}
1373
+ type="button"
1374
+ aria-label={t(STATUS_BUTTON_LABEL_KEY[status.type])}
1375
+ aria-describedby={statusTooltip.describedBy}
1376
+ onClick={e => e.stopPropagation()}
1377
+ {...stylex.props(
1378
+ focusOutlineStyles.focusVisible,
1379
+ styles.statusButton,
1380
+ )}>
1279
1381
  <Icon
1280
1382
  icon={STATUS_ICON_MAP[status.type]}
1281
1383
  size="sm"
1282
1384
  color={STATUS_ICON_COLOR_MAP[status.type]}
1385
+ xstyle={styles.triggerIcon}
1283
1386
  />
1284
- )
1387
+ </button>
1285
1388
  ) : (
1286
1389
  <Icon
1287
- icon="chevronDown"
1390
+ icon={STATUS_ICON_MAP[status.type]}
1288
1391
  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
- })}
1392
+ color={STATUS_ICON_COLOR_MAP[status.type]}
1393
+ xstyle={styles.triggerIcon}
1298
1394
  />
1299
- )}
1300
- </span>
1395
+ )
1396
+ ) : (
1397
+ <Icon
1398
+ icon="chevronDown"
1399
+ size="sm"
1400
+ color="secondary"
1401
+ // The rotation rides on the glyph, alongside the box and color
1402
+ // the wrapper used to provide, so one element carries the mark,
1403
+ // its open/closed transform, and the theme target.
1404
+ xstyle={[
1405
+ styles.triggerIcon,
1406
+ styles.triggerIconRotation,
1407
+ popover.isOpen && styles.triggerIconOpen,
1408
+ ]}
1409
+ // Stable theme target on the chevron glyph itself, so a theme can
1410
+ // restyle just this icon (color, size, hover) — and its
1411
+ // open/closed state — via `defineTheme`. Same-element rules in
1412
+ // @layer astryx-theme win over the icon's own base color/size,
1413
+ // which a button-level target could not reach.
1414
+ {...themeProps('selector-indicator-icon', {
1415
+ state: popover.isOpen ? 'expanded' : 'collapsed',
1416
+ })}
1417
+ />
1418
+ )}
1301
1419
  </div>
1302
1420
 
1303
1421
  {popover.render(
@@ -1309,7 +1427,10 @@ export function Selector<T extends SelectorOptionType>(
1309
1427
  id={listboxId}
1310
1428
  role="listbox"
1311
1429
  aria-labelledby={triggerId}
1312
- {...stylex.props(styles.dropdown)}>
1430
+ {...stylex.props(
1431
+ styles.dropdown,
1432
+ variant !== 'ghost' && styles.dropdownInput,
1433
+ )}>
1313
1434
  {renderOptions()}
1314
1435
  </div>
1315
1436
  </div>
@@ -1321,6 +1442,7 @@ export function Selector<T extends SelectorOptionType>(
1321
1442
  aria-labelledby={triggerId}
1322
1443
  {...stylex.props(
1323
1444
  styles.dropdown,
1445
+ variant !== 'ghost' && styles.dropdownInput,
1324
1446
  !isPositioned && styles.dropdownHidden,
1325
1447
  )}>
1326
1448
  {renderOptions()}
@@ -1329,6 +1451,12 @@ export function Selector<T extends SelectorOptionType>(
1329
1451
  {
1330
1452
  placement: popoverPlacement,
1331
1453
  alignment: 'start',
1454
+ // The system's standard menu clearance, except in overlay mode:
1455
+ // there the measured negative margin owns the block geometry and
1456
+ // the menu is meant to sit on the trigger, not clear it.
1457
+ offset: shouldOverlaySelectedItem
1458
+ ? undefined
1459
+ : spacingVars['--spacing-1'],
1332
1460
  xstyle: [styles.popover, layerAnimations[popoverPlacement]],
1333
1461
  style: popoverOffsetStyle,
1334
1462
  },