@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,15 +4,36 @@
4
4
 
5
5
  /**
6
6
  * @file hooks.ts
7
+ * @input Uses untransformed DOM layout geometry from the Selector's outer
8
+ * anchor, listbox, and selected option
7
9
  * @output Hooks for Selector
8
10
  * @position Internal hooks; used by Selector.tsx
9
11
  */
10
12
 
11
- import {useCallback, useRef, useState} from 'react';
13
+ import {useCallback, useState} from 'react';
12
14
  import {useIsomorphicLayoutEffect} from '../hooks/useIsomorphicLayoutEffect';
13
15
  import type {RefObject} from 'react';
14
16
  import type {SelectorOptionData} from './types';
15
17
 
18
+ // The selected row renders one optical pixel below the closed trigger label at
19
+ // the same mathematical center, so compensate before viewport clamping.
20
+ const SELECTED_ITEM_OPTICAL_OFFSET = 1;
21
+
22
+ /**
23
+ * Return an element's document-relative layout top without CSS transforms.
24
+ * getBoundingClientRect includes the popover's entry scale, which would make
25
+ * the measured error grow with each option's distance from the menu top.
26
+ */
27
+ function getLayoutTop(element: HTMLElement): number {
28
+ let top = 0;
29
+ let current: HTMLElement | null = element;
30
+ while (current) {
31
+ top += current.offsetTop;
32
+ current = current.offsetParent as HTMLElement | null;
33
+ }
34
+ return top;
35
+ }
36
+
16
37
  // =============================================================================
17
38
  // useSelectedItemOffset - Position dropdown to center selected item over trigger
18
39
  // =============================================================================
@@ -22,7 +43,7 @@ interface UseSelectedItemOffsetOptions {
22
43
  selectedItemIndex: number;
23
44
  listboxId: string;
24
45
  listboxRef: RefObject<HTMLDivElement | null>;
25
- triggerRef: RefObject<HTMLButtonElement | null>;
46
+ anchorRef: RefObject<HTMLElement | null>;
26
47
  }
27
48
 
28
49
  interface UseSelectedItemOffsetResult {
@@ -32,9 +53,9 @@ interface UseSelectedItemOffsetResult {
32
53
 
33
54
  /**
34
55
  * Calculates the offset needed to position the dropdown so that the selected
35
- * item appears centered over the trigger button (macOS-style selector).
56
+ * item appears centered over the outer selector control (macOS-style selector).
36
57
  *
37
- * The desired dropdown top is calculated directly from the trigger center and
58
+ * The desired dropdown top is calculated directly from the anchor center and
38
59
  * selected-item center, then clamped to the viewport. This preserves the
39
60
  * default "selected item over trigger" behavior while letting the menu slide
40
61
  * upward near the bottom edge or downward near the top edge instead of being
@@ -45,7 +66,7 @@ export function useSelectedItemOffset({
45
66
  selectedItemIndex,
46
67
  listboxId,
47
68
  listboxRef,
48
- triggerRef,
69
+ anchorRef,
49
70
  }: UseSelectedItemOffsetOptions): UseSelectedItemOffsetResult {
50
71
  const [offset, setOffset] = useState(0);
51
72
  const [isPositioned, setIsPositioned] = useState(false);
@@ -67,7 +88,7 @@ export function useSelectedItemOffset({
67
88
  return;
68
89
  }
69
90
 
70
- if (!listboxRef.current || !triggerRef.current) {
91
+ if (!listboxRef.current || !anchorRef.current) {
71
92
  commitPosition(0, true);
72
93
  return;
73
94
  }
@@ -83,34 +104,37 @@ export function useSelectedItemOffset({
83
104
  return;
84
105
  }
85
106
 
86
- // Get positions. JSDOM returns zero rects by default, but browsers provide
87
- // real dimensions before paint via layout effect.
88
- const listboxRect = listboxRef.current.getBoundingClientRect();
89
- const itemRect = targetItem.getBoundingClientRect();
90
- const triggerRect = triggerRef.current.getBoundingClientRect();
107
+ const listbox = listboxRef.current;
108
+ const anchorRect = anchorRef.current.getBoundingClientRect();
91
109
 
92
- const listboxHeight = listboxRect.height;
110
+ // offset* metrics intentionally exclude the popover's entry transform.
111
+ const listboxHeight = listbox.offsetHeight;
93
112
  if (listboxHeight <= 0) {
94
113
  commitPosition(0, true);
95
114
  return;
96
115
  }
97
116
 
98
117
  // Item center relative to listbox top. This remains stable even as the
99
- // popover's top changes between measurements.
118
+ // popover animates between scale values. scrollTop keeps the calculation
119
+ // correct when a previously scrolled listbox is reopened.
100
120
  const itemCenterInListbox =
101
- itemRect.top - listboxRect.top + itemRect.height / 2;
102
- const triggerCenter = triggerRect.top + triggerRect.height / 2;
103
-
104
- // Desired top aligns the selected item's center with trigger center.
105
- const desiredTop = triggerCenter - itemCenterInListbox;
121
+ getLayoutTop(targetItem) -
122
+ getLayoutTop(listbox) -
123
+ listbox.scrollTop +
124
+ targetItem.offsetHeight / 2;
125
+ const anchorCenter = anchorRect.top + anchorRect.height / 2;
126
+
127
+ // Desired top aligns the selected item's center with the anchor center.
128
+ const desiredTop =
129
+ anchorCenter - itemCenterInListbox - SELECTED_ITEM_OPTICAL_OFFSET;
106
130
  const viewportHeight = window.innerHeight;
107
131
  const maxTop = Math.max(0, viewportHeight - listboxHeight);
108
132
  const clampedTop = Math.min(Math.max(desiredTop, 0), maxTop);
109
133
 
110
- // useLayer positions the popover below the trigger. Apply a negative
134
+ // useLayer positions the popover below the outer anchor. Apply a negative
111
135
  // block-start margin to the layer container so the listbox top moves from
112
- // triggerRect.bottom to clampedTop.
113
- const clampedOffset = Math.max(0, triggerRect.bottom - clampedTop);
136
+ // anchorRect.bottom to clampedTop.
137
+ const clampedOffset = Math.max(0, anchorRect.bottom - clampedTop);
114
138
 
115
139
  commitPosition(clampedOffset, true);
116
140
  }, [
@@ -118,7 +142,7 @@ export function useSelectedItemOffset({
118
142
  selectedItemIndex,
119
143
  listboxId,
120
144
  listboxRef,
121
- triggerRef,
145
+ anchorRef,
122
146
  commitPosition,
123
147
  ]);
124
148
 
@@ -126,7 +150,7 @@ export function useSelectedItemOffset({
126
150
  }
127
151
 
128
152
  // =============================================================================
129
- // useCombobox - Keyboard navigation, typeahead, and selection
153
+ // useCombobox - Keyboard navigation and selection
130
154
  // =============================================================================
131
155
 
132
156
  interface UseComboboxOptions {
@@ -145,6 +169,13 @@ interface UseComboboxOptions {
145
169
  * navigation owns those keys there) or when there is no value.
146
170
  */
147
171
  onClear?: () => void;
172
+ /**
173
+ * With `hasSearch`, printable characters typed on the trigger are appended to
174
+ * the search query (opening the popup if needed), so type-to-find works
175
+ * without a separate open step. Characters keep arriving here until focus
176
+ * lands in the search input, which then owns its own typing.
177
+ */
178
+ onSearchSeed?: (char: string) => void;
148
179
  listboxId: string;
149
180
  }
150
181
 
@@ -159,7 +190,12 @@ interface UseComboboxResult {
159
190
  }
160
191
 
161
192
  /**
162
- * Handles keyboard navigation, typeahead search, and selection for combobox/listbox patterns.
193
+ * Handles keyboard navigation and selection for combobox/listbox patterns.
194
+ *
195
+ * Type-to-select is not handled here: callers that want it compose the shared
196
+ * `useTypeahead` hook and run it ahead of this handler (see Selector). That
197
+ * keeps matching consistent with the other collections and leaves consumers
198
+ * whose own input already filters the items (CommandPalette) untouched.
163
199
  */
164
200
  export function useCombobox({
165
201
  selectableItems,
@@ -171,13 +207,10 @@ export function useCombobox({
171
207
  onClose,
172
208
  onSelect,
173
209
  onClear,
210
+ onSearchSeed,
174
211
  listboxId,
175
212
  }: UseComboboxOptions): UseComboboxResult {
176
213
  const [highlightedIndex, setHighlightedIndex] = useState<number>(-1);
177
- const [typeahead, setTypeahead] = useState('');
178
- const typeaheadTimeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(
179
- undefined,
180
- );
181
214
 
182
215
  const getItemId = useCallback(
183
216
  (index: number) => `${listboxId}-item-${index}`,
@@ -274,6 +307,8 @@ export function useCombobox({
274
307
  if (hasSearch) {
275
308
  break;
276
309
  }
310
+ // A space mid-typeahead extends the query instead of activating; the
311
+ // caller's useTypeahead claims it before this handler ever runs.
277
312
  // falls through
278
313
  case 'Enter':
279
314
  e.preventDefault();
@@ -349,28 +384,20 @@ export function useCombobox({
349
384
  break;
350
385
 
351
386
  default:
352
- if (!hasSearch && e.key.length === 1 && !e.ctrlKey && !e.metaKey) {
353
- const newTypeahead = typeahead + e.key.toLowerCase();
354
- setTypeahead(newTypeahead);
355
-
356
- if (typeaheadTimeoutRef.current) {
357
- clearTimeout(typeaheadTimeoutRef.current);
358
- }
359
- typeaheadTimeoutRef.current = setTimeout(() => {
360
- setTypeahead('');
361
- }, 500);
362
-
363
- const matchIndex = selectableItems.findIndex(
364
- item =>
365
- !item.disabled &&
366
- item.label?.toLowerCase().startsWith(newTypeahead),
367
- );
368
- if (matchIndex >= 0) {
369
- if (!isOpen) {
370
- onOpen();
371
- }
372
- setHighlightedIndex(matchIndex);
387
+ // Keys land here only while the trigger holds focus — once the search
388
+ // input takes over it handles its own typing — so they belong in the
389
+ // query, including the ones racing the open.
390
+ if (
391
+ hasSearch &&
392
+ onSearchSeed &&
393
+ e.key.length === 1 &&
394
+ !e.ctrlKey &&
395
+ !e.metaKey
396
+ ) {
397
+ if (!isOpen) {
398
+ onOpen();
373
399
  }
400
+ onSearchSeed(e.key);
374
401
  }
375
402
  break;
376
403
  }
@@ -385,9 +412,9 @@ export function useCombobox({
385
412
  selectItem,
386
413
  findSelectedIndex,
387
414
  getEnabledIndices,
388
- typeahead,
389
415
  hasSearch,
390
416
  onClear,
417
+ onSearchSeed,
391
418
  value,
392
419
  ],
393
420
  );
@@ -183,6 +183,27 @@ describe('SideNav', () => {
183
183
  expect(nav.children).toHaveLength(1);
184
184
  });
185
185
 
186
+ it('centers footer content when collapsed, matching children alignment', () => {
187
+ render(
188
+ <SideNav
189
+ data-testid="nav"
190
+ collapsible={{isCollapsed: true, hasButton: false}}
191
+ footer={<span data-testid="footer-content">F</span>}>
192
+ <span data-testid="children-content">C</span>
193
+ </SideNav>,
194
+ );
195
+
196
+ // scrollableCollapsed (wraps children) and stickyBottomCollapsed (wraps
197
+ // footer) are structurally parallel collapsed-rail containers; both
198
+ // must center their content the same way, or full-width footer content
199
+ // stretches to the collapsed rail's width instead of centering.
200
+ const childrenContainer =
201
+ screen.getByTestId('children-content').parentElement;
202
+ const footerContainer = screen.getByTestId('footer-content').parentElement;
203
+ expect(getComputedStyle(childrenContainer!).alignItems).toBe('center');
204
+ expect(getComputedStyle(footerContainer!).alignItems).toBe('center');
205
+ });
206
+
186
207
  it('fires a consumer onClick on the collapse button in addition to toggling', async () => {
187
208
  const user = userEvent.setup();
188
209
  const onClick = vi.fn();
@@ -592,6 +613,31 @@ describe('SideNavHeading collapsed', () => {
592
613
  expect(menu!.contains(button)).toBe(false);
593
614
  }
594
615
  });
616
+
617
+ it('anchors the collapsed icon-only trigger so the popover positions against it', () => {
618
+ render(
619
+ <CollapsedWrapper>
620
+ <SideNavHeading
621
+ heading="My App"
622
+ icon={<span data-testid="app-icon">🏠</span>}
623
+ menu={<div role="menuitem">Alpha</div>}
624
+ />
625
+ </CollapsedWrapper>,
626
+ );
627
+ const trigger = screen.getByRole('button', {name: 'My App'});
628
+ // The same element also carries the collapsed-item Tooltip's own
629
+ // anchor-name (via anchorRef={collapsedItemRef}), so a plain
630
+ // non-empty check would pass even when the menu popover itself isn't
631
+ // anchored. Assert the popover's own position-anchor id specifically
632
+ // appears in the trigger's (possibly multi-value) anchor-name list.
633
+ const popoverEl = document.querySelector('[popover]') as HTMLElement;
634
+ const anchorId = popoverEl.style.positionAnchor;
635
+ expect(anchorId).not.toBe('');
636
+ const triggerAnchorNames = trigger.style.anchorName
637
+ .split(',')
638
+ .map(s => s.trim());
639
+ expect(triggerAnchorNames).toContain(anchorId);
640
+ });
595
641
  });
596
642
 
597
643
  // =============================================================================
@@ -143,6 +143,7 @@ const styles = stylex.create({
143
143
  },
144
144
  stickyBottomCollapsed: {
145
145
  paddingBlockStart: 0,
146
+ alignItems: 'center',
146
147
  },
147
148
  // Drawer footer — pushed to bottom of the scrollable content area
148
149
  drawerFooter: {
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file SideNavCollapseButton.tsx
7
- * @input Uses React, StyleX, SideNavCollapseContext, getIcon
7
+ * @input Uses React, StyleX, SideNavCollapseContext, Icon
8
8
  * @output Exports SideNavCollapseButton component
9
9
  * @position Composable toggle button for sidenav collapse
10
10
  *
@@ -20,7 +20,7 @@
20
20
  import React, {type ReactNode} from 'react';
21
21
  import * as stylex from '@stylexjs/stylex';
22
22
  import {durationVars, easeVars} from '../theme/tokens.stylex';
23
- import {useIcon} from '../Icon';
23
+ import {Icon} from '../Icon';
24
24
  import {Button} from '../Button';
25
25
  import type {BaseProps} from '../BaseProps';
26
26
  import {composeEventHandlers, rtlStyles} from '../utils';
@@ -107,7 +107,6 @@ export function SideNavCollapseButton({
107
107
  ...props
108
108
  }: SideNavCollapseButtonProps) {
109
109
  const t = useTranslator();
110
- const chevronLeftIcon = useIcon('chevronLeft');
111
110
  const {isCollapsed, toggle, isCollapsible} =
112
111
  useSideNavCollapseState(handleRef);
113
112
  const {isMobile} = useAppShellMobile();
@@ -132,14 +131,20 @@ export function SideNavCollapseButton({
132
131
  onClick={composeEventHandlers(onClickProp, toggle)}
133
132
  icon={
134
133
  children ?? (
134
+ // The RTL mirror stays on its own element, wrapping (not merged
135
+ // into) the state rotation: both are `transform`, so on a single
136
+ // element one would overwrite the other and the chevron would stop
137
+ // mirroring under RTL. See utils/rtlStyles.ts.
135
138
  <span {...stylex.props(rtlStyles.mirror)}>
136
- <span
137
- {...stylex.props(
138
- styles.chevron,
139
- isCollapsed && styles.chevronCollapsed,
140
- )}>
141
- {chevronLeftIcon}
142
- </span>
139
+ {/* `sm` (1rem) matches what this glyph already renders at: Button's
140
+ icon slot pins its wrapper to 16px, and the registry SVG is
141
+ 1em, so the chevron is 16px today. */}
142
+ <Icon
143
+ icon="chevronLeft"
144
+ size="sm"
145
+ color="inherit"
146
+ xstyle={[styles.chevron, isCollapsed && styles.chevronCollapsed]}
147
+ />
143
148
  </span>
144
149
  )
145
150
  }
@@ -33,7 +33,7 @@ import {
33
33
  // of lazy loading layer resources.
34
34
  import {usePopover} from '../Popover/usePopover';
35
35
  import {Link} from '../Link';
36
- import {useIcon} from '../Icon';
36
+ import {Icon} from '../Icon';
37
37
  import {Tooltip} from '../Tooltip';
38
38
  import {navItemStyles} from '../NavItem/navItemStyles.stylex';
39
39
  import {useSideNavCollapse} from './SideNavCollapseContext';
@@ -172,6 +172,11 @@ const styles = stylex.create({
172
172
  minWidth: spacingVars['--spacing-7'],
173
173
  minHeight: spacingVars['--spacing-7'],
174
174
  color: colorVars['--color-icon-secondary'],
175
+ // 28px is the hit/alignment box, not the glyph. Icon sizes its own span
176
+ // with a matching font-size (the registry chevron is a 1em SVG), so pin
177
+ // font-size back to inherit to keep the glyph at the 14px it renders at
178
+ // today. The 28px min box still wins over Icon's width/height.
179
+ fontSize: 'inherit',
175
180
  },
176
181
  headerEndContent: {
177
182
  flexShrink: 0,
@@ -217,8 +222,15 @@ const styles = stylex.create({
217
222
  minWidth: spacingVars['--spacing-7'],
218
223
  minHeight: spacingVars['--spacing-7'],
219
224
  color: colorVars['--color-icon-secondary'],
225
+ // See `chevron` — keep the glyph on the inherited font-size.
226
+ fontSize: 'inherit',
220
227
  transform: 'rotate(180deg)',
221
228
  },
229
+ // Glyph inside a chevron *trigger* (the button already carries the 28px box
230
+ // and the color, so the Icon only has to avoid resizing itself).
231
+ chevronGlyph: {
232
+ fontSize: 'inherit',
233
+ },
222
234
  popover: {
223
235
  minWidth: 'anchor-size(width)',
224
236
  marginBlockStart: spacingVars['--spacing-1'],
@@ -344,7 +356,6 @@ export function SideNavHeading({
344
356
  ...props
345
357
  }: SideNavHeadingProps) {
346
358
  const t = useTranslator();
347
- const chevronDownIcon = useIcon('chevronDown');
348
359
  const LinkComponent = useLinkComponent(as);
349
360
  const {isCollapsed} = useSideNavCollapse();
350
361
  const rootRef = useRef<HTMLDivElement>(null);
@@ -387,7 +398,11 @@ export function SideNavHeading({
387
398
  if (isCollapsed && icon) {
388
399
  const collapsedIcon = <span {...stylex.props(styles.icon)}>{icon}</span>;
389
400
 
390
- const collapsedSetRef = mergeRefs<HTMLElement>(collapsedItemRef, ref);
401
+ const collapsedSetRef = mergeRefs<HTMLElement>(
402
+ collapsedItemRef,
403
+ ref,
404
+ menu ? popover.triggerRef : undefined,
405
+ );
391
406
 
392
407
  let collapsedElement: ReactNode;
393
408
 
@@ -454,9 +469,12 @@ export function SideNavHeading({
454
469
  )}>
455
470
  {heading}
456
471
  </span>
457
- <span {...stylex.props(styles.popoverChevron)}>
458
- {chevronDownIcon}
459
- </span>
472
+ <Icon
473
+ icon="chevronDown"
474
+ size="sm"
475
+ color="secondary"
476
+ xstyle={styles.popoverChevron}
477
+ />
460
478
  </span>
461
479
  {subheading && (
462
480
  <span {...stylex.props(styles.subheading)}>
@@ -551,7 +569,12 @@ export function SideNavHeading({
551
569
  );
552
570
 
553
571
  const chevronElement = showChevron && (
554
- <span {...stylex.props(styles.chevron)}>{chevronDownIcon}</span>
572
+ <Icon
573
+ icon="chevronDown"
574
+ size="sm"
575
+ color="secondary"
576
+ xstyle={styles.chevron}
577
+ />
555
578
  );
556
579
 
557
580
  const headerEndContentElement = headerEndContent && (
@@ -567,7 +590,12 @@ export function SideNavHeading({
567
590
  onClick={triggerProps.onClick}>
568
591
  {icon && <span {...stylex.props(styles.icon)}>{icon}</span>}
569
592
  {renderTextContent(
570
- <span {...stylex.props(styles.popoverChevron)}>{chevronDownIcon}</span>,
593
+ <Icon
594
+ icon="chevronDown"
595
+ size="sm"
596
+ color="secondary"
597
+ xstyle={styles.popoverChevron}
598
+ />,
571
599
  )}
572
600
  </button>
573
601
  );
@@ -619,7 +647,12 @@ export function SideNavHeading({
619
647
  }}
620
648
  {...popover.triggerProps}
621
649
  {...stylex.props(styles.chevron, styles.interactive)}>
622
- {chevronDownIcon}
650
+ <Icon
651
+ icon="chevronDown"
652
+ size="sm"
653
+ color="inherit"
654
+ xstyle={styles.chevronGlyph}
655
+ />
623
656
  </button>,
624
657
  )}
625
658
  {headerEndContentElement}
@@ -685,7 +718,12 @@ export function SideNavHeading({
685
718
  }}
686
719
  {...popover.triggerProps}
687
720
  {...stylex.props(styles.chevron, styles.interactive)}>
688
- {chevronDownIcon}
721
+ <Icon
722
+ icon="chevronDown"
723
+ size="sm"
724
+ color="inherit"
725
+ xstyle={styles.chevronGlyph}
726
+ />
689
727
  </button>
690
728
  ) : undefined,
691
729
  )}
@@ -38,7 +38,7 @@ import {
38
38
  borderVars,
39
39
  radiusVars,
40
40
  } from '../theme/tokens.stylex';
41
- import {renderIconSlot, useIcon, type IconType} from '../Icon';
41
+ import {Icon, renderIconSlot, type IconType} from '../Icon';
42
42
  import {useLinkComponent} from '../Link/useLinkComponent';
43
43
  import type {LinkComponentType} from '../Link/types';
44
44
  import {usePopover} from '../Popover/usePopover';
@@ -108,6 +108,11 @@ const styles = stylex.create({
108
108
  justifyContent: 'center',
109
109
  width: spacingVars['--spacing-6'],
110
110
  height: spacingVars['--spacing-6'],
111
+ // Icon's `lg` would also set font-size: 1.5rem, and the registry chevron
112
+ // is a 1em SVG — that would blow the glyph up from the 14px it inherits
113
+ // from the row to the full 24px box. The 24px box is the touch/alignment
114
+ // target, not the glyph size, so keep the glyph on the inherited size.
115
+ fontSize: 'inherit',
111
116
  transitionProperty: 'transform',
112
117
  transitionDuration: durationVars['--duration-fast'],
113
118
  transitionTimingFunction: easeVars['--ease-standard'],
@@ -358,7 +363,6 @@ export function SideNavItem({
358
363
  xstyle,
359
364
  }: SideNavItemProps) {
360
365
  const t = useTranslator();
361
- const chevronDownIcon = useIcon('chevronDown');
362
366
  const {isCollapsed} = useSideNavCollapse();
363
367
  const renderMode = useSideNavRenderMode();
364
368
  const {closeMobileNav} = useAppShellMobile();
@@ -574,13 +578,15 @@ export function SideNavItem({
574
578
  <span {...stylex.props(styles.endContent)}>{endContent}</span>
575
579
  )}
576
580
  {!isCollapsed && isItemCollapsible && !hasIndependentToggle && (
577
- <span
578
- {...stylex.props(
581
+ <Icon
582
+ icon="chevronDown"
583
+ size="lg"
584
+ color="inherit"
585
+ xstyle={[
579
586
  styles.expandChevron,
580
587
  !isItemCollapsed && styles.expandChevronExpanded,
581
- )}>
582
- {chevronDownIcon}
583
- </span>
588
+ ]}
589
+ />
584
590
  )}
585
591
  </>
586
592
  );
@@ -637,13 +643,15 @@ export function SideNavItem({
637
643
  aria-expanded={!isItemCollapsed}
638
644
  aria-controls={`${id}-children`}
639
645
  {...stylex.props(styles.expandToggle)}>
640
- <span
641
- {...stylex.props(
646
+ <Icon
647
+ icon="chevronDown"
648
+ size="lg"
649
+ color="inherit"
650
+ xstyle={[
642
651
  styles.expandChevron,
643
652
  !isItemCollapsed && styles.expandChevronExpanded,
644
- )}>
645
- {chevronDownIcon}
646
- </span>
653
+ ]}
654
+ />
647
655
  </button>
648
656
  </div>
649
657
  );