@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
@@ -12,6 +12,13 @@
12
12
  * eliminating z-index stacking. CSS anchor positioning places the panel below
13
13
  * the nav wrapper.
14
14
  *
15
+ * The default (desktop) trigger opens on hover and click. Hover opens are
16
+ * transient; click/keyboard opens are pinned. A click shortly after hover-open
17
+ * confirms and pins the panel instead of closing it. The panel remains an auto
18
+ * popover for native dismissal and sibling exclusivity; `popoverTarget`
19
+ * registers the trigger as its native invoker so the guard runs before any
20
+ * dismiss.
21
+ *
15
22
  * Supports three render modes via TopNavRenderContext:
16
23
  * - 'default': desktop popover mega menu (hover/click triggered)
17
24
  * - 'mobile-bar': returns null (hidden in compact mobile bar)
@@ -44,13 +51,14 @@ import {
44
51
  } from '../theme/tokens.stylex';
45
52
  import {usePopover} from '../Popover/usePopover';
46
53
  import {Grid} from '../Grid/Grid';
47
- import {useIcon} from '../Icon';
54
+ import {Icon} from '../Icon';
48
55
  import {mergeProps, mergeRefs} from '../utils';
49
56
  import type {BaseProps} from '../BaseProps';
50
57
  import {navItemStyles} from '../NavItem/navItemStyles.stylex';
51
58
  import {useTopNavSlot} from './TopNavContext';
52
59
  import {useTopNavRenderMode} from './TopNavRenderContext';
53
60
  import {themeProps} from '../utils/themeProps';
61
+ import {focusOutlineProps} from '../utils/focusOutline.stylex';
54
62
 
55
63
  // =============================================================================
56
64
  // Styles
@@ -79,14 +87,6 @@ const styles = stylex.create({
79
87
  '@media (hover: hover)': colorVars['--color-overlay-hover'],
80
88
  },
81
89
  },
82
- outline: {
83
- default: null,
84
- ':focus-visible': `2px solid ${colorVars['--color-accent']}`,
85
- },
86
- outlineOffset: {
87
- default: '0',
88
- ':focus-visible': '2px',
89
- },
90
90
  border: 'none',
91
91
  fontFamily: 'inherit',
92
92
  },
@@ -97,6 +97,14 @@ const styles = stylex.create({
97
97
  chevron: {
98
98
  display: 'inline-flex',
99
99
  alignItems: 'center',
100
+ // The registry chevron is a 1em SVG, so it has always rendered at the
101
+ // trigger's own font size (--text-label-size). Icon's size box would repin
102
+ // it to a fixed rem (the nearest, sm, is 1rem = 16px vs the 14px here), so
103
+ // hold it on the inherited em: same pixels, and still tracks the type
104
+ // scale when a theme changes the label size.
105
+ width: '1em',
106
+ height: '1em',
107
+ fontSize: 'inherit',
100
108
  transitionProperty: 'transform',
101
109
  transitionDuration: durationVars['--duration-fast'],
102
110
  transitionTimingFunction: easeVars['--ease-standard'],
@@ -131,7 +139,10 @@ const styles = stylex.create({
131
139
  // own content, keeping the surface radius/shadow static at the edges.
132
140
  // Internal scroll is a stopgap until the mobile bottom-sheet lands.
133
141
  panelViewportFit: {
134
- display: 'flex',
142
+ display: {
143
+ default: 'none',
144
+ ':popover-open': 'flex',
145
+ },
135
146
  flexDirection: 'column',
136
147
  maxHeight: `calc(100% - ${spacingVars['--spacing-3']})`,
137
148
  },
@@ -197,6 +208,11 @@ const styles = stylex.create({
197
208
  },
198
209
  drawerChevron: {
199
210
  display: 'inline-flex',
211
+ // Same em pin as styles.chevron above — the drawer header inherits
212
+ // --text-label-size from navItemStyles.item.
213
+ width: '1em',
214
+ height: '1em',
215
+ fontSize: 'inherit',
200
216
  transitionProperty: 'transform',
201
217
  transitionDuration: durationVars['--duration-fast'],
202
218
  transitionTimingFunction: easeVars['--ease-standard'],
@@ -354,6 +370,8 @@ TopNavMegaMenu.displayName = 'TopNavMegaMenu';
354
370
  // DefaultMegaMenu — desktop popover mode
355
371
  // =============================================================================
356
372
 
373
+ const CLICK_GUARD_MS = 500;
374
+
357
375
  function DefaultMegaMenu({
358
376
  ref,
359
377
  label,
@@ -364,30 +382,39 @@ function DefaultMegaMenu({
364
382
  onOpenChange,
365
383
  }: TopNavMegaMenuProps) {
366
384
  const slot = useTopNavSlot();
367
- const chevronDownIcon = useIcon('chevronDown');
368
385
  const showTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
369
386
  const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
370
387
  const triggerButtonRef = useRef<HTMLButtonElement | null>(null);
371
- const clickLockedRef = useRef(false);
388
+ const hoverOpenedAtRef = useRef(0);
389
+ const stickyRef = useRef(false);
372
390
 
373
391
  const handlePopoverShow = useCallback(() => {
374
392
  onOpenChange?.(true);
375
393
  }, [onOpenChange]);
376
394
 
377
395
  const handlePopoverHide = useCallback(() => {
396
+ hoverOpenedAtRef.current = 0;
397
+ stickyRef.current = false;
378
398
  onOpenChange?.(false);
379
399
  }, [onOpenChange]);
380
400
 
381
401
  const popover = usePopover({
382
402
  // role: 'none' — the panel exposes its own role="group" labeled by
383
- // `label`. Focus stays on the trigger while the panel is open, so a
384
- // role="dialog" aria-modal="true" wrapper would announce an unnamed
385
- // modal dialog around a grid of links.
403
+ // `label`. Pointer/hover opens keep focus on the trigger; keyboard and
404
+ // assistive-tech opens move focus into the panel (a labeled group you exit
405
+ // with Escape or by tabbing out). Either way role="dialog"
406
+ // aria-modal="true" would be wrong: it announces an unnamed modal dialog
407
+ // around a grid of links (and, when focus stays on the trigger, marks the
408
+ // focused control inert).
386
409
  role: 'none',
387
410
  // hasSurface: false — mega menu provides its own surface (panelContainer)
388
411
  // with border-top and custom overflow. Animation is applied via the
389
412
  // render() call's xstyle prop (panelAnimation), not the hook options.
390
413
  hasSurface: false,
414
+ // Keep native outside-click/Escape dismissal and sibling exclusivity.
415
+ // The trigger's popoverTarget association prevents its activation from
416
+ // being treated as an ordinary outside interaction.
417
+ hasLightDismiss: true,
391
418
  onShow: handlePopoverShow,
392
419
  onHide: handlePopoverHide,
393
420
  });
@@ -417,40 +444,75 @@ function DefaultMegaMenu({
417
444
  const scheduleShow = useCallback(() => {
418
445
  clearTimeouts();
419
446
  showTimeoutRef.current = setTimeout(() => {
447
+ hoverOpenedAtRef.current = Date.now();
420
448
  popover.show({skipAutoFocus: true});
421
449
  }, delay);
422
- }, [clearTimeouts, popover, delay]);
450
+ }, [clearTimeouts, delay, popover]);
423
451
 
424
452
  const scheduleHide = useCallback(() => {
425
453
  clearTimeouts();
426
454
  hideTimeoutRef.current = setTimeout(() => {
427
455
  popover.hide();
428
456
  }, hideDelay);
429
- }, [clearTimeouts, popover, hideDelay]);
457
+ }, [clearTimeouts, hideDelay, popover]);
458
+
459
+ const focusFirstPanelItem = useCallback(() => {
460
+ popover.contentRef.current
461
+ ?.querySelector<HTMLElement>(
462
+ 'a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])',
463
+ )
464
+ ?.focus();
465
+ }, [popover.contentRef]);
430
466
 
431
- const handleMouseEnter = useCallback(() => {
432
- if (!clickLockedRef.current) {
467
+ const handleTriggerMouseEnter = useCallback(() => {
468
+ clearTimeouts();
469
+ if (!popover.isOpen) {
433
470
  scheduleShow();
434
471
  }
435
- }, [scheduleShow]);
472
+ }, [clearTimeouts, popover.isOpen, scheduleShow]);
473
+
474
+ const handlePanelMouseEnter = useCallback(() => {
475
+ clearTimeouts();
476
+ }, [clearTimeouts]);
436
477
 
437
478
  const handleMouseLeave = useCallback(() => {
438
- if (!clickLockedRef.current) {
479
+ if (!stickyRef.current) {
439
480
  scheduleHide();
440
481
  }
441
482
  }, [scheduleHide]);
442
483
 
443
- const handleClick = useCallback(() => {
444
- clearTimeouts();
445
- if (popover.isOpen) {
446
- clickLockedRef.current = false;
447
- popover.hide();
448
- triggerButtonRef.current?.focus();
449
- } else {
450
- clickLockedRef.current = true;
451
- popover.show();
452
- }
453
- }, [popover, clearTimeouts]);
484
+ const handleClick = useCallback(
485
+ (event: React.MouseEvent<HTMLButtonElement>) => {
486
+ // Cancel the native invoker toggle so this guard is the single source of
487
+ // truth for trigger activation. popoverTarget still establishes the
488
+ // invoker relationship used by native light-dismiss and stacking.
489
+ event.preventDefault();
490
+ clearTimeouts();
491
+
492
+ if (event.detail === 0) {
493
+ stickyRef.current = true;
494
+ hoverOpenedAtRef.current = 0;
495
+ if (popover.isOpen) {
496
+ focusFirstPanelItem();
497
+ } else {
498
+ popover.show();
499
+ }
500
+ } else if (!popover.isOpen) {
501
+ stickyRef.current = true;
502
+ popover.show({skipAutoFocus: true});
503
+ } else if (Date.now() - hoverOpenedAtRef.current < CLICK_GUARD_MS) {
504
+ // A click that naturally follows a hover-open confirms the open state
505
+ // instead of toggling the panel shut. From here it behaves like any
506
+ // other click-open and stays pinned until explicit dismissal.
507
+ stickyRef.current = true;
508
+ hoverOpenedAtRef.current = 0;
509
+ } else {
510
+ popover.hide();
511
+ triggerButtonRef.current?.focus();
512
+ }
513
+ },
514
+ [clearTimeouts, focusFirstPanelItem, popover],
515
+ );
454
516
 
455
517
  useEffect(() => {
456
518
  return () => {
@@ -464,21 +526,25 @@ function DefaultMegaMenu({
464
526
  ref={mergeRefs(triggerButtonRef, ref)}
465
527
  type="button"
466
528
  {...popover.triggerProps}
529
+ // Native invoker prevents trigger light-dismiss.
530
+ popoverTarget={popover.id}
467
531
  onClick={handleClick}
468
- onMouseEnter={handleMouseEnter}
532
+ onMouseEnter={handleTriggerMouseEnter}
469
533
  onMouseLeave={handleMouseLeave}
470
534
  {...mergeProps(
471
535
  themeProps('top-nav-mega-menu'),
472
- stylex.props(styles.trigger, popover.isOpen && styles.triggerOpen),
536
+ focusOutlineProps.focusVisible(
537
+ styles.trigger,
538
+ popover.isOpen && styles.triggerOpen,
539
+ ),
473
540
  )}>
474
541
  {label}
475
- <span
476
- {...stylex.props(
477
- styles.chevron,
478
- popover.isOpen && styles.chevronOpen,
479
- )}>
480
- {chevronDownIcon}
481
- </span>
542
+ <Icon
543
+ icon="chevronDown"
544
+ size="sm"
545
+ color="inherit"
546
+ xstyle={[styles.chevron, popover.isOpen && styles.chevronOpen]}
547
+ />
482
548
  </button>
483
549
  {popover.render(
484
550
  <div
@@ -487,17 +553,15 @@ function DefaultMegaMenu({
487
553
  // for action menus; link mega menus are the documented anti-case).
488
554
  role="group"
489
555
  aria-label={label}
490
- onMouseEnter={handleMouseEnter}
556
+ onMouseEnter={handlePanelMouseEnter}
491
557
  onMouseLeave={handleMouseLeave}
492
558
  {...stylex.props(styles.panelContainer)}>
493
559
  <div {...stylex.props(styles.panelContent)}>
494
560
  {/* Menu items section */}
495
561
  {items != null && (
496
- <div {...stylex.props(styles.menuWrapper)}>
497
- <Grid columns={2} gap={2}>
498
- {items}
499
- </Grid>
500
- </div>
562
+ <Grid columns={2} gap={2} xstyle={styles.menuWrapper}>
563
+ {items}
564
+ </Grid>
501
565
  )}
502
566
 
503
567
  {/* Featured section */}
@@ -526,7 +590,6 @@ function DrawerMegaMenu({
526
590
  featured,
527
591
  }: Pick<TopNavMegaMenuProps, 'label' | 'items' | 'featured'>) {
528
592
  const [isExpanded, setIsExpanded] = useState(false);
529
- const chevronDownIcon = useIcon('chevronDown');
530
593
  const menuId = `mega-menu-${label.toLowerCase().replace(/\s+/g, '-')}`;
531
594
 
532
595
  return (
@@ -542,13 +605,15 @@ function DrawerMegaMenu({
542
605
  stylex.props(navItemStyles.item, styles.drawerHeader),
543
606
  )}>
544
607
  {label}
545
- <span
546
- {...stylex.props(
608
+ <Icon
609
+ icon="chevronDown"
610
+ size="sm"
611
+ color="inherit"
612
+ xstyle={[
547
613
  styles.drawerChevron,
548
614
  isExpanded && styles.drawerChevronExpanded,
549
- )}>
550
- {chevronDownIcon}
551
- </span>
615
+ ]}
616
+ />
552
617
  </button>
553
618
 
554
619
  {/* Animated expand/collapse container */}
@@ -34,6 +34,7 @@ import {mergeProps} from '../utils';
34
34
  import type {BaseProps} from '../BaseProps';
35
35
  import {useAppShellMobile} from '../AppShell/AppShellMobileContext';
36
36
  import {themeProps} from '../utils/themeProps';
37
+ import {focusOutlineProps} from '../utils/focusOutline.stylex';
37
38
 
38
39
  // =============================================================================
39
40
  // Styles
@@ -61,14 +62,6 @@ const styles = stylex.create({
61
62
  ':active': colorVars['--color-overlay-pressed'],
62
63
  },
63
64
  border: 'none',
64
- outline: {
65
- default: null,
66
- ':focus-visible': `2px solid ${colorVars['--color-accent']}`,
67
- },
68
- outlineOffset: {
69
- default: '0',
70
- ':focus-visible': '2px',
71
- },
72
65
  color: 'inherit',
73
66
  fontFamily: 'inherit',
74
67
  textAlign: 'start',
@@ -249,7 +242,7 @@ export function TopNavMegaMenuItem({
249
242
  tabIndex={tabIndex}
250
243
  {...mergeProps(
251
244
  themeProps('top-nav-mega-menu-item'),
252
- stylex.props(styles.desktop),
245
+ focusOutlineProps.focusVisible(styles.desktop),
253
246
  )}>
254
247
  {icon && <div {...stylex.props(styles.desktopIcon)}>{icon}</div>}
255
248
  <div {...stylex.props(styles.desktopContent)}>
@@ -28,7 +28,7 @@ import {usePopover} from '../Popover/usePopover';
28
28
  import {useMenuHover} from '../hooks/useMenuHover';
29
29
  import {useListFocus} from '../hooks/useListFocus';
30
30
  import {useTypeahead} from '../hooks/useTypeahead';
31
- import {useIcon} from '../Icon';
31
+ import {Icon} from '../Icon';
32
32
  import {mergeProps, mergeRefs} from '../utils';
33
33
  import type {BaseProps} from '../BaseProps';
34
34
  import {navItemStyles} from '../NavItem/navItemStyles.stylex';
@@ -37,6 +37,7 @@ import {useTopNavRenderMode} from './TopNavRenderContext';
37
37
  import {useAppShellMobile} from '../AppShell/AppShellMobileContext';
38
38
  import {useLinkComponent} from '../Link/useLinkComponent';
39
39
  import {themeProps} from '../utils/themeProps';
40
+ import {focusOutlineProps} from '../utils/focusOutline.stylex';
40
41
  import {
41
42
  colorVars,
42
43
  spacingVars,
@@ -74,14 +75,6 @@ const styles = stylex.create({
74
75
  '@media (hover: hover)': colorVars['--color-overlay-hover'],
75
76
  },
76
77
  },
77
- outline: {
78
- default: null,
79
- ':focus-visible': `2px solid ${colorVars['--color-accent']}`,
80
- },
81
- outlineOffset: {
82
- default: '0',
83
- ':focus-visible': '2px',
84
- },
85
78
  border: 'none',
86
79
  fontFamily: 'inherit',
87
80
  },
@@ -92,6 +85,14 @@ const styles = stylex.create({
92
85
  chevron: {
93
86
  display: 'inline-flex',
94
87
  alignItems: 'center',
88
+ // The registry chevron is a 1em SVG, so it has always rendered at the
89
+ // trigger's own font size (--text-label-size). Icon's size box would repin
90
+ // it to a fixed rem (the nearest, sm, is 1rem = 16px vs the 14px here), so
91
+ // hold it on the inherited em: same pixels, and still tracks the type
92
+ // scale when a theme changes the label size.
93
+ width: '1em',
94
+ height: '1em',
95
+ fontSize: 'inherit',
95
96
  transitionProperty: 'transform',
96
97
  transitionDuration: durationVars['--duration-fast'],
97
98
  transitionTimingFunction: easeVars['--ease-standard'],
@@ -106,9 +107,6 @@ const styles = stylex.create({
106
107
  minWidth: 280,
107
108
  padding: spacingVars['--spacing-1'],
108
109
  },
109
- menuOffset: {
110
- marginBlockStart: spacingVars['--spacing-1'],
111
- },
112
110
  menuItem: {
113
111
  display: 'flex',
114
112
  alignItems: 'center',
@@ -128,14 +126,6 @@ const styles = stylex.create({
128
126
  },
129
127
  },
130
128
  border: 'none',
131
- outline: {
132
- default: null,
133
- ':focus-visible': `2px solid ${colorVars['--color-accent']}`,
134
- },
135
- outlineOffset: {
136
- default: '0',
137
- ':focus-visible': '2px',
138
- },
139
129
  },
140
130
  menuItemIcon: {
141
131
  display: 'flex',
@@ -179,6 +169,11 @@ const drawerStyles = stylex.create({
179
169
  },
180
170
  chevron: {
181
171
  display: 'inline-flex',
172
+ // Same em pin as styles.chevron above — the drawer header inherits
173
+ // --text-label-size from navItemStyles.item.
174
+ width: '1em',
175
+ height: '1em',
176
+ fontSize: 'inherit',
182
177
  transitionProperty: 'transform',
183
178
  transitionDuration: durationVars['--duration-fast'],
184
179
  transitionTimingFunction: easeVars['--ease-standard'],
@@ -332,7 +327,6 @@ export function TopNavMenu({
332
327
  hideDelay = 200,
333
328
  }: TopNavMenuProps) {
334
329
  const renderMode = useTopNavRenderMode();
335
- const chevronDownIcon = useIcon('chevronDown');
336
330
  const {closeMobileNav} = useAppShellMobile();
337
331
  const LinkComponent = useLinkComponent();
338
332
  const [drawerExpanded, setDrawerExpanded] = useState(false);
@@ -346,7 +340,6 @@ export function TopNavMenu({
346
340
  // wrapper would announce an unnamed dialog around the menu and make the
347
341
  // trigger claim aria-haspopup="dialog" for menu content (see TabMenu).
348
342
  role: 'none',
349
- xstyle: styles.menuOffset,
350
343
  });
351
344
 
352
345
  const {triggerProps, contentProps, menuRef, setTriggerEl} =
@@ -441,13 +434,15 @@ export function TopNavMenu({
441
434
  aria-controls={`${menuId}-items`}
442
435
  {...stylex.props(navItemStyles.item, drawerStyles.header)}>
443
436
  {label}
444
- <span
445
- {...stylex.props(
437
+ <Icon
438
+ icon="chevronDown"
439
+ size="sm"
440
+ color="inherit"
441
+ xstyle={[
446
442
  drawerStyles.chevron,
447
443
  drawerExpanded && drawerStyles.chevronExpanded,
448
- )}>
449
- {chevronDownIcon}
450
- </span>
444
+ ]}
445
+ />
451
446
  </button>
452
447
  <div
453
448
  id={`${menuId}-items`}
@@ -496,16 +491,18 @@ export function TopNavMenu({
496
491
  {...triggerProps}
497
492
  {...mergeProps(
498
493
  themeProps('top-nav-menu'),
499
- stylex.props(styles.trigger, popover.isOpen && styles.triggerOpen),
494
+ focusOutlineProps.focusVisible(
495
+ styles.trigger,
496
+ popover.isOpen && styles.triggerOpen,
497
+ ),
500
498
  )}>
501
499
  {label}
502
- <span
503
- {...stylex.props(
504
- styles.chevron,
505
- popover.isOpen && styles.chevronOpen,
506
- )}>
507
- {chevronDownIcon}
508
- </span>
500
+ <Icon
501
+ icon="chevronDown"
502
+ size="sm"
503
+ color="inherit"
504
+ xstyle={[styles.chevron, popover.isOpen && styles.chevronOpen]}
505
+ />
509
506
  </button>
510
507
  {popover.render(
511
508
  <div
@@ -530,7 +527,7 @@ export function TopNavMenu({
530
527
  tabIndex={-1}
531
528
  href={item.href}
532
529
  onClick={item.onClick}
533
- {...stylex.props(styles.menuItem)}>
530
+ {...focusOutlineProps.focusVisible(styles.menuItem)}>
534
531
  <div {...stylex.props(styles.menuItemIcon)}>{item.icon}</div>
535
532
  <div {...stylex.props(styles.menuItemContent)}>
536
533
  <span {...stylex.props(styles.menuItemTitle)}>
@@ -549,7 +546,7 @@ export function TopNavMenu({
549
546
  {
550
547
  placement: 'below',
551
548
  alignment: slot,
552
- xstyle: styles.menuOffset,
549
+ offset: spacingVars['--spacing-1'],
553
550
  },
554
551
  )}
555
552
  </>
@@ -32,6 +32,7 @@ export const docs = {
32
32
  ],
33
33
  vars: [
34
34
  {name: '--tree-list-indent', description: 'Per-level indentation step. Each nesting level indents its rows by this distance, and the guide lines follow it so they stay aligned. Set it on the `tree-list` target to retune the metric (e.g. `var(--spacing-5)` for a wider indent).', default: 'var(--spacing-4)'},
35
+ {name: '--tree-list-row-gap', description: 'Vertical gap between adjacent rows. Default `2px` (var(--spacing-0-5)) gives a subtle separation; set it on the `tree-list` target to widen or close the gap. The connector guides span the gap automatically (the line stays continuous) and do not overhang the last row, so no guide-height tuning is needed.', default: 'var(--spacing-0-5)'},
35
36
  ],
36
37
  },
37
38
  components: [
@@ -82,6 +83,7 @@ export const docs = {
82
83
  bestPractices: [
83
84
  {guidance: true, description: 'Provide meaningful labels and icons for each node to make the hierarchy easy to scan.'},
84
85
  {guidance: true, description: 'Pre-expand important branches so users see key content immediately.'},
86
+ {guidance: true, description: 'Leaf rows reserve space for a chevron column whenever the tree has any expandable item to line up under; only a fully flat tree (no expandable items at all) renders its rows flush. Rely on this rather than nudging indentation with custom CSS.'},
85
87
  {guidance: false, description: 'Nest more than 4–5 levels deep; flatten the structure or use a different pattern.'},
86
88
  {guidance: false, description: 'Use a tree for flat, non-hierarchical data; use a List instead.'},
87
89
  ],
@@ -109,6 +111,7 @@ export const docsZh = {
109
111
  ],
110
112
  vars: [
111
113
  {name: '--tree-list-indent', description: '每级缩进步长。每个嵌套层级的行按此距离缩进,引导线随之对齐。在 `tree-list` 目标上设置以调整该度量(例如用 `var(--spacing-5)` 获得更宽的缩进)。', default: 'var(--spacing-4)'},
114
+ {name: '--tree-list-row-gap', description: '相邻行之间的垂直间距。默认 `2px`(var(--spacing-0-5))提供细微的分隔;在 `tree-list` 目标上设置以加宽或关闭间距。连接引导线会自动跨越该间距(线保持连续)且不会超出最后一行,因此无需调整引导线高度。', default: 'var(--spacing-0-5)'},
112
115
  ],
113
116
  },
114
117
  components: [
@@ -159,6 +162,7 @@ export const docsZh = {
159
162
  bestPractices: [
160
163
  {guidance: true, description: 'Provide meaningful labels and icons for each node to make the hierarchy easy to scan.'},
161
164
  {guidance: true, description: 'Pre-expand important branches so users see key content immediately.'},
165
+ {guidance: true, description: 'Leaf rows reserve space for a chevron column whenever the tree has any expandable item to line up under; only a fully flat tree (no expandable items at all) renders its rows flush. Rely on this rather than nudging indentation with custom CSS.'},
162
166
  {guidance: false, description: 'Nest more than 4–5 levels deep; flatten the structure or use a different pattern.'},
163
167
  {guidance: false, description: 'Use a tree for flat, non-hierarchical data; use a List instead.'},
164
168
  ],
@@ -175,6 +179,7 @@ export const docsDense = {
175
179
  bestPractices: [
176
180
  {guidance: true, description: 'Provide meaningful labels and icons for each node to make the hierarchy easy to scan.'},
177
181
  {guidance: true, description: 'Pre-expand important branches so users see key content immediately.'},
182
+ {guidance: true, description: 'Leaf rows reserve space for a chevron column whenever the tree has any expandable item to line up under; only a fully flat tree (no expandable items at all) renders its rows flush. Rely on this rather than nudging indentation with custom CSS.'},
178
183
  {guidance: false, description: 'Nest more than 4–5 levels deep; flatten the structure or use a different pattern.'},
179
184
  {guidance: false, description: 'Use a tree for flat, non-hierarchical data; use a List instead.'},
180
185
  ],