@galaxy-io/dls 1.6.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (538) hide show
  1. package/README.md +47 -50
  2. package/biome/index.json +74 -0
  3. package/biome/plugins/no-hex-literal.grit +20 -0
  4. package/biome/plugins/no-inline-style.grit +13 -0
  5. package/biome/plugins/no-margin.grit +9 -0
  6. package/biome/plugins/warn/no-hex-literal.grit +23 -0
  7. package/biome/plugins/warn/no-inline-style.grit +13 -0
  8. package/biome/plugins/warn/no-margin.grit +9 -0
  9. package/dist/a11y/FocusScope.d.ts +44 -0
  10. package/dist/a11y/FocusScope.js +229 -0
  11. package/dist/a11y/VisuallyHidden.d.ts +21 -0
  12. package/dist/a11y/VisuallyHidden.js +30 -0
  13. package/dist/avatar/Avatar.d.ts +56 -14
  14. package/dist/avatar/Avatar.js +250 -96
  15. package/dist/avatar/AvatarGroup.d.ts +43 -0
  16. package/dist/avatar/AvatarGroup.js +153 -0
  17. package/dist/backgrounds/GridBackground.d.ts +48 -0
  18. package/dist/backgrounds/GridBackground.js +146 -0
  19. package/dist/beacons/Beacon.d.ts +86 -22
  20. package/dist/beacons/Beacon.js +170 -47
  21. package/dist/brand/GalaxyFilamentWordmark.d.ts +30 -0
  22. package/dist/brand/GalaxyFilamentWordmark.js +39 -0
  23. package/dist/brand/GalaxyLogomark.d.ts +26 -0
  24. package/dist/brand/GalaxyLogomark.js +41 -0
  25. package/dist/brand/GalaxyLogomarkAnimation.d.ts +36 -0
  26. package/dist/brand/GalaxyLogomarkAnimation.js +107 -0
  27. package/dist/brand/GalaxyWordmark.d.ts +30 -0
  28. package/dist/brand/GalaxyWordmark.js +63 -0
  29. package/dist/brand/assets/galaxy-logomark-animation.js +136678 -0
  30. package/dist/brand/brandMark.d.ts +26 -0
  31. package/dist/brand/brandMark.js +35 -0
  32. package/dist/buttons/Button.d.ts +148 -59
  33. package/dist/buttons/Button.js +437 -227
  34. package/dist/buttons/ButtonGroup.d.ts +38 -0
  35. package/dist/buttons/ButtonGroup.js +68 -0
  36. package/dist/buttons/CopyButton.d.ts +77 -0
  37. package/dist/buttons/CopyButton.js +65 -0
  38. package/dist/charts/AreaChart.d.ts +49 -0
  39. package/dist/charts/AreaChart.js +31 -0
  40. package/dist/charts/BarChart.d.ts +54 -67
  41. package/dist/charts/BarChart.js +136 -116
  42. package/dist/charts/ChartAxis.d.ts +35 -40
  43. package/dist/charts/ChartAxis.js +114 -90
  44. package/dist/charts/ChartCategoryTargets.d.ts +12 -26
  45. package/dist/charts/ChartCategoryTargets.js +32 -20
  46. package/dist/charts/ChartFrame.d.ts +69 -116
  47. package/dist/charts/ChartFrame.js +253 -119
  48. package/dist/charts/ChartGroupProvider.d.ts +30 -41
  49. package/dist/charts/ChartGroupProvider.js +20 -7
  50. package/dist/charts/ChartLegend.d.ts +27 -48
  51. package/dist/charts/ChartLegend.js +206 -125
  52. package/dist/charts/ChartMarkTargets.d.ts +12 -28
  53. package/dist/charts/ChartMarkTargets.js +33 -20
  54. package/dist/charts/ChartPrimitives.d.ts +50 -305
  55. package/dist/charts/ChartPrimitives.js +65 -413
  56. package/dist/charts/ChartTooltip.d.ts +20 -26
  57. package/dist/charts/ChartTooltip.js +77 -40
  58. package/dist/charts/Heatmap.d.ts +35 -0
  59. package/dist/charts/Heatmap.js +295 -0
  60. package/dist/charts/LineChart.d.ts +54 -47
  61. package/dist/charts/LineChart.js +159 -117
  62. package/dist/charts/PieChart.d.ts +32 -53
  63. package/dist/charts/PieChart.js +149 -135
  64. package/dist/charts/Sparkline.d.ts +107 -0
  65. package/dist/charts/Sparkline.js +244 -0
  66. package/dist/charts/StatChart.d.ts +37 -13
  67. package/dist/charts/StatChart.js +82 -35
  68. package/dist/charts/barChartGeometry.d.ts +138 -86
  69. package/dist/charts/barChartGeometry.js +122 -101
  70. package/dist/charts/barChartLegend.d.ts +14 -18
  71. package/dist/charts/barChartLegend.js +18 -13
  72. package/dist/charts/chartFormat.d.ts +12 -18
  73. package/dist/charts/chartFormat.js +20 -52
  74. package/dist/charts/chartPalette.d.ts +33 -0
  75. package/dist/charts/chartPalette.js +68 -0
  76. package/dist/charts/chartScales.d.ts +41 -108
  77. package/dist/charts/chartScales.js +62 -128
  78. package/dist/charts/constants.d.ts +96 -256
  79. package/dist/charts/constants.js +105 -275
  80. package/dist/charts/heatmapGeometry.d.ts +95 -0
  81. package/dist/charts/heatmapGeometry.js +155 -0
  82. package/dist/charts/lineChartGeometry.d.ts +108 -58
  83. package/dist/charts/lineChartGeometry.js +120 -78
  84. package/dist/charts/pieChartGeometry.d.ts +66 -40
  85. package/dist/charts/pieChartGeometry.js +68 -38
  86. package/dist/charts/types.d.ts +197 -466
  87. package/dist/charts/types.js +55 -144
  88. package/dist/charts/useCartesianChartLayout.d.ts +28 -59
  89. package/dist/charts/useCartesianChartLayout.js +47 -32
  90. package/dist/charts/useChartDimensions.d.ts +19 -40
  91. package/dist/charts/useChartDimensions.js +40 -56
  92. package/dist/charts/useChartFormatters.d.ts +6 -15
  93. package/dist/charts/useChartFormatters.js +4 -9
  94. package/dist/charts/useChartInteraction.d.ts +47 -116
  95. package/dist/charts/useChartInteraction.js +95 -71
  96. package/dist/charts/useChartTooltipPosition.d.ts +29 -39
  97. package/dist/charts/useChartTooltipPosition.js +14 -5
  98. package/dist/charts/useSeriesColorResolver.d.ts +11 -33
  99. package/dist/charts/useSeriesColorResolver.js +19 -12
  100. package/dist/chips/Chip.d.ts +155 -44
  101. package/dist/chips/Chip.js +329 -155
  102. package/dist/chips/ChipGroup.d.ts +53 -0
  103. package/dist/chips/ChipGroup.js +98 -0
  104. package/dist/drawer/Drawer.d.ts +81 -17
  105. package/dist/drawer/Drawer.js +370 -65
  106. package/dist/dropdown/Dropdown.d.ts +80 -63
  107. package/dist/dropdown/Dropdown.js +127 -129
  108. package/dist/editor/CodeEditor.d.ts +119 -40
  109. package/dist/editor/CodeEditor.js +490 -400
  110. package/dist/editor/CodeEditorReactWidget.d.ts +20 -17
  111. package/dist/editor/CodeEditorReactWidget.js +28 -21
  112. package/dist/feedback/Alert.d.ts +49 -0
  113. package/dist/feedback/Alert.js +172 -0
  114. package/dist/feedback/EmptyState.d.ts +39 -0
  115. package/dist/feedback/EmptyState.js +109 -0
  116. package/dist/feedback/ProgressBar.d.ts +125 -0
  117. package/dist/feedback/ProgressBar.js +183 -0
  118. package/dist/feedback/ProgressCircle.d.ts +99 -0
  119. package/dist/feedback/ProgressCircle.js +187 -0
  120. package/dist/feedback/Skeleton.d.ts +69 -0
  121. package/dist/feedback/Skeleton.js +130 -0
  122. package/dist/feedback/Spinner.d.ts +63 -0
  123. package/dist/feedback/Spinner.js +141 -0
  124. package/dist/fonts.css +70 -0
  125. package/dist/hooks/internal/useIsClient.d.ts +2 -0
  126. package/dist/hooks/internal/useIsClient.js +14 -0
  127. package/dist/hooks/useClipboard.d.ts +19 -0
  128. package/dist/hooks/useClipboard.js +45 -0
  129. package/dist/hooks/useControlledOpenState.d.ts +21 -0
  130. package/dist/hooks/useControlledOpenState.js +19 -0
  131. package/dist/hooks/useControlledState.d.ts +19 -0
  132. package/dist/hooks/useControlledState.js +22 -0
  133. package/dist/hooks/useDebouncedValue.d.ts +14 -0
  134. package/dist/hooks/useDebouncedValue.js +33 -0
  135. package/dist/hooks/useDisclosure.d.ts +26 -0
  136. package/dist/hooks/useDisclosure.js +36 -0
  137. package/dist/hooks/useDismiss.d.ts +23 -27
  138. package/dist/hooks/useDismiss.js +39 -27
  139. package/dist/hooks/useElementClientSize.d.ts +10 -10
  140. package/dist/hooks/useElementClientSize.js +8 -11
  141. package/dist/hooks/useElementWidth.d.ts +6 -13
  142. package/dist/hooks/useElementWidth.js +6 -14
  143. package/dist/hooks/useField.d.ts +47 -0
  144. package/dist/hooks/useField.js +40 -0
  145. package/dist/hooks/useHotkey.d.ts +77 -0
  146. package/dist/hooks/useHotkey.js +246 -0
  147. package/dist/hooks/useIsMac.d.ts +12 -0
  148. package/dist/hooks/useIsMac.js +27 -0
  149. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +17 -0
  150. package/dist/hooks/useIsomorphicLayoutEffect.js +20 -0
  151. package/dist/hooks/useLocalStorage.d.ts +28 -0
  152. package/dist/hooks/useLocalStorage.js +145 -0
  153. package/dist/hooks/useMediaQuery.d.ts +11 -0
  154. package/dist/hooks/useMediaQuery.js +23 -0
  155. package/dist/hooks/usePrefersReducedMotion.d.ts +12 -0
  156. package/dist/hooks/usePrefersReducedMotion.js +25 -0
  157. package/dist/hooks/useResize.d.ts +42 -62
  158. package/dist/hooks/useResize.js +43 -31
  159. package/dist/icons/Icon.d.ts +64 -37
  160. package/dist/icons/Icon.js +96 -37
  161. package/dist/icons/internal/IconSlot.d.ts +10 -0
  162. package/dist/icons/internal/IconSlot.js +32 -0
  163. package/dist/inputs/CheckboxGroup.d.ts +115 -0
  164. package/dist/inputs/CheckboxGroup.js +183 -0
  165. package/dist/inputs/CheckboxInput.d.ts +98 -28
  166. package/dist/inputs/CheckboxInput.js +218 -88
  167. package/dist/inputs/ColorInput.d.ts +115 -29
  168. package/dist/inputs/ColorInput.js +748 -326
  169. package/dist/inputs/CopyInput.d.ts +49 -20
  170. package/dist/inputs/CopyInput.js +57 -49
  171. package/dist/inputs/CronInput.d.ts +94 -0
  172. package/dist/inputs/CronInput.js +618 -0
  173. package/dist/inputs/DateInput.d.ts +175 -28
  174. package/dist/inputs/DateInput.js +1109 -451
  175. package/dist/inputs/DurationInput.d.ts +101 -0
  176. package/dist/inputs/DurationInput.js +441 -0
  177. package/dist/inputs/Field.d.ts +75 -0
  178. package/dist/inputs/Field.js +247 -0
  179. package/dist/inputs/Fieldset.d.ts +53 -0
  180. package/dist/inputs/Fieldset.js +149 -0
  181. package/dist/inputs/FileInput.d.ts +110 -0
  182. package/dist/inputs/FileInput.js +476 -0
  183. package/dist/inputs/Input.d.ts +148 -187
  184. package/dist/inputs/Input.js +339 -259
  185. package/dist/inputs/KeyValueInput.d.ts +120 -0
  186. package/dist/inputs/KeyValueInput.js +383 -0
  187. package/dist/inputs/MultiSelectInput.d.ts +165 -54
  188. package/dist/inputs/MultiSelectInput.js +175 -559
  189. package/dist/inputs/NumberInput.d.ts +65 -9
  190. package/dist/inputs/NumberInput.js +197 -40
  191. package/dist/inputs/PasswordInput.d.ts +17 -12
  192. package/dist/inputs/PasswordInput.js +33 -33
  193. package/dist/inputs/PinInput.d.ts +117 -0
  194. package/dist/inputs/PinInput.js +364 -0
  195. package/dist/inputs/RadioGroup.d.ts +115 -0
  196. package/dist/inputs/RadioGroup.js +179 -0
  197. package/dist/inputs/RadioInput.d.ts +87 -24
  198. package/dist/inputs/RadioInput.js +182 -95
  199. package/dist/inputs/SearchInput.d.ts +66 -0
  200. package/dist/inputs/SearchInput.js +156 -0
  201. package/dist/inputs/SelectInput.d.ts +195 -55
  202. package/dist/inputs/SelectInput.js +1308 -446
  203. package/dist/inputs/SliderInput.d.ts +150 -30
  204. package/dist/inputs/SliderInput.js +441 -186
  205. package/dist/inputs/SwitchInput.d.ts +109 -0
  206. package/dist/inputs/SwitchInput.js +248 -0
  207. package/dist/inputs/TagInput.d.ts +117 -0
  208. package/dist/inputs/TagInput.js +408 -0
  209. package/dist/inputs/TextAreaInput.d.ts +146 -44
  210. package/dist/inputs/TextAreaInput.js +292 -198
  211. package/dist/inputs/TextInput.d.ts +4 -13
  212. package/dist/inputs/TextInput.js +13 -48
  213. package/dist/inputs/ToggleInput.d.ts +120 -22
  214. package/dist/inputs/ToggleInput.js +262 -116
  215. package/dist/inputs/internal/bareField.d.ts +18 -0
  216. package/dist/inputs/internal/bareField.js +38 -0
  217. package/dist/inputs/internal/devWarn.d.ts +7 -0
  218. package/dist/inputs/internal/devWarn.js +30 -0
  219. package/dist/inputs/internal/fieldFrame.d.ts +34 -0
  220. package/dist/inputs/internal/fieldFrame.js +64 -0
  221. package/dist/inputs/internal/fieldWiring.d.ts +50 -0
  222. package/dist/inputs/internal/fieldWiring.js +38 -0
  223. package/dist/inputs/internal/innerButton.d.ts +2 -0
  224. package/dist/inputs/internal/innerButton.js +24 -0
  225. package/dist/inputs/internal/ownField.d.ts +45 -0
  226. package/dist/inputs/internal/ownField.js +58 -0
  227. package/dist/inputs/internal/predicates.d.ts +9 -0
  228. package/dist/inputs/internal/predicates.js +11 -0
  229. package/dist/inputs/internal/useComboboxPopover.d.ts +46 -0
  230. package/dist/inputs/internal/useComboboxPopover.js +92 -0
  231. package/dist/json/JsonViewer.d.ts +62 -0
  232. package/dist/json/JsonViewer.js +483 -0
  233. package/dist/layout/Box.d.ts +87 -0
  234. package/dist/layout/Box.js +109 -0
  235. package/dist/layout/Divider.d.ts +25 -0
  236. package/dist/layout/Divider.js +70 -0
  237. package/dist/layout/Flex.d.ts +139 -0
  238. package/dist/layout/Flex.js +165 -0
  239. package/dist/layout/FlexItem.d.ts +72 -0
  240. package/dist/layout/FlexItem.js +84 -0
  241. package/dist/layout/Grid.d.ts +140 -0
  242. package/dist/layout/Grid.js +178 -0
  243. package/dist/layout/Portal.d.ts +29 -0
  244. package/dist/layout/Portal.js +27 -0
  245. package/dist/layout/ResizablePanels.d.ts +88 -0
  246. package/dist/layout/ResizablePanels.js +198 -0
  247. package/dist/layout/ResizeHandle.d.ts +48 -0
  248. package/dist/layout/ResizeHandle.js +143 -0
  249. package/dist/layout/ScrollArea.d.ts +30 -0
  250. package/dist/layout/ScrollArea.js +138 -0
  251. package/dist/links/Link.d.ts +101 -1
  252. package/dist/links/Link.js +166 -4
  253. package/dist/lists/BulletedList.d.ts +25 -7
  254. package/dist/lists/BulletedList.js +72 -27
  255. package/dist/lists/DescriptionList.d.ts +91 -0
  256. package/dist/lists/DescriptionList.js +147 -0
  257. package/dist/menu/ContextMenu.d.ts +64 -0
  258. package/dist/menu/ContextMenu.js +34 -0
  259. package/dist/menu/Menu.d.ts +280 -0
  260. package/dist/menu/Menu.js +1003 -0
  261. package/dist/modal/ConfirmDialog.d.ts +55 -0
  262. package/dist/modal/ConfirmDialog.js +151 -0
  263. package/dist/modal/Modal.d.ts +64 -14
  264. package/dist/modal/Modal.js +189 -48
  265. package/dist/navigation/Breadcrumbs.d.ts +65 -0
  266. package/dist/navigation/Breadcrumbs.js +243 -0
  267. package/dist/navigation/CommandPalette.d.ts +83 -0
  268. package/dist/navigation/CommandPalette.js +509 -0
  269. package/dist/navigation/Pagination.d.ts +87 -0
  270. package/dist/navigation/Pagination.js +300 -0
  271. package/dist/navigation/SidebarNav.d.ts +107 -0
  272. package/dist/navigation/SidebarNav.js +341 -0
  273. package/dist/navigation/Stepper.d.ts +52 -0
  274. package/dist/navigation/Stepper.js +207 -0
  275. package/dist/navigation/Tabs.d.ts +113 -0
  276. package/dist/navigation/Tabs.js +543 -0
  277. package/dist/navigation/Topbar.d.ts +20 -0
  278. package/dist/navigation/Topbar.js +62 -0
  279. package/dist/overlay/OverlayProvider.d.ts +28 -32
  280. package/dist/overlay/OverlayProvider.js +42 -93
  281. package/dist/overlay/useOverlay.d.ts +88 -12
  282. package/dist/overlay/useOverlay.js +220 -43
  283. package/dist/overlays/Popover.d.ts +114 -0
  284. package/dist/overlays/Popover.js +389 -0
  285. package/dist/shapes/Circle.d.ts +84 -8
  286. package/dist/shapes/Circle.js +122 -20
  287. package/dist/shapes/Square.d.ts +84 -8
  288. package/dist/shapes/Square.js +123 -20
  289. package/dist/styles/mixins.d.ts +35 -0
  290. package/dist/styles/mixins.js +60 -0
  291. package/dist/styles.css +1 -202
  292. package/dist/table/InfiniteSpreadsheet.d.ts +140 -10
  293. package/dist/table/InfiniteSpreadsheet.js +762 -225
  294. package/dist/table/InfiniteTable.d.ts +116 -14
  295. package/dist/table/InfiniteTable.js +287 -429
  296. package/dist/table/SpreadsheetCellEditor.d.ts +54 -6
  297. package/dist/table/SpreadsheetCellEditor.js +163 -84
  298. package/dist/table/TableCore.d.ts +252 -0
  299. package/dist/table/TableCore.js +1077 -0
  300. package/dist/table/VirtualizedInfiniteTable.d.ts +104 -14
  301. package/dist/table/VirtualizedInfiniteTable.js +280 -219
  302. package/dist/table/types.d.ts +66 -244
  303. package/dist/table/types.js +0 -51
  304. package/dist/table/useInfiniteScrollSentinel.d.ts +25 -21
  305. package/dist/table/useInfiniteScrollSentinel.js +38 -30
  306. package/dist/table/useSpreadsheetCellNavigation.d.ts +44 -0
  307. package/dist/table/useSpreadsheetCellNavigation.js +141 -0
  308. package/dist/table/useTableColumnLayout.d.ts +90 -25
  309. package/dist/table/useTableColumnLayout.js +255 -50
  310. package/dist/table/useTableKeyboardNavigation.d.ts +32 -21
  311. package/dist/table/useTableKeyboardNavigation.js +95 -71
  312. package/dist/table/useTableRowSelection.d.ts +24 -25
  313. package/dist/table/useTableRowSelection.js +57 -84
  314. package/dist/table/useTableVirtualizer.d.ts +20 -0
  315. package/dist/table/useTableVirtualizer.js +48 -0
  316. package/dist/text/Bold.d.ts +5 -6
  317. package/dist/text/Bold.js +16 -15
  318. package/dist/text/Code.d.ts +5 -6
  319. package/dist/text/Code.js +16 -25
  320. package/dist/text/CodeBlock.d.ts +77 -0
  321. package/dist/text/CodeBlock.js +373 -0
  322. package/dist/text/EditableText.d.ts +55 -15
  323. package/dist/text/EditableText.js +153 -135
  324. package/dist/text/Ellipsis.d.ts +34 -8
  325. package/dist/text/Ellipsis.js +55 -23
  326. package/dist/text/Kbd.d.ts +72 -0
  327. package/dist/text/Kbd.js +284 -0
  328. package/dist/text/MarkdownText.d.ts +27 -10
  329. package/dist/text/MarkdownText.js +317 -300
  330. package/dist/text/RequiredMarker.d.ts +17 -5
  331. package/dist/text/RequiredMarker.js +34 -36
  332. package/dist/text/Selectable.d.ts +5 -6
  333. package/dist/text/Selectable.js +16 -13
  334. package/dist/text/Span.d.ts +82 -0
  335. package/dist/text/Span.js +115 -0
  336. package/dist/text/Text.d.ts +128 -41
  337. package/dist/text/Text.js +209 -76
  338. package/dist/theme/GalaxyProvider.d.ts +75 -0
  339. package/dist/theme/GalaxyProvider.js +223 -0
  340. package/dist/theme/ThemeSwitcher.d.ts +52 -0
  341. package/dist/theme/ThemeSwitcher.js +94 -0
  342. package/dist/theme/enums.d.ts +118 -0
  343. package/dist/theme/enums.js +144 -0
  344. package/dist/theme/tokens/dark.d.ts +2 -0
  345. package/dist/theme/tokens/dark.js +275 -0
  346. package/dist/theme/tokens/generate.d.ts +15 -0
  347. package/dist/theme/tokens/generate.js +47 -0
  348. package/dist/theme/tokens/light.d.ts +2 -0
  349. package/dist/theme/tokens/light.js +274 -0
  350. package/dist/theme/tokens/palette.d.ts +14 -0
  351. package/dist/theme/tokens/palette.js +153 -0
  352. package/dist/theme/tokens/scales.d.ts +26 -0
  353. package/dist/theme/tokens/scales.js +154 -0
  354. package/dist/theme/tokens/t.d.ts +3 -0
  355. package/dist/theme/tokens/t.js +25 -0
  356. package/dist/theme/tokens/types.d.ts +189 -0
  357. package/dist/theme/tokens/types.js +0 -0
  358. package/dist/theme/useGalaxyTheme.d.ts +46 -0
  359. package/dist/theme/useGalaxyTheme.js +36 -0
  360. package/dist/theme/useInverseScope.d.ts +18 -0
  361. package/dist/theme/useInverseScope.js +33 -0
  362. package/dist/three/GalaxyLogomark3D.d.ts +46 -0
  363. package/dist/three/GalaxyLogomark3D.js +134 -0
  364. package/dist/three/assets/galaxy-logomark.js +4 -0
  365. package/dist/three/galaxyLogomark3DScene.d.ts +27 -0
  366. package/dist/three/galaxyLogomark3DScene.js +165 -0
  367. package/dist/timeline/Timeline.d.ts +99 -0
  368. package/dist/timeline/Timeline.js +269 -0
  369. package/dist/toast/Toast.d.ts +43 -19
  370. package/dist/toast/Toast.js +130 -89
  371. package/dist/toast/ToastProvider.d.ts +23 -23
  372. package/dist/toast/ToastProvider.js +298 -101
  373. package/dist/toast/ToastViewport.d.ts +12 -0
  374. package/dist/toast/ToastViewport.js +210 -0
  375. package/dist/toast/useToast.d.ts +139 -5
  376. package/dist/toast/useToast.js +15 -13
  377. package/dist/tokens.css +654 -0
  378. package/dist/tooltip/Tooltip.d.ts +64 -44
  379. package/dist/tooltip/Tooltip.js +280 -73
  380. package/dist/tooltip/internal/LazyTooltip.d.ts +7 -0
  381. package/dist/tooltip/internal/LazyTooltip.js +53 -0
  382. package/dist/transform/Fade.d.ts +33 -11
  383. package/dist/transform/Fade.js +71 -19
  384. package/dist/transform/Flasher.d.ts +25 -0
  385. package/dist/transform/Flasher.js +39 -0
  386. package/dist/transform/Rotate.d.ts +24 -12
  387. package/dist/transform/Rotate.js +36 -22
  388. package/dist/transform/ScaleFade.d.ts +36 -11
  389. package/dist/transform/ScaleFade.js +86 -28
  390. package/dist/transform/internal/CollapseMotion.d.ts +10 -0
  391. package/dist/transform/internal/CollapseMotion.js +65 -0
  392. package/dist/tree/Tree.d.ts +85 -0
  393. package/dist/tree/Tree.js +387 -0
  394. package/dist/tree/treeRow.d.ts +39 -0
  395. package/dist/tree/treeRow.js +75 -0
  396. package/dist/utils/colors.d.ts +46 -13
  397. package/dist/utils/colors.js +92 -34
  398. package/dist/utils/css.d.ts +23 -0
  399. package/dist/utils/css.js +30 -0
  400. package/dist/utils/format.d.ts +58 -0
  401. package/dist/utils/format.js +220 -0
  402. package/dist/vite/index.d.ts +16 -0
  403. package/dist/vite/index.js +52 -0
  404. package/dist/widget/Widget.d.ts +164 -48
  405. package/dist/widget/Widget.js +335 -96
  406. package/dist/widget/WidgetGroup.d.ts +36 -0
  407. package/dist/widget/WidgetGroup.js +103 -0
  408. package/package.json +851 -157
  409. package/dist/accordion/Accordion.d.ts +0 -54
  410. package/dist/accordion/Accordion.js +0 -183
  411. package/dist/assets/components/GalaxyFilamentWordmarkDark.d.ts +0 -3
  412. package/dist/assets/components/GalaxyFilamentWordmarkDark.js +0 -14
  413. package/dist/assets/components/GalaxyFilamentWordmarkLight.d.ts +0 -3
  414. package/dist/assets/components/GalaxyFilamentWordmarkLight.js +0 -14
  415. package/dist/assets/components/GalaxyLogomarkDark.d.ts +0 -3
  416. package/dist/assets/components/GalaxyLogomarkDark.js +0 -11
  417. package/dist/assets/components/GalaxyLogomarkLight.d.ts +0 -3
  418. package/dist/assets/components/GalaxyLogomarkLight.js +0 -17
  419. package/dist/assets/components/GalaxyWordmarkDark.d.ts +0 -3
  420. package/dist/assets/components/GalaxyWordmarkDark.js +0 -15
  421. package/dist/assets/components/GalaxyWordmarkLight.d.ts +0 -3
  422. package/dist/assets/components/GalaxyWordmarkLight.js +0 -28
  423. package/dist/assets/models/galaxy-animation.js +0 -136666
  424. package/dist/assets/models/galaxy-logomark.js +0 -4
  425. package/dist/avatar/AvatarShimmer.d.ts +0 -30
  426. package/dist/avatar/AvatarShimmer.js +0 -22
  427. package/dist/backgrounds/CellGridBackground.d.ts +0 -24
  428. package/dist/backgrounds/CellGridBackground.js +0 -44
  429. package/dist/backgrounds/CrossGridBackground.d.ts +0 -26
  430. package/dist/backgrounds/CrossGridBackground.js +0 -49
  431. package/dist/backgrounds/DotGridBackground.d.ts +0 -24
  432. package/dist/backgrounds/DotGridBackground.js +0 -47
  433. package/dist/badge/Badge.d.ts +0 -42
  434. package/dist/badge/Badge.js +0 -99
  435. package/dist/charts/ChartEmptyState.d.ts +0 -17
  436. package/dist/charts/ChartEmptyState.js +0 -29
  437. package/dist/charts/ProgressBar.d.ts +0 -29
  438. package/dist/charts/ProgressBar.js +0 -65
  439. package/dist/charts/chartTheme.d.ts +0 -18
  440. package/dist/charts/chartTheme.js +0 -26
  441. package/dist/containers/FlexItem.d.ts +0 -50
  442. package/dist/containers/FlexItem.js +0 -91
  443. package/dist/containers/FlexWrapper.d.ts +0 -96
  444. package/dist/containers/FlexWrapper.js +0 -143
  445. package/dist/containers/GridWrapper.d.ts +0 -79
  446. package/dist/containers/GridWrapper.js +0 -125
  447. package/dist/containers/Spacing.d.ts +0 -23
  448. package/dist/containers/Spacing.js +0 -59
  449. package/dist/containers/Wrapper.d.ts +0 -26
  450. package/dist/containers/Wrapper.js +0 -54
  451. package/dist/dividers/HorizontalDivider.d.ts +0 -7
  452. package/dist/dividers/HorizontalDivider.js +0 -39
  453. package/dist/dividers/VerticalDivider.d.ts +0 -6
  454. package/dist/dividers/VerticalDivider.js +0 -21
  455. package/dist/icons/GalaxyFilamentWordmark.d.ts +0 -11
  456. package/dist/icons/GalaxyFilamentWordmark.js +0 -25
  457. package/dist/icons/GalaxyLogomark.d.ts +0 -13
  458. package/dist/icons/GalaxyLogomark.js +0 -27
  459. package/dist/icons/GalaxyLogomark3D.d.ts +0 -56
  460. package/dist/icons/GalaxyLogomark3D.js +0 -319
  461. package/dist/icons/GalaxyLogomarkAnimation.d.ts +0 -18
  462. package/dist/icons/GalaxyLogomarkAnimation.js +0 -48
  463. package/dist/icons/GalaxyWordmark.d.ts +0 -11
  464. package/dist/icons/GalaxyWordmark.js +0 -25
  465. package/dist/inputs/MultiTextInput.d.ts +0 -32
  466. package/dist/inputs/MultiTextInput.js +0 -180
  467. package/dist/inputs/SwitcherInput.d.ts +0 -30
  468. package/dist/inputs/SwitcherInput.js +0 -81
  469. package/dist/inputs/hooks.d.ts +0 -10
  470. package/dist/inputs/hooks.js +0 -22
  471. package/dist/overlay/constants.d.ts +0 -28
  472. package/dist/overlay/constants.js +0 -37
  473. package/dist/resizable/HorizontalResizeHandle.d.ts +0 -17
  474. package/dist/resizable/HorizontalResizeHandle.js +0 -38
  475. package/dist/resizable/VerticalResizeHandle.d.ts +0 -18
  476. package/dist/resizable/VerticalResizeHandle.js +0 -39
  477. package/dist/table/SpreadsheetCell.d.ts +0 -21
  478. package/dist/table/SpreadsheetCell.js +0 -71
  479. package/dist/table/SpreadsheetHeaderCell.d.ts +0 -23
  480. package/dist/table/SpreadsheetHeaderCell.js +0 -91
  481. package/dist/table/SpreadsheetMenuItem.d.ts +0 -14
  482. package/dist/table/SpreadsheetMenuItem.js +0 -33
  483. package/dist/table/SpreadsheetPrimitives.d.ts +0 -172
  484. package/dist/table/SpreadsheetPrimitives.js +0 -105
  485. package/dist/table/SpreadsheetRow.d.ts +0 -33
  486. package/dist/table/SpreadsheetRow.js +0 -73
  487. package/dist/table/SpreadsheetRowActionCell.d.ts +0 -14
  488. package/dist/table/SpreadsheetRowActionCell.js +0 -51
  489. package/dist/table/TableExpandCell.d.ts +0 -11
  490. package/dist/table/TableExpandCell.js +0 -24
  491. package/dist/table/TableExpandedRow.d.ts +0 -16
  492. package/dist/table/TableExpandedRow.js +0 -77
  493. package/dist/table/TableHeaderCellContent.d.ts +0 -30
  494. package/dist/table/TableHeaderCellContent.js +0 -48
  495. package/dist/table/TablePrimitives.d.ts +0 -313
  496. package/dist/table/TablePrimitives.js +0 -302
  497. package/dist/table/TableSelectCell.d.ts +0 -18
  498. package/dist/table/TableSelectCell.js +0 -27
  499. package/dist/table/TableStatusRow.d.ts +0 -18
  500. package/dist/table/TableStatusRow.js +0 -50
  501. package/dist/table/useSpreadsheetEditing.d.ts +0 -13
  502. package/dist/table/useSpreadsheetEditing.js +0 -41
  503. package/dist/table/useTableColumnResize.d.ts +0 -38
  504. package/dist/table/useTableColumnResize.js +0 -155
  505. package/dist/table/useTableRowExpansion.d.ts +0 -24
  506. package/dist/table/useTableRowExpansion.js +0 -62
  507. package/dist/table/utils.d.ts +0 -50
  508. package/dist/table/utils.js +0 -78
  509. package/dist/text/HotKeys.d.ts +0 -30
  510. package/dist/text/HotKeys.js +0 -74
  511. package/dist/text/Paragraph.d.ts +0 -33
  512. package/dist/text/Paragraph.js +0 -83
  513. package/dist/text/TextShimmer.d.ts +0 -14
  514. package/dist/text/TextShimmer.js +0 -34
  515. package/dist/theme/GalaxyTheme.d.ts +0 -67
  516. package/dist/theme/GalaxyTheme.js +0 -119
  517. package/dist/theme/constants.d.ts +0 -8
  518. package/dist/theme/constants.js +0 -38
  519. package/dist/theme/index.d.ts +0 -6
  520. package/dist/theme/index.js +0 -7
  521. package/dist/theme/types.d.ts +0 -195
  522. package/dist/theme/types.js +0 -10
  523. package/dist/theme/typography.d.ts +0 -2
  524. package/dist/theme/typography.js +0 -73
  525. package/dist/theme/variants/dark.d.ts +0 -2
  526. package/dist/theme/variants/dark.js +0 -125
  527. package/dist/theme/variants/light.d.ts +0 -2
  528. package/dist/theme/variants/light.js +0 -125
  529. package/dist/toast/ToastContainer.d.ts +0 -10
  530. package/dist/toast/ToastContainer.js +0 -31
  531. package/dist/toast/ToastWrapper.d.ts +0 -6
  532. package/dist/toast/ToastWrapper.js +0 -27
  533. package/dist/transform/Flash.d.ts +0 -7
  534. package/dist/transform/Flash.js +0 -18
  535. package/dist/transform/Spin.d.ts +0 -14
  536. package/dist/transform/Spin.js +0 -25
  537. package/dist/utils/linaria.d.ts +0 -1
  538. package/dist/utils/linaria.js +0 -8
@@ -0,0 +1,1003 @@
1
+ import { useIsomorphicLayoutEffect } from "../hooks/useIsomorphicLayoutEffect.js";
2
+ import VisuallyHidden from "../a11y/VisuallyHidden.js";
3
+ import { Placement } from "../theme/enums.js";
4
+ import Text, { TextSize, TextVariant, TextWeight } from "../text/Text.js";
5
+ import { useControlledState } from "../hooks/useControlledState.js";
6
+ import { useControlledOpenState } from "../hooks/useControlledOpenState.js";
7
+ import Kbd, { KbdSize, KbdVariant } from "../text/Kbd.js";
8
+ import Tooltip from "../tooltip/Tooltip.js";
9
+ import Box from "../layout/Box.js";
10
+ import Divider from "../layout/Divider.js";
11
+ import Popover, { PopoverRole, PopoverTrigger, PopoverVariant } from "../overlays/Popover.js";
12
+ import Icon, { IconVariant } from "../icons/Icon.js";
13
+ import { InputSize } from "../inputs/Input.js";
14
+ import SearchInput from "../inputs/SearchInput.js";
15
+ /* empty css */
16
+ import { styled } from "@linaria/react";
17
+ import { cloneElement, createContext, forwardRef, useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
18
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
19
+ import { cx } from "@linaria/core";
20
+ import { useMergeRefs } from "@floating-ui/react";
21
+ import { ArrowUpRightIcon, CaretRightIcon, CheckIcon } from "@phosphor-icons/react";
22
+ //#region src/menu/Menu.tsx
23
+ /**
24
+ * The menu button: a trigger element that opens a floating list of commands, navigated with the
25
+ * arrow keys and typeahead, where choosing a command runs it and closes the list. The parts are
26
+ * the rows of that list: `MenuItem` (a command, a link, or the opener of a submenu),
27
+ * `MenuCheckboxItem` (an on/off option), `MenuRadioGroup` (one choice among options), `MenuGroup`
28
+ * (a labelled section) and `MenuSeparator`. `isSearchable` adds a field that filters the rows.
29
+ *
30
+ * Built on `Popover` (`role` `MENU`): placement, stacking, Escape, outside press, motion and focus
31
+ * return are Popover's. Menu adds the row anatomy, a roving-`tabIndex` keyboard model over the
32
+ * rendered rows in DOM order, typeahead, the filter and submenus (each a nested `MANUAL` Popover).
33
+ * `MenuRoot` is the shared engine that `ContextMenu` opens on right-click.
34
+ *
35
+ * A panel of fields or free content is a `Dropdown` or `Popover`; a form value is a `SelectInput`.
36
+ *
37
+ * SSR: only the trigger renders on the server. Nothing here touches `window` or `document` at
38
+ * module scope; typeahead and hover timers live in refs.
39
+ */
40
+ /** Row rung (canonical subset): 24px or 32px rows. */
41
+ var MenuSize = /* @__PURE__ */ function(MenuSize) {
42
+ /** 24px rows, `body_sm` labels, 12px icons, 10px submenu caret: dense menus (table cells, toolbars; the 1.x density). */
43
+ MenuSize["SMALL"] = "SMALL";
44
+ /** 32px rows, `body_md` labels, 14px icons, 12px submenu caret. The default. */
45
+ MenuSize["MEDIUM"] = "MEDIUM";
46
+ return MenuSize;
47
+ }({});
48
+ /** Panel fill: a surface step (Constitution V-A surface set). */
49
+ var MenuVariant = /* @__PURE__ */ function(MenuVariant) {
50
+ /** The canvas fill, `background.base`. The default. */
51
+ MenuVariant["BASE"] = "BASE";
52
+ /** A panel fill, `background.primary`. */
53
+ MenuVariant["PRIMARY"] = "PRIMARY";
54
+ /** A raised fill, `background.secondary`. */
55
+ MenuVariant["SECONDARY"] = "SECONDARY";
56
+ /** The most elevated fill, `background.tertiary`. */
57
+ MenuVariant["TERTIARY"] = "TERTIARY";
58
+ return MenuVariant;
59
+ }({});
60
+ /** Row mode (Constitution V-A: MenuItem `DEFAULT` / `ERROR`; declared in `scripts/lint-dls.ts` `MODE_SETS`). */
61
+ var MenuItemVariant = /* @__PURE__ */ function(MenuItemVariant) {
62
+ /** A monochrome row. The default. */
63
+ MenuItemVariant["DEFAULT"] = "DEFAULT";
64
+ /** A destructive command: error text and icon, error-tinted highlight. */
65
+ MenuItemVariant["ERROR"] = "ERROR";
66
+ return MenuItemVariant;
67
+ }({});
68
+ /** Narrowest and widest list (no width token exists; the `TOOLTIP_MAX_WIDTH` precedent). */
69
+ /** The panel is `border-box` with a 0.5px hairline top and bottom (as in Dropdown). */
70
+ /** Pointer rest before a submenu opens, or before an open one closes (a behavior constant, not motion). */
71
+ var MENU_SUBMENU_HOVER_DELAY_MS = 150;
72
+ /** Pause after which the typeahead prefix starts over. */
73
+ var MENU_TYPEAHEAD_RESET_MS = 500;
74
+ /** Every row role a list navigates. */
75
+ var ROW_SELECTOR = "[role=\"menuitem\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"]";
76
+ /**
77
+ * The row. Rendered as a `<button>`, or as a link (`as`) for `href` rows. `INTERACTIVE_RESET` sets
78
+ * `padding: 0` and `background: none`, so this block is declared before every class composed onto
79
+ * the row (`MENU_SIZE_TO_ITEM_CSS_MAP`, `MENU_ITEM_VARIANT_TO_CSS_MAP`, `ITEM_DISABLED_CSS`): at
80
+ * equal specificity the later rule in the stylesheet wins.
81
+ */
82
+ var ItemRoot = /*#__PURE__*/ styled("button")({
83
+ name: "ItemRoot",
84
+ class: "gx-Menu-ItemRoot-i1kxcddz",
85
+ propsAsIs: false
86
+ });
87
+ /** Row height, inline and block padding, and gap per rung (Constitution III-A.4). */
88
+ var MENU_SIZE_TO_ITEM_CSS_MAP = {
89
+ ["SMALL"]: "gx-Menu-SMALL-s14ltqej",
90
+ ["MEDIUM"]: "gx-Menu-MEDIUM-m1sw24v2"
91
+ };
92
+ /** Label type step per rung. */
93
+ var MENU_SIZE_TO_TEXT_SIZE_MAP = {
94
+ ["SMALL"]: TextSize.BODY_SM,
95
+ ["MEDIUM"]: TextSize.BODY_MD
96
+ };
97
+ /** Description and group-label type step per rung. */
98
+ var MENU_SIZE_TO_SECONDARY_TEXT_SIZE_MAP = {
99
+ ["SMALL"]: TextSize.CAPTION,
100
+ ["MEDIUM"]: TextSize.BODY_SM
101
+ };
102
+ /** Icon px per rung: one step below the rung's III-A.4 icon (Mitch, 2026-10-04). */
103
+ var MENU_SIZE_TO_ICON_PX_MAP = {
104
+ ["SMALL"]: 12,
105
+ ["MEDIUM"]: 14
106
+ };
107
+ /** The submenu caret: 12px, 10px on the 24px rows (the collapsible Widget's caret). */
108
+ var MENU_SIZE_TO_CARET_PX_MAP = {
109
+ ["SMALL"]: 10,
110
+ ["MEDIUM"]: 12
111
+ };
112
+ /** The caps that pair with the label step (Kbd pairing table). */
113
+ var MENU_SIZE_TO_KBD_SIZE_MAP = {
114
+ ["SMALL"]: KbdSize.SMALL,
115
+ ["MEDIUM"]: KbdSize.MEDIUM
116
+ };
117
+ /** The search field takes the menu's rung. */
118
+ var MENU_SIZE_TO_INPUT_SIZE_MAP = {
119
+ ["SMALL"]: InputSize.SMALL,
120
+ ["MEDIUM"]: InputSize.MEDIUM
121
+ };
122
+ /** The check marker's reserved width: the icon's width, so rows align checked or not. */
123
+ var MENU_SIZE_TO_CHECK_SLOT_CSS_MAP = {
124
+ ["SMALL"]: "gx-Menu-SMALL-s1ce9q2a",
125
+ ["MEDIUM"]: "gx-Menu-MEDIUM-mitmqfw"
126
+ };
127
+ /** Group heading height and inset per rung. */
128
+ var MENU_SIZE_TO_GROUP_LABEL_CSS_MAP = {
129
+ ["SMALL"]: "gx-Menu-SMALL-subhcxf",
130
+ ["MEDIUM"]: "gx-Menu-MEDIUM-me676av"
131
+ };
132
+ /** Identity over the four shared surface steps; the fill CSS is Popover's. */
133
+ var MENU_VARIANT_TO_POPOVER_VARIANT_MAP = {
134
+ ["BASE"]: PopoverVariant.BASE,
135
+ ["PRIMARY"]: PopoverVariant.PRIMARY,
136
+ ["SECONDARY"]: PopoverVariant.SECONDARY,
137
+ ["TERTIARY"]: PopoverVariant.TERTIARY
138
+ };
139
+ /** Caps one surface step above the panel (the Tooltip rule). */
140
+ var MENU_VARIANT_TO_KBD_VARIANT_MAP = {
141
+ ["BASE"]: KbdVariant.PRIMARY,
142
+ ["PRIMARY"]: KbdVariant.SECONDARY,
143
+ ["SECONDARY"]: KbdVariant.TERTIARY,
144
+ ["TERTIARY"]: KbdVariant.SECONDARY
145
+ };
146
+ /** Label color per row mode. */
147
+ var MENU_ITEM_VARIANT_TO_TEXT_VARIANT_MAP = {
148
+ ["DEFAULT"]: TextVariant.PRIMARY,
149
+ ["ERROR"]: TextVariant.ERROR
150
+ };
151
+ /** Icon color per row mode. */
152
+ var MENU_ITEM_VARIANT_TO_ICON_VARIANT_MAP = {
153
+ ["DEFAULT"]: IconVariant.SECONDARY,
154
+ ["ERROR"]: IconVariant.ERROR
155
+ };
156
+ /** The row list: content width between the two bounds, a 4px inset. */
157
+ var List = /*#__PURE__*/ styled("div")({
158
+ name: "List",
159
+ class: "gx-Menu-List-letxokg",
160
+ propsAsIs: false
161
+ });
162
+ /** With search: the pinned field over the scrolling list, capped to the room on screen. */
163
+ var SearchLayout = /*#__PURE__*/ styled("div")({
164
+ name: "SearchLayout",
165
+ class: "gx-Menu-SearchLayout-s1m37gth",
166
+ propsAsIs: false
167
+ });
168
+ /** With search: only the rows scroll. */
169
+ var SEARCH_LIST_CSS = "gx-Menu-SEARCH_LIST_CSS-s1ab151u";
170
+ /** "No results": a row's box, not interactive. */
171
+ var MenuEmpty = /*#__PURE__*/ styled("div")({
172
+ name: "MenuEmpty",
173
+ class: "gx-Menu-MenuEmpty-m1nyz30c",
174
+ propsAsIs: false
175
+ });
176
+ /**
177
+ * Highlight (hover, focus, an open submenu's row) and press per mode. Hover and press skip a
178
+ * disabled row (the `aria-disabled` state attribute); focus keeps its fill so keyboard users see
179
+ * where they are.
180
+ */
181
+ var MENU_ITEM_VARIANT_TO_CSS_MAP = {
182
+ ["DEFAULT"]: "gx-Menu-DEFAULT-d1hougl1",
183
+ ["ERROR"]: "gx-Menu-ERROR-ejsjxm5"
184
+ };
185
+ /** A disabled row. Declared after the mode map. */
186
+ var ITEM_DISABLED_CSS = "gx-Menu-ITEM_DISABLED_CSS-i11wn83l";
187
+ /** `leading` / `trailing`: never squeezed, so only the text shrinks. */
188
+ var Slot = /*#__PURE__*/ styled("span")({
189
+ name: "Slot",
190
+ class: "gx-Menu-Slot-sotc445",
191
+ propsAsIs: false
192
+ });
193
+ /** Label and description, stacked; the only part that shrinks. */
194
+ var Content = /*#__PURE__*/ styled("span")({
195
+ name: "Content",
196
+ class: "gx-Menu-Content-cmfg9k5",
197
+ propsAsIs: false
198
+ });
199
+ /** The check marker's box (width per rung). */
200
+ var CheckSlot = /*#__PURE__*/ styled("span")({
201
+ name: "CheckSlot",
202
+ class: "gx-Menu-CheckSlot-c1aves2k",
203
+ propsAsIs: false
204
+ });
205
+ /** Icons, caps and markers never shrink. */
206
+ var NO_SHRINK_CSS = "gx-Menu-NO_SHRINK_CSS-n1n04r8w";
207
+ /** A section of rows. */
208
+ var GroupRoot = /*#__PURE__*/ styled("div")({
209
+ name: "GroupRoot",
210
+ class: "gx-Menu-GroupRoot-gwavq3l",
211
+ propsAsIs: false
212
+ });
213
+ /** The section heading. */
214
+ var GroupLabel = /*#__PURE__*/ styled("div")({
215
+ name: "GroupLabel",
216
+ class: "gx-Menu-GroupLabel-g1dkclye",
217
+ propsAsIs: false
218
+ });
219
+ /** While a term is set, a section with no row left disappears (a structural role selector). */
220
+ var GROUP_FILTERED_CSS = "gx-Menu-GROUP_FILTERED_CSS-g1wbdfpl";
221
+ /** The separator wrapper (`role="none"`; the `<hr>` inside is the separator). */
222
+ var SeparatorRoot = /*#__PURE__*/ styled("div")({
223
+ name: "SeparatorRoot",
224
+ class: "gx-Menu-SeparatorRoot-s1e1rrjq",
225
+ propsAsIs: false
226
+ });
227
+ /** Space above and below a separator's rule. */
228
+ var SEPARATOR_CSS = "gx-Menu-SEPARATOR_CSS-s28zrrg";
229
+ var MenuRootContext = createContext(null);
230
+ var MenuContext = createContext(null);
231
+ /** The context for a part; throws outside a menu. */
232
+ function useMenuContext(part) {
233
+ const context = useContext(MenuContext);
234
+ if (context === null) throw new Error(`${part} must be rendered inside a Menu or ContextMenu`);
235
+ return context;
236
+ }
237
+ /** Lower-cased, trimmed term (the filter's comparison form). */
238
+ function normalizeTerm(term) {
239
+ return term.trim().toLocaleLowerCase();
240
+ }
241
+ /** A row matches when the term is empty or its label (or description) contains it. */
242
+ function matches(term, label, description) {
243
+ if (term === "") return true;
244
+ if (label.toLocaleLowerCase().includes(term)) return true;
245
+ return description?.toLocaleLowerCase().includes(term) ?? false;
246
+ }
247
+ /** The rows of a list element, in DOM order (portaled submenus are not descendants). */
248
+ function getRows(list) {
249
+ if (list === null) return [];
250
+ return Array.from(list.querySelectorAll(ROW_SELECTOR));
251
+ }
252
+ /** Gives one row of the list `tabIndex` 0 and the rest -1. */
253
+ function setRoving(list, target) {
254
+ for (const row of getRows(list)) row.tabIndex = row === target ? 0 : -1;
255
+ }
256
+ /** Focuses a row and makes it the list's roving row. */
257
+ function focusRow(list, row, preventScroll = false) {
258
+ if (row === void 0) return;
259
+ setRoving(list, row);
260
+ row.focus({ preventScroll });
261
+ }
262
+ /** A printable character that should drive typeahead or the search term. */
263
+ function isPrintableKey(event) {
264
+ return event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey;
265
+ }
266
+ /** A list of rows: roving focus, arrow keys, typeahead, submenu coordination. */
267
+ function MenuList({ children, menuAttributes, className }) {
268
+ const root = useContext(MenuRootContext);
269
+ const outer = useContext(MenuContext);
270
+ if (root === null) throw new Error("MenuList must be rendered inside a Menu or ContextMenu");
271
+ const listRef = useRef(null);
272
+ const [openSubmenuId, setOpenSubmenuId] = useState(null);
273
+ const pendingRef = useRef(null);
274
+ const shouldFocusSubmenuRef = useRef(false);
275
+ const childListRef = useRef(null);
276
+ const typeaheadRef = useRef({
277
+ buffer: "",
278
+ timer: null
279
+ });
280
+ const labels = useMemo(() => /* @__PURE__ */ new WeakMap(), []);
281
+ const cancelPending = useCallback((rowId) => {
282
+ const pending = pendingRef.current;
283
+ if (pending === null) return;
284
+ if (rowId !== void 0 && !(pending.kind === "open" && pending.rowId === rowId)) return;
285
+ clearTimeout(pending.timer);
286
+ pendingRef.current = null;
287
+ }, []);
288
+ const setOpenSubmenu = useCallback((rowId, shouldFocus = false) => {
289
+ cancelPending();
290
+ shouldFocusSubmenuRef.current = shouldFocus;
291
+ setOpenSubmenuId(rowId);
292
+ }, [cancelPending]);
293
+ const scheduleSubmenu = useCallback((pending) => {
294
+ cancelPending();
295
+ const timer = setTimeout(() => {
296
+ pendingRef.current = null;
297
+ shouldFocusSubmenuRef.current = false;
298
+ setOpenSubmenuId(pending.kind === "open" ? pending.rowId : null);
299
+ }, MENU_SUBMENU_HOVER_DELAY_MS);
300
+ pendingRef.current = {
301
+ ...pending,
302
+ timer
303
+ };
304
+ }, [cancelPending]);
305
+ useEffect(() => () => {
306
+ if (pendingRef.current !== null) clearTimeout(pendingRef.current.timer);
307
+ if (typeaheadRef.current.timer !== null) clearTimeout(typeaheadRef.current.timer);
308
+ }, []);
309
+ const list = useMemo(() => ({
310
+ listRef,
311
+ openSubmenuId,
312
+ setOpenSubmenu,
313
+ scheduleSubmenu,
314
+ cancelPending,
315
+ shouldFocusSubmenuRef,
316
+ childListRef
317
+ }), [
318
+ openSubmenuId,
319
+ setOpenSubmenu,
320
+ scheduleSubmenu,
321
+ cancelPending
322
+ ]);
323
+ const parentSubmenu = useContext(SubmenuContext);
324
+ const depth = parentSubmenu === null ? 0 : (outer?.depth ?? 0) + 1;
325
+ const value = useMemo(() => ({
326
+ ...root,
327
+ term: depth === 0 ? root.term : "",
328
+ depth,
329
+ labels,
330
+ list,
331
+ parent: parentSubmenu
332
+ }), [
333
+ root,
334
+ depth,
335
+ labels,
336
+ list,
337
+ parentSubmenu
338
+ ]);
339
+ const setListRef = useCallback((node) => {
340
+ listRef.current = node;
341
+ if (parentSubmenu !== null) parentSubmenu.list.childListRef.current = node;
342
+ else root.rootListRef.current = node;
343
+ }, [parentSubmenu, root.rootListRef]);
344
+ useIsomorphicLayoutEffect(() => {
345
+ const rows = getRows(listRef.current);
346
+ if (parentSubmenu === null) {
347
+ const target = root.initialFocusRef.current === "last" ? rows.at(-1) : rows[0];
348
+ root.initialFocusRef.current = "first";
349
+ setRoving(listRef.current, target);
350
+ } else if (parentSubmenu.list.shouldFocusSubmenuRef.current) {
351
+ parentSubmenu.list.shouldFocusSubmenuRef.current = false;
352
+ focusRow(listRef.current, rows[0], true);
353
+ } else setRoving(listRef.current, rows[0]);
354
+ }, []);
355
+ useIsomorphicLayoutEffect(() => {
356
+ const rows = getRows(listRef.current);
357
+ if (rows.length > 0 && !rows.some((row) => row.tabIndex === 0)) setRoving(listRef.current, rows[0]);
358
+ });
359
+ /** Typeahead: the next row (wrapping) whose label starts with the typed prefix. */
360
+ const typeahead = (key, current, rows) => {
361
+ const state = typeaheadRef.current;
362
+ if (state.timer !== null) clearTimeout(state.timer);
363
+ state.buffer += key.toLocaleLowerCase();
364
+ state.timer = setTimeout(() => {
365
+ state.buffer = "";
366
+ state.timer = null;
367
+ }, MENU_TYPEAHEAD_RESET_MS);
368
+ const isRepeat = [...state.buffer].every((char) => char === state.buffer[0]);
369
+ const prefix = isRepeat ? state.buffer.slice(0, 1) : state.buffer;
370
+ const index = rows.indexOf(current);
371
+ const start = isRepeat ? index + 1 : index;
372
+ for (let offset = 0; offset < rows.length; offset += 1) {
373
+ const row = rows[(start + offset + rows.length) % rows.length];
374
+ if (row === void 0) continue;
375
+ if ((labels.get(row) ?? "").toLocaleLowerCase().startsWith(prefix)) {
376
+ focusRow(listRef.current, row);
377
+ return;
378
+ }
379
+ }
380
+ };
381
+ const handleKeyDown = (event) => {
382
+ const listElement = listRef.current;
383
+ const target = event.target;
384
+ if (listElement === null || !listElement.contains(target) || !target.matches(ROW_SELECTOR)) return;
385
+ if (event.defaultPrevented || event.nativeEvent.isComposing) return;
386
+ const rows = getRows(listElement);
387
+ const index = rows.indexOf(target);
388
+ const last = rows.length - 1;
389
+ const search = depth === 0 ? root.search : null;
390
+ switch (event.key) {
391
+ case "ArrowDown":
392
+ event.preventDefault();
393
+ focusRow(listElement, rows[index >= last ? 0 : index + 1]);
394
+ return;
395
+ case "ArrowUp":
396
+ event.preventDefault();
397
+ if (index === 0 && search !== null) {
398
+ search.inputRef.current?.focus();
399
+ return;
400
+ }
401
+ focusRow(listElement, rows[index <= 0 ? last : index - 1]);
402
+ return;
403
+ case "Home":
404
+ event.preventDefault();
405
+ focusRow(listElement, rows[0]);
406
+ return;
407
+ case "End":
408
+ event.preventDefault();
409
+ focusRow(listElement, rows[last]);
410
+ return;
411
+ case "ArrowLeft":
412
+ if (parentSubmenu === null) return;
413
+ event.preventDefault();
414
+ parentSubmenu.list.setOpenSubmenu(null);
415
+ parentSubmenu.rowRef.current?.focus();
416
+ return;
417
+ case "Tab":
418
+ if (parentSubmenu === null) return;
419
+ event.preventDefault();
420
+ root.closeTree();
421
+ return;
422
+ case "Backspace":
423
+ if (search === null) return;
424
+ event.preventDefault();
425
+ search.setRawTerm(search.rawTerm.slice(0, -1));
426
+ search.inputRef.current?.focus();
427
+ return;
428
+ default:
429
+ if (!isPrintableKey(event)) return;
430
+ event.preventDefault();
431
+ if (search !== null) {
432
+ search.setRawTerm(search.rawTerm + event.key);
433
+ search.inputRef.current?.focus();
434
+ return;
435
+ }
436
+ if (event.key === " ") return;
437
+ typeahead(event.key, target, rows);
438
+ }
439
+ };
440
+ /** A focused row becomes the roving row. */
441
+ const handleFocus = (event) => {
442
+ const target = event.target;
443
+ if (listRef.current?.contains(target) && target.matches(ROW_SELECTOR)) setRoving(listRef.current, target);
444
+ };
445
+ /** Entering a submenu cancels its parent's pending close. */
446
+ const handlePointerEnter = () => {
447
+ parentSubmenu?.list.cancelPending();
448
+ };
449
+ return /* @__PURE__ */ jsx(MenuContext.Provider, {
450
+ value,
451
+ children: /* @__PURE__ */ jsx(List, {
452
+ ...menuAttributes,
453
+ ref: setListRef,
454
+ className,
455
+ onKeyDown: handleKeyDown,
456
+ onFocus: handleFocus,
457
+ onPointerEnter: handlePointerEnter,
458
+ children
459
+ })
460
+ });
461
+ }
462
+ /** Set by a submenu row around its submenu's list: the parent list and the row. */
463
+ var SubmenuContext = createContext(null);
464
+ /** Renders one row element (not a component, so Popover and Tooltip clone the row itself). */
465
+ function renderRow({ context, role, label, description, icon, leading, trailing, hotKeys, variant, isDisabled, isChecked, marker, onActivate, onKeyDown, rowId, isSubmenuRow, elementProps, className, style }) {
466
+ const { size, list, isSearchable, depth } = context;
467
+ const iconPx = MENU_SIZE_TO_ICON_PX_MAP[size];
468
+ const iconVariant = isDisabled ? IconVariant.DISABLED : MENU_ITEM_VARIANT_TO_ICON_VARIANT_MAP[variant];
469
+ const hasLeading = leading !== void 0 && leading !== null && leading !== false;
470
+ const hasTrailing = trailing !== void 0 && trailing !== null && trailing !== false;
471
+ const hoverFocuses = !(isSearchable && depth === 0);
472
+ const handleClick = (event) => {
473
+ if (isDisabled) {
474
+ event.preventDefault();
475
+ return;
476
+ }
477
+ onActivate(event);
478
+ };
479
+ const handleKeyDown = (event) => {
480
+ onKeyDown?.(event);
481
+ if (event.defaultPrevented) return;
482
+ if (event.key === "Enter" || event.key === " ") {
483
+ event.preventDefault();
484
+ event.currentTarget.click();
485
+ }
486
+ };
487
+ /** Space activates on keydown; keep the native keyup click from firing a second time. */
488
+ const handleKeyUp = (event) => {
489
+ if (event.key === " ") event.preventDefault();
490
+ };
491
+ const handlePointerMove = (event) => {
492
+ if (event.pointerType !== "mouse" || !hoverFocuses) return;
493
+ if (event.currentTarget.ownerDocument.activeElement !== event.currentTarget) focusRow(list.listRef.current, event.currentTarget, true);
494
+ };
495
+ const handlePointerEnter = (event) => {
496
+ if (event.pointerType !== "mouse") return;
497
+ if (isSubmenuRow) if (list.openSubmenuId === rowId) list.cancelPending();
498
+ else list.scheduleSubmenu({
499
+ kind: "open",
500
+ rowId
501
+ });
502
+ else if (list.openSubmenuId !== null) list.scheduleSubmenu({
503
+ kind: "close",
504
+ rowId
505
+ });
506
+ else list.cancelPending();
507
+ };
508
+ const handlePointerLeave = () => {
509
+ list.cancelPending(rowId);
510
+ };
511
+ return /* @__PURE__ */ jsxs(ItemRoot, {
512
+ ...elementProps,
513
+ role,
514
+ tabIndex: -1,
515
+ ...isDisabled ? { "aria-disabled": true } : {},
516
+ ...isChecked === void 0 ? {} : { "aria-checked": isChecked },
517
+ onClick: handleClick,
518
+ onKeyDown: handleKeyDown,
519
+ onKeyUp: handleKeyUp,
520
+ onPointerMove: handlePointerMove,
521
+ onPointerEnter: handlePointerEnter,
522
+ onPointerLeave: handlePointerLeave,
523
+ className: cx(MENU_SIZE_TO_ITEM_CSS_MAP[size], MENU_ITEM_VARIANT_TO_CSS_MAP[variant], isDisabled && ITEM_DISABLED_CSS, className),
524
+ style,
525
+ children: [
526
+ hasLeading && /* @__PURE__ */ jsx(Slot, { children: leading }),
527
+ icon !== void 0 && /* @__PURE__ */ jsx(Icon, {
528
+ component: icon,
529
+ size: iconPx,
530
+ variant: iconVariant,
531
+ className: NO_SHRINK_CSS
532
+ }),
533
+ /* @__PURE__ */ jsxs(Content, { children: [/* @__PURE__ */ jsx(Text, {
534
+ as: "span",
535
+ size: MENU_SIZE_TO_TEXT_SIZE_MAP[size],
536
+ variant: isDisabled ? TextVariant.DISABLED : MENU_ITEM_VARIANT_TO_TEXT_VARIANT_MAP[variant],
537
+ lineClamp: 1,
538
+ children: label
539
+ }), description !== void 0 && /* @__PURE__ */ jsx(Text, {
540
+ as: "span",
541
+ size: MENU_SIZE_TO_SECONDARY_TEXT_SIZE_MAP[size],
542
+ variant: isDisabled ? TextVariant.DISABLED : TextVariant.TERTIARY,
543
+ lineClamp: 2,
544
+ children: description
545
+ })] }),
546
+ hasTrailing && /* @__PURE__ */ jsx(Slot, { children: trailing }),
547
+ hotKeys !== void 0 && hotKeys.length > 0 && /* @__PURE__ */ jsx(Kbd, {
548
+ hotKeys,
549
+ size: MENU_SIZE_TO_KBD_SIZE_MAP[size],
550
+ variant: MENU_VARIANT_TO_KBD_VARIANT_MAP[context.variant],
551
+ isDisabled,
552
+ "aria-hidden": true,
553
+ className: NO_SHRINK_CSS
554
+ }),
555
+ isChecked !== void 0 && /* @__PURE__ */ jsx(CheckSlot, {
556
+ className: MENU_SIZE_TO_CHECK_SLOT_CSS_MAP[size],
557
+ children: isChecked && /* @__PURE__ */ jsx(Icon, {
558
+ component: CheckIcon,
559
+ size: iconPx,
560
+ variant: isDisabled ? IconVariant.DISABLED : IconVariant.PRIMARY
561
+ })
562
+ }),
563
+ marker === "submenu" && /* @__PURE__ */ jsx(Icon, {
564
+ component: CaretRightIcon,
565
+ size: MENU_SIZE_TO_CARET_PX_MAP[size],
566
+ variant: isDisabled ? IconVariant.DISABLED : IconVariant.SECONDARY,
567
+ className: NO_SHRINK_CSS
568
+ }),
569
+ marker === "external" && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Icon, {
570
+ component: ArrowUpRightIcon,
571
+ size: iconPx,
572
+ variant: iconVariant,
573
+ className: NO_SHRINK_CSS
574
+ }), /* @__PURE__ */ jsx(VisuallyHidden, { children: " (opens in a new tab)" })] })
575
+ ]
576
+ });
577
+ }
578
+ /** Wraps a disabled row with a reason in a Tooltip to its right. */
579
+ function withDisabledReason(row, isDisabled, disabledReason) {
580
+ if (!isDisabled || disabledReason === void 0 || disabledReason === "") return row;
581
+ return /* @__PURE__ */ jsx(Tooltip, {
582
+ body: disabledReason,
583
+ placement: Placement.RIGHT,
584
+ children: row
585
+ });
586
+ }
587
+ /** A command, a link, or the opener of a submenu. */
588
+ var MenuItem = forwardRef(function MenuItem({ label, description, icon, leading, trailing, hotKeys, variant: variantProp, isDisabled = false, disabledReason, onSelect, href, as, isExternal = false, children, className, style, ...rest }, ref) {
589
+ const variant = variantProp ?? "DEFAULT";
590
+ const context = useMenuContext("MenuItem");
591
+ const rowId = useId();
592
+ const rowRef = useRef(null);
593
+ const mergedRef = useMergeRefs([useCallback((node) => {
594
+ rowRef.current = node;
595
+ if (node !== null) context.labels.set(node, label);
596
+ }, [context.labels, label]), ref]);
597
+ const isSubmenuRow = children !== void 0 && children !== null && children !== false;
598
+ const hasSubmenu = isSubmenuRow && !isDisabled;
599
+ const isSubmenuOpen = hasSubmenu && context.list.openSubmenuId === rowId;
600
+ const submenuParent = useMemo(() => ({
601
+ list: context.list,
602
+ rowRef,
603
+ rowId
604
+ }), [context.list, rowId]);
605
+ if (!matches(context.term, label, isSubmenuRow ? void 0 : description)) return null;
606
+ const isLink = href !== void 0 && !isSubmenuRow;
607
+ const elementProps = {
608
+ ...rest,
609
+ ref: mergedRef
610
+ };
611
+ if (isLink) {
612
+ elementProps.as = isDisabled ? "a" : as ?? "a";
613
+ if (!isDisabled) {
614
+ elementProps.href = href;
615
+ if (isExternal) {
616
+ elementProps.target = "_blank";
617
+ elementProps.rel = "noopener noreferrer";
618
+ }
619
+ }
620
+ } else elementProps.type = "button";
621
+ const onActivate = () => {
622
+ if (isSubmenuRow) {
623
+ if (isSubmenuOpen) {
624
+ const childList = context.list.childListRef.current;
625
+ focusRow(childList, getRows(childList)[0]);
626
+ } else context.list.setOpenSubmenu(rowId, true);
627
+ return;
628
+ }
629
+ onSelect?.();
630
+ context.closeTree();
631
+ };
632
+ const onKeyDown = (event) => {
633
+ if (!hasSubmenu || event.key !== "ArrowRight") return;
634
+ event.preventDefault();
635
+ onActivate();
636
+ };
637
+ const row = renderRow({
638
+ context,
639
+ role: "menuitem",
640
+ label,
641
+ description,
642
+ icon,
643
+ leading,
644
+ trailing,
645
+ hotKeys,
646
+ variant,
647
+ isDisabled,
648
+ isChecked: void 0,
649
+ marker: isSubmenuRow ? "submenu" : isLink && isExternal ? "external" : null,
650
+ onActivate,
651
+ onKeyDown,
652
+ rowId,
653
+ isSubmenuRow: hasSubmenu,
654
+ elementProps,
655
+ className,
656
+ style
657
+ });
658
+ if (!hasSubmenu) return withDisabledReason(row, isDisabled, disabledReason);
659
+ return /* @__PURE__ */ jsx(Popover, {
660
+ trigger: PopoverTrigger.MANUAL,
661
+ role: PopoverRole.MENU,
662
+ placement: Placement.RIGHT_START,
663
+ variant: MENU_VARIANT_TO_POPOVER_VARIANT_MAP[context.variant],
664
+ isOpen: isSubmenuOpen,
665
+ onOpenChange: (isOpen) => {
666
+ if (!isOpen && context.list.openSubmenuId === rowId) context.list.setOpenSubmenu(null);
667
+ },
668
+ body: /* @__PURE__ */ jsx(SubmenuContext.Provider, {
669
+ value: submenuParent,
670
+ children: /* @__PURE__ */ jsx(MenuList, { children })
671
+ }),
672
+ children: row
673
+ });
674
+ });
675
+ MenuItem.displayName = "MenuItem";
676
+ /** An on/off option; toggling keeps the menu open. */
677
+ var MenuCheckboxItem = forwardRef(function MenuCheckboxItem({ label, description, icon, leading, hotKeys, isChecked: isCheckedProp, defaultIsChecked = false, onChange, isDisabled = false, disabledReason, className, style, ...rest }, ref) {
678
+ const context = useMenuContext("MenuCheckboxItem");
679
+ const rowId = useId();
680
+ const mergedRef = useMergeRefs([useCallback((node) => {
681
+ if (node !== null) context.labels.set(node, label);
682
+ }, [context.labels, label]), ref]);
683
+ const [isChecked, setIsChecked] = useControlledState({
684
+ value: isCheckedProp,
685
+ defaultValue: defaultIsChecked,
686
+ onChange
687
+ });
688
+ if (!matches(context.term, label, description)) return null;
689
+ return withDisabledReason(renderRow({
690
+ context,
691
+ role: "menuitemcheckbox",
692
+ label,
693
+ description,
694
+ icon,
695
+ leading,
696
+ trailing: void 0,
697
+ hotKeys,
698
+ variant: "DEFAULT",
699
+ isDisabled,
700
+ isChecked,
701
+ marker: null,
702
+ onActivate: () => setIsChecked(!isChecked),
703
+ rowId,
704
+ isSubmenuRow: false,
705
+ elementProps: {
706
+ ...rest,
707
+ ref: mergedRef,
708
+ type: "button"
709
+ },
710
+ className,
711
+ style
712
+ }), isDisabled, disabledReason);
713
+ });
714
+ MenuCheckboxItem.displayName = "MenuCheckboxItem";
715
+ /** One radio option row (internal; `MenuRadioGroup` renders one per option). */
716
+ function MenuRadioRow({ option, isChecked, onChoose }) {
717
+ const context = useMenuContext("MenuRadioGroup");
718
+ const rowId = useId();
719
+ const register = useCallback((node) => {
720
+ if (node !== null) context.labels.set(node, option.label);
721
+ }, [context.labels, option.label]);
722
+ if (!matches(context.term, option.label, option.description)) return null;
723
+ const isDisabled = option.isDisabled ?? false;
724
+ return withDisabledReason(renderRow({
725
+ context,
726
+ role: "menuitemradio",
727
+ label: option.label,
728
+ description: option.description,
729
+ icon: option.icon,
730
+ leading: option.leading,
731
+ trailing: void 0,
732
+ hotKeys: option.hotKeys,
733
+ variant: "DEFAULT",
734
+ isDisabled,
735
+ isChecked,
736
+ marker: null,
737
+ onActivate: () => onChoose(option.id),
738
+ rowId,
739
+ isSubmenuRow: false,
740
+ elementProps: {
741
+ ref: register,
742
+ type: "button"
743
+ },
744
+ className: void 0,
745
+ style: void 0
746
+ }), isDisabled, option.disabledReason);
747
+ }
748
+ /** The heading of a group (and its accessible name). */
749
+ function GroupHeading({ id, label, size }) {
750
+ return /* @__PURE__ */ jsx(GroupLabel, {
751
+ role: "presentation",
752
+ id,
753
+ className: MENU_SIZE_TO_GROUP_LABEL_CSS_MAP[size],
754
+ children: /* @__PURE__ */ jsx(Text, {
755
+ as: "span",
756
+ size: MENU_SIZE_TO_SECONDARY_TEXT_SIZE_MAP[size],
757
+ weight: TextWeight.MEDIUM,
758
+ variant: TextVariant.TERTIARY,
759
+ lineClamp: 1,
760
+ children: label
761
+ })
762
+ });
763
+ }
764
+ /** One choice among options; choosing closes the menu. */
765
+ var MenuRadioGroupInner = forwardRef(function MenuRadioGroup({ options, value: valueProp, defaultValue = null, onChange, label, className, style, ...rest }, ref) {
766
+ const context = useMenuContext("MenuRadioGroup");
767
+ const headingId = useId();
768
+ const [value, setValue] = useControlledState({
769
+ value: valueProp,
770
+ defaultValue,
771
+ onChange: (next) => {
772
+ if (next !== null) onChange?.(next);
773
+ }
774
+ });
775
+ const hasLabel = label !== void 0 && label !== "";
776
+ const choose = (id) => {
777
+ setValue(id);
778
+ context.closeTree();
779
+ };
780
+ return /* @__PURE__ */ jsxs(GroupRoot, {
781
+ ...rest,
782
+ ref,
783
+ role: "group",
784
+ ...hasLabel ? { "aria-labelledby": headingId } : {},
785
+ className: cx(context.term !== "" && GROUP_FILTERED_CSS, className),
786
+ style,
787
+ children: [hasLabel && /* @__PURE__ */ jsx(GroupHeading, {
788
+ id: headingId,
789
+ label,
790
+ size: context.size
791
+ }), options.map((option) => /* @__PURE__ */ jsx(MenuRadioRow, {
792
+ option,
793
+ isChecked: value === option.id,
794
+ onChoose: choose
795
+ }, option.id))]
796
+ });
797
+ });
798
+ MenuRadioGroupInner.displayName = "MenuRadioGroup";
799
+ /** One choice among options; choosing closes the menu. */
800
+ var MenuRadioGroup = MenuRadioGroupInner;
801
+ /** A labelled section of rows. */
802
+ var MenuGroup = forwardRef(function MenuGroup({ label, children, className, style, ...rest }, ref) {
803
+ const context = useMenuContext("MenuGroup");
804
+ const headingId = useId();
805
+ const hasLabel = label !== void 0 && label !== "";
806
+ return /* @__PURE__ */ jsxs(GroupRoot, {
807
+ ...rest,
808
+ ref,
809
+ role: "group",
810
+ ...hasLabel ? { "aria-labelledby": headingId } : {},
811
+ className: cx(context.term !== "" && GROUP_FILTERED_CSS, className),
812
+ style,
813
+ children: [hasLabel && /* @__PURE__ */ jsx(GroupHeading, {
814
+ id: headingId,
815
+ label,
816
+ size: context.size
817
+ }), children]
818
+ });
819
+ });
820
+ MenuGroup.displayName = "MenuGroup";
821
+ /** A hairline between rows; renders nothing while a search term is set. */
822
+ var MenuSeparator = forwardRef(function MenuSeparator({ className, style, ...rest }, ref) {
823
+ if (useMenuContext("MenuSeparator").term !== "") return null;
824
+ return /* @__PURE__ */ jsx(SeparatorRoot, {
825
+ ...rest,
826
+ ref,
827
+ role: "none",
828
+ className: cx(SEPARATOR_CSS, className),
829
+ style,
830
+ children: /* @__PURE__ */ jsx(Divider, {})
831
+ });
832
+ });
833
+ MenuSeparator.displayName = "MenuSeparator";
834
+ /** The searchable body: the pinned field, the filtered `role="menu"` list and "No results". */
835
+ function MenuSearchBody({ children, listId, triggerId, ariaLabel }) {
836
+ const root = useContext(MenuRootContext);
837
+ const layoutRef = useRef(null);
838
+ const [isEmpty, setIsEmpty] = useState(false);
839
+ const term = root?.term ?? "";
840
+ useIsomorphicLayoutEffect(() => {
841
+ setIsEmpty(term !== "" && getRows(layoutRef.current).length === 0);
842
+ }, [term]);
843
+ if (root === null || root.search === null) return null;
844
+ const { search, size } = root;
845
+ const handleKeyDown = (event) => {
846
+ if (event.nativeEvent.isComposing) return;
847
+ const rows = getRows(root.rootListRef.current);
848
+ if (event.key === "ArrowDown") {
849
+ event.preventDefault();
850
+ focusRow(root.rootListRef.current, rows[0]);
851
+ } else if (event.key === "Enter") {
852
+ event.preventDefault();
853
+ rows.find((row) => row.getAttribute("aria-disabled") !== "true")?.click();
854
+ }
855
+ };
856
+ return /* @__PURE__ */ jsxs(SearchLayout, {
857
+ ref: layoutRef,
858
+ children: [
859
+ /* @__PURE__ */ jsx(Box, {
860
+ padding: 4,
861
+ children: /* @__PURE__ */ jsx(SearchInput, {
862
+ ref: search.inputRef,
863
+ value: search.rawTerm,
864
+ onChange: search.setRawTerm,
865
+ size: MENU_SIZE_TO_INPUT_SIZE_MAP[size],
866
+ isGhost: true,
867
+ fillWidth: true,
868
+ ariaLabel: "Search",
869
+ "aria-controls": listId,
870
+ onKeyDown: handleKeyDown
871
+ })
872
+ }),
873
+ /* @__PURE__ */ jsx(Divider, {}),
874
+ /* @__PURE__ */ jsx(MenuList, {
875
+ className: SEARCH_LIST_CSS,
876
+ menuAttributes: {
877
+ role: "menu",
878
+ id: listId,
879
+ ...ariaLabel === void 0 ? { "aria-labelledby": triggerId } : { "aria-label": ariaLabel }
880
+ },
881
+ children
882
+ }),
883
+ isEmpty && /* @__PURE__ */ jsx(MenuEmpty, {
884
+ className: MENU_SIZE_TO_ITEM_CSS_MAP[size],
885
+ children: /* @__PURE__ */ jsx(Text, {
886
+ size: MENU_SIZE_TO_TEXT_SIZE_MAP[size],
887
+ variant: TextVariant.TERTIARY,
888
+ children: "No results"
889
+ })
890
+ })
891
+ ]
892
+ });
893
+ }
894
+ /**
895
+ * @internal Shared by Menu and ContextMenu; apps use those. The menu engine: a Popover in `MENU`
896
+ * role (or `DIALOG` around a search field) holding the rows, opened by `popoverTrigger`.
897
+ */
898
+ var MenuRoot = forwardRef(function MenuRoot({ trigger, children, size = "MEDIUM", variant: variantProp, placement = Placement.BOTTOM_START, isSearchable = false, isOpen, defaultIsOpen = false, onOpenChange, isDisabled = false, ariaLabel, popoverTrigger, id, className, style, ...rest }, ref) {
899
+ const variant = variantProp ?? "BASE";
900
+ const { isOpen: isOpenState, setOpen } = useControlledOpenState({
901
+ isOpen,
902
+ defaultIsOpen,
903
+ onOpenChange
904
+ });
905
+ const [rawTerm, setRawTerm] = useState("");
906
+ const [wasOpen, setWasOpen] = useState(isOpenState);
907
+ if (wasOpen !== isOpenState) {
908
+ setWasOpen(isOpenState);
909
+ if (isOpenState) setRawTerm("");
910
+ }
911
+ const initialFocusRef = useRef("first");
912
+ const rootListRef = useRef(null);
913
+ const inputRef = useRef(null);
914
+ const generatedTriggerId = useId();
915
+ const listId = useId();
916
+ const triggerProps = trigger.props;
917
+ const triggerId = typeof triggerProps.id === "string" ? triggerProps.id : generatedTriggerId;
918
+ const closeTree = useCallback(() => setOpen(false), [setOpen]);
919
+ const term = isSearchable ? normalizeTerm(rawTerm) : "";
920
+ const rootValue = useMemo(() => ({
921
+ size,
922
+ variant,
923
+ term,
924
+ isSearchable,
925
+ closeTree,
926
+ search: isSearchable ? {
927
+ inputRef,
928
+ rawTerm,
929
+ setRawTerm
930
+ } : null,
931
+ initialFocusRef,
932
+ rootListRef
933
+ }), [
934
+ size,
935
+ variant,
936
+ term,
937
+ isSearchable,
938
+ closeTree,
939
+ rawTerm
940
+ ]);
941
+ /** ArrowDown / ArrowUp on a `CLICK` trigger open the menu on the first / last row. */
942
+ const handleTriggerKeyDown = (event) => {
943
+ const own = triggerProps.onKeyDown;
944
+ if (typeof own === "function") own(event);
945
+ if (event.defaultPrevented || isDisabled) return;
946
+ if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
947
+ event.preventDefault();
948
+ const edge = event.key === "ArrowDown" ? "first" : "last";
949
+ if (!isOpenState) {
950
+ initialFocusRef.current = edge;
951
+ setOpen(true);
952
+ return;
953
+ }
954
+ if (isSearchable) {
955
+ inputRef.current?.focus();
956
+ return;
957
+ }
958
+ const rows = getRows(rootListRef.current);
959
+ focusRow(rootListRef.current, edge === "first" ? rows[0] : rows.at(-1));
960
+ };
961
+ const triggerClone = cloneElement(trigger, {
962
+ id: triggerId,
963
+ ...popoverTrigger === PopoverTrigger.CLICK ? { onKeyDown: handleTriggerKeyDown } : {}
964
+ });
965
+ const body = isSearchable ? /* @__PURE__ */ jsx(MenuSearchBody, {
966
+ listId,
967
+ triggerId,
968
+ ariaLabel,
969
+ children
970
+ }) : /* @__PURE__ */ jsx(MenuList, { children });
971
+ return /* @__PURE__ */ jsx(MenuRootContext.Provider, {
972
+ value: rootValue,
973
+ children: /* @__PURE__ */ jsx(Popover, {
974
+ ...rest,
975
+ ref,
976
+ trigger: popoverTrigger,
977
+ role: isSearchable ? PopoverRole.DIALOG : PopoverRole.MENU,
978
+ variant: MENU_VARIANT_TO_POPOVER_VARIANT_MAP[variant],
979
+ placement,
980
+ isOpen: isOpenState,
981
+ onOpenChange: setOpen,
982
+ isDisabled,
983
+ ...ariaLabel === void 0 ? {} : { ariaLabel },
984
+ ...id === void 0 ? {} : { id },
985
+ ...className === void 0 ? {} : { className },
986
+ ...style === void 0 ? {} : { style },
987
+ body,
988
+ children: triggerClone
989
+ })
990
+ });
991
+ });
992
+ MenuRoot.displayName = "MenuRoot";
993
+ /** A menu button: a trigger that opens a list of commands, navigated with arrow keys and typeahead. */
994
+ var Menu = forwardRef(function Menu(props, ref) {
995
+ return /* @__PURE__ */ jsx(MenuRoot, {
996
+ ...props,
997
+ ref,
998
+ popoverTrigger: PopoverTrigger.CLICK
999
+ });
1000
+ });
1001
+ Menu.displayName = "Menu";
1002
+ //#endregion
1003
+ export { MenuCheckboxItem, MenuGroup, MenuItem, MenuItemVariant, MenuRadioGroup, MenuRoot, MenuSeparator, MenuSize, MenuVariant, Menu as default };