@astryxdesign/core 0.5.0 → 0.5.1-canary.f64186a

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 (597) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +45 -20
  5. package/dist/AspectRatio/AspectRatio.d.ts +6 -6
  6. package/dist/Avatar/Avatar.d.ts +25 -1
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +43 -9
  9. package/dist/Avatar/index.d.ts +2 -2
  10. package/dist/Avatar/index.d.ts.map +1 -1
  11. package/dist/Avatar/index.js +1 -1
  12. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  13. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroup.js +5 -2
  15. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  16. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  17. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroupOverflow.js +11 -7
  19. package/dist/Badge/Badge.d.ts.map +1 -1
  20. package/dist/Badge/Badge.js +26 -2
  21. package/dist/Banner/Banner.d.ts +10 -1
  22. package/dist/Banner/Banner.d.ts.map +1 -1
  23. package/dist/Banner/Banner.js +11 -2
  24. package/dist/Button/Button.d.ts.map +1 -1
  25. package/dist/Button/Button.js +8 -7
  26. package/dist/Calendar/Calendar.d.ts +4 -2
  27. package/dist/Calendar/Calendar.d.ts.map +1 -1
  28. package/dist/Calendar/Calendar.js +15 -21
  29. package/dist/Calendar/hooks/useCalendarDays.js +4 -6
  30. package/dist/Calendar/hooks/useCalendarNavigation.js +4 -6
  31. package/dist/Calendar/styles.d.ts +5 -20
  32. package/dist/Calendar/styles.d.ts.map +1 -1
  33. package/dist/Calendar/styles.js +15 -17
  34. package/dist/Card/Card.d.ts +12 -12
  35. package/dist/Card/Card.d.ts.map +1 -1
  36. package/dist/Card/Card.js +17 -9
  37. package/dist/Card/index.d.ts +35 -1
  38. package/dist/Card/index.d.ts.map +1 -1
  39. package/dist/Card/index.js +21 -1
  40. package/dist/Carousel/Carousel.d.ts.map +1 -1
  41. package/dist/Carousel/Carousel.js +108 -7
  42. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  43. package/dist/CheckboxInput/CheckboxInput.js +7 -1
  44. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  45. package/dist/CodeBlock/CodeBlock.js +15 -4
  46. package/dist/CodeBlock/highlightRanges.js +1 -1
  47. package/dist/CodeBlock/highlightStyles.js +13 -13
  48. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  49. package/dist/CommandPalette/CommandPaletteItem.js +2 -7
  50. package/dist/ComplexSelector/ComplexSelector.d.ts +10 -2
  51. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  52. package/dist/ComplexSelector/ComplexSelector.js +14 -7
  53. package/dist/DateInput/DateInput.d.ts +43 -0
  54. package/dist/DateInput/DateInput.d.ts.map +1 -1
  55. package/dist/DateInput/DateInput.js +22 -5
  56. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  57. package/dist/DateInput/MonthScroller.js +5 -3
  58. package/dist/DateInput/MonthYearWheels.d.ts.map +1 -1
  59. package/dist/DateInput/MonthYearWheels.js +6 -4
  60. package/dist/DateInput/NativeDateField.d.ts +10 -0
  61. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  62. package/dist/DateInput/NativeDateField.js +494 -0
  63. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  64. package/dist/DateInput/TouchDateField.js +52 -25
  65. package/dist/DateInput/Wheel.d.ts.map +1 -1
  66. package/dist/DateInput/Wheel.js +1 -0
  67. package/dist/DateInput/index.d.ts +1 -1
  68. package/dist/DateInput/index.d.ts.map +1 -1
  69. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  70. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  71. package/dist/DateInput/nativeDateSegments.js +111 -0
  72. package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
  73. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  74. package/dist/DateRangeInput/DateRangeInput.js +3 -5
  75. package/dist/DateTimeInput/DateTimeInput.d.ts +23 -24
  76. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  77. package/dist/DateTimeInput/DateTimeInput.js +35 -10
  78. package/dist/DateTimeInput/TouchDateTimeField.d.ts +6 -0
  79. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -0
  80. package/dist/DateTimeInput/TouchDateTimeField.js +1021 -0
  81. package/dist/Dialog/Dialog.d.ts +16 -2
  82. package/dist/Dialog/Dialog.d.ts.map +1 -1
  83. package/dist/Dialog/Dialog.js +28 -7
  84. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  85. package/dist/DropdownMenu/DropdownMenu.js +4 -13
  86. package/dist/Field/FieldLabel.d.ts.map +1 -1
  87. package/dist/Field/FieldLabel.js +9 -1
  88. package/dist/Field/InputClearButton.d.ts +9 -3
  89. package/dist/Field/InputClearButton.d.ts.map +1 -1
  90. package/dist/Field/InputClearButton.js +14 -3
  91. package/dist/Heading/Heading.d.ts.map +1 -1
  92. package/dist/Heading/Heading.js +0 -1
  93. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  94. package/dist/HoverCard/HoverCard.js +104 -3
  95. package/dist/HoverCard/useHoverCard.d.ts +14 -2
  96. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  97. package/dist/HoverCard/useHoverCard.js +7 -1
  98. package/dist/Icon/Icon.d.ts +4 -2
  99. package/dist/Icon/Icon.d.ts.map +1 -1
  100. package/dist/Icon/defaultIcons.d.ts +3 -2
  101. package/dist/Icon/defaultIcons.d.ts.map +1 -1
  102. package/dist/Icon/defaultIcons.js +7 -0
  103. package/dist/Icon/globalIconRegistry.d.ts +13 -0
  104. package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
  105. package/dist/Icon/globalIconRegistry.js +34 -6
  106. package/dist/Icon/index.d.ts +1 -1
  107. package/dist/Icon/index.d.ts.map +1 -1
  108. package/dist/Icon/useIcon.d.ts +5 -2
  109. package/dist/Icon/useIcon.d.ts.map +1 -1
  110. package/dist/Icon/useIcon.js +3 -0
  111. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  112. package/dist/Indicator/CheckboxIndicator.js +6 -2
  113. package/dist/Item/Item.d.ts.map +1 -1
  114. package/dist/Item/Item.js +2 -2
  115. package/dist/Kbd/Kbd.d.ts.map +1 -1
  116. package/dist/Kbd/Kbd.js +2 -26
  117. package/dist/Layer/gestureCounter.d.ts +8 -0
  118. package/dist/Layer/gestureCounter.d.ts.map +1 -0
  119. package/dist/Layer/gestureCounter.js +53 -0
  120. package/dist/Layer/useLayer.d.ts +23 -13
  121. package/dist/Layer/useLayer.d.ts.map +1 -1
  122. package/dist/Layer/useLayer.js +146 -24
  123. package/dist/List/List.d.ts +1 -1
  124. package/dist/List/List.d.ts.map +1 -1
  125. package/dist/List/List.js +15 -4
  126. package/dist/Markdown/Markdown.d.ts +1 -1
  127. package/dist/Markdown/Markdown.d.ts.map +1 -1
  128. package/dist/Markdown/Markdown.js +20 -7
  129. package/dist/Markdown/parser.d.ts.map +1 -1
  130. package/dist/Markdown/parser.js +5 -3
  131. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  132. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  133. package/dist/MetadataList/MetadataListItem.js +4 -1
  134. package/dist/MultiSelector/MultiSelector.d.ts +18 -1
  135. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  136. package/dist/MultiSelector/MultiSelector.js +58 -11
  137. package/dist/MultiSelector/hooks.d.ts +7 -1
  138. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  139. package/dist/MultiSelector/hooks.js +3 -2
  140. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  141. package/dist/NavIcon/NavIcon.js +5 -1
  142. package/dist/NavItem/navItemStyles.stylex.d.ts +0 -8
  143. package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
  144. package/dist/NavItem/navItemStyles.stylex.js +0 -2
  145. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  146. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  147. package/dist/NavMenu/NavHeadingMenu.js +7 -4
  148. package/dist/NumberInput/NumberInput.d.ts +6 -1
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +95 -126
  151. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  152. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  153. package/dist/NumberInput/numberInputCommit.js +71 -0
  154. package/dist/NumberInput/numberParser.d.ts +64 -0
  155. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  156. package/dist/NumberInput/numberParser.js +350 -0
  157. package/dist/Outline/Outline.d.ts.map +1 -1
  158. package/dist/Outline/Outline.js +2 -3
  159. package/dist/OverflowList/OverflowList.d.ts +41 -1
  160. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  161. package/dist/OverflowList/OverflowList.js +43 -2
  162. package/dist/Popover/Popover.d.ts.map +1 -1
  163. package/dist/Popover/Popover.js +8 -14
  164. package/dist/Popover/usePopover.d.ts +15 -41
  165. package/dist/Popover/usePopover.d.ts.map +1 -1
  166. package/dist/Popover/usePopover.js +26 -7
  167. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchValueEditor.js +91 -18
  169. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  170. package/dist/PowerSearch/formatFilterValue.js +4 -2
  171. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  172. package/dist/ProgressBar/ProgressBar.js +18 -5
  173. package/dist/Resizable/useResizable.d.ts +19 -1
  174. package/dist/Resizable/useResizable.d.ts.map +1 -1
  175. package/dist/Resizable/useResizable.js +104 -38
  176. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  177. package/dist/SelectableCard/SelectableCard.js +9 -0
  178. package/dist/Selector/Selector.d.ts +18 -1
  179. package/dist/Selector/Selector.d.ts.map +1 -1
  180. package/dist/Selector/Selector.js +92 -21
  181. package/dist/Selector/hooks.d.ts +7 -1
  182. package/dist/Selector/hooks.d.ts.map +1 -1
  183. package/dist/Selector/hooks.js +3 -2
  184. package/dist/SideNav/SideNav.d.ts +6 -1
  185. package/dist/SideNav/SideNav.d.ts.map +1 -1
  186. package/dist/SideNav/SideNav.js +57 -27
  187. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  188. package/dist/SideNav/SideNavHeading.js +5 -4
  189. package/dist/SideNav/SideNavItem.d.ts +29 -4
  190. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  191. package/dist/SideNav/SideNavItem.js +75 -20
  192. package/dist/Slider/Slider.d.ts.map +1 -1
  193. package/dist/Slider/Slider.js +34 -2
  194. package/dist/Spinner/Spinner.d.ts +3 -1
  195. package/dist/Spinner/Spinner.d.ts.map +1 -1
  196. package/dist/Spinner/Spinner.js +199 -20
  197. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  198. package/dist/StatusDot/StatusDot.js +6 -1
  199. package/dist/Stepper/Step.d.ts.map +1 -1
  200. package/dist/Stepper/Step.js +7 -6
  201. package/dist/Switch/Switch.d.ts.map +1 -1
  202. package/dist/Switch/Switch.js +5 -1
  203. package/dist/Table/BaseTable.d.ts.map +1 -1
  204. package/dist/Table/BaseTable.js +6 -1
  205. package/dist/Table/Table.d.ts.map +1 -1
  206. package/dist/Table/Table.js +3 -6
  207. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  208. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  209. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
  210. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  211. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +34 -3
  212. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  213. package/dist/Table/plugins/selection/useTableSelection.js +25 -1
  214. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  215. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  216. package/dist/Text/Text.d.ts.map +1 -1
  217. package/dist/Text/Text.js +0 -1
  218. package/dist/TextArea/TextArea.d.ts.map +1 -1
  219. package/dist/TextArea/TextArea.js +13 -8
  220. package/dist/Timestamp/Timestamp.d.ts +1 -1
  221. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  222. package/dist/Timestamp/Timestamp.js +10 -18
  223. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  224. package/dist/Timestamp/formatInstant.js +10 -5
  225. package/dist/Toast/Toast.d.ts +17 -2
  226. package/dist/Toast/Toast.d.ts.map +1 -1
  227. package/dist/Toast/Toast.js +77 -11
  228. package/dist/Toast/ToastViewport.d.ts +1 -0
  229. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  230. package/dist/Toast/ToastViewport.js +76 -21
  231. package/dist/Toast/index.d.ts +1 -1
  232. package/dist/Toast/index.d.ts.map +1 -1
  233. package/dist/Toast/types.d.ts +38 -0
  234. package/dist/Toast/types.d.ts.map +1 -1
  235. package/dist/Toast/useToastGesture.d.ts +26 -0
  236. package/dist/Toast/useToastGesture.d.ts.map +1 -0
  237. package/dist/Toast/useToastGesture.js +223 -0
  238. package/dist/Token/Token.d.ts +1 -1
  239. package/dist/Token/Token.d.ts.map +1 -1
  240. package/dist/Token/Token.js +23 -12
  241. package/dist/Token/TokenLink.d.ts +1 -1
  242. package/dist/Token/TokenLink.d.ts.map +1 -1
  243. package/dist/Token/TokenLink.js +5 -2
  244. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  245. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  246. package/dist/Tokenizer/Tokenizer.js +31 -21
  247. package/dist/TopNav/TopNavHeading.js +2 -2
  248. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  249. package/dist/TopNav/TopNavItem.js +3 -3
  250. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  251. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  252. package/dist/TopNav/TopNavMegaMenu.js +30 -9
  253. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  254. package/dist/TopNav/TopNavMegaMenuItem.js +3 -3
  255. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  256. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMenu.js +21 -6
  258. package/dist/TreeList/TreeList.d.ts +1 -1
  259. package/dist/TreeList/TreeList.d.ts.map +1 -1
  260. package/dist/TreeList/TreeList.js +7 -2
  261. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  262. package/dist/TreeList/TreeListItem.js +2 -2
  263. package/dist/Typeahead/BaseTypeahead.d.ts +33 -0
  264. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  265. package/dist/Typeahead/BaseTypeahead.js +51 -8
  266. package/dist/Typeahead/Typeahead.d.ts +8 -1
  267. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  268. package/dist/Typeahead/Typeahead.js +2 -0
  269. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  270. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  271. package/dist/Typeahead/TypeaheadItem.js +7 -2
  272. package/dist/astryx.css +87 -22
  273. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  274. package/dist/hooks/useHotkeys.js +3 -25
  275. package/dist/hooks/useOverflow.d.ts.map +1 -1
  276. package/dist/hooks/useOverflow.js +14 -4
  277. package/dist/index.d.ts +1 -1
  278. package/dist/index.d.ts.map +1 -1
  279. package/dist/theme/Theme.d.ts.map +1 -1
  280. package/dist/theme/Theme.js +46 -10
  281. package/dist/theme/defineTheme.d.ts +9 -3
  282. package/dist/theme/defineTheme.d.ts.map +1 -1
  283. package/dist/theme/defineTheme.js +5 -0
  284. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  285. package/dist/theme/derivedVarRegistry.js +24 -4
  286. package/dist/theme/generateThemeRules.d.ts +21 -0
  287. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  288. package/dist/theme/generateThemeRules.js +26 -0
  289. package/dist/theme/syntax/tokens.d.ts +1 -1
  290. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  291. package/dist/theme/syntax/tokens.js +5 -2
  292. package/dist/theme/useTheme.d.ts.map +1 -1
  293. package/dist/theme/useTheme.js +6 -7
  294. package/dist/utils/dateParser.d.ts +5 -8
  295. package/dist/utils/dateParser.d.ts.map +1 -1
  296. package/dist/utils/dateParser.js +10 -11
  297. package/dist/utils/focusOutline.stylex.d.ts +25 -0
  298. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  299. package/dist/utils/focusOutline.stylex.js +15 -0
  300. package/dist/utils/interactionOverlay.stylex.d.ts +26 -0
  301. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -0
  302. package/dist/utils/interactionOverlay.stylex.js +42 -0
  303. package/dist/utils/isApplePlatform.d.ts +18 -0
  304. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  305. package/dist/utils/isApplePlatform.js +37 -0
  306. package/dist/utils/plainDate.d.ts +11 -0
  307. package/dist/utils/plainDate.d.ts.map +1 -1
  308. package/dist/utils/plainDate.js +20 -4
  309. package/locales/af-ZA.json +7 -7
  310. package/locales/ar-SA.json +7 -7
  311. package/locales/ca-ES.json +6 -6
  312. package/locales/cs-CZ.json +7 -7
  313. package/locales/da-DK.json +7 -7
  314. package/locales/de-DE.json +7 -7
  315. package/locales/el-GR.json +7 -7
  316. package/locales/en.json +178 -6
  317. package/locales/es-ES.json +6 -6
  318. package/locales/fi-FI.json +7 -7
  319. package/locales/fr-FR.json +7 -7
  320. package/locales/he-IL.json +7 -7
  321. package/locales/hu-HU.json +7 -7
  322. package/locales/it-IT.json +7 -7
  323. package/locales/ja-JP.json +7 -7
  324. package/locales/ko-KR.json +7 -7
  325. package/locales/nl-NL.json +7 -7
  326. package/locales/no-NO.json +7 -7
  327. package/locales/pl-PL.json +7 -7
  328. package/locales/pseudo.json +130 -1
  329. package/locales/pt-BR.json +7 -7
  330. package/locales/pt-PT.json +7 -7
  331. package/locales/ro-RO.json +7 -7
  332. package/locales/ru-RU.json +7 -7
  333. package/locales/sr-SP.json +7 -7
  334. package/locales/sv-SE.json +7 -7
  335. package/locales/tr-TR.json +7 -7
  336. package/locales/uk-UA.json +7 -7
  337. package/locales/vi-VN.json +7 -7
  338. package/locales/zh-CN.json +7 -7
  339. package/locales/zh-TW.json +7 -7
  340. package/package.json +4 -5
  341. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  342. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  343. package/src/AlertDialog/AlertDialog.tsx +62 -20
  344. package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
  345. package/src/AspectRatio/AspectRatio.tsx +6 -6
  346. package/src/Avatar/Avatar.doc.mjs +12 -2
  347. package/src/Avatar/Avatar.test.tsx +80 -0
  348. package/src/Avatar/Avatar.tsx +64 -14
  349. package/src/Avatar/index.ts +2 -2
  350. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  351. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  352. package/src/AvatarGroup/AvatarGroup.tsx +12 -4
  353. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  354. package/src/AvatarGroup/AvatarGroupOverflow.tsx +12 -12
  355. package/src/Badge/Badge.doc.mjs +3 -2
  356. package/src/Badge/Badge.test.tsx +32 -3
  357. package/src/Badge/Badge.tsx +42 -1
  358. package/src/Banner/Banner.doc.mjs +9 -0
  359. package/src/Banner/Banner.test.tsx +76 -11
  360. package/src/Banner/Banner.tsx +21 -2
  361. package/src/Button/Button.doc.mjs +2 -1
  362. package/src/Button/Button.test.tsx +19 -4
  363. package/src/Button/Button.tsx +9 -29
  364. package/src/ButtonGroup/ButtonGroup.doc.mjs +2 -2
  365. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -0
  366. package/src/Calendar/Calendar.doc.mjs +3 -3
  367. package/src/Calendar/Calendar.test.tsx +112 -0
  368. package/src/Calendar/Calendar.tsx +18 -16
  369. package/src/Calendar/hooks/useCalendarDays.ts +4 -4
  370. package/src/Calendar/hooks/useCalendarNavigation.ts +4 -4
  371. package/src/Calendar/styles.ts +48 -42
  372. package/src/Card/Card.doc.mjs +10 -7
  373. package/src/Card/Card.test.tsx +113 -19
  374. package/src/Card/Card.tsx +67 -89
  375. package/src/Card/index.ts +36 -1
  376. package/src/Carousel/Carousel.doc.mjs +3 -0
  377. package/src/Carousel/Carousel.test.tsx +360 -0
  378. package/src/Carousel/Carousel.tsx +116 -15
  379. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  380. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  381. package/src/CheckboxInput/CheckboxInput.tsx +5 -0
  382. package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
  383. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  384. package/src/CodeBlock/CodeBlock.tsx +20 -4
  385. package/src/CodeBlock/highlightRanges.ts +1 -1
  386. package/src/CodeBlock/highlightStyles.ts +13 -13
  387. package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
  388. package/src/ComplexSelector/ComplexSelector.doc.mjs +7 -0
  389. package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
  390. package/src/ComplexSelector/ComplexSelector.tsx +22 -12
  391. package/src/DateInput/DateInput.doc.mjs +16 -0
  392. package/src/DateInput/DateInput.test.tsx +9 -4
  393. package/src/DateInput/DateInput.tsx +54 -3
  394. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  395. package/src/DateInput/MonthScroller.tsx +5 -1
  396. package/src/DateInput/MonthYearWheels.tsx +7 -4
  397. package/src/DateInput/NativeDateField.test.tsx +635 -0
  398. package/src/DateInput/NativeDateField.tsx +641 -0
  399. package/src/DateInput/TouchDateField.tsx +83 -33
  400. package/src/DateInput/Wheel.tsx +1 -0
  401. package/src/DateInput/index.ts +1 -0
  402. package/src/DateInput/nativeDateSegments.ts +127 -0
  403. package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
  404. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
  405. package/src/DateRangeInput/DateRangeInput.tsx +8 -13
  406. package/src/DateTimeInput/DateTimeInput.doc.mjs +38 -21
  407. package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
  408. package/src/DateTimeInput/DateTimeInput.tsx +54 -20
  409. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
  410. package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
  411. package/src/Dialog/Dialog.test.tsx +185 -18
  412. package/src/Dialog/Dialog.tsx +35 -11
  413. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  414. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  415. package/src/Field/FieldLabel.test.tsx +29 -0
  416. package/src/Field/FieldLabel.tsx +7 -0
  417. package/src/Field/InputClearButton.test.tsx +15 -1
  418. package/src/Field/InputClearButton.tsx +28 -4
  419. package/src/Heading/Heading.tsx +0 -1
  420. package/src/HoverCard/HoverCard.doc.mjs +8 -2
  421. package/src/HoverCard/HoverCard.test.tsx +154 -4
  422. package/src/HoverCard/HoverCard.tsx +137 -3
  423. package/src/HoverCard/useHoverCard.tsx +23 -3
  424. package/src/Icon/Icon.test.tsx +55 -1
  425. package/src/Icon/Icon.tsx +5 -3
  426. package/src/Icon/defaultIcons.tsx +11 -2
  427. package/src/Icon/globalIconRegistry.test.tsx +16 -3
  428. package/src/Icon/globalIconRegistry.tsx +37 -6
  429. package/src/Icon/index.ts +1 -0
  430. package/src/Icon/useIcon.ts +9 -2
  431. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  432. package/src/Indicator/Indicator.doc.mjs +2 -0
  433. package/src/Item/Item.tsx +2 -7
  434. package/src/Kbd/Kbd.test.tsx +0 -17
  435. package/src/Kbd/Kbd.tsx +2 -26
  436. package/src/Layer/gestureCounter.ts +57 -0
  437. package/src/Layer/useLayer.test.tsx +368 -16
  438. package/src/Layer/useLayer.tsx +208 -35
  439. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  440. package/src/List/List.test.tsx +38 -0
  441. package/src/List/List.tsx +8 -1
  442. package/src/Markdown/Markdown.test.tsx +37 -0
  443. package/src/Markdown/Markdown.tsx +16 -5
  444. package/src/Markdown/parser.test.ts +33 -0
  445. package/src/Markdown/parser.ts +9 -3
  446. package/src/MetadataList/MetadataList.test.tsx +75 -2
  447. package/src/MetadataList/MetadataListItem.tsx +5 -2
  448. package/src/MultiSelector/MultiSelector.doc.mjs +22 -1
  449. package/src/MultiSelector/MultiSelector.test.tsx +205 -0
  450. package/src/MultiSelector/MultiSelector.tsx +103 -16
  451. package/src/MultiSelector/hooks.ts +9 -2
  452. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  453. package/src/NavIcon/NavIcon.test.tsx +9 -0
  454. package/src/NavIcon/NavIcon.tsx +5 -1
  455. package/src/NavItem/navItemStyles.stylex.ts +0 -8
  456. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  457. package/src/NavMenu/NavHeadingMenu.tsx +7 -4
  458. package/src/NumberInput/NumberInput.doc.mjs +26 -7
  459. package/src/NumberInput/NumberInput.test.tsx +563 -8
  460. package/src/NumberInput/NumberInput.tsx +77 -131
  461. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  462. package/src/NumberInput/numberInputCommit.ts +103 -0
  463. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  464. package/src/NumberInput/numberParser.test.ts +222 -0
  465. package/src/NumberInput/numberParser.ts +403 -0
  466. package/src/Outline/Outline.tsx +2 -4
  467. package/src/OverflowList/OverflowList.doc.mjs +102 -21
  468. package/src/OverflowList/OverflowList.test.tsx +550 -4
  469. package/src/OverflowList/OverflowList.tsx +100 -2
  470. package/src/Pagination/Pagination.test.tsx +3 -2
  471. package/src/Popover/Popover.doc.mjs +2 -2
  472. package/src/Popover/Popover.test.tsx +38 -0
  473. package/src/Popover/Popover.tsx +28 -66
  474. package/src/Popover/usePopover.tsx +44 -5
  475. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
  476. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
  477. package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
  478. package/src/PowerSearch/formatFilterValue.test.ts +16 -1
  479. package/src/PowerSearch/formatFilterValue.ts +2 -0
  480. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  481. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  482. package/src/ProgressBar/ProgressBar.tsx +28 -8
  483. package/src/Resizable/Resizable.doc.mjs +2 -2
  484. package/src/Resizable/useResizable.doc.mjs +21 -2
  485. package/src/Resizable/useResizable.test.ts +421 -0
  486. package/src/Resizable/useResizable.ts +133 -48
  487. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  488. package/src/SelectableCard/SelectableCard.tsx +16 -0
  489. package/src/Selector/Selector.doc.mjs +14 -0
  490. package/src/Selector/Selector.source-build.test.mjs +65 -0
  491. package/src/Selector/Selector.test.tsx +301 -0
  492. package/src/Selector/Selector.tsx +145 -32
  493. package/src/Selector/hooks.ts +17 -2
  494. package/src/SideNav/SideNav.doc.mjs +2 -2
  495. package/src/SideNav/SideNav.test.tsx +1069 -6
  496. package/src/SideNav/SideNav.tsx +109 -38
  497. package/src/SideNav/SideNavHeading.tsx +5 -2
  498. package/src/SideNav/SideNavItem.doc.mjs +24 -3
  499. package/src/SideNav/SideNavItem.tsx +134 -44
  500. package/src/Slider/Slider.test.tsx +106 -1
  501. package/src/Slider/Slider.tsx +52 -1
  502. package/src/Spinner/Spinner.doc.mjs +17 -5
  503. package/src/Spinner/Spinner.test.tsx +164 -0
  504. package/src/Spinner/Spinner.tsx +252 -22
  505. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  506. package/src/StatusDot/StatusDot.test.tsx +9 -0
  507. package/src/StatusDot/StatusDot.tsx +7 -1
  508. package/src/Stepper/Step.doc.mjs +1 -1
  509. package/src/Stepper/Step.tsx +7 -14
  510. package/src/Switch/Switch.doc.mjs +2 -0
  511. package/src/Switch/Switch.test.tsx +10 -0
  512. package/src/Switch/Switch.tsx +3 -0
  513. package/src/Table/BaseTable.tsx +6 -1
  514. package/src/Table/Table.doc.mjs +5 -3
  515. package/src/Table/Table.tsx +3 -8
  516. package/src/Table/TableBody.doc.mjs +2 -2
  517. package/src/Table/TableFooter.doc.mjs +1 -1
  518. package/src/Table/TableHeader.doc.mjs +1 -1
  519. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  520. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  521. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
  522. package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
  523. package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
  524. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  525. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  526. package/src/Table/useTablePagination.doc.mjs +1 -1
  527. package/src/Table/useTableSelection.doc.mjs +1 -1
  528. package/src/Text/Text.test.tsx +44 -0
  529. package/src/Text/Text.tsx +0 -1
  530. package/src/TextArea/TextArea.doc.mjs +12 -2
  531. package/src/TextArea/TextArea.test.tsx +11 -0
  532. package/src/TextArea/TextArea.tsx +34 -22
  533. package/src/Timestamp/Timestamp.test.tsx +89 -0
  534. package/src/Timestamp/Timestamp.tsx +8 -8
  535. package/src/Timestamp/formatInstant.ts +5 -0
  536. package/src/Toast/Toast.doc.mjs +213 -44
  537. package/src/Toast/Toast.tsx +118 -23
  538. package/src/Toast/ToastViewport.test.tsx +1434 -8
  539. package/src/Toast/ToastViewport.tsx +85 -14
  540. package/src/Toast/index.ts +2 -0
  541. package/src/Toast/types.ts +43 -5
  542. package/src/Toast/useToastGesture.ts +361 -0
  543. package/src/Token/Token.test.tsx +95 -0
  544. package/src/Token/Token.tsx +19 -17
  545. package/src/Token/TokenLink.tsx +12 -3
  546. package/src/Tokenizer/Tokenizer.doc.mjs +16 -3
  547. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  548. package/src/Tokenizer/Tokenizer.tsx +49 -24
  549. package/src/TopNav/TopNavHeading.tsx +2 -2
  550. package/src/TopNav/TopNavItem.tsx +3 -7
  551. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  552. package/src/TopNav/TopNavMegaMenu.tsx +47 -4
  553. package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
  554. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  555. package/src/TopNav/TopNavMenu.tsx +38 -5
  556. package/src/TreeList/TreeList.test.tsx +49 -0
  557. package/src/TreeList/TreeList.tsx +7 -2
  558. package/src/TreeList/TreeListItem.tsx +2 -7
  559. package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
  560. package/src/Typeahead/BaseTypeahead.tsx +96 -6
  561. package/src/Typeahead/Typeahead.doc.mjs +6 -0
  562. package/src/Typeahead/Typeahead.test.tsx +154 -0
  563. package/src/Typeahead/Typeahead.tsx +9 -0
  564. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  565. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  566. package/src/hooks/useAnnounce.doc.mjs +96 -0
  567. package/src/hooks/useDevWarning.doc.mjs +96 -0
  568. package/src/hooks/useHotkeys.test.ts +0 -18
  569. package/src/hooks/useHotkeys.ts +3 -25
  570. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  571. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  572. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  573. package/src/hooks/useLongPress.doc.mjs +123 -0
  574. package/src/hooks/useOverflow.doc.mjs +58 -17
  575. package/src/hooks/useOverflow.ts +16 -4
  576. package/src/hooks/useTypeahead.doc.mjs +153 -0
  577. package/src/index.ts +2 -0
  578. package/src/raw-import.d.ts +14 -0
  579. package/src/theme/Theme.test.tsx +104 -2
  580. package/src/theme/Theme.tsx +49 -14
  581. package/src/theme/defineTheme.test.ts +23 -0
  582. package/src/theme/defineTheme.ts +12 -3
  583. package/src/theme/derivedVarRegistry.test.ts +87 -3
  584. package/src/theme/derivedVarRegistry.ts +23 -4
  585. package/src/theme/generateThemeRules.test.ts +99 -1
  586. package/src/theme/generateThemeRules.ts +28 -0
  587. package/src/theme/syntax/tokens.ts +5 -2
  588. package/src/theme/useTheme.test.tsx +10 -0
  589. package/src/theme/useTheme.ts +16 -10
  590. package/src/utils/dateParser.test.ts +34 -2
  591. package/src/utils/dateParser.ts +11 -14
  592. package/src/utils/focusOutline.stylex.ts +50 -0
  593. package/src/utils/interactionOverlay.stylex.ts +74 -0
  594. package/src/utils/isApplePlatform.test.ts +61 -0
  595. package/src/utils/isApplePlatform.ts +37 -0
  596. package/src/utils/plainDate.test.ts +46 -0
  597. package/src/utils/plainDate.ts +18 -3
@@ -21,13 +21,7 @@
21
21
  * - /packages/cli/assets/templates/blocks/components/SideNav/ (showcase blocks)
22
22
  */
23
23
 
24
- import {
25
- useCallback,
26
- useImperativeHandle,
27
- useRef,
28
- useState,
29
- type ReactNode,
30
- } from 'react';
24
+ import {useCallback, useImperativeHandle, useRef, type ReactNode} from 'react';
31
25
  import type {BaseProps} from '../BaseProps';
32
26
  import * as stylex from '@stylexjs/stylex';
33
27
  import type {StyleXStyles} from '@stylexjs/stylex';
@@ -47,6 +41,7 @@ import type {ResizableConfig} from '../Resizable/useResizable';
47
41
  import {ResizeHandle} from '../Resizable/ResizeHandle';
48
42
  import {themeProps} from '../utils/themeProps';
49
43
  import {SizeProvider} from '../SizeContext/SizeContext';
44
+ import {useDevWarning} from '../hooks/useDevWarning';
50
45
  import {useTranslator} from '../i18n';
51
46
 
52
47
  import {useMergedRefs} from '../hooks/useMergedRefs';
@@ -57,6 +52,85 @@ import {useMergedRefs} from '../hooks/useMergedRefs';
57
52
  /** Width below which dragging collapses the sidebar (when collapsible). */
58
53
  const COLLAPSE_THRESHOLD = 160;
59
54
 
55
+ // =============================================================================
56
+ // Collapse config
57
+ // =============================================================================
58
+
59
+ interface ResolvedCollapseConfig {
60
+ isCollapsible: boolean;
61
+ defaultIsCollapsed: boolean;
62
+ isCollapsed: boolean | undefined;
63
+ onCollapsedChange: ((isCollapsed: boolean) => void) | undefined;
64
+ /** Dev-warning text when both props address the same state, else null. */
65
+ conflict: string | null;
66
+ }
67
+
68
+ /**
69
+ * `collapsible` and `resizable` can each carry collapse state, so they are
70
+ * normalized here into one config with one owner — two independently
71
+ * initialized copies of the same boolean is what rendered an expanded nav at
72
+ * width 0 in #4790. `resizable` is the superset, so its keys win.
73
+ */
74
+ function resolveCollapseConfig(
75
+ collapsible: boolean | SideNavCollapsibleConfig,
76
+ resizable: boolean | ResizableConfig,
77
+ ): ResolvedCollapseConfig {
78
+ const fromCollapsible = typeof collapsible === 'object' ? collapsible : {};
79
+ const fromResizable = typeof resizable === 'object' ? resizable : {};
80
+
81
+ const resizableCarriesCollapse =
82
+ fromResizable.defaultIsCollapsed !== undefined ||
83
+ fromResizable.isCollapsed !== undefined ||
84
+ fromResizable.onCollapseChange !== undefined;
85
+
86
+ return {
87
+ isCollapsible: !!collapsible || resizableCarriesCollapse,
88
+ defaultIsCollapsed:
89
+ (resizableCarriesCollapse
90
+ ? fromResizable.defaultIsCollapsed
91
+ : fromCollapsible.defaultIsCollapsed) ?? false,
92
+ isCollapsed: resizableCarriesCollapse
93
+ ? fromResizable.isCollapsed
94
+ : fromCollapsible.isCollapsed,
95
+ onCollapsedChange: resizableCarriesCollapse
96
+ ? fromResizable.onCollapseChange
97
+ : fromCollapsible.onCollapsedChange,
98
+ conflict: describeCollapseConflict(fromCollapsible, fromResizable),
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Names the keys that address the same collapse state on both props, and
104
+ * which one won. Silent for the common non-overlapping combinations —
105
+ * `collapsible: true` alongside a resize config is not a conflict.
106
+ */
107
+ function describeCollapseConflict(
108
+ collapsible: SideNavCollapsibleConfig,
109
+ resizable: ResizableConfig,
110
+ ): string | null {
111
+ const collapsibleKeys = [
112
+ collapsible.defaultIsCollapsed !== undefined && 'defaultIsCollapsed',
113
+ collapsible.isCollapsed !== undefined && 'isCollapsed',
114
+ collapsible.onCollapsedChange !== undefined && 'onCollapsedChange',
115
+ ].filter((key): key is string => key !== false);
116
+ const resizableKeys = [
117
+ resizable.defaultIsCollapsed !== undefined && 'defaultIsCollapsed',
118
+ resizable.isCollapsed !== undefined && 'isCollapsed',
119
+ resizable.onCollapseChange !== undefined && 'onCollapseChange',
120
+ ].filter((key): key is string => key !== false);
121
+
122
+ if (collapsibleKeys.length === 0 || resizableKeys.length === 0) {
123
+ return null;
124
+ }
125
+
126
+ return (
127
+ `${collapsibleKeys.map(key => `collapsible.${key}`).join(', ')} and ` +
128
+ `${resizableKeys.map(key => `resizable.${key}`).join(', ')} address the ` +
129
+ `same collapse state. resizable wins; the collapsible ` +
130
+ `${collapsibleKeys.length === 1 ? 'value is' : 'values are'} ignored.`
131
+ );
132
+ }
133
+
60
134
  // =============================================================================
61
135
  // Styles
62
136
  // =============================================================================
@@ -269,8 +343,13 @@ export interface SideNavProps extends BaseProps<HTMLElement> {
269
343
  * - `defaultWidth` — initial width in pixels (default: 260)
270
344
  * - `minWidth` — minimum width in pixels (default: 180)
271
345
  * - `maxWidth` — maximum width in pixels (default: 480)
272
- * - `autoSaveId` — localStorage key for persisting width
346
+ * - `autoSaveId` — localStorage key for persisting width and collapse state
273
347
  * - `onWidthChange` — called when the width changes
348
+ * - `defaultIsCollapsed` / `isCollapsed` / `onCollapseChange` — collapse
349
+ * state, when `resizable` should own it rather than `collapsible`
350
+ *
351
+ * When both props carry collapse state, `resizable` wins and a dev warning
352
+ * names the conflicting keys.
274
353
  *
275
354
  * @default false
276
355
  */
@@ -334,40 +413,31 @@ export function SideNav({
334
413
  const t = useTranslator();
335
414
  // Parse collapsible prop
336
415
  const collapsibleConfig = typeof collapsible === 'object' ? collapsible : {};
337
- const isCollapsible = !!collapsible;
338
416
  const hasCollapseButton = collapsibleConfig.hasButton ?? true;
339
- const defaultIsCollapsed = collapsibleConfig.defaultIsCollapsed ?? false;
340
- const controlledCollapsed = collapsibleConfig.isCollapsed;
341
- const onCollapsedChange = collapsibleConfig.onCollapsedChange;
342
417
 
343
418
  // Resizable config
344
419
  const resizableConfig = typeof resizable === 'object' ? resizable : {};
345
420
  const isResizable = !!resizable;
346
421
 
347
- // Collapse state (controlled + uncontrolled)
348
- const isControlled = controlledCollapsed !== undefined;
349
- const [uncontrolledCollapsed, setUncontrolledCollapsed] =
350
- useState(defaultIsCollapsed);
351
- const collapsed = isControlled ? controlledCollapsed : uncontrolledCollapsed;
422
+ const collapseConfig = resolveCollapseConfig(collapsible, resizable);
423
+ const {isCollapsible, onCollapsedChange} = collapseConfig;
424
+
425
+ useDevWarning(
426
+ 'SideNav',
427
+ collapseConfig.conflict ?? '',
428
+ collapseConfig.conflict != null,
429
+ );
430
+
352
431
  const navRef = useRef<HTMLElement>(null);
353
432
  const mergedNavRef = useMergedRefs(ref, navRef);
354
433
  const collapseStateRef = useRef<SideNavCollapseState>({
355
- isCollapsed: collapsed,
434
+ isCollapsed: false,
356
435
  toggle: () => {},
357
436
  isCollapsible,
358
437
  });
359
438
 
360
- const setCollapsedState = useCallback(
361
- (value: boolean) => {
362
- if (!isControlled) {
363
- setUncontrolledCollapsed(value);
364
- }
365
- onCollapsedChange?.(value);
366
- },
367
- [isControlled, onCollapsedChange],
368
- );
369
-
370
- // Resize hook — callbacks keep SideNav in sync without effects.
439
+ // useResizable is the sole collapse owner in every SideNav mode. Keeping that
440
+ // owner mounted when resize is toggled preserves the current collapse state.
371
441
  const resizableHook = useResizable({
372
442
  defaultSize: resizableConfig.defaultWidth ?? 260,
373
443
  minSizePx: resizableConfig.minWidth ?? 180,
@@ -375,10 +445,14 @@ export function SideNav({
375
445
  collapsible: isCollapsible,
376
446
  collapsedSize: COLLAPSE_THRESHOLD,
377
447
  autoSaveId: resizableConfig.autoSaveId,
448
+ defaultIsCollapsed: collapseConfig.defaultIsCollapsed,
449
+ isCollapsed: collapseConfig.isCollapsed,
378
450
  onSizeChange: resizableConfig.onWidthChange,
379
- onCollapseChange: isCollapsible ? setCollapsedState : undefined,
451
+ onCollapseChange: onCollapsedChange,
380
452
  });
381
453
 
454
+ const collapsed = resizableHook.isCollapsed;
455
+
382
456
  const toggle = useCallback(() => {
383
457
  const next = !collapsed;
384
458
 
@@ -389,15 +463,12 @@ export function SideNav({
389
463
  isCollapsed: next,
390
464
  };
391
465
 
392
- setCollapsedState(next);
393
- if (isResizable) {
394
- if (next) {
395
- resizableHook.collapse();
396
- } else {
397
- resizableHook.expand();
398
- }
466
+ if (next) {
467
+ resizableHook.collapse();
468
+ } else {
469
+ resizableHook.expand();
399
470
  }
400
- }, [collapsed, setCollapsedState, isResizable, resizableHook]);
471
+ }, [collapsed, resizableHook]);
401
472
 
402
473
  const showResizeHandle = isResizable && !collapsed;
403
474
 
@@ -37,6 +37,7 @@ import {Icon} from '../Icon';
37
37
  import {Tooltip} from '../Tooltip';
38
38
  import {navItemStyles} from '../NavItem/navItemStyles.stylex';
39
39
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
40
+ import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
40
41
  import {useSideNavCollapse} from './SideNavCollapseContext';
41
42
  import {useLinkComponent} from '../Link/useLinkComponent';
42
43
  import type {LinkComponentType} from '../Link/types';
@@ -60,7 +61,7 @@ const styles = stylex.create({
60
61
  minHeight: spacingVars['--spacing-8'],
61
62
  paddingInlineStart: {
62
63
  default: spacingVars['--spacing-2'],
63
- ':has(.astryx-navicon)': 0,
64
+ ':has(.astryx-nav-icon)': 0,
64
65
  },
65
66
  paddingInlineEnd: spacingVars['--spacing-2'],
66
67
  paddingBlock: 0,
@@ -212,7 +213,7 @@ const styles = stylex.create({
212
213
  minHeight: spacingVars['--spacing-8'],
213
214
  paddingInlineStart: {
214
215
  default: spacingVars['--spacing-2'],
215
- ':has(.astryx-navicon)': 0,
216
+ ':has(.astryx-nav-icon)': 0,
216
217
  },
217
218
  paddingInlineEnd: spacingVars['--spacing-2'],
218
219
  paddingBlock: 0,
@@ -433,6 +434,7 @@ export function SideNavHeading({
433
434
  themeProps('side-nav-heading'),
434
435
  focusOutlineProps.focusVisible(
435
436
  navItemStyles.item,
437
+ interactionOverlayStyles.backgroundColor,
436
438
  styles.rootCollapsed,
437
439
  xstyle,
438
440
  ),
@@ -456,6 +458,7 @@ export function SideNavHeading({
456
458
  themeProps('side-nav-heading'),
457
459
  focusOutlineProps.focusVisible(
458
460
  navItemStyles.item,
461
+ interactionOverlayStyles.backgroundColor,
459
462
  styles.rootCollapsed,
460
463
  styles.menuTrigger,
461
464
  xstyle,
@@ -55,7 +55,7 @@ export const docs = {
55
55
  {
56
56
  name: 'endContent',
57
57
  type: 'ReactNode',
58
- description: 'Right-side content such as badges or counts.',
58
+ description: 'Passive right-side content only (badges, counts). Interactive controls go in actions.',
59
59
  slotElements: [
60
60
  {
61
61
  __element: 'Icon',
@@ -72,6 +72,18 @@ export const docs = {
72
72
  },
73
73
  ],
74
74
  },
75
+ {
76
+ name: 'actions',
77
+ type: 'ReactNode',
78
+ description:
79
+ 'Row-level secondary controls (icon buttons, menus) rendered as siblings of the primary element at the trailing edge of the row — after the expand/collapse toggle, before any nested children in DOM and focus order. Each control owns its accessible name and behavior. Controls inherit the row control size through SizeContext, so an unsized icon button matches the built-in expand/collapse toggle; an explicit size still wins. Hidden while the SideNav rail is collapsed. Use endContent for passive content (badges, counts); use actions for anything interactive.',
80
+ slotElements: [
81
+ {
82
+ __element: 'Button',
83
+ props: {label: 'Rename', variant: 'ghost', size: 'sm'},
84
+ },
85
+ ],
86
+ },
75
87
  {
76
88
  name: 'children',
77
89
  type: 'ReactNode',
@@ -152,7 +164,13 @@ export const docsZh = {
152
164
  {
153
165
  name: 'endContent',
154
166
  type: 'ReactNode',
155
- description: '右侧内容,如徽章或计数。',
167
+ description: '仅用于被动右侧内容(徽章、计数)。交互控件请使用 actions。',
168
+ },
169
+ {
170
+ name: 'actions',
171
+ type: 'ReactNode',
172
+ description:
173
+ '行级次要控件(图标按钮、菜单),作为主元素的同级节点渲染在行尾——位于展开/折叠切换按钮之后、任何嵌套子项之前(DOM 与焦点顺序一致)。每个控件自行负责其无障碍名称与行为。控件通过 SizeContext 继承行内控件尺寸,因此未指定尺寸的图标按钮会与内置的展开/折叠切换按钮保持同一尺寸;显式指定的 size 优先。侧边栏折叠为图标栏时隐藏。被动内容(徽章、计数)请使用 endContent;交互内容请使用 actions。',
156
174
  },
157
175
  {
158
176
  name: 'children',
@@ -188,7 +206,10 @@ export const docsDense = {
188
206
  isDisabled: 'Disabled state.',
189
207
  href: 'Navigation URL.',
190
208
  onClick: 'Click handler.',
191
- endContent: 'Right-side content such as badges or counts.',
209
+ endContent:
210
+ 'Passive right-side content only (badges, counts). Interactive controls go in actions.',
211
+ actions:
212
+ 'Row-level secondary controls (icon buttons, menus) rendered as siblings of the primary element, after the expand/collapse toggle and before nested children in DOM/focus order. Inherit the row control size via SizeContext (explicit size wins). Hidden when rail collapsed. Passive content goes in endContent; interactive content goes here.',
192
213
  children: 'Sub-items for nesting.',
193
214
  collapsible: 'Enables collapse for items w/ children. true=uncontrolled, object=controlled mode.',
194
215
  size: "Row size variant: 'sm' | 'md' | 'lg'.",
@@ -8,7 +8,7 @@
8
8
  * @output Exports SideNavItem component and SideNavItemProps
9
9
  * @position Core implementation; used inside SideNav children
10
10
  *
11
- * Navigation item with icon, selected state, and nesting.
11
+ * Navigation item with icon, selected state, row-level actions, and nesting.
12
12
  *
13
13
  * Collapsed items with children open their submenu flyout through
14
14
  * `useMenuHover`, the shared hover-intent hook (same one `SideNavHeading` and
@@ -51,7 +51,9 @@ import {mergeProps} from '../utils';
51
51
  import type {BaseProps} from '../BaseProps';
52
52
  import {Tooltip} from '../Tooltip';
53
53
  import {navItemStyles, type NavItemSize} from '../NavItem/navItemStyles.stylex';
54
+ import {SizeProvider} from '../SizeContext/SizeContext';
54
55
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
56
+ import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
55
57
  import {
56
58
  useSideNavCollapse,
57
59
  SideNavCollapseContext,
@@ -91,6 +93,18 @@ const styles = stylex.create({
91
93
  display: 'flex',
92
94
  alignItems: 'center',
93
95
  },
96
+ // Row-level secondary controls (actions slot) — siblings of the primary
97
+ // element at the trailing edge of the row. pointerEvents opts back in when
98
+ // a disabled row's navItemStyles.disabled sets pointer-events: none on the
99
+ // wrapper: the slot is passthrough, so each control owns its own disabled
100
+ // state (keyboard focus already reaches it either way).
101
+ actions: {
102
+ flexShrink: 0,
103
+ display: 'flex',
104
+ alignItems: 'center',
105
+ gap: spacingVars['--spacing-1'],
106
+ pointerEvents: 'auto',
107
+ },
94
108
  children: {
95
109
  paddingInlineStart: spacingVars['--spacing-6'],
96
110
  },
@@ -135,7 +149,13 @@ const styles = stylex.create({
135
149
  transform: 'rotate(180deg)',
136
150
  },
137
151
  // Standalone toggle button for the chevron when collapsible + href.
152
+ // Boxed like a `size="sm"` icon Button so it and whatever sits in
153
+ // `actions` paint one size of hover pill; without a box of its own it
154
+ // shrank to the 24px chevron beside a 28px menu button.
155
+ // SYNC: matches ROW_CONTROL_SIZE below.
138
156
  expandToggle: {
157
+ width: sizeVars['--size-element-sm'],
158
+ height: sizeVars['--size-element-sm'],
139
159
  display: 'inline-flex',
140
160
  alignItems: 'center',
141
161
  justifyContent: 'center',
@@ -151,14 +171,6 @@ const styles = stylex.create({
151
171
  ':is(:disabled,[aria-disabled="true"])': 'default',
152
172
  },
153
173
  borderRadius: radiusVars['--radius-element'],
154
- ':hover:where(:not(:disabled,[aria-disabled="true"]))': {
155
- '@media (hover: hover)': {
156
- backgroundColor: colorVars['--color-overlay-hover'],
157
- },
158
- },
159
- ':active': {
160
- backgroundColor: colorVars['--color-overlay-pressed'],
161
- },
162
174
  },
163
175
  // Primary action element inside the split-action row (link or button).
164
176
  // Flex:1 so it fills remaining space, giving a wide click target.
@@ -217,6 +229,16 @@ const styles = stylex.create({
217
229
  },
218
230
  });
219
231
 
232
+ /**
233
+ * Cascaded to the `actions` slot through `SizeContext` so a consumer's row
234
+ * controls come out the same height as the built-in expand/collapse toggle,
235
+ * the way `SideNav` already cascades one size to its footer icons. An
236
+ * explicit `size` on a supplied control still wins.
237
+ *
238
+ * SYNC: `styles.expandToggle` carries the matching box.
239
+ */
240
+ const ROW_CONTROL_SIZE = 'sm';
241
+
220
242
  // Non-collapsed state for popover children — ensures nested items render expanded
221
243
  const EXPANDED_COLLAPSE_STATE = {
222
244
  isCollapsed: false,
@@ -319,9 +341,24 @@ export interface SideNavItemProps extends BaseProps<HTMLElement> {
319
341
  */
320
342
  onClick?: (e: React.MouseEvent) => void;
321
343
  /**
322
- * Right-side content (badges, counts).
344
+ * Passive right-side content only (badges, counts). Interactive
345
+ * controls (icon buttons, menus) go in `actions`. `endContent`
346
+ * renders inside the primary link or button.
323
347
  */
324
348
  endContent?: ReactNode;
349
+ /**
350
+ * Row-level secondary controls (icon buttons, menus) rendered as siblings
351
+ * of the primary element at the trailing edge of the row — after the
352
+ * expand/collapse toggle, and before any nested children in DOM and focus
353
+ * order. Content is passthrough: each control owns its accessible name,
354
+ * keyboard behavior, and disabled state. Hidden while the SideNav rail is
355
+ * collapsed.
356
+ *
357
+ * Controls inherit the row's control size through `SizeContext`, so an
358
+ * unsized icon button comes out the same box as the built-in
359
+ * expand/collapse toggle. An explicit `size` still wins.
360
+ */
361
+ actions?: ReactNode;
325
362
  /**
326
363
  * Sub-items for nesting.
327
364
  */
@@ -358,7 +395,10 @@ export interface SideNavItemProps extends BaseProps<HTMLElement> {
358
395
  /**
359
396
  * Navigation item for SideNav.
360
397
  *
361
- * Supports icons, selected state, nesting, and end content like badges or counts.
398
+ * Supports icons, selected state, nesting, and end content like badges or
399
+ * counts. Interactive row-level controls (menus, icon buttons) go in
400
+ * `actions`, which renders them as siblings of the primary element — never
401
+ * nested inside it — before any nested children in DOM and focus order.
362
402
  *
363
403
  * @example
364
404
  * ```
@@ -373,6 +413,13 @@ export interface SideNavItemProps extends BaseProps<HTMLElement> {
373
413
  * <SideNavItem label="General" href="/settings/general" />
374
414
  * <SideNavItem label="Security" href="/settings/security" />
375
415
  * </SideNavItem>
416
+ * <SideNavItem
417
+ * label="Projects"
418
+ * href="/projects"
419
+ * collapsible
420
+ * actions={<MoreMenu label="Project actions" items={items} />}>
421
+ * <SideNavItem label="Alpha" href="/projects/alpha" />
422
+ * </SideNavItem>
376
423
  * ```
377
424
  */
378
425
  export function SideNavItem({
@@ -385,6 +432,7 @@ export function SideNavItem({
385
432
  href,
386
433
  onClick,
387
434
  endContent,
435
+ actions,
388
436
  children,
389
437
  collapsible: itemCollapsible,
390
438
  size = 'md',
@@ -442,6 +490,7 @@ export function SideNavItem({
442
490
  const hasPrimaryAction = !!href || !!onClick;
443
491
  const hasIndependentToggle =
444
492
  isItemCollapsible && hasPrimaryAction && !isCollapsed;
493
+ const hasActions = !!actions;
445
494
 
446
495
  const handleClick = (e: React.MouseEvent) => {
447
496
  if (isDisabled) {
@@ -512,6 +561,7 @@ export function SideNavItem({
512
561
  }),
513
562
  focusOutlineProps.focusVisible(
514
563
  navItemStyles.item,
564
+ interactionOverlayStyles.backgroundColor,
515
565
  navItemStyles[size],
516
566
  styles.itemCollapsed,
517
567
  size === 'sm' && styles.itemCollapsedSm,
@@ -617,30 +667,56 @@ export function SideNavItem({
617
667
 
618
668
  const itemStyleArgs = [
619
669
  navItemStyles.item,
670
+ interactionOverlayStyles.backgroundColor,
620
671
  navItemStyles[size],
621
672
  isSelected && navItemStyles.selected,
622
673
  isDisabled && navItemStyles.disabled,
623
674
  ] as const;
624
675
 
625
- // Two shapes of the same row appearance:
626
- // - `rowProps` for the split-action path, where the row is a plain <div>
627
- // container and its children take focus (so the ring belongs on them);
628
- // - `focusableRowProps` for every other path, where the row element is
629
- // itself the focusable control.
676
+ // Three shapes of the same row appearance:
677
+ // - `rowProps` — split-action path (toggle, no actions): presentational
678
+ // <div>; the ring belongs on each child tab stop.
679
+ // - `focusableRowProps` — ordinary row: the row element is the control.
680
+ // - `actionsRowProps` — same pill, but the ring is drawn for the primary
681
+ // only. The wrapper is not a tab stop, so `:focus-visible` on it would
682
+ // never match, and matching any descendant instead would light the whole
683
+ // row around the chevron's or an action's own ring.
630
684
  const rowProps = mergeProps(itemThemeProps, stylex.props(...itemStyleArgs));
631
685
  const focusableRowProps = mergeProps(
632
686
  itemThemeProps,
633
687
  focusOutlineProps.focusVisible(...itemStyleArgs),
634
688
  );
689
+ const actionsRowProps = mergeProps(
690
+ itemThemeProps,
691
+ focusOutlineProps.focusWithinFirstChild(...itemStyleArgs),
692
+ );
693
+
694
+ // Row-wrapper path: primary element + row controls as siblings.
695
+ //
696
+ // Used when the row carries more than one control: an independent
697
+ // expand/collapse toggle (collapsible + href/onClick), consumer-supplied
698
+ // actions, or both. A <div> is the styled flex row; the primary link or
699
+ // button, the chevron toggle, and the actions slot render as siblings so
700
+ // no interactive element nests inside another, and every row-level
701
+ // control precedes the nested children group in DOM and focus order.
702
+ const hasRowWrapper = hasIndependentToggle || hasActions;
635
703
 
636
- // Split-action path: collapsible plus a primary action renders the primary
637
- // element and the chevron toggle as siblings in a <div> row, since a
638
- // <button> cannot nest inside an <a>.
639
704
  let itemElement;
640
705
 
641
- if (hasIndependentToggle) {
706
+ if (hasRowWrapper) {
707
+ // aria-expanded/-controls stay on the primary element only when the
708
+ // whole row is the collapse toggle (no independent chevron button).
709
+ const rowPrimaryAriaProps = hasIndependentToggle
710
+ ? {'aria-current': isSelected ? ('page' as const) : undefined}
711
+ : {
712
+ 'aria-current': isSelected ? ('page' as const) : undefined,
713
+ 'aria-disabled': isDisabled || undefined,
714
+ 'aria-expanded': isItemCollapsible ? !isItemCollapsed : undefined,
715
+ 'aria-controls': isItemCollapsible ? `${id}-children` : undefined,
716
+ };
717
+
642
718
  itemElement = (
643
- <div data-testid={testId} {...rowProps}>
719
+ <div data-testid={testId} {...(hasActions ? actionsRowProps : rowProps)}>
644
720
  <NavItemElement
645
721
  ref={ref}
646
722
  href={href}
@@ -648,31 +724,45 @@ export function SideNavItem({
648
724
  isDisabled={isDisabled}
649
725
  onClick={handleClick}
650
726
  {...rest}
651
- aria-current={isSelected ? ('page' as const) : undefined}
652
- {...focusOutlineProps.focusVisible(styles.splitAction)}>
727
+ {...rowPrimaryAriaProps}
728
+ {...(hasActions
729
+ ? // The wrapper rings for this element; suppressing here is what
730
+ // keeps the UA's own ring from painting inside that one.
731
+ focusOutlineProps.suppressed(styles.splitAction)
732
+ : focusOutlineProps.focusVisible(styles.splitAction))}>
653
733
  {itemContent}
654
734
  </NavItemElement>
655
- <button
656
- type="button"
657
- onClick={handleToggleClick}
658
- aria-label={
659
- isItemCollapsed
660
- ? t('@astryx.sideNavItem.expand', {label})
661
- : t('@astryx.sideNavItem.collapse', {label})
662
- }
663
- aria-expanded={!isItemCollapsed}
664
- aria-controls={`${id}-children`}
665
- {...focusOutlineProps.focusVisible(styles.expandToggle)}>
666
- <Icon
667
- icon="chevronDown"
668
- size="lg"
669
- color="inherit"
670
- xstyle={[
671
- styles.expandChevron,
672
- !isItemCollapsed && styles.expandChevronExpanded,
673
- ]}
674
- />
675
- </button>
735
+ {hasIndependentToggle && (
736
+ <button
737
+ type="button"
738
+ onClick={handleToggleClick}
739
+ aria-label={
740
+ isItemCollapsed
741
+ ? t('@astryx.sideNavItem.expand', {label})
742
+ : t('@astryx.sideNavItem.collapse', {label})
743
+ }
744
+ aria-expanded={!isItemCollapsed}
745
+ aria-controls={`${id}-children`}
746
+ {...focusOutlineProps.focusVisible(
747
+ styles.expandToggle,
748
+ interactionOverlayStyles.backgroundColor,
749
+ )}>
750
+ <Icon
751
+ icon="chevronDown"
752
+ size="lg"
753
+ color="inherit"
754
+ xstyle={[
755
+ styles.expandChevron,
756
+ !isItemCollapsed && styles.expandChevronExpanded,
757
+ ]}
758
+ />
759
+ </button>
760
+ )}
761
+ {hasActions && (
762
+ <span {...stylex.props(styles.actions)}>
763
+ <SizeProvider value={ROW_CONTROL_SIZE}>{actions}</SizeProvider>
764
+ </span>
765
+ )}
676
766
  </div>
677
767
  );
678
768
  } else {