@galaxy-io/dls 1.6.0 → 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.
- package/README.md +47 -50
- package/biome/index.json +74 -0
- package/biome/plugins/no-hex-literal.grit +20 -0
- package/biome/plugins/no-inline-style.grit +13 -0
- package/biome/plugins/no-margin.grit +9 -0
- package/biome/plugins/warn/no-hex-literal.grit +23 -0
- package/biome/plugins/warn/no-inline-style.grit +13 -0
- package/biome/plugins/warn/no-margin.grit +9 -0
- package/dist/a11y/FocusScope.d.ts +44 -0
- package/dist/a11y/FocusScope.js +229 -0
- package/dist/a11y/VisuallyHidden.d.ts +21 -0
- package/dist/a11y/VisuallyHidden.js +30 -0
- package/dist/avatar/Avatar.d.ts +56 -14
- package/dist/avatar/Avatar.js +250 -96
- package/dist/avatar/AvatarGroup.d.ts +43 -0
- package/dist/avatar/AvatarGroup.js +153 -0
- package/dist/backgrounds/GridBackground.d.ts +48 -0
- package/dist/backgrounds/GridBackground.js +146 -0
- package/dist/beacons/Beacon.d.ts +86 -22
- package/dist/beacons/Beacon.js +170 -47
- package/dist/brand/GalaxyFilamentWordmark.d.ts +30 -0
- package/dist/brand/GalaxyFilamentWordmark.js +39 -0
- package/dist/brand/GalaxyLogomark.d.ts +26 -0
- package/dist/brand/GalaxyLogomark.js +41 -0
- package/dist/brand/GalaxyLogomarkAnimation.d.ts +36 -0
- package/dist/brand/GalaxyLogomarkAnimation.js +107 -0
- package/dist/brand/GalaxyWordmark.d.ts +30 -0
- package/dist/brand/GalaxyWordmark.js +63 -0
- package/dist/brand/assets/galaxy-logomark-animation.js +136678 -0
- package/dist/brand/brandMark.d.ts +26 -0
- package/dist/brand/brandMark.js +35 -0
- package/dist/buttons/Button.d.ts +148 -59
- package/dist/buttons/Button.js +437 -227
- package/dist/buttons/ButtonGroup.d.ts +38 -0
- package/dist/buttons/ButtonGroup.js +68 -0
- package/dist/buttons/CopyButton.d.ts +77 -0
- package/dist/buttons/CopyButton.js +65 -0
- package/dist/charts/AreaChart.d.ts +49 -0
- package/dist/charts/AreaChart.js +31 -0
- package/dist/charts/BarChart.d.ts +54 -67
- package/dist/charts/BarChart.js +136 -116
- package/dist/charts/ChartAxis.d.ts +35 -40
- package/dist/charts/ChartAxis.js +114 -90
- package/dist/charts/ChartCategoryTargets.d.ts +12 -26
- package/dist/charts/ChartCategoryTargets.js +32 -20
- package/dist/charts/ChartFrame.d.ts +69 -116
- package/dist/charts/ChartFrame.js +253 -119
- package/dist/charts/ChartGroupProvider.d.ts +30 -41
- package/dist/charts/ChartGroupProvider.js +20 -7
- package/dist/charts/ChartLegend.d.ts +27 -48
- package/dist/charts/ChartLegend.js +206 -125
- package/dist/charts/ChartMarkTargets.d.ts +12 -28
- package/dist/charts/ChartMarkTargets.js +33 -20
- package/dist/charts/ChartPrimitives.d.ts +50 -305
- package/dist/charts/ChartPrimitives.js +65 -413
- package/dist/charts/ChartTooltip.d.ts +20 -26
- package/dist/charts/ChartTooltip.js +77 -40
- package/dist/charts/Heatmap.d.ts +35 -0
- package/dist/charts/Heatmap.js +295 -0
- package/dist/charts/LineChart.d.ts +54 -47
- package/dist/charts/LineChart.js +159 -117
- package/dist/charts/PieChart.d.ts +32 -53
- package/dist/charts/PieChart.js +149 -135
- package/dist/charts/Sparkline.d.ts +107 -0
- package/dist/charts/Sparkline.js +244 -0
- package/dist/charts/StatChart.d.ts +37 -13
- package/dist/charts/StatChart.js +82 -35
- package/dist/charts/barChartGeometry.d.ts +138 -86
- package/dist/charts/barChartGeometry.js +122 -101
- package/dist/charts/barChartLegend.d.ts +14 -18
- package/dist/charts/barChartLegend.js +18 -13
- package/dist/charts/chartFormat.d.ts +12 -18
- package/dist/charts/chartFormat.js +20 -52
- package/dist/charts/chartPalette.d.ts +33 -0
- package/dist/charts/chartPalette.js +68 -0
- package/dist/charts/chartScales.d.ts +41 -108
- package/dist/charts/chartScales.js +62 -128
- package/dist/charts/constants.d.ts +96 -256
- package/dist/charts/constants.js +105 -275
- package/dist/charts/heatmapGeometry.d.ts +95 -0
- package/dist/charts/heatmapGeometry.js +155 -0
- package/dist/charts/lineChartGeometry.d.ts +108 -58
- package/dist/charts/lineChartGeometry.js +120 -78
- package/dist/charts/pieChartGeometry.d.ts +66 -40
- package/dist/charts/pieChartGeometry.js +68 -38
- package/dist/charts/types.d.ts +197 -466
- package/dist/charts/types.js +55 -144
- package/dist/charts/useCartesianChartLayout.d.ts +28 -59
- package/dist/charts/useCartesianChartLayout.js +47 -32
- package/dist/charts/useChartDimensions.d.ts +19 -40
- package/dist/charts/useChartDimensions.js +40 -56
- package/dist/charts/useChartFormatters.d.ts +6 -15
- package/dist/charts/useChartFormatters.js +4 -9
- package/dist/charts/useChartInteraction.d.ts +47 -116
- package/dist/charts/useChartInteraction.js +95 -71
- package/dist/charts/useChartTooltipPosition.d.ts +29 -39
- package/dist/charts/useChartTooltipPosition.js +14 -5
- package/dist/charts/useSeriesColorResolver.d.ts +11 -33
- package/dist/charts/useSeriesColorResolver.js +19 -12
- package/dist/chips/Chip.d.ts +155 -44
- package/dist/chips/Chip.js +329 -155
- package/dist/chips/ChipGroup.d.ts +53 -0
- package/dist/chips/ChipGroup.js +98 -0
- package/dist/drawer/Drawer.d.ts +81 -17
- package/dist/drawer/Drawer.js +370 -65
- package/dist/dropdown/Dropdown.d.ts +80 -63
- package/dist/dropdown/Dropdown.js +127 -129
- package/dist/editor/CodeEditor.d.ts +119 -40
- package/dist/editor/CodeEditor.js +490 -400
- package/dist/editor/CodeEditorReactWidget.d.ts +20 -17
- package/dist/editor/CodeEditorReactWidget.js +28 -21
- package/dist/feedback/Alert.d.ts +49 -0
- package/dist/feedback/Alert.js +172 -0
- package/dist/feedback/EmptyState.d.ts +39 -0
- package/dist/feedback/EmptyState.js +109 -0
- package/dist/feedback/ProgressBar.d.ts +125 -0
- package/dist/feedback/ProgressBar.js +183 -0
- package/dist/feedback/ProgressCircle.d.ts +99 -0
- package/dist/feedback/ProgressCircle.js +187 -0
- package/dist/feedback/Skeleton.d.ts +69 -0
- package/dist/feedback/Skeleton.js +130 -0
- package/dist/feedback/Spinner.d.ts +63 -0
- package/dist/feedback/Spinner.js +141 -0
- package/dist/fonts.css +70 -0
- package/dist/hooks/internal/useIsClient.d.ts +2 -0
- package/dist/hooks/internal/useIsClient.js +14 -0
- package/dist/hooks/useClipboard.d.ts +19 -0
- package/dist/hooks/useClipboard.js +45 -0
- package/dist/hooks/useControlledOpenState.d.ts +21 -0
- package/dist/hooks/useControlledOpenState.js +19 -0
- package/dist/hooks/useControlledState.d.ts +19 -0
- package/dist/hooks/useControlledState.js +22 -0
- package/dist/hooks/useDebouncedValue.d.ts +14 -0
- package/dist/hooks/useDebouncedValue.js +33 -0
- package/dist/hooks/useDisclosure.d.ts +26 -0
- package/dist/hooks/useDisclosure.js +36 -0
- package/dist/hooks/useDismiss.d.ts +23 -27
- package/dist/hooks/useDismiss.js +39 -27
- package/dist/hooks/useElementClientSize.d.ts +10 -10
- package/dist/hooks/useElementClientSize.js +8 -11
- package/dist/hooks/useElementWidth.d.ts +6 -13
- package/dist/hooks/useElementWidth.js +6 -14
- package/dist/hooks/useField.d.ts +47 -0
- package/dist/hooks/useField.js +40 -0
- package/dist/hooks/useHotkey.d.ts +77 -0
- package/dist/hooks/useHotkey.js +246 -0
- package/dist/hooks/useIsMac.d.ts +12 -0
- package/dist/hooks/useIsMac.js +27 -0
- package/dist/hooks/useIsomorphicLayoutEffect.d.ts +17 -0
- package/dist/hooks/useIsomorphicLayoutEffect.js +20 -0
- package/dist/hooks/useLocalStorage.d.ts +28 -0
- package/dist/hooks/useLocalStorage.js +145 -0
- package/dist/hooks/useMediaQuery.d.ts +11 -0
- package/dist/hooks/useMediaQuery.js +23 -0
- package/dist/hooks/usePrefersReducedMotion.d.ts +12 -0
- package/dist/hooks/usePrefersReducedMotion.js +25 -0
- package/dist/hooks/useResize.d.ts +42 -62
- package/dist/hooks/useResize.js +43 -31
- package/dist/icons/Icon.d.ts +64 -37
- package/dist/icons/Icon.js +96 -37
- package/dist/icons/internal/IconSlot.d.ts +10 -0
- package/dist/icons/internal/IconSlot.js +32 -0
- package/dist/inputs/CheckboxGroup.d.ts +115 -0
- package/dist/inputs/CheckboxGroup.js +183 -0
- package/dist/inputs/CheckboxInput.d.ts +98 -28
- package/dist/inputs/CheckboxInput.js +218 -88
- package/dist/inputs/ColorInput.d.ts +115 -29
- package/dist/inputs/ColorInput.js +748 -326
- package/dist/inputs/CopyInput.d.ts +49 -20
- package/dist/inputs/CopyInput.js +57 -49
- package/dist/inputs/CronInput.d.ts +94 -0
- package/dist/inputs/CronInput.js +618 -0
- package/dist/inputs/DateInput.d.ts +175 -28
- package/dist/inputs/DateInput.js +1109 -451
- package/dist/inputs/DurationInput.d.ts +101 -0
- package/dist/inputs/DurationInput.js +441 -0
- package/dist/inputs/Field.d.ts +75 -0
- package/dist/inputs/Field.js +247 -0
- package/dist/inputs/Fieldset.d.ts +53 -0
- package/dist/inputs/Fieldset.js +149 -0
- package/dist/inputs/FileInput.d.ts +110 -0
- package/dist/inputs/FileInput.js +476 -0
- package/dist/inputs/Input.d.ts +148 -187
- package/dist/inputs/Input.js +339 -259
- package/dist/inputs/KeyValueInput.d.ts +120 -0
- package/dist/inputs/KeyValueInput.js +383 -0
- package/dist/inputs/MultiSelectInput.d.ts +165 -54
- package/dist/inputs/MultiSelectInput.js +175 -559
- package/dist/inputs/NumberInput.d.ts +65 -9
- package/dist/inputs/NumberInput.js +197 -40
- package/dist/inputs/PasswordInput.d.ts +17 -12
- package/dist/inputs/PasswordInput.js +33 -33
- package/dist/inputs/PinInput.d.ts +117 -0
- package/dist/inputs/PinInput.js +364 -0
- package/dist/inputs/RadioGroup.d.ts +115 -0
- package/dist/inputs/RadioGroup.js +179 -0
- package/dist/inputs/RadioInput.d.ts +87 -24
- package/dist/inputs/RadioInput.js +182 -95
- package/dist/inputs/SearchInput.d.ts +66 -0
- package/dist/inputs/SearchInput.js +156 -0
- package/dist/inputs/SelectInput.d.ts +195 -55
- package/dist/inputs/SelectInput.js +1308 -446
- package/dist/inputs/SliderInput.d.ts +150 -30
- package/dist/inputs/SliderInput.js +441 -186
- package/dist/inputs/SwitchInput.d.ts +109 -0
- package/dist/inputs/SwitchInput.js +248 -0
- package/dist/inputs/TagInput.d.ts +117 -0
- package/dist/inputs/TagInput.js +408 -0
- package/dist/inputs/TextAreaInput.d.ts +146 -44
- package/dist/inputs/TextAreaInput.js +292 -198
- package/dist/inputs/TextInput.d.ts +4 -13
- package/dist/inputs/TextInput.js +13 -48
- package/dist/inputs/ToggleInput.d.ts +120 -22
- package/dist/inputs/ToggleInput.js +262 -116
- package/dist/inputs/internal/bareField.d.ts +18 -0
- package/dist/inputs/internal/bareField.js +38 -0
- package/dist/inputs/internal/devWarn.d.ts +7 -0
- package/dist/inputs/internal/devWarn.js +30 -0
- package/dist/inputs/internal/fieldFrame.d.ts +34 -0
- package/dist/inputs/internal/fieldFrame.js +64 -0
- package/dist/inputs/internal/fieldWiring.d.ts +50 -0
- package/dist/inputs/internal/fieldWiring.js +38 -0
- package/dist/inputs/internal/innerButton.d.ts +2 -0
- package/dist/inputs/internal/innerButton.js +24 -0
- package/dist/inputs/internal/ownField.d.ts +45 -0
- package/dist/inputs/internal/ownField.js +58 -0
- package/dist/inputs/internal/predicates.d.ts +9 -0
- package/dist/inputs/internal/predicates.js +11 -0
- package/dist/inputs/internal/useComboboxPopover.d.ts +46 -0
- package/dist/inputs/internal/useComboboxPopover.js +92 -0
- package/dist/json/JsonViewer.d.ts +62 -0
- package/dist/json/JsonViewer.js +483 -0
- package/dist/layout/Box.d.ts +87 -0
- package/dist/layout/Box.js +109 -0
- package/dist/layout/Divider.d.ts +25 -0
- package/dist/layout/Divider.js +70 -0
- package/dist/layout/Flex.d.ts +139 -0
- package/dist/layout/Flex.js +165 -0
- package/dist/layout/FlexItem.d.ts +72 -0
- package/dist/layout/FlexItem.js +84 -0
- package/dist/layout/Grid.d.ts +140 -0
- package/dist/layout/Grid.js +178 -0
- package/dist/layout/Portal.d.ts +29 -0
- package/dist/layout/Portal.js +27 -0
- package/dist/layout/ResizablePanels.d.ts +88 -0
- package/dist/layout/ResizablePanels.js +198 -0
- package/dist/layout/ResizeHandle.d.ts +48 -0
- package/dist/layout/ResizeHandle.js +143 -0
- package/dist/layout/ScrollArea.d.ts +30 -0
- package/dist/layout/ScrollArea.js +138 -0
- package/dist/links/Link.d.ts +101 -1
- package/dist/links/Link.js +166 -4
- package/dist/lists/BulletedList.d.ts +25 -7
- package/dist/lists/BulletedList.js +72 -27
- package/dist/lists/DescriptionList.d.ts +91 -0
- package/dist/lists/DescriptionList.js +147 -0
- package/dist/menu/ContextMenu.d.ts +64 -0
- package/dist/menu/ContextMenu.js +34 -0
- package/dist/menu/Menu.d.ts +280 -0
- package/dist/menu/Menu.js +1003 -0
- package/dist/modal/ConfirmDialog.d.ts +55 -0
- package/dist/modal/ConfirmDialog.js +151 -0
- package/dist/modal/Modal.d.ts +64 -14
- package/dist/modal/Modal.js +189 -48
- package/dist/navigation/Breadcrumbs.d.ts +65 -0
- package/dist/navigation/Breadcrumbs.js +243 -0
- package/dist/navigation/CommandPalette.d.ts +83 -0
- package/dist/navigation/CommandPalette.js +509 -0
- package/dist/navigation/Pagination.d.ts +87 -0
- package/dist/navigation/Pagination.js +300 -0
- package/dist/navigation/SidebarNav.d.ts +107 -0
- package/dist/navigation/SidebarNav.js +341 -0
- package/dist/navigation/Stepper.d.ts +52 -0
- package/dist/navigation/Stepper.js +207 -0
- package/dist/navigation/Tabs.d.ts +113 -0
- package/dist/navigation/Tabs.js +543 -0
- package/dist/navigation/Topbar.d.ts +20 -0
- package/dist/navigation/Topbar.js +62 -0
- package/dist/overlay/OverlayProvider.d.ts +28 -32
- package/dist/overlay/OverlayProvider.js +42 -93
- package/dist/overlay/useOverlay.d.ts +88 -12
- package/dist/overlay/useOverlay.js +220 -43
- package/dist/overlays/Popover.d.ts +114 -0
- package/dist/overlays/Popover.js +389 -0
- package/dist/shapes/Circle.d.ts +84 -8
- package/dist/shapes/Circle.js +122 -20
- package/dist/shapes/Square.d.ts +84 -8
- package/dist/shapes/Square.js +123 -20
- package/dist/styles/mixins.d.ts +35 -0
- package/dist/styles/mixins.js +60 -0
- package/dist/styles.css +1 -202
- package/dist/table/InfiniteSpreadsheet.d.ts +140 -10
- package/dist/table/InfiniteSpreadsheet.js +762 -225
- package/dist/table/InfiniteTable.d.ts +116 -14
- package/dist/table/InfiniteTable.js +287 -429
- package/dist/table/SpreadsheetCellEditor.d.ts +54 -6
- package/dist/table/SpreadsheetCellEditor.js +163 -84
- package/dist/table/TableCore.d.ts +252 -0
- package/dist/table/TableCore.js +1077 -0
- package/dist/table/VirtualizedInfiniteTable.d.ts +104 -14
- package/dist/table/VirtualizedInfiniteTable.js +280 -219
- package/dist/table/types.d.ts +66 -244
- package/dist/table/types.js +0 -51
- package/dist/table/useInfiniteScrollSentinel.d.ts +25 -21
- package/dist/table/useInfiniteScrollSentinel.js +38 -30
- package/dist/table/useSpreadsheetCellNavigation.d.ts +44 -0
- package/dist/table/useSpreadsheetCellNavigation.js +141 -0
- package/dist/table/useTableColumnLayout.d.ts +90 -25
- package/dist/table/useTableColumnLayout.js +255 -50
- package/dist/table/useTableKeyboardNavigation.d.ts +32 -21
- package/dist/table/useTableKeyboardNavigation.js +95 -71
- package/dist/table/useTableRowSelection.d.ts +24 -25
- package/dist/table/useTableRowSelection.js +57 -84
- package/dist/table/useTableVirtualizer.d.ts +20 -0
- package/dist/table/useTableVirtualizer.js +48 -0
- package/dist/text/Bold.d.ts +5 -6
- package/dist/text/Bold.js +16 -15
- package/dist/text/Code.d.ts +5 -6
- package/dist/text/Code.js +16 -25
- package/dist/text/CodeBlock.d.ts +77 -0
- package/dist/text/CodeBlock.js +373 -0
- package/dist/text/EditableText.d.ts +55 -15
- package/dist/text/EditableText.js +153 -135
- package/dist/text/Ellipsis.d.ts +34 -8
- package/dist/text/Ellipsis.js +55 -23
- package/dist/text/Kbd.d.ts +72 -0
- package/dist/text/Kbd.js +284 -0
- package/dist/text/MarkdownText.d.ts +27 -10
- package/dist/text/MarkdownText.js +317 -300
- package/dist/text/RequiredMarker.d.ts +17 -5
- package/dist/text/RequiredMarker.js +34 -36
- package/dist/text/Selectable.d.ts +5 -6
- package/dist/text/Selectable.js +16 -13
- package/dist/text/Span.d.ts +82 -0
- package/dist/text/Span.js +115 -0
- package/dist/text/Text.d.ts +128 -41
- package/dist/text/Text.js +209 -76
- package/dist/theme/GalaxyProvider.d.ts +75 -0
- package/dist/theme/GalaxyProvider.js +223 -0
- package/dist/theme/ThemeSwitcher.d.ts +52 -0
- package/dist/theme/ThemeSwitcher.js +94 -0
- package/dist/theme/enums.d.ts +118 -0
- package/dist/theme/enums.js +144 -0
- package/dist/theme/tokens/dark.d.ts +2 -0
- package/dist/theme/tokens/dark.js +275 -0
- package/dist/theme/tokens/generate.d.ts +15 -0
- package/dist/theme/tokens/generate.js +47 -0
- package/dist/theme/tokens/light.d.ts +2 -0
- package/dist/theme/tokens/light.js +274 -0
- package/dist/theme/tokens/palette.d.ts +14 -0
- package/dist/theme/tokens/palette.js +153 -0
- package/dist/theme/tokens/scales.d.ts +26 -0
- package/dist/theme/tokens/scales.js +154 -0
- package/dist/theme/tokens/t.d.ts +3 -0
- package/dist/theme/tokens/t.js +25 -0
- package/dist/theme/tokens/types.d.ts +189 -0
- package/dist/theme/tokens/types.js +0 -0
- package/dist/theme/useGalaxyTheme.d.ts +46 -0
- package/dist/theme/useGalaxyTheme.js +36 -0
- package/dist/theme/useInverseScope.d.ts +18 -0
- package/dist/theme/useInverseScope.js +33 -0
- package/dist/three/GalaxyLogomark3D.d.ts +46 -0
- package/dist/three/GalaxyLogomark3D.js +134 -0
- package/dist/three/assets/galaxy-logomark.js +4 -0
- package/dist/three/galaxyLogomark3DScene.d.ts +27 -0
- package/dist/three/galaxyLogomark3DScene.js +165 -0
- package/dist/timeline/Timeline.d.ts +99 -0
- package/dist/timeline/Timeline.js +269 -0
- package/dist/toast/Toast.d.ts +43 -19
- package/dist/toast/Toast.js +130 -89
- package/dist/toast/ToastProvider.d.ts +23 -23
- package/dist/toast/ToastProvider.js +298 -101
- package/dist/toast/ToastViewport.d.ts +12 -0
- package/dist/toast/ToastViewport.js +210 -0
- package/dist/toast/useToast.d.ts +139 -5
- package/dist/toast/useToast.js +15 -13
- package/dist/tokens.css +654 -0
- package/dist/tooltip/Tooltip.d.ts +64 -44
- package/dist/tooltip/Tooltip.js +280 -73
- package/dist/tooltip/internal/LazyTooltip.d.ts +7 -0
- package/dist/tooltip/internal/LazyTooltip.js +53 -0
- package/dist/transform/Fade.d.ts +33 -11
- package/dist/transform/Fade.js +71 -19
- package/dist/transform/Flasher.d.ts +25 -0
- package/dist/transform/Flasher.js +39 -0
- package/dist/transform/Rotate.d.ts +24 -12
- package/dist/transform/Rotate.js +36 -22
- package/dist/transform/ScaleFade.d.ts +36 -11
- package/dist/transform/ScaleFade.js +86 -28
- package/dist/transform/internal/CollapseMotion.d.ts +10 -0
- package/dist/transform/internal/CollapseMotion.js +65 -0
- package/dist/tree/Tree.d.ts +85 -0
- package/dist/tree/Tree.js +387 -0
- package/dist/tree/treeRow.d.ts +39 -0
- package/dist/tree/treeRow.js +75 -0
- package/dist/utils/colors.d.ts +46 -13
- package/dist/utils/colors.js +92 -34
- package/dist/utils/css.d.ts +23 -0
- package/dist/utils/css.js +30 -0
- package/dist/utils/format.d.ts +58 -0
- package/dist/utils/format.js +220 -0
- package/dist/vite/index.d.ts +16 -0
- package/dist/vite/index.js +52 -0
- package/dist/widget/Widget.d.ts +164 -48
- package/dist/widget/Widget.js +335 -96
- package/dist/widget/WidgetGroup.d.ts +36 -0
- package/dist/widget/WidgetGroup.js +103 -0
- package/package.json +851 -157
- package/dist/accordion/Accordion.d.ts +0 -54
- package/dist/accordion/Accordion.js +0 -183
- package/dist/assets/components/GalaxyFilamentWordmarkDark.d.ts +0 -3
- package/dist/assets/components/GalaxyFilamentWordmarkDark.js +0 -14
- package/dist/assets/components/GalaxyFilamentWordmarkLight.d.ts +0 -3
- package/dist/assets/components/GalaxyFilamentWordmarkLight.js +0 -14
- package/dist/assets/components/GalaxyLogomarkDark.d.ts +0 -3
- package/dist/assets/components/GalaxyLogomarkDark.js +0 -11
- package/dist/assets/components/GalaxyLogomarkLight.d.ts +0 -3
- package/dist/assets/components/GalaxyLogomarkLight.js +0 -17
- package/dist/assets/components/GalaxyWordmarkDark.d.ts +0 -3
- package/dist/assets/components/GalaxyWordmarkDark.js +0 -15
- package/dist/assets/components/GalaxyWordmarkLight.d.ts +0 -3
- package/dist/assets/components/GalaxyWordmarkLight.js +0 -28
- package/dist/assets/models/galaxy-animation.js +0 -136666
- package/dist/assets/models/galaxy-logomark.js +0 -4
- package/dist/avatar/AvatarShimmer.d.ts +0 -30
- package/dist/avatar/AvatarShimmer.js +0 -22
- package/dist/backgrounds/CellGridBackground.d.ts +0 -24
- package/dist/backgrounds/CellGridBackground.js +0 -44
- package/dist/backgrounds/CrossGridBackground.d.ts +0 -26
- package/dist/backgrounds/CrossGridBackground.js +0 -49
- package/dist/backgrounds/DotGridBackground.d.ts +0 -24
- package/dist/backgrounds/DotGridBackground.js +0 -47
- package/dist/badge/Badge.d.ts +0 -42
- package/dist/badge/Badge.js +0 -99
- package/dist/charts/ChartEmptyState.d.ts +0 -17
- package/dist/charts/ChartEmptyState.js +0 -29
- package/dist/charts/ProgressBar.d.ts +0 -29
- package/dist/charts/ProgressBar.js +0 -65
- package/dist/charts/chartTheme.d.ts +0 -18
- package/dist/charts/chartTheme.js +0 -26
- package/dist/containers/FlexItem.d.ts +0 -50
- package/dist/containers/FlexItem.js +0 -91
- package/dist/containers/FlexWrapper.d.ts +0 -96
- package/dist/containers/FlexWrapper.js +0 -143
- package/dist/containers/GridWrapper.d.ts +0 -79
- package/dist/containers/GridWrapper.js +0 -125
- package/dist/containers/Spacing.d.ts +0 -23
- package/dist/containers/Spacing.js +0 -59
- package/dist/containers/Wrapper.d.ts +0 -26
- package/dist/containers/Wrapper.js +0 -54
- package/dist/dividers/HorizontalDivider.d.ts +0 -7
- package/dist/dividers/HorizontalDivider.js +0 -39
- package/dist/dividers/VerticalDivider.d.ts +0 -6
- package/dist/dividers/VerticalDivider.js +0 -21
- package/dist/icons/GalaxyFilamentWordmark.d.ts +0 -11
- package/dist/icons/GalaxyFilamentWordmark.js +0 -25
- package/dist/icons/GalaxyLogomark.d.ts +0 -13
- package/dist/icons/GalaxyLogomark.js +0 -27
- package/dist/icons/GalaxyLogomark3D.d.ts +0 -56
- package/dist/icons/GalaxyLogomark3D.js +0 -319
- package/dist/icons/GalaxyLogomarkAnimation.d.ts +0 -18
- package/dist/icons/GalaxyLogomarkAnimation.js +0 -48
- package/dist/icons/GalaxyWordmark.d.ts +0 -11
- package/dist/icons/GalaxyWordmark.js +0 -25
- package/dist/inputs/MultiTextInput.d.ts +0 -32
- package/dist/inputs/MultiTextInput.js +0 -180
- package/dist/inputs/SwitcherInput.d.ts +0 -27
- package/dist/inputs/SwitcherInput.js +0 -64
- package/dist/inputs/hooks.d.ts +0 -10
- package/dist/inputs/hooks.js +0 -22
- package/dist/overlay/constants.d.ts +0 -28
- package/dist/overlay/constants.js +0 -37
- package/dist/resizable/HorizontalResizeHandle.d.ts +0 -17
- package/dist/resizable/HorizontalResizeHandle.js +0 -38
- package/dist/resizable/VerticalResizeHandle.d.ts +0 -18
- package/dist/resizable/VerticalResizeHandle.js +0 -39
- package/dist/table/SpreadsheetCell.d.ts +0 -21
- package/dist/table/SpreadsheetCell.js +0 -71
- package/dist/table/SpreadsheetHeaderCell.d.ts +0 -23
- package/dist/table/SpreadsheetHeaderCell.js +0 -91
- package/dist/table/SpreadsheetMenuItem.d.ts +0 -14
- package/dist/table/SpreadsheetMenuItem.js +0 -33
- package/dist/table/SpreadsheetPrimitives.d.ts +0 -172
- package/dist/table/SpreadsheetPrimitives.js +0 -105
- package/dist/table/SpreadsheetRow.d.ts +0 -33
- package/dist/table/SpreadsheetRow.js +0 -73
- package/dist/table/SpreadsheetRowActionCell.d.ts +0 -14
- package/dist/table/SpreadsheetRowActionCell.js +0 -51
- package/dist/table/TableExpandCell.d.ts +0 -11
- package/dist/table/TableExpandCell.js +0 -24
- package/dist/table/TableExpandedRow.d.ts +0 -16
- package/dist/table/TableExpandedRow.js +0 -77
- package/dist/table/TableHeaderCellContent.d.ts +0 -30
- package/dist/table/TableHeaderCellContent.js +0 -48
- package/dist/table/TablePrimitives.d.ts +0 -313
- package/dist/table/TablePrimitives.js +0 -302
- package/dist/table/TableSelectCell.d.ts +0 -18
- package/dist/table/TableSelectCell.js +0 -27
- package/dist/table/TableStatusRow.d.ts +0 -18
- package/dist/table/TableStatusRow.js +0 -50
- package/dist/table/useSpreadsheetEditing.d.ts +0 -13
- package/dist/table/useSpreadsheetEditing.js +0 -41
- package/dist/table/useTableColumnResize.d.ts +0 -38
- package/dist/table/useTableColumnResize.js +0 -155
- package/dist/table/useTableRowExpansion.d.ts +0 -24
- package/dist/table/useTableRowExpansion.js +0 -62
- package/dist/table/utils.d.ts +0 -50
- package/dist/table/utils.js +0 -78
- package/dist/text/HotKeys.d.ts +0 -30
- package/dist/text/HotKeys.js +0 -74
- package/dist/text/Paragraph.d.ts +0 -33
- package/dist/text/Paragraph.js +0 -83
- package/dist/text/TextShimmer.d.ts +0 -14
- package/dist/text/TextShimmer.js +0 -34
- package/dist/theme/GalaxyTheme.d.ts +0 -67
- package/dist/theme/GalaxyTheme.js +0 -119
- package/dist/theme/constants.d.ts +0 -8
- package/dist/theme/constants.js +0 -38
- package/dist/theme/index.d.ts +0 -6
- package/dist/theme/index.js +0 -7
- package/dist/theme/types.d.ts +0 -195
- package/dist/theme/types.js +0 -10
- package/dist/theme/typography.d.ts +0 -2
- package/dist/theme/typography.js +0 -73
- package/dist/theme/variants/dark.d.ts +0 -2
- package/dist/theme/variants/dark.js +0 -125
- package/dist/theme/variants/light.d.ts +0 -2
- package/dist/theme/variants/light.js +0 -125
- package/dist/toast/ToastContainer.d.ts +0 -10
- package/dist/toast/ToastContainer.js +0 -31
- package/dist/toast/ToastWrapper.d.ts +0 -6
- package/dist/toast/ToastWrapper.js +0 -27
- package/dist/transform/Flash.d.ts +0 -7
- package/dist/transform/Flash.js +0 -18
- package/dist/transform/Spin.d.ts +0 -14
- package/dist/transform/Spin.js +0 -25
- package/dist/utils/linaria.d.ts +0 -1
- 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 };
|