@astryxdesign/core 0.1.9 → 0.2.0-canary.136a00f

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 (560) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/dist/Avatar/Avatar.d.ts +42 -3
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +190 -59
  5. package/dist/Avatar/AvatarStatusDot.d.ts +6 -4
  6. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  7. package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
  8. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  9. package/dist/AvatarGroup/AvatarGroup.js +58 -6
  10. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  11. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  12. package/dist/AvatarGroup/AvatarGroupOverflow.js +7 -2
  13. package/dist/Banner/Banner.js +2 -2
  14. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  15. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -4
  16. package/dist/Breadcrumbs/index.d.ts +1 -0
  17. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  18. package/dist/Breadcrumbs/index.js +2 -1
  19. package/dist/Button/Button.d.ts +1 -1
  20. package/dist/Button/Button.d.ts.map +1 -1
  21. package/dist/Button/Button.js +6 -4
  22. package/dist/Calendar/Calendar.d.ts.map +1 -1
  23. package/dist/Calendar/Calendar.js +50 -9
  24. package/dist/Calendar/dayCellUtils.d.ts +4 -4
  25. package/dist/Calendar/dayCellUtils.js +2 -2
  26. package/dist/Calendar/styles.d.ts +30 -31
  27. package/dist/Calendar/styles.d.ts.map +1 -1
  28. package/dist/Calendar/styles.js +30 -31
  29. package/dist/Card/Card.js +1 -1
  30. package/dist/Carousel/Carousel.d.ts.map +1 -1
  31. package/dist/Carousel/Carousel.js +22 -12
  32. package/dist/Chat/ChatComposerInput.js +1 -1
  33. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  34. package/dist/Chat/ChatDictationButton.js +3 -1
  35. package/dist/Chat/ChatLayout.js +4 -4
  36. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  37. package/dist/Chat/ChatMessageBubble.js +8 -8
  38. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  39. package/dist/Chat/ChatToolCalls.js +10 -3
  40. package/dist/Chat/useTriggerMenu.js +2 -2
  41. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  42. package/dist/CheckboxInput/CheckboxInput.js +6 -6
  43. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  44. package/dist/CheckboxList/CheckboxListItem.js +19 -4
  45. package/dist/Citation/Citation.d.ts +22 -1
  46. package/dist/Citation/Citation.d.ts.map +1 -1
  47. package/dist/Citation/Citation.js +20 -6
  48. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  49. package/dist/CodeBlock/CodeBlock.js +16 -10
  50. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  51. package/dist/Collapsible/Collapsible.js +3 -1
  52. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  53. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  54. package/dist/CommandPalette/CommandPalette.js +42 -3
  55. package/dist/CommandPalette/CommandPaletteItem.js +1 -1
  56. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  57. package/dist/ContextMenu/ContextMenu.js +23 -5
  58. package/dist/ContextMenu/index.d.ts +1 -0
  59. package/dist/ContextMenu/index.d.ts.map +1 -1
  60. package/dist/ContextMenu/index.js +3 -1
  61. package/dist/DateInput/DateInput.d.ts +10 -2
  62. package/dist/DateInput/DateInput.d.ts.map +1 -1
  63. package/dist/DateInput/DateInput.js +33 -19
  64. package/dist/DateRangeInput/DateRangeInput.d.ts +10 -2
  65. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  66. package/dist/DateRangeInput/DateRangeInput.js +23 -20
  67. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  68. package/dist/DateTimeInput/DateTimeInput.js +23 -18
  69. package/dist/Divider/Divider.d.ts +2 -2
  70. package/dist/Divider/Divider.d.ts.map +1 -1
  71. package/dist/Divider/Divider.js +13 -0
  72. package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
  73. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  74. package/dist/DropdownMenu/DropdownMenu.js +22 -5
  75. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  76. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +4 -1
  77. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  78. package/dist/DropdownMenu/DropdownMenuItem.js +5 -2
  79. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +8 -11
  80. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
  81. package/dist/DropdownMenu/DropdownMenuRadioGroup.js +3 -1
  82. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +1 -1
  83. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  84. package/dist/DropdownMenu/DropdownMenuRadioItem.js +5 -2
  85. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
  86. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
  87. package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
  88. package/dist/DropdownMenu/index.d.ts +10 -0
  89. package/dist/DropdownMenu/index.d.ts.map +1 -1
  90. package/dist/DropdownMenu/index.js +13 -0
  91. package/dist/DropdownMenu/menuItemHover.d.ts +23 -0
  92. package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
  93. package/dist/DropdownMenu/menuItemHover.js +33 -0
  94. package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
  95. package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
  96. package/dist/DropdownMenu/menuItemRoles.js +10 -1
  97. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  98. package/dist/DropdownMenu/renderDropdownItems.js +21 -6
  99. package/dist/Field/Field.d.ts +3 -1
  100. package/dist/Field/Field.d.ts.map +1 -1
  101. package/dist/Field/Field.js +4 -1
  102. package/dist/Field/FieldLabel.d.ts +2 -1
  103. package/dist/Field/FieldLabel.d.ts.map +1 -1
  104. package/dist/Field/FieldLabel.js +9 -5
  105. package/dist/Field/inputStyles.stylex.d.ts +1 -0
  106. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  107. package/dist/Field/inputStyles.stylex.js +1 -0
  108. package/dist/FieldStatus/FieldStatus.d.ts +10 -0
  109. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  110. package/dist/FieldStatus/FieldStatus.js +39 -3
  111. package/dist/FileInput/FileInput.d.ts +10 -2
  112. package/dist/FileInput/FileInput.d.ts.map +1 -1
  113. package/dist/FileInput/FileInput.js +93 -65
  114. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  115. package/dist/HoverCard/useHoverCard.js +10 -4
  116. package/dist/Icon/Icon.d.ts +15 -1
  117. package/dist/Icon/Icon.d.ts.map +1 -1
  118. package/dist/Icon/Icon.js +19 -3
  119. package/dist/Item/Item.d.ts +16 -3
  120. package/dist/Item/Item.d.ts.map +1 -1
  121. package/dist/Item/Item.js +31 -6
  122. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  123. package/dist/Layer/layerAnimations.stylex.js +10 -2
  124. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  125. package/dist/Lightbox/Lightbox.js +19 -13
  126. package/dist/List/List.d.ts.map +1 -1
  127. package/dist/List/List.js +6 -3
  128. package/dist/List/ListItem.d.ts +11 -1
  129. package/dist/List/ListItem.d.ts.map +1 -1
  130. package/dist/List/ListItem.js +2 -0
  131. package/dist/Markdown/Markdown.d.ts.map +1 -1
  132. package/dist/Markdown/Markdown.js +7 -0
  133. package/dist/MetadataList/MetadataList.d.ts +1 -1
  134. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  135. package/dist/MetadataList/MetadataList.js +4 -2
  136. package/dist/MultiSelector/MultiSelector.d.ts +9 -1
  137. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  138. package/dist/MultiSelector/MultiSelector.js +80 -42
  139. package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
  140. package/dist/NumberInput/NumberInput.d.ts +10 -2
  141. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  142. package/dist/NumberInput/NumberInput.js +22 -17
  143. package/dist/Outline/Outline.js +2 -2
  144. package/dist/Pagination/Pagination.d.ts.map +1 -1
  145. package/dist/Pagination/Pagination.js +11 -3
  146. package/dist/PowerSearch/PowerSearch.d.ts +9 -2
  147. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  148. package/dist/PowerSearch/PowerSearch.js +2 -0
  149. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  150. package/dist/ProgressBar/ProgressBar.js +6 -1
  151. package/dist/RadioList/RadioList.d.ts +2 -2
  152. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  153. package/dist/RadioList/RadioListItem.js +5 -5
  154. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  155. package/dist/Resizable/ResizeHandle.js +49 -19
  156. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  157. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  158. package/dist/SegmentedControl/SegmentedControlItem.js +5 -3
  159. package/dist/Selector/Selector.d.ts +8 -0
  160. package/dist/Selector/Selector.d.ts.map +1 -1
  161. package/dist/Selector/Selector.js +66 -17
  162. package/dist/SideNav/SideNav.d.ts.map +1 -1
  163. package/dist/SideNav/SideNav.js +5 -5
  164. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  165. package/dist/SideNav/SideNavCollapseButton.js +13 -10
  166. package/dist/SideNav/SideNavItem.d.ts +1 -1
  167. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  168. package/dist/SideNav/SideNavItem.js +12 -10
  169. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  170. package/dist/Skeleton/Skeleton.js +2 -2
  171. package/dist/Slider/Slider.d.ts.map +1 -1
  172. package/dist/Slider/Slider.js +87 -34
  173. package/dist/Spinner/Spinner.d.ts +3 -2
  174. package/dist/Spinner/Spinner.d.ts.map +1 -1
  175. package/dist/Spinner/Spinner.js +11 -2
  176. package/dist/Switch/Switch.d.ts +8 -1
  177. package/dist/Switch/Switch.d.ts.map +1 -1
  178. package/dist/Switch/Switch.js +171 -91
  179. package/dist/TabList/Tab.js +2 -2
  180. package/dist/TabList/TabList.d.ts +2 -11
  181. package/dist/TabList/TabList.d.ts.map +1 -1
  182. package/dist/TabList/TabList.js +5 -9
  183. package/dist/TabList/TabListContext.d.ts +0 -5
  184. package/dist/TabList/TabListContext.d.ts.map +1 -1
  185. package/dist/TabList/TabListContext.js +0 -5
  186. package/dist/TabList/TabMenu.js +1 -1
  187. package/dist/Table/BaseTable.d.ts.map +1 -1
  188. package/dist/Table/BaseTable.js +30 -4
  189. package/dist/Table/TableCell.js +3 -3
  190. package/dist/Table/TableHeaderCell.js +3 -3
  191. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  192. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
  193. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  194. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +37 -27
  195. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  196. package/dist/Table/plugins/selection/useTableSelection.js +3 -0
  197. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  198. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +15 -7
  199. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  200. package/dist/Table/plugins/tree/useTableTreeData.js +29 -23
  201. package/dist/Table/types.d.ts +32 -0
  202. package/dist/Table/types.d.ts.map +1 -1
  203. package/dist/TextArea/TextArea.d.ts +10 -1
  204. package/dist/TextArea/TextArea.d.ts.map +1 -1
  205. package/dist/TextArea/TextArea.js +18 -19
  206. package/dist/TextInput/TextInput.d.ts +10 -2
  207. package/dist/TextInput/TextInput.d.ts.map +1 -1
  208. package/dist/TextInput/TextInput.js +20 -17
  209. package/dist/Thumbnail/Thumbnail.js +2 -2
  210. package/dist/TimeInput/TimeInput.d.ts +10 -2
  211. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  212. package/dist/TimeInput/TimeInput.js +17 -17
  213. package/dist/Timestamp/Timestamp.d.ts +31 -3
  214. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  215. package/dist/Timestamp/Timestamp.js +47 -76
  216. package/dist/Timestamp/formatInstant.d.ts +41 -0
  217. package/dist/Timestamp/formatInstant.d.ts.map +1 -0
  218. package/dist/Timestamp/formatInstant.js +177 -0
  219. package/dist/Timestamp/index.d.ts +1 -0
  220. package/dist/Timestamp/index.d.ts.map +1 -1
  221. package/dist/Timestamp/tooltipEntries.d.ts +56 -0
  222. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -0
  223. package/dist/Timestamp/tooltipEntries.js +163 -0
  224. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  225. package/dist/Toast/ToastViewport.js +61 -9
  226. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  227. package/dist/ToggleButton/ToggleButton.js +3 -1
  228. package/dist/Token/Token.d.ts +34 -4
  229. package/dist/Token/Token.d.ts.map +1 -1
  230. package/dist/Token/Token.js +85 -45
  231. package/dist/Token/TokenLink.d.ts +62 -0
  232. package/dist/Token/TokenLink.d.ts.map +1 -0
  233. package/dist/Token/TokenLink.js +76 -0
  234. package/dist/Token/index.d.ts +1 -1
  235. package/dist/Token/index.d.ts.map +1 -1
  236. package/dist/Tokenizer/Tokenizer.d.ts +9 -2
  237. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  238. package/dist/Tokenizer/Tokenizer.js +4 -2
  239. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  240. package/dist/Tooltip/useTooltip.js +17 -1
  241. package/dist/TopNav/TopNavItem.d.ts +3 -1
  242. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  243. package/dist/TopNav/TopNavItem.js +30 -3
  244. package/dist/TreeList/TreeList.d.ts.map +1 -1
  245. package/dist/TreeList/TreeList.js +1 -0
  246. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  247. package/dist/TreeList/TreeListBranches.js +8 -6
  248. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  249. package/dist/TreeList/TreeListItem.js +32 -14
  250. package/dist/Typeahead/BaseTypeahead.d.ts +9 -0
  251. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  252. package/dist/Typeahead/BaseTypeahead.js +22 -11
  253. package/dist/Typeahead/Typeahead.d.ts +9 -2
  254. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  255. package/dist/Typeahead/Typeahead.js +11 -2
  256. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  257. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  258. package/dist/Typeahead/TypeaheadItem.js +20 -10
  259. package/dist/astryx.css +70 -30
  260. package/dist/astryx.umd.js +51 -51
  261. package/dist/astryx.umd.js.map +4 -4
  262. package/dist/hooks/index.d.ts +2 -0
  263. package/dist/hooks/index.d.ts.map +1 -1
  264. package/dist/hooks/index.js +1 -0
  265. package/dist/hooks/isRtlElement.d.ts +18 -0
  266. package/dist/hooks/isRtlElement.d.ts.map +1 -0
  267. package/dist/hooks/isRtlElement.js +27 -0
  268. package/dist/hooks/useAnnounce.d.ts +3 -0
  269. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  270. package/dist/hooks/useAnnounce.js +39 -1
  271. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  272. package/dist/hooks/useFocusTrap.js +52 -11
  273. package/dist/hooks/useGridFocus.d.ts +6 -1
  274. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  275. package/dist/hooks/useGridFocus.js +12 -9
  276. package/dist/hooks/useHotkeys.d.ts +9 -0
  277. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  278. package/dist/hooks/useHotkeys.js +9 -0
  279. package/dist/hooks/useInputStatusIcon.d.ts +38 -0
  280. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
  281. package/dist/hooks/useInputStatusIcon.js +158 -0
  282. package/dist/hooks/useKeyboardHint.d.ts +1 -1
  283. package/dist/hooks/useKeyboardHint.d.ts.map +1 -1
  284. package/dist/hooks/useKeyboardHint.js +4 -2
  285. package/dist/hooks/useListFocus.d.ts +39 -1
  286. package/dist/hooks/useListFocus.d.ts.map +1 -1
  287. package/dist/hooks/useListFocus.js +54 -9
  288. package/dist/i18n/InternationalizationContext.d.ts +1 -0
  289. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  290. package/dist/i18n/InternationalizationContext.js +3 -0
  291. package/dist/i18n/InternationalizationProvider.d.ts +8 -1
  292. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  293. package/dist/i18n/InternationalizationProvider.js +5 -1
  294. package/dist/i18n/getLocaleDirection.d.ts +18 -0
  295. package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
  296. package/dist/i18n/getLocaleDirection.js +29 -0
  297. package/dist/i18n/index.d.ts +6 -0
  298. package/dist/i18n/index.d.ts.map +1 -1
  299. package/dist/i18n/index.js +7 -1
  300. package/dist/i18n/useDirection.d.ts +2 -0
  301. package/dist/i18n/useDirection.d.ts.map +1 -0
  302. package/dist/i18n/useDirection.js +27 -0
  303. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  304. package/dist/theme/derivedVarRegistry.js +13 -0
  305. package/dist/utils/index.d.ts +1 -0
  306. package/dist/utils/index.d.ts.map +1 -1
  307. package/dist/utils/index.js +2 -1
  308. package/dist/utils/plainDate.d.ts +17 -0
  309. package/dist/utils/plainDate.d.ts.map +1 -1
  310. package/dist/utils/plainDate.js +23 -4
  311. package/dist/utils/rtlStyles.d.ts +24 -0
  312. package/dist/utils/rtlStyles.d.ts.map +1 -0
  313. package/dist/utils/rtlStyles.js +27 -0
  314. package/locales/en.json +112 -0
  315. package/locales/pseudo.json +84 -0
  316. package/package.json +6 -1
  317. package/src/Avatar/Avatar.doc.mjs +50 -3
  318. package/src/Avatar/Avatar.test.tsx +218 -0
  319. package/src/Avatar/Avatar.tsx +285 -79
  320. package/src/Avatar/AvatarStatusDot.doc.mjs +4 -4
  321. package/src/Avatar/AvatarStatusDot.tsx +6 -4
  322. package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
  323. package/src/AvatarGroup/AvatarGroup.test.tsx +162 -2
  324. package/src/AvatarGroup/AvatarGroup.tsx +58 -3
  325. package/src/AvatarGroup/AvatarGroupOverflow.tsx +5 -2
  326. package/src/Banner/Banner.tsx +6 -6
  327. package/src/Breadcrumbs/BreadcrumbItem.tsx +10 -10
  328. package/src/Breadcrumbs/Breadcrumbs.test.tsx +52 -1
  329. package/src/Breadcrumbs/index.ts +4 -0
  330. package/src/Button/Button.doc.mjs +0 -4
  331. package/src/Button/Button.test.tsx +16 -0
  332. package/src/Button/Button.tsx +6 -4
  333. package/src/Calendar/Calendar.test.tsx +170 -20
  334. package/src/Calendar/Calendar.tsx +73 -16
  335. package/src/Calendar/dayCellUtils.test.ts +18 -18
  336. package/src/Calendar/dayCellUtils.ts +2 -2
  337. package/src/Calendar/styles.ts +33 -39
  338. package/src/Card/Card.tsx +1 -1
  339. package/src/Carousel/Carousel.tsx +25 -6
  340. package/src/Chat/ChatComposer.doc.mjs +2 -2
  341. package/src/Chat/ChatComposerInput.doc.mjs +1 -1
  342. package/src/Chat/ChatComposerInput.tsx +2 -2
  343. package/src/Chat/ChatDictationButton.tsx +7 -1
  344. package/src/Chat/ChatLayout.tsx +4 -4
  345. package/src/Chat/ChatMessageBubble.tsx +15 -10
  346. package/src/Chat/ChatSystemMessage.test.tsx +5 -0
  347. package/src/Chat/ChatToolCalls.tsx +9 -2
  348. package/src/Chat/useTriggerMenu.tsx +1 -1
  349. package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
  350. package/src/CheckboxInput/CheckboxInput.test.tsx +23 -0
  351. package/src/CheckboxInput/CheckboxInput.tsx +21 -6
  352. package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
  353. package/src/CheckboxList/CheckboxList.test.tsx +94 -3
  354. package/src/CheckboxList/CheckboxListItem.tsx +17 -10
  355. package/src/Citation/Citation.doc.mjs +4 -3
  356. package/src/Citation/Citation.test.tsx +97 -0
  357. package/src/Citation/Citation.tsx +43 -11
  358. package/src/CodeBlock/CodeBlock.test.tsx +17 -0
  359. package/src/CodeBlock/CodeBlock.tsx +38 -11
  360. package/src/Collapsible/Collapsible.doc.mjs +1 -0
  361. package/src/Collapsible/Collapsible.test.tsx +7 -0
  362. package/src/Collapsible/Collapsible.tsx +16 -6
  363. package/src/CommandPalette/CommandPalette.test.tsx +95 -1
  364. package/src/CommandPalette/CommandPalette.tsx +41 -2
  365. package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
  366. package/src/ContextMenu/ContextMenu.test.tsx +59 -2
  367. package/src/ContextMenu/ContextMenu.tsx +22 -11
  368. package/src/ContextMenu/index.ts +5 -0
  369. package/src/DateInput/DateInput.doc.mjs +25 -0
  370. package/src/DateInput/DateInput.test.tsx +230 -0
  371. package/src/DateInput/DateInput.tsx +51 -29
  372. package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
  373. package/src/DateRangeInput/DateRangeInput.test.tsx +140 -0
  374. package/src/DateRangeInput/DateRangeInput.tsx +42 -30
  375. package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
  376. package/src/DateTimeInput/DateTimeInput.test.tsx +112 -0
  377. package/src/DateTimeInput/DateTimeInput.tsx +44 -39
  378. package/src/Divider/Divider.test.tsx +32 -8
  379. package/src/Divider/Divider.tsx +14 -1
  380. package/src/DropdownMenu/DropdownMenu.test.tsx +60 -0
  381. package/src/DropdownMenu/DropdownMenu.tsx +31 -12
  382. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +8 -2
  383. package/src/DropdownMenu/DropdownMenuItem.tsx +9 -3
  384. package/src/DropdownMenu/DropdownMenuRadioGroup.doc.mjs +4 -12
  385. package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +9 -10
  386. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +9 -3
  387. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +20 -2
  388. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
  389. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
  390. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
  391. package/src/DropdownMenu/index.ts +16 -0
  392. package/src/DropdownMenu/menuItemHover.ts +39 -0
  393. package/src/DropdownMenu/menuItemRoles.ts +9 -0
  394. package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
  395. package/src/Field/Field.tsx +14 -9
  396. package/src/Field/FieldLabel.test.tsx +25 -0
  397. package/src/Field/FieldLabel.tsx +12 -3
  398. package/src/Field/inputStyles.stylex.ts +2 -0
  399. package/src/FieldStatus/FieldStatus.test.tsx +72 -0
  400. package/src/FieldStatus/FieldStatus.tsx +48 -2
  401. package/src/FileInput/FileInput.doc.mjs +23 -2
  402. package/src/FileInput/FileInput.test.tsx +104 -13
  403. package/src/FileInput/FileInput.tsx +106 -79
  404. package/src/HoverCard/useHoverCard.tsx +15 -3
  405. package/src/Icon/Icon.doc.mjs +13 -0
  406. package/src/Icon/Icon.test.tsx +89 -0
  407. package/src/Icon/Icon.tsx +51 -3
  408. package/src/Item/Item.doc.mjs +5 -0
  409. package/src/Item/Item.test.tsx +88 -0
  410. package/src/Item/Item.tsx +57 -11
  411. package/src/Layer/layerAnimations.stylex.ts +23 -0
  412. package/src/Lightbox/Lightbox.tsx +15 -7
  413. package/src/List/List.test.tsx +17 -29
  414. package/src/List/List.tsx +6 -1
  415. package/src/List/ListItem.doc.mjs +12 -0
  416. package/src/List/ListItem.tsx +13 -0
  417. package/src/Markdown/Markdown.test.tsx +21 -0
  418. package/src/Markdown/Markdown.tsx +4 -0
  419. package/src/MetadataList/MetadataList.test.tsx +24 -0
  420. package/src/MetadataList/MetadataList.tsx +6 -2
  421. package/src/MultiSelector/MultiSelector.doc.mjs +20 -0
  422. package/src/MultiSelector/MultiSelector.test.tsx +402 -0
  423. package/src/MultiSelector/MultiSelector.tsx +120 -59
  424. package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
  425. package/src/NumberInput/NumberInput.doc.mjs +21 -0
  426. package/src/NumberInput/NumberInput.test.tsx +71 -0
  427. package/src/NumberInput/NumberInput.tsx +35 -26
  428. package/src/Outline/Outline.test.tsx +12 -12
  429. package/src/Outline/Outline.tsx +2 -2
  430. package/src/Pagination/Pagination.tsx +11 -3
  431. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  432. package/src/PowerSearch/PowerSearch.test.tsx +23 -0
  433. package/src/PowerSearch/PowerSearch.tsx +10 -1
  434. package/src/ProgressBar/ProgressBar.test.tsx +34 -0
  435. package/src/ProgressBar/ProgressBar.tsx +16 -1
  436. package/src/RadioList/RadioList.doc.mjs +6 -0
  437. package/src/RadioList/RadioList.test.tsx +26 -4
  438. package/src/RadioList/RadioList.tsx +2 -2
  439. package/src/RadioList/RadioListItem.tsx +12 -5
  440. package/src/Resizable/ResizeHandle.test.tsx +94 -0
  441. package/src/Resizable/ResizeHandle.tsx +70 -20
  442. package/src/SegmentedControl/SegmentedControl.test.tsx +28 -0
  443. package/src/SegmentedControl/SegmentedControlItem.tsx +22 -2
  444. package/src/Selector/Selector.doc.mjs +15 -0
  445. package/src/Selector/Selector.test.tsx +370 -0
  446. package/src/Selector/Selector.tsx +88 -20
  447. package/src/SideNav/SideNav.tsx +1 -8
  448. package/src/SideNav/SideNavCollapseButton.tsx +9 -7
  449. package/src/SideNav/SideNavItem.tsx +5 -3
  450. package/src/Skeleton/Skeleton.test.tsx +16 -0
  451. package/src/Skeleton/Skeleton.tsx +13 -1
  452. package/src/Slider/Slider.doc.mjs +6 -0
  453. package/src/Slider/Slider.test.tsx +240 -12
  454. package/src/Slider/Slider.tsx +96 -23
  455. package/src/Spinner/Spinner.test.tsx +10 -8
  456. package/src/Spinner/Spinner.tsx +15 -5
  457. package/src/Switch/Switch.doc.mjs +142 -42
  458. package/src/Switch/Switch.test.tsx +111 -0
  459. package/src/Switch/Switch.tsx +149 -32
  460. package/src/TabList/Tab.tsx +2 -2
  461. package/src/TabList/TabList.doc.mjs +0 -6
  462. package/src/TabList/TabList.test.tsx +3 -15
  463. package/src/TabList/TabList.tsx +6 -17
  464. package/src/TabList/TabListContext.ts +0 -6
  465. package/src/TabList/TabMenu.tsx +2 -2
  466. package/src/Table/BaseTable.tsx +34 -2
  467. package/src/Table/Table.doc.mjs +11 -0
  468. package/src/Table/Table.test.tsx +85 -0
  469. package/src/Table/TableCell.tsx +3 -3
  470. package/src/Table/TableHeaderCell.tsx +3 -3
  471. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +9 -6
  472. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +19 -0
  473. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +27 -18
  474. package/src/Table/plugins/selection/useTableSelection.test.tsx +61 -3
  475. package/src/Table/plugins/selection/useTableSelection.tsx +3 -0
  476. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +38 -9
  477. package/src/Table/plugins/tree/useTableTreeData.tsx +17 -13
  478. package/src/Table/types.ts +33 -0
  479. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  480. package/src/TextArea/TextArea.doc.mjs +21 -0
  481. package/src/TextArea/TextArea.test.tsx +23 -0
  482. package/src/TextArea/TextArea.tsx +27 -26
  483. package/src/TextInput/TextInput.doc.mjs +21 -0
  484. package/src/TextInput/TextInput.test.tsx +150 -0
  485. package/src/TextInput/TextInput.tsx +28 -25
  486. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  487. package/src/Thumbnail/Thumbnail.tsx +1 -1
  488. package/src/TimeInput/TimeInput.doc.mjs +21 -0
  489. package/src/TimeInput/TimeInput.test.tsx +23 -0
  490. package/src/TimeInput/TimeInput.tsx +24 -25
  491. package/src/Timestamp/Timestamp.doc.mjs +32 -6
  492. package/src/Timestamp/Timestamp.test.tsx +371 -0
  493. package/src/Timestamp/Timestamp.tsx +96 -93
  494. package/src/Timestamp/formatInstant.ts +218 -0
  495. package/src/Timestamp/index.ts +4 -0
  496. package/src/Timestamp/tooltipEntries.test.ts +552 -0
  497. package/src/Timestamp/tooltipEntries.ts +210 -0
  498. package/src/Toast/ToastViewport.test.tsx +218 -8
  499. package/src/Toast/ToastViewport.tsx +71 -12
  500. package/src/ToggleButton/ToggleButton.test.tsx +24 -0
  501. package/src/ToggleButton/ToggleButton.tsx +19 -1
  502. package/src/Token/Token.test.tsx +166 -15
  503. package/src/Token/Token.tsx +104 -47
  504. package/src/Token/TokenLink.tsx +107 -0
  505. package/src/Token/index.ts +1 -1
  506. package/src/Tokenizer/Tokenizer.doc.mjs +23 -1
  507. package/src/Tokenizer/Tokenizer.test.tsx +23 -0
  508. package/src/Tokenizer/Tokenizer.tsx +14 -2
  509. package/src/Tooltip/Tooltip.test.tsx +46 -0
  510. package/src/Tooltip/useTooltip.tsx +20 -0
  511. package/src/TopNav/TopNav.test.tsx +93 -2
  512. package/src/TopNav/TopNavItem.doc.mjs +3 -3
  513. package/src/TopNav/TopNavItem.tsx +35 -6
  514. package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +1 -1
  515. package/src/TreeList/TreeList.doc.mjs +6 -0
  516. package/src/TreeList/TreeList.test.tsx +50 -10
  517. package/src/TreeList/TreeList.tsx +5 -0
  518. package/src/TreeList/TreeListBranches.tsx +8 -6
  519. package/src/TreeList/TreeListItem.tsx +33 -11
  520. package/src/Typeahead/BaseTypeahead.tsx +42 -15
  521. package/src/Typeahead/Typeahead.doc.mjs +13 -0
  522. package/src/Typeahead/Typeahead.test.tsx +112 -0
  523. package/src/Typeahead/Typeahead.tsx +17 -1
  524. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  525. package/src/__tests__/forcedColors.ts +60 -0
  526. package/src/__tests__/inputWidthContract.test.tsx +62 -0
  527. package/src/doc-mjs.d.ts +19 -0
  528. package/src/hooks/index.ts +6 -0
  529. package/src/hooks/isRtlElement.ts +27 -0
  530. package/src/hooks/useAnnounce.test.tsx +75 -2
  531. package/src/hooks/useAnnounce.ts +47 -1
  532. package/src/hooks/useFocusTrap.test.tsx +104 -0
  533. package/src/hooks/useFocusTrap.ts +61 -12
  534. package/src/hooks/useGridFocus.doc.mjs +3 -3
  535. package/src/hooks/useGridFocus.test.tsx +41 -0
  536. package/src/hooks/useGridFocus.ts +21 -10
  537. package/src/hooks/useHotkeys.ts +9 -0
  538. package/src/hooks/useInputStatusIcon.test.tsx +162 -0
  539. package/src/hooks/useInputStatusIcon.tsx +224 -0
  540. package/src/hooks/useKeyboardHint.test.tsx +22 -0
  541. package/src/hooks/useKeyboardHint.tsx +6 -2
  542. package/src/hooks/useListFocus.doc.mjs +25 -3
  543. package/src/hooks/useListFocus.test.tsx +153 -1
  544. package/src/hooks/useListFocus.ts +102 -9
  545. package/src/i18n/InternationalizationContext.ts +4 -0
  546. package/src/i18n/InternationalizationProvider.tsx +12 -2
  547. package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
  548. package/src/i18n/__tests__/useDirection.test.tsx +66 -0
  549. package/src/i18n/getLocaleDirection.ts +29 -0
  550. package/src/i18n/index.ts +6 -0
  551. package/src/i18n/useDirection.ts +29 -0
  552. package/src/reset.css +0 -26
  553. package/src/reset.test.ts +60 -0
  554. package/src/theme/derivedVarRegistry.test.ts +1 -0
  555. package/src/theme/derivedVarRegistry.ts +6 -0
  556. package/src/theme/generateThemeRules.test.ts +42 -0
  557. package/src/utils/index.ts +2 -0
  558. package/src/utils/plainDate.test.ts +24 -6
  559. package/src/utils/plainDate.ts +18 -4
  560. package/src/utils/rtlStyles.ts +27 -0
@@ -0,0 +1,427 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file DropdownMenuSubMenu.tsx
7
+ * @input React, stylex, useLayer (context mode), useListFocus, useMenuHover,
8
+ * useTypeahead, Item, Icon, Spinner, DropdownMenu context + item roles.
9
+ * @output Exports DropdownMenuSubMenu — a single menu row that reveals a nested
10
+ * flyout menu of its own children/items.
11
+ * @position Sub-component; place inside a DropdownMenu (or ContextMenu)
12
+ * alongside plain items.
13
+ *
14
+ * One component, not three. The row itself adopts DropdownMenuItem semantics
15
+ * (label / icon / description / isDisabled) and its children become the
16
+ * flyout's content. This mirrors how SideNavItem / TreeListItem promote a
17
+ * normal row into a nested surface when given children, rather than the Radix
18
+ * Sub / SubTrigger / SubContent split. Data-driven menus never touch this
19
+ * component directly — renderDropdownItems renders it from a nested `items`
20
+ * array and passes the rendered children in.
21
+ *
22
+ * Built on existing primitives — no bespoke floating code:
23
+ * - Positioning: useLayer context mode opens the flyout inline-end with
24
+ * viewport auto-flip via CSS anchor positioning (RTL-correct by default).
25
+ * - Pointer: useMenuHover for open/close intent.
26
+ * - Keyboard: a per-level useListFocus + useTypeahead. Right (Left in RTL) /
27
+ * Enter / Space opens the flyout and focuses its first item; Left (Right in
28
+ * RTL) / Escape closes it and returns focus to the trigger row.
29
+ *
30
+ * Prior art: legacy internal XDS `XDSDropdownSubMenuItem` (APG menubar-
31
+ * navigation submenu). This re-expresses the same contract on Astryx primitives.
32
+ *
33
+ * SYNC: When modified, update these files to stay in sync:
34
+ * - /packages/core/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs
35
+ * - /packages/core/src/DropdownMenu/DropdownMenuSubMenu.test.tsx
36
+ * - /packages/core/src/DropdownMenu/index.ts
37
+ * - /apps/storybook/stories/DropdownMenu.stories.tsx
38
+ * - /packages/cli/templates/blocks/components/DropdownMenu/ (showcase blocks)
39
+ */
40
+ import React, { useCallback, useId, useMemo, useRef, useState } from 'react';
41
+ import * as stylex from '@stylexjs/stylex';
42
+ import { Icon, renderIconSlot } from "../Icon/index.js";
43
+ import { Spinner } from "../Spinner/index.js";
44
+ import { Item } from "../Item/index.js";
45
+ import { useLayer } from "../Layer/useLayer.js";
46
+ import { layerAnimations } from "../Layer/layerAnimations.stylex.js";
47
+ import { useListFocus } from "../hooks/useListFocus.js";
48
+ import { useMenuHover } from "../hooks/useMenuHover.js";
49
+ import { useTypeahead } from "../hooks/useTypeahead.js";
50
+ import "../theme/tokens.stylex.js";
51
+ import { colorVars, spacingVars, radiusVars, durationVars, easeVars, shadowVars, typographyVars, typeScaleVars } from "../theme/tokens.stylex.js";
52
+ import { mergeProps } from "../utils/index.js";
53
+ import { themeProps } from "../utils/themeProps.js";
54
+ import { MENU_ITEM_ROLES, MENU_ITEM_SELECTOR, MENU_BOUNDARY_SELECTOR } from "./menuItemRoles.js";
55
+ import { DropdownMenuContext, useDropdownMenuContext } from "./DropdownMenuContext.js";
56
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
57
+ const triggerStyles = {
58
+ root: {
59
+ kB7OPa: "x9f619",
60
+ kzqmXN: "xh8yej3",
61
+ k8WAf4: "xce4md1",
62
+ kg3NbH: "xf314gf",
63
+ kaIpWk: "x1ws5lxm",
64
+ kMv6JI: "x9ynric",
65
+ kGuDYH: "xcr08ib",
66
+ kMwMTN: "x1tgivj0",
67
+ kWkggS: "xjbqb8w x1c52tdz",
68
+ kHE3J0: "xe9uy6x",
69
+ kkrTdU: "x1ypdohk",
70
+ k9WMMc: "x1yc453h",
71
+ kI3sdo: "x1a2a7pz",
72
+ $$css: true
73
+ },
74
+ open: {
75
+ kWkggS: "x1lmrjuc",
76
+ $$css: true
77
+ },
78
+ disabled: {
79
+ kSiTet: "xbyyjgo",
80
+ kkrTdU: "x1h6gzvc",
81
+ $$css: true
82
+ }
83
+ };
84
+ const triggerSizeStyles = {
85
+ sm: {
86
+ k8WAf4: "xu0wf1k",
87
+ kg3NbH: "xf314gf",
88
+ $$css: true
89
+ },
90
+ md: {
91
+ k8WAf4: "x1vofgu7",
92
+ $$css: true
93
+ },
94
+ lg: {
95
+ $$css: true
96
+ }
97
+ };
98
+ const _temp = {
99
+ keTefX: "x11g1kdw",
100
+ k71WvV: "xnur1sd",
101
+ "$$css": true
102
+ };
103
+ const flyoutStyles = {
104
+ popover: {
105
+ k7Eaqz: "x5w4yej",
106
+ keTefX: "x11g1kdw",
107
+ k71WvV: "xnur1sd",
108
+ $$css: true
109
+ },
110
+ popoverCustomWidth: width => [_temp, {
111
+ k7Eaqz: (typeof width === 'number' ? `${width}px` : width) != null ? "xkj4a21" : typeof width === 'number' ? `${width}px` : width,
112
+ $$css: true
113
+ }, {
114
+ "--x-minWidth": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(typeof width === 'number' ? `${width}px` : width)
115
+ }]
116
+ };
117
+ /**
118
+ * A single menu row that reveals a nested flyout of its own items. The row
119
+ * adopts DropdownMenuItem semantics (label / icon / description / isDisabled);
120
+ * its `children` become the flyout content. Place inside a DropdownMenu (or
121
+ * ContextMenu) alongside plain items.
122
+ *
123
+ * For data-driven menus, don't use this directly — give a menu item a nested
124
+ * `items` array and DropdownMenu/ContextMenu renders the submenu for you.
125
+ *
126
+ * @example
127
+ * ```
128
+ * <DropdownMenu button={{label: 'Actions'}}>
129
+ * <DropdownMenuItem label="Rename" onClick={rename} />
130
+ * <DropdownMenuSubMenu label="Move to" icon="folder">
131
+ * <DropdownMenuItem label="Folder A" onClick={() => move('a')} />
132
+ * <DropdownMenuItem label="Folder B" onClick={() => move('b')} />
133
+ * </DropdownMenuSubMenu>
134
+ * </DropdownMenu>
135
+ * ```
136
+ */
137
+ export function DropdownMenuSubMenu(props) {
138
+ const {
139
+ icon,
140
+ label,
141
+ description,
142
+ isDisabled = false,
143
+ hasSpinner = false,
144
+ menuWidth,
145
+ onOpenChange,
146
+ children,
147
+ xstyle,
148
+ className,
149
+ style,
150
+ 'data-testid': testId,
151
+ menuDataTestId
152
+ } = props;
153
+ const menuCtx = useDropdownMenuContext();
154
+ const menuSize = menuCtx?.menuSize ?? 'md';
155
+ const canOpen = !isDisabled;
156
+ const contentId = useId();
157
+ const triggerId = useId();
158
+ const triggerRef = useRef(null);
159
+ const [isOpen, setIsOpen] = useState(false);
160
+ const layer = useLayer({
161
+ mode: 'context',
162
+ lightDismiss: false,
163
+ onShow: useCallback(() => {
164
+ setIsOpen(true);
165
+ onOpenChange?.(true);
166
+ }, [onOpenChange]),
167
+ onHide: useCallback(() => {
168
+ setIsOpen(false);
169
+ onOpenChange?.(false);
170
+ }, [onOpenChange])
171
+ });
172
+ const showLayer = useCallback(() => {
173
+ if (canOpen) {
174
+ layer.show();
175
+ }
176
+ }, [canOpen, layer]);
177
+ const hideLayer = useCallback(() => {
178
+ layer.hide();
179
+ }, [layer]);
180
+
181
+ // Dedicated roving-focus + typeahead for this flyout level. The boundary
182
+ // selector scopes item collection and key handling to this flyout's own
183
+ // `role="menu"` — so a submenu nested inside this one (also inline, also
184
+ // `role="menu"`) doesn't pollute this level's items or double-handle keys.
185
+ const {
186
+ listRef: menuRef,
187
+ handleKeyDown: listNavKeyDown,
188
+ focusFirst,
189
+ focusItem,
190
+ ownsEvent,
191
+ getItems
192
+ } = useListFocus({
193
+ itemSelector: MENU_ITEM_SELECTOR,
194
+ boundarySelector: MENU_BOUNDARY_SELECTOR,
195
+ wrap: false,
196
+ onEscape: () => close({
197
+ focusTrigger: true
198
+ })
199
+ });
200
+ const typeahead = useTypeahead({
201
+ getItemLabels: () => getItems().map(el => el.textContent),
202
+ onMatch: focusItem,
203
+ getCurrentIndex: () => getItems().findIndex(el => el === document.activeElement || el.contains(document.activeElement))
204
+ });
205
+
206
+ // Hover-intent: entering the trigger opens after a short delay; leaving
207
+ // either surface closes after a delay. Hover-open does not steal focus.
208
+ const {
209
+ triggerProps,
210
+ contentProps
211
+ } = useMenuHover({
212
+ show: showLayer,
213
+ hide: hideLayer,
214
+ isOpen,
215
+ isEnabled: canOpen
216
+ });
217
+ const open = useCallback(options => {
218
+ if (!canOpen) {
219
+ return;
220
+ }
221
+ layer.show();
222
+ if (options?.focusFirst) {
223
+ requestAnimationFrame(() => {
224
+ // Move focus into the flyout. When it has no focusable items yet
225
+ // (e.g. an async submenu showing only a disabled "Loading…" row via
226
+ // hasSpinner), focusFirst() finds nothing — fall back to focusing the
227
+ // flyout container itself so keyboard ownership still transfers off
228
+ // the parent list. Otherwise the parent would keep focus, letting
229
+ // arrow keys rove the parent while the empty flyout stays open.
230
+ const focusedItem = focusFirst();
231
+ if (!focusedItem) {
232
+ menuRef.current?.focus();
233
+ }
234
+ });
235
+ }
236
+ }, [canOpen, layer, focusFirst, menuRef]);
237
+ const close = useCallback(options => {
238
+ layer.hide();
239
+ if (options?.focusTrigger !== false) {
240
+ triggerRef.current?.focus();
241
+ }
242
+ }, [layer]);
243
+
244
+ // Single ref for the trigger row: store it for focus management AND wire it
245
+ // as the flyout's positioning anchor (CSS anchor positioning).
246
+ const setTriggerEl = useCallback(el => {
247
+ triggerRef.current = el;
248
+ layer.ref(el);
249
+ }, [layer]);
250
+ const handleTriggerClick = useCallback(() => {
251
+ if (isDisabled) {
252
+ return;
253
+ }
254
+ // Click toggles the flyout, moving focus into it on open.
255
+ if (isOpen) {
256
+ close({
257
+ focusTrigger: true
258
+ });
259
+ } else {
260
+ open({
261
+ focusFirst: true
262
+ });
263
+ }
264
+ }, [isDisabled, isOpen, open, close]);
265
+ const handleTriggerKeyDown = useCallback(e => {
266
+ if (isDisabled) {
267
+ return;
268
+ }
269
+ const isRtl = typeof window !== 'undefined' && triggerRef.current ? window.getComputedStyle(triggerRef.current).direction === 'rtl' : false;
270
+ const openKey = isRtl ? 'ArrowLeft' : 'ArrowRight';
271
+ if (e.key === openKey || e.key === 'Enter' || e.key === ' ') {
272
+ e.preventDefault();
273
+ // The trigger row is a direct child of the parent menu (not a nested
274
+ // role="menu"), so the parent's key handler would otherwise also act on
275
+ // this event (e.g. Enter clicking the focused row). Stop it here — this
276
+ // level fully handles opening the flyout.
277
+ e.stopPropagation();
278
+ open({
279
+ focusFirst: true
280
+ });
281
+ }
282
+ }, [isDisabled, open]);
283
+
284
+ // Enter/Space activate the focused row; typeahead jumps by first character;
285
+ // the close key (Left, or Right in RTL) returns focus to the trigger;
286
+ // arrows/Home/End defer to useListFocus (RTL-aware).
287
+ //
288
+ // The flyout renders inline (useLayer context mode is a native popover, not a
289
+ // portal), so a submenu nested inside this one bubbles its key events up to
290
+ // this handler. `ownsEvent` (from useListFocus, scoped by boundarySelector)
291
+ // tells us whether the event originated in THIS flyout or a deeper one; we
292
+ // only act on our own, letting the deeper level keep ownership. No manual
293
+ // stopPropagation needed — each level self-filters.
294
+ const handleContentKeyDown = useCallback(e => {
295
+ if (!ownsEvent(e)) {
296
+ return;
297
+ }
298
+ // Escape closes just this submenu and returns focus to its trigger (APG:
299
+ // Escape collapses the current level, not the whole stack). The root
300
+ // popover's focus-trap listens for Escape at the document level and bails
301
+ // when the event is already handled, so we mark it handled here (stop
302
+ // propagation + preventDefault) to keep the parent menu open.
303
+ if (e.key === 'Escape') {
304
+ e.preventDefault();
305
+ e.stopPropagation();
306
+ close({
307
+ focusTrigger: true
308
+ });
309
+ return;
310
+ }
311
+ if (e.key === 'Enter' || e.key === ' ') {
312
+ e.preventDefault();
313
+ const focused = document.activeElement;
314
+ if (focused && MENU_ITEM_ROLES.has(focused.getAttribute('role') ?? '')) {
315
+ focused.click();
316
+ }
317
+ return;
318
+ }
319
+ const isRtl = typeof window !== 'undefined' && menuRef.current ? window.getComputedStyle(menuRef.current).direction === 'rtl' : false;
320
+ const closeKey = isRtl ? 'ArrowRight' : 'ArrowLeft';
321
+ if (e.key === closeKey) {
322
+ e.preventDefault();
323
+ close({
324
+ focusTrigger: true
325
+ });
326
+ return;
327
+ }
328
+ if (typeahead.onKeyDown(e)) {
329
+ e.preventDefault();
330
+ return;
331
+ }
332
+ listNavKeyDown(e);
333
+ }, [ownsEvent, close, listNavKeyDown, typeahead, menuRef]);
334
+
335
+ // Re-provide the menu context so nested items behave exactly like top-level
336
+ // ones. Selecting a leaf item must dismiss the WHOLE stack, not just this
337
+ // flyout: close this level (without stealing focus back to the trigger) and
338
+ // propagate up via the parent menu's closeMenu. Because every level
339
+ // re-provides the context, this chains from the deepest flyout all the way to
340
+ // the root DropdownMenu (whose closeMenu hides the popover).
341
+ const nestedMenuContext = useMemo(() => ({
342
+ menuSize,
343
+ closeMenu: () => {
344
+ close({
345
+ focusTrigger: false
346
+ });
347
+ menuCtx?.closeMenu();
348
+ }
349
+ }), [menuSize, close, menuCtx]);
350
+ const endAffordance = hasSpinner ? /*#__PURE__*/_jsx("span", {
351
+ ...{
352
+ className: "x78zum5 x6s0dn4"
353
+ },
354
+ children: /*#__PURE__*/_jsx(Spinner, {
355
+ size: "sm"
356
+ })
357
+ }) : /*#__PURE__*/_jsx("span", {
358
+ ...{
359
+ className: "x78zum5 x6s0dn4"
360
+ },
361
+ children: /*#__PURE__*/_jsx(Icon, {
362
+ icon: "chevronRight",
363
+ size: "sm",
364
+ color: "secondary"
365
+ })
366
+ });
367
+ const popoverXstyle = menuWidth ? flyoutStyles.popoverCustomWidth(menuWidth) : flyoutStyles.popover;
368
+ return /*#__PURE__*/_jsxs(_Fragment, {
369
+ children: [/*#__PURE__*/_jsx(Item, {
370
+ ref: el => setTriggerEl(el),
371
+ id: triggerId,
372
+ role: "menuitem",
373
+ tabIndex: isDisabled ? undefined : -1,
374
+ "aria-haspopup": "menu",
375
+ "aria-expanded": isOpen,
376
+ "aria-controls": isOpen ? contentId : undefined,
377
+ "aria-disabled": isDisabled || undefined,
378
+ "data-testid": testId,
379
+ onMouseEnter: triggerProps.onMouseEnter,
380
+ onMouseLeave: triggerProps.onMouseLeave,
381
+ startContent: icon ? renderIconSlot(icon, {
382
+ size: 'sm',
383
+ color: 'secondary'
384
+ }) : undefined,
385
+ label: label,
386
+ description: description,
387
+ endContent: endAffordance,
388
+ onClick: handleTriggerClick,
389
+ onKeyDown: handleTriggerKeyDown,
390
+ isDisabled: isDisabled,
391
+ xstyle: [triggerStyles.root, triggerSizeStyles[menuSize], isOpen && triggerStyles.open, isDisabled && triggerStyles.disabled, xstyle],
392
+ ...mergeProps(themeProps('dropdown-menu-item', {
393
+ size: menuSize
394
+ }), {
395
+ className,
396
+ style
397
+ })
398
+ }), layer.render(/*#__PURE__*/_jsx("div", {
399
+ ref: menuRef,
400
+ id: contentId,
401
+ role: "menu"
402
+ // Focusable as a fallback target so an empty/loading flyout (e.g.
403
+ // hasSpinner with only a disabled row) can still receive keyboard
404
+ // focus and own arrow/Escape keys instead of leaving focus on the
405
+ // parent list.
406
+ ,
407
+ tabIndex: -1,
408
+ "aria-labelledby": triggerId,
409
+ onKeyDown: handleContentKeyDown,
410
+ onMouseEnter: contentProps.onMouseEnter,
411
+ onMouseLeave: contentProps.onMouseLeave,
412
+ "data-testid": menuDataTestId,
413
+ ...mergeProps(themeProps('dropdown-menu'), {
414
+ className: "x9f619 x78zum5 xdt5ytf x1lsbc85 xuyqlj2 x1odjw0f x1fcsqxe xgory14 x9epnlk x1n97fys x1prclbq x1i5ehqx x1hc1fzr x19991ni xuedmi6 xlr8y92"
415
+ }),
416
+ children: /*#__PURE__*/_jsx(DropdownMenuContext, {
417
+ value: nestedMenuContext,
418
+ children: children
419
+ })
420
+ }), {
421
+ placement: 'end',
422
+ alignment: 'start',
423
+ xstyle: [popoverXstyle, layerAnimations.end]
424
+ })]
425
+ });
426
+ }
427
+ DropdownMenuSubMenu.displayName = 'DropdownMenuSubMenu';
@@ -2,11 +2,21 @@
2
2
  * @file index.ts
3
3
  * @output Exports DropdownMenu, DropdownMenuItem and related types
4
4
  * @position Public API entry point
5
+ *
6
+ * SYNC: The item components below are re-exported (aliased) by the other menu
7
+ * surfaces that reuse the DropdownMenu item pipeline. When you add or remove an
8
+ * item component here, mirror it in:
9
+ * - /packages/core/src/ContextMenu/index.ts (ContextMenu* aliases)
10
+ * - /packages/core/src/Breadcrumbs/index.ts (BreadcrumbMenu* aliases)
11
+ * Those surfaces render menu items through the same renderDropdownItems +
12
+ * DropdownMenuContext + useListFocus path, so a new item type (e.g. a submenu)
13
+ * only shows up in their public API once it's aliased there too.
5
14
  */
6
15
  export { DropdownMenu, type DropdownMenuProps, type DropdownMenuButtonProps, type DropdownMenuItemData, type DropdownMenuDivider, type DropdownMenuSection, type DropdownMenuOption, } from './DropdownMenu';
7
16
  export { DropdownMenuItem, type DropdownMenuItemProps } from './DropdownMenuItem';
8
17
  export { DropdownMenuCheckboxItem, type DropdownMenuCheckboxItemProps, } from './DropdownMenuCheckboxItem';
9
18
  export { DropdownMenuRadioGroup, type DropdownMenuRadioGroupProps, } from './DropdownMenuRadioGroup';
10
19
  export { DropdownMenuRadioItem, type DropdownMenuRadioItemProps, } from './DropdownMenuRadioItem';
20
+ export { DropdownMenuSubMenu, type DropdownMenuSubMenuProps, } from './DropdownMenuSubMenu';
11
21
  export { DropdownMenuContext, useDropdownMenuContext, type DropdownMenuContextValue, type DropdownMenuSize, } from './DropdownMenuContext';
12
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/index.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAC,gBAAgB,EAAE,KAAK,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAGhF,OAAO,EACL,wBAAwB,EACxB,KAAK,6BAA6B,GACnC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,KAAK,2BAA2B,GACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,GAChC,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAC,gBAAgB,EAAE,KAAK,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAGhF,OAAO,EACL,wBAAwB,EACxB,KAAK,6BAA6B,GACnC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,KAAK,2BAA2B,GACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,qBAAqB,EACrB,KAAK,0BAA0B,GAChC,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EACL,mBAAmB,EACnB,KAAK,wBAAwB,GAC9B,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC"}
@@ -6,6 +6,15 @@
6
6
  * @file index.ts
7
7
  * @output Exports DropdownMenu, DropdownMenuItem and related types
8
8
  * @position Public API entry point
9
+ *
10
+ * SYNC: The item components below are re-exported (aliased) by the other menu
11
+ * surfaces that reuse the DropdownMenu item pipeline. When you add or remove an
12
+ * item component here, mirror it in:
13
+ * - /packages/core/src/ContextMenu/index.ts (ContextMenu* aliases)
14
+ * - /packages/core/src/Breadcrumbs/index.ts (BreadcrumbMenu* aliases)
15
+ * Those surfaces render menu items through the same renderDropdownItems +
16
+ * DropdownMenuContext + useListFocus path, so a new item type (e.g. a submenu)
17
+ * only shows up in their public API once it's aliased there too.
9
18
  */
10
19
  export { DropdownMenu } from "./DropdownMenu.js";
11
20
  export { DropdownMenuItem } from "./DropdownMenuItem.js";
@@ -15,6 +24,10 @@ export { DropdownMenuCheckboxItem } from "./DropdownMenuCheckboxItem.js";
15
24
  export { DropdownMenuRadioGroup } from "./DropdownMenuRadioGroup.js";
16
25
  export { DropdownMenuRadioItem } from "./DropdownMenuRadioItem.js";
17
26
 
27
+ // Submenu — a single menu row that reveals a nested flyout of its own
28
+ // children/items. Data mode via DropdownMenuItemData.items.
29
+ export { DropdownMenuSubMenu } from "./DropdownMenuSubMenu.js";
30
+
18
31
  // Menu-coordination context — public so consumers can build custom menu items
19
32
  // that read the menu size / close the menu.
20
33
  export { DropdownMenuContext, useDropdownMenuContext } from "./DropdownMenuContext.js";
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @file menuItemHover.ts
3
+ * @output Exports focusMenuItemOnHover
4
+ * @position Shared helper for DropdownMenu/ContextMenu item components
5
+ *
6
+ * Menus keep a single highlighted item by using DOM focus as the sole
7
+ * highlight source. Mouse hover moves focus onto the pointed-at item so the
8
+ * one focus highlight follows the pointer — instead of a separate `:hover`
9
+ * background leaving the keyboard-focused item highlighted at the same time.
10
+ *
11
+ * SYNC: When modified, update the item components that use it:
12
+ * - /packages/core/src/DropdownMenu/DropdownMenuItem.tsx
13
+ * - /packages/core/src/DropdownMenu/DropdownMenuCheckboxItem.tsx
14
+ * - /packages/core/src/DropdownMenu/DropdownMenuRadioItem.tsx
15
+ */
16
+ import type { PointerEvent } from 'react';
17
+ /**
18
+ * Move focus to a menu item as the pointer moves over it, so hover and
19
+ * keyboard navigation share a single focus-driven highlight. Only reacts to a
20
+ * real mouse (not touch/pen, which have no hover), and skips disabled items.
21
+ */
22
+ export declare function focusMenuItemOnHover(e: PointerEvent<HTMLElement>, isDisabled?: boolean): void;
23
+ //# sourceMappingURL=menuItemHover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menuItemHover.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/menuItemHover.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,OAAO,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,YAAY,CAAC,WAAW,CAAC,EAC5B,UAAU,CAAC,EAAE,OAAO,GACnB,IAAI,CAQN"}
@@ -0,0 +1,33 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file menuItemHover.ts
7
+ * @output Exports focusMenuItemOnHover
8
+ * @position Shared helper for DropdownMenu/ContextMenu item components
9
+ *
10
+ * Menus keep a single highlighted item by using DOM focus as the sole
11
+ * highlight source. Mouse hover moves focus onto the pointed-at item so the
12
+ * one focus highlight follows the pointer — instead of a separate `:hover`
13
+ * background leaving the keyboard-focused item highlighted at the same time.
14
+ *
15
+ * SYNC: When modified, update the item components that use it:
16
+ * - /packages/core/src/DropdownMenu/DropdownMenuItem.tsx
17
+ * - /packages/core/src/DropdownMenu/DropdownMenuCheckboxItem.tsx
18
+ * - /packages/core/src/DropdownMenu/DropdownMenuRadioItem.tsx
19
+ */
20
+ /**
21
+ * Move focus to a menu item as the pointer moves over it, so hover and
22
+ * keyboard navigation share a single focus-driven highlight. Only reacts to a
23
+ * real mouse (not touch/pen, which have no hover), and skips disabled items.
24
+ */
25
+ export function focusMenuItemOnHover(e, isDisabled) {
26
+ if (isDisabled || e.pointerType !== 'mouse') {
27
+ return;
28
+ }
29
+ const el = e.currentTarget;
30
+ if (el !== el.ownerDocument.activeElement) {
31
+ el.focus();
32
+ }
33
+ }
@@ -10,4 +10,12 @@
10
10
  */
11
11
  export declare const MENU_ITEM_ROLES: ReadonlySet<string>;
12
12
  export declare const MENU_ITEM_SELECTOR: string;
13
+ /**
14
+ * Boundary selector for a single menu level. A menu and its submenu flyouts
15
+ * both use `role="menu"`, and flyouts render inline (native popover, not a
16
+ * portal), so a nested menu's items and key events would otherwise be picked
17
+ * up by the parent. Pass this as `useListFocus`'s `boundarySelector` so each
18
+ * level scopes item collection and key handling to its own container.
19
+ */
20
+ export declare const MENU_BOUNDARY_SELECTOR = "[role=\"menu\"]";
13
21
  //# sourceMappingURL=menuItemRoles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"menuItemRoles.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/menuItemRoles.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAI9C,CAAC;AAEH,eAAO,MAAM,kBAAkB,EAAE,MAErB,CAAC"}
1
+ {"version":3,"file":"menuItemRoles.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/menuItemRoles.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAI9C,CAAC;AAEH,eAAO,MAAM,kBAAkB,EAAE,MAErB,CAAC;AAEb;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,oBAAkB,CAAC"}
@@ -12,4 +12,13 @@
12
12
  */
13
13
 
14
14
  export const MENU_ITEM_ROLES = new Set(['menuitem', 'menuitemradio', 'menuitemcheckbox']);
15
- export const MENU_ITEM_SELECTOR = [...MENU_ITEM_ROLES].map(role => `[role="${role}"]:not([aria-disabled="true"])`).join(',');
15
+ export const MENU_ITEM_SELECTOR = [...MENU_ITEM_ROLES].map(role => `[role="${role}"]:not([aria-disabled="true"])`).join(',');
16
+
17
+ /**
18
+ * Boundary selector for a single menu level. A menu and its submenu flyouts
19
+ * both use `role="menu"`, and flyouts render inline (native popover, not a
20
+ * portal), so a nested menu's items and key events would otherwise be picked
21
+ * up by the parent. Pass this as `useListFocus`'s `boundarySelector` so each
22
+ * level scopes item collection and key handling to its own container.
23
+ */
24
+ export const MENU_BOUNDARY_SELECTOR = '[role="menu"]';
@@ -1 +1 @@
1
- {"version":3,"file":"renderDropdownItems.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/renderDropdownItems.tsx"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAUrC,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,gBAAgB,CAAC;AAyBxB;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,kBAAkB,EAAE,GAC1B,SAAS,CA8CX"}
1
+ {"version":3,"file":"renderDropdownItems.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/renderDropdownItems.tsx"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAWrC,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,gBAAgB,CAAC;AAyBxB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,EAAE,GAAG,SAAS,CA6D1E"}
@@ -9,6 +9,7 @@
9
9
  import * as stylex from '@stylexjs/stylex';
10
10
  import { Divider } from "../Divider/index.js";
11
11
  import { DropdownMenuItem } from "./DropdownMenuItem.js";
12
+ import { DropdownMenuSubMenu } from "./DropdownMenuSubMenu.js";
12
13
  import "../theme/tokens.stylex.js";
13
14
  import { spacingVars, typographyVars, typeScaleVars, colorVars } from "../theme/tokens.stylex.js";
14
15
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -55,12 +56,26 @@ export function renderDropdownItems(items) {
55
56
  }, getItemKey(item)))]
56
57
  }, getSectionKey(option, i)));
57
58
  } else if (!('type' in option)) {
58
- elements.push(/*#__PURE__*/_jsx(DropdownMenuItem, {
59
- icon: option.icon,
60
- label: option.label,
61
- onClick: option.onClick,
62
- isDisabled: option.isDisabled
63
- }, getItemKey(option)));
59
+ // A plain item that declares nested `items` becomes a submenu (data-mode
60
+ // parity with the compound DropdownMenuSubMenu API); otherwise it's a
61
+ // leaf. renderDropdownItems owns the recursion and hands the rendered
62
+ // children to DropdownMenuSubMenu — so DropdownMenuSubMenu never imports
63
+ // this module back (no import cycle).
64
+ if (option.items && option.items.length > 0) {
65
+ elements.push(/*#__PURE__*/_jsx(DropdownMenuSubMenu, {
66
+ icon: option.icon,
67
+ label: option.label,
68
+ isDisabled: option.isDisabled,
69
+ children: renderDropdownItems(option.items)
70
+ }, getItemKey(option)));
71
+ } else {
72
+ elements.push(/*#__PURE__*/_jsx(DropdownMenuItem, {
73
+ icon: option.icon,
74
+ label: option.label,
75
+ onClick: option.onClick,
76
+ isDisabled: option.isDisabled
77
+ }, getItemKey(option)));
78
+ }
64
79
  }
65
80
  }
66
81
  return elements;
@@ -14,6 +14,7 @@
14
14
  import { type ReactNode } from 'react';
15
15
  import type { BaseProps } from '../BaseProps';
16
16
  import type { SizeValue } from '../utils/types';
17
+ import type { FieldStatusVariant } from '../FieldStatus/FieldStatus';
17
18
  import type { IconType } from '../Icon';
18
19
  export type { SizeValue } from '../utils/types';
19
20
  export type FieldStatusType = 'warning' | 'error' | 'success';
@@ -105,9 +106,10 @@ export interface FieldProps extends Omit<BaseProps<HTMLDivElement>, 'children'>
105
106
  * How the status message is rendered relative to the input.
106
107
  * - 'attached': Status sits directly below the input (default, for bordered inputs)
107
108
  * - 'detached': Status is a separate element below the field (for checkboxes, switches, sliders)
109
+ * - 'tooltip': No message box; the input surfaces status through a tooltip on its on-field icon
108
110
  * @default 'attached'
109
111
  */
110
- statusVariant?: 'attached' | 'detached';
112
+ statusVariant?: FieldStatusVariant;
111
113
  /**
112
114
  * Width of the field. Numbers are treated as pixels, strings are used as-is
113
115
  * (e.g. `'100%'`). Sizes the whole field — label, control, and status — so
@@ -1 +1 @@
1
- {"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../src/Field/Field.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAM,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAI9C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAqCtC,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,EAAE,eAAe,CAAC;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAW,SAAQ,IAAI,CACtC,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACxC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,OAAO,EACP,OAAO,EACP,YAAoB,EACpB,aAAa,EACb,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAA0B,EAC1B,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,UAAU,+BAqGZ;yBA3He,KAAK"}
1
+ {"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../../src/Field/Field.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,KAAK,SAAS,EAAM,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAG9C,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAEnE,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAqCtC,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,IAAI,EAAE,eAAe,CAAC;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAW,SAAQ,IAAI,CACtC,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,OAAO,EACP,OAAO,EACP,YAAoB,EACpB,aAAa,EACb,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,SAAS,EACT,MAAM,EACN,YAAY,EACZ,aAA0B,EAC1B,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,UAAU,+BAwGZ;yBA9He,KAAK"}