@mks2508/mks-ui 0.5.4 → 0.5.8
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/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts +23 -4
- package/dist/react-ui/primitives/waapi/Gooey/Gooey.types.d.ts.map +1 -1
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts +2 -2
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.d.ts.map +1 -1
- package/dist/react-ui/primitives/waapi/Gooey/GooeyCanvas.js +292 -31
- package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts +7 -0
- package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.d.ts.map +1 -1
- package/dist/react-ui/primitives/waapi/Gooey/gooey-utils.js +6 -1
- package/dist/react-ui/ui/DynamicToggle/{DynamicToggle-Cm6-VceQ.css → DynamicToggle-DJLwEkHr.css} +116 -51
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.css +116 -51
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts +1 -0
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.styles.js +9 -3
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts +61 -31
- package/dist/react-ui/ui/DynamicToggle/DynamicToggle.types.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/index.d.ts +9 -3
- package/dist/react-ui/ui/DynamicToggle/index.d.ts.map +1 -1
- package/dist/react-ui/ui/DynamicToggle/index.js +68 -37
- package/package.json +52 -13
- package/src/assets/react.svg +0 -1
- package/src/core/index.ts +0 -7
- package/src/core/types.ts +0 -82
- package/src/css.d.ts +0 -7
- package/src/index.css +0 -129
- package/src/index.ts +0 -29
- package/src/react-ui/blocks/Terminal/ResttyAdapter.ts +0 -278
- package/src/react-ui/blocks/Terminal/Terminal.adapter.ts +0 -97
- package/src/react-ui/blocks/Terminal/Terminal.theme.restty.ts +0 -155
- package/src/react-ui/blocks/Terminal/Terminal.theme.ts +0 -80
- package/src/react-ui/blocks/Terminal/Terminal.types.ts +0 -438
- package/src/react-ui/blocks/Terminal/TerminalDisplay.styles.ts +0 -38
- package/src/react-ui/blocks/Terminal/TerminalDisplay.tsx +0 -254
- package/src/react-ui/blocks/Terminal/TerminalDisplay.types.ts +0 -73
- package/src/react-ui/blocks/Terminal/TerminalPanel.tsx +0 -269
- package/src/react-ui/blocks/Terminal/TerminalRestty.tsx +0 -326
- package/src/react-ui/blocks/Terminal/TerminalXterm.tsx +0 -230
- package/src/react-ui/blocks/Terminal/XTermAdapter.ts +0 -163
- package/src/react-ui/blocks/Terminal/chrome.ts +0 -25
- package/src/react-ui/blocks/Terminal/components/LogLineBadges.tsx +0 -316
- package/src/react-ui/blocks/Terminal/components/SpecializedSyntaxHighlighter.tsx +0 -218
- package/src/react-ui/blocks/Terminal/components/SyntaxHighlight.tsx +0 -386
- package/src/react-ui/blocks/Terminal/components/TerminalLogBadge.tsx +0 -67
- package/src/react-ui/blocks/Terminal/components/index.ts +0 -10
- package/src/react-ui/blocks/Terminal/display.ts +0 -46
- package/src/react-ui/blocks/Terminal/hooks/index.ts +0 -22
- package/src/react-ui/blocks/Terminal/hooks/useTerminalSettings.ts +0 -229
- package/src/react-ui/blocks/Terminal/hooks/useTerminalWebSocket.ts +0 -292
- package/src/react-ui/blocks/Terminal/index.ts +0 -111
- package/src/react-ui/blocks/Terminal/panel/LogLinesViewer.tsx +0 -330
- package/src/react-ui/blocks/Terminal/panel/TerminalDebugPanel.tsx +0 -242
- package/src/react-ui/blocks/Terminal/panel/TerminalFilterDropdown.tsx +0 -202
- package/src/react-ui/blocks/Terminal/panel/TerminalFilterTabs.tsx +0 -140
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.tsx +0 -68
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanel.types.ts +0 -85
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelRestty.tsx +0 -383
- package/src/react-ui/blocks/Terminal/panel/TerminalInteractivePanelXterm.tsx +0 -439
- package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.tsx +0 -550
- package/src/react-ui/blocks/Terminal/panel/TerminalLogsPanel.types.ts +0 -259
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.styles.ts +0 -75
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.tsx +0 -266
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelChrome.types.ts +0 -82
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelFooter.tsx +0 -112
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelHeader.tsx +0 -178
- package/src/react-ui/blocks/Terminal/panel/TerminalPanelToolbar.tsx +0 -203
- package/src/react-ui/blocks/Terminal/panel/TerminalSessionControl.tsx +0 -252
- package/src/react-ui/blocks/Terminal/panel/TerminalSessionTabs.tsx +0 -334
- package/src/react-ui/blocks/Terminal/panel/TerminalSettingsPopover.tsx +0 -261
- package/src/react-ui/blocks/Terminal/panel/TerminalThemeSelector.tsx +0 -248
- package/src/react-ui/blocks/Terminal/panel/index.ts +0 -72
- package/src/react-ui/blocks/Terminal/panel/terminal-filter-dropdown.module.css +0 -59
- package/src/react-ui/blocks/Terminal/panel/terminal-session-tabs.module.css +0 -59
- package/src/react-ui/blocks/Terminal/parsing/BadgeFormatter.ts +0 -180
- package/src/react-ui/blocks/Terminal/parsing/HttpLogParser.ts +0 -248
- package/src/react-ui/blocks/Terminal/parsing/LogParser.types.ts +0 -283
- package/src/react-ui/blocks/Terminal/parsing/LogParserService.ts +0 -686
- package/src/react-ui/blocks/Terminal/parsing/MultilineAggregator.ts +0 -466
- package/src/react-ui/blocks/Terminal/parsing/PersistentLogBuffer.ts +0 -343
- package/src/react-ui/blocks/Terminal/parsing/SyntaxHighlighter.ts +0 -167
- package/src/react-ui/blocks/Terminal/parsing/TableParser.ts +0 -348
- package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiColorMapper.ts +0 -251
- package/src/react-ui/blocks/Terminal/parsing/ansi/AnsiParser.ts +0 -390
- package/src/react-ui/blocks/Terminal/parsing/ansi/ansi.constants.ts +0 -320
- package/src/react-ui/blocks/Terminal/parsing/ansi/index.ts +0 -20
- package/src/react-ui/blocks/Terminal/parsing/index.ts +0 -69
- package/src/react-ui/blocks/Terminal/parsing/levels/LogLevel.types.ts +0 -68
- package/src/react-ui/blocks/Terminal/parsing/levels/LogLevelDetector.ts +0 -436
- package/src/react-ui/blocks/Terminal/parsing/levels/index.ts +0 -14
- package/src/react-ui/blocks/index.ts +0 -11
- package/src/react-ui/components/MorphingPopover/MorphingPopover.types.ts +0 -49
- package/src/react-ui/components/MorphingPopover/index.tsx +0 -186
- package/src/react-ui/components/MorphingPopover/morphing-popover.module.css +0 -153
- package/src/react-ui/components/index.ts +0 -9
- package/src/react-ui/hooks/Animation/UseAutoHeight.tsx +0 -123
- package/src/react-ui/hooks/DOM/UseIsInView.tsx +0 -44
- package/src/react-ui/hooks/Formatting/UseListFormat.ts +0 -134
- package/src/react-ui/hooks/State/UseControlledState.tsx +0 -57
- package/src/react-ui/hooks/State/UseDataState.tsx +0 -76
- package/src/react-ui/hooks/index.ts +0 -20
- package/src/react-ui/icons/index.ts +0 -12
- package/src/react-ui/icons/lucide-animated/activity.tsx +0 -109
- package/src/react-ui/icons/lucide-animated/arrow-down-to-line.tsx +0 -51
- package/src/react-ui/icons/lucide-animated/arrow-up.tsx +0 -50
- package/src/react-ui/icons/lucide-animated/bell-electric.tsx +0 -124
- package/src/react-ui/icons/lucide-animated/bell.tsx +0 -93
- package/src/react-ui/icons/lucide-animated/bot.tsx +0 -122
- package/src/react-ui/icons/lucide-animated/box.tsx +0 -117
- package/src/react-ui/icons/lucide-animated/check.tsx +0 -21
- package/src/react-ui/icons/lucide-animated/circle-check.tsx +0 -107
- package/src/react-ui/icons/lucide-animated/delete.tsx +0 -133
- package/src/react-ui/icons/lucide-animated/download.tsx +0 -99
- package/src/react-ui/icons/lucide-animated/edit-2.tsx +0 -21
- package/src/react-ui/icons/lucide-animated/globe.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/home.tsx +0 -103
- package/src/react-ui/icons/lucide-animated/index.ts +0 -38
- package/src/react-ui/icons/lucide-animated/layers.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/layout-panel-top.tsx +0 -143
- package/src/react-ui/icons/lucide-animated/list.tsx +0 -54
- package/src/react-ui/icons/lucide-animated/package.tsx +0 -24
- package/src/react-ui/icons/lucide-animated/palette.tsx +0 -25
- package/src/react-ui/icons/lucide-animated/plus.tsx +0 -92
- package/src/react-ui/icons/lucide-animated/refresh-cw.tsx +0 -24
- package/src/react-ui/icons/lucide-animated/rocket.tsx +0 -24
- package/src/react-ui/icons/lucide-animated/save.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/search.tsx +0 -94
- package/src/react-ui/icons/lucide-animated/settings.tsx +0 -92
- package/src/react-ui/icons/lucide-animated/terminal.tsx +0 -46
- package/src/react-ui/icons/lucide-animated/trash-2.tsx +0 -25
- package/src/react-ui/icons/lucide-animated/trending-down.tsx +0 -151
- package/src/react-ui/icons/lucide-animated/trending-up.tsx +0 -150
- package/src/react-ui/icons/lucide-animated/type.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/upload.tsx +0 -23
- package/src/react-ui/icons/lucide-animated/x.tsx +0 -102
- package/src/react-ui/index.ts +0 -30
- package/src/react-ui/lib/get-strict-context.tsx +0 -56
- package/src/react-ui/lib/icon-wrapper.tsx +0 -70
- package/src/react-ui/lib/index.ts +0 -9
- package/src/react-ui/lib/utils.ts +0 -24
- package/src/react-ui/primitives/AutoHeight/index.tsx +0 -74
- package/src/react-ui/primitives/CountingNumber/index.tsx +0 -147
- package/src/react-ui/primitives/Highlight/Highlight.types.ts +0 -136
- package/src/react-ui/primitives/Highlight/index.tsx +0 -577
- package/src/react-ui/primitives/Slot/index.tsx +0 -128
- package/src/react-ui/primitives/index.ts +0 -16
- package/src/react-ui/primitives/waapi/Gooey/Gooey.types.ts +0 -123
- package/src/react-ui/primitives/waapi/Gooey/GooeyCanvas.tsx +0 -80
- package/src/react-ui/primitives/waapi/Gooey/GooeyFilter.tsx +0 -77
- package/src/react-ui/primitives/waapi/Gooey/MorphPath.tsx +0 -58
- package/src/react-ui/primitives/waapi/Gooey/gooey-utils.ts +0 -244
- package/src/react-ui/primitives/waapi/Gooey/index.ts +0 -50
- package/src/react-ui/primitives/waapi/Gooey/useMorphPath.ts +0 -48
- package/src/react-ui/primitives/waapi/Morph/Morph.types.ts +0 -106
- package/src/react-ui/primitives/waapi/Morph/MorphContext.tsx +0 -21
- package/src/react-ui/primitives/waapi/Morph/index.tsx +0 -56
- package/src/react-ui/primitives/waapi/Morph/techniques/index.ts +0 -12
- package/src/react-ui/primitives/waapi/Morph/techniques/useCSSGridMorph.ts +0 -89
- package/src/react-ui/primitives/waapi/Morph/techniques/useFLIPClipPath.ts +0 -176
- package/src/react-ui/primitives/waapi/Morph/techniques/useViewTransitions.ts +0 -87
- package/src/react-ui/primitives/waapi/Morph/useMorph.ts +0 -101
- package/src/react-ui/primitives/waapi/Reorder/Reorder.types.ts +0 -177
- package/src/react-ui/primitives/waapi/Reorder/index.tsx +0 -260
- package/src/react-ui/primitives/waapi/Reorder/useReorder.ts +0 -47
- package/src/react-ui/primitives/waapi/Reorder/useReorderPresence.ts +0 -209
- package/src/react-ui/primitives/waapi/Reorder/utils/separatorCoordination.ts +0 -104
- package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.styles.ts +0 -14
- package/src/react-ui/primitives/waapi/SlidingNumber/SlidingNumber.types.ts +0 -84
- package/src/react-ui/primitives/waapi/SlidingNumber/index.tsx +0 -474
- package/src/react-ui/primitives/waapi/SlidingText/SlidingText.styles.ts +0 -32
- package/src/react-ui/primitives/waapi/SlidingText/SlidingText.types.ts +0 -69
- package/src/react-ui/primitives/waapi/SlidingText/index.tsx +0 -140
- package/src/react-ui/primitives/waapi/core/animationConstants.ts +0 -215
- package/src/react-ui/primitives/waapi/core/index.ts +0 -53
- package/src/react-ui/primitives/waapi/core/types.ts +0 -200
- package/src/react-ui/primitives/waapi/core/useAnimationOrchestrator.ts +0 -430
- package/src/react-ui/primitives/waapi/core/useElementRegistry.ts +0 -81
- package/src/react-ui/primitives/waapi/core/useFLIPAnimation.ts +0 -138
- package/src/react-ui/primitives/waapi/core/usePositionCapture.ts +0 -106
- package/src/react-ui/primitives/waapi/index.ts +0 -139
- package/src/react-ui/styles/animations.css +0 -369
- package/src/react-ui/ui/Accordion/Accordion.styles.ts +0 -72
- package/src/react-ui/ui/Accordion/Accordion.types.ts +0 -199
- package/src/react-ui/ui/Accordion/index.tsx +0 -362
- package/src/react-ui/ui/AlertDialog/AlertDialog.styles.ts +0 -38
- package/src/react-ui/ui/AlertDialog/AlertDialog.types.ts +0 -296
- package/src/react-ui/ui/AlertDialog/index.tsx +0 -540
- package/src/react-ui/ui/Badge/Badge.styles.ts +0 -43
- package/src/react-ui/ui/Badge/Badge.types.ts +0 -26
- package/src/react-ui/ui/Badge/index.tsx +0 -34
- package/src/react-ui/ui/Button/Button.styles.ts +0 -57
- package/src/react-ui/ui/Button/Button.types.ts +0 -63
- package/src/react-ui/ui/Button/index.tsx +0 -155
- package/src/react-ui/ui/Card/Card.styles.ts +0 -32
- package/src/react-ui/ui/Card/Card.types.ts +0 -39
- package/src/react-ui/ui/Card/index.tsx +0 -130
- package/src/react-ui/ui/Checkbox/Checkbox.styles.ts +0 -40
- package/src/react-ui/ui/Checkbox/Checkbox.types.ts +0 -98
- package/src/react-ui/ui/Checkbox/index.tsx +0 -233
- package/src/react-ui/ui/Combobox/Combobox.styles.ts +0 -34
- package/src/react-ui/ui/Combobox/Combobox.types.ts +0 -89
- package/src/react-ui/ui/Combobox/index.tsx +0 -331
- package/src/react-ui/ui/CornerBracket/CornerBracket.styles.ts +0 -38
- package/src/react-ui/ui/CornerBracket/CornerBracket.types.ts +0 -15
- package/src/react-ui/ui/CornerBracket/index.tsx +0 -49
- package/src/react-ui/ui/DataCard/DataCard.styles.ts +0 -94
- package/src/react-ui/ui/DataCard/DataCard.types.ts +0 -125
- package/src/react-ui/ui/DataCard/index.tsx +0 -340
- package/src/react-ui/ui/Dialog/Dialog.styles.ts +0 -59
- package/src/react-ui/ui/Dialog/Dialog.types.ts +0 -284
- package/src/react-ui/ui/Dialog/index.tsx +0 -452
- package/src/react-ui/ui/DropdownMenu/DropdownMenu.styles.ts +0 -35
- package/src/react-ui/ui/DropdownMenu/DropdownMenu.types.ts +0 -81
- package/src/react-ui/ui/DropdownMenu/index.tsx +0 -300
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.css +0 -303
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.styles.ts +0 -85
- package/src/react-ui/ui/DynamicToggle/DynamicToggle.types.ts +0 -174
- package/src/react-ui/ui/DynamicToggle/index.tsx +0 -294
- package/src/react-ui/ui/DynamicToggle/prototype-v7.html +0 -615
- package/src/react-ui/ui/DynamicToggle/prototype.html +0 -419
- package/src/react-ui/ui/Field/Field.styles.ts +0 -47
- package/src/react-ui/ui/Field/Field.types.ts +0 -60
- package/src/react-ui/ui/Field/index.tsx +0 -254
- package/src/react-ui/ui/Input/Input.styles.ts +0 -11
- package/src/react-ui/ui/Input/Input.types.ts +0 -10
- package/src/react-ui/ui/Input/index.tsx +0 -32
- package/src/react-ui/ui/InputGroup/InputGroup.styles.ts +0 -53
- package/src/react-ui/ui/InputGroup/InputGroup.types.ts +0 -44
- package/src/react-ui/ui/InputGroup/index.tsx +0 -149
- package/src/react-ui/ui/Label/Label.styles.ts +0 -10
- package/src/react-ui/ui/Label/Label.types.ts +0 -9
- package/src/react-ui/ui/Label/index.tsx +0 -27
- package/src/react-ui/ui/Menu/Menu.styles.ts +0 -71
- package/src/react-ui/ui/Menu/Menu.types.ts +0 -425
- package/src/react-ui/ui/Menu/index.tsx +0 -900
- package/src/react-ui/ui/Popover/Popover.styles.ts +0 -55
- package/src/react-ui/ui/Popover/Popover.types.ts +0 -261
- package/src/react-ui/ui/Popover/index.tsx +0 -422
- package/src/react-ui/ui/Progress/Progress.styles.ts +0 -36
- package/src/react-ui/ui/Progress/Progress.types.ts +0 -162
- package/src/react-ui/ui/Progress/index.tsx +0 -254
- package/src/react-ui/ui/Select/Select.styles.ts +0 -30
- package/src/react-ui/ui/Select/Select.types.ts +0 -51
- package/src/react-ui/ui/Select/index.tsx +0 -225
- package/src/react-ui/ui/Separator/Separator.styles.ts +0 -10
- package/src/react-ui/ui/Separator/Separator.types.ts +0 -10
- package/src/react-ui/ui/Separator/index.tsx +0 -37
- package/src/react-ui/ui/Switch/Switch.styles.ts +0 -50
- package/src/react-ui/ui/Switch/Switch.types.ts +0 -155
- package/src/react-ui/ui/Switch/index.tsx +0 -253
- package/src/react-ui/ui/Tabs/Tabs.css +0 -39
- package/src/react-ui/ui/Tabs/Tabs.styles.ts +0 -148
- package/src/react-ui/ui/Tabs/Tabs.types.ts +0 -255
- package/src/react-ui/ui/Tabs/index.tsx +0 -529
- package/src/react-ui/ui/TextFlow/TextFlow.styles.ts +0 -36
- package/src/react-ui/ui/TextFlow/TextFlow.types.ts +0 -118
- package/src/react-ui/ui/TextFlow/index.tsx +0 -276
- package/src/react-ui/ui/Textarea/Textarea.styles.ts +0 -10
- package/src/react-ui/ui/Textarea/Textarea.types.ts +0 -9
- package/src/react-ui/ui/Textarea/index.tsx +0 -27
- package/src/react-ui/ui/Tooltip/Tooltip.styles.ts +0 -43
- package/src/react-ui/ui/Tooltip/Tooltip.types.ts +0 -253
- package/src/react-ui/ui/Tooltip/index.tsx +0 -394
- package/src/react-ui/ui/index.ts +0 -41
- package/src/types/css-modules.d.ts +0 -18
|
@@ -1,900 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Menu component -- animated dropdown/context menu built on base-ui Menu
|
|
5
|
-
* with motion transitions, highlight tracking, and the v0.2.0 slot system.
|
|
6
|
-
*
|
|
7
|
-
* Provides sub-components for triggers, items, checkbox items, radio groups,
|
|
8
|
-
* submenus, keyboard shortcut hints, separators, and animated highlights.
|
|
9
|
-
*
|
|
10
|
-
* @module @mks2508/mks-ui/react/ui/Menu
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```tsx
|
|
14
|
-
* <Menu>
|
|
15
|
-
* <MenuTrigger>Open Menu</MenuTrigger>
|
|
16
|
-
* <MenuPortal>
|
|
17
|
-
* <MenuPositioner sideOffset={8}>
|
|
18
|
-
* <MenuPopup className="rounded-lg border bg-zinc-900 p-1 shadow-xl">
|
|
19
|
-
* <MenuHighlight className="rounded-md bg-white/10" />
|
|
20
|
-
* <MenuHighlightItem>
|
|
21
|
-
* <MenuItem id="edit">Edit</MenuItem>
|
|
22
|
-
* </MenuHighlightItem>
|
|
23
|
-
* <MenuSeparator className="my-1 border-white/10" />
|
|
24
|
-
* <MenuHighlightItem>
|
|
25
|
-
* <MenuItem id="delete">Delete</MenuItem>
|
|
26
|
-
* </MenuHighlightItem>
|
|
27
|
-
* </MenuPopup>
|
|
28
|
-
* </MenuPositioner>
|
|
29
|
-
* </MenuPortal>
|
|
30
|
-
* </Menu>
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
|
|
34
|
-
import * as React from 'react';
|
|
35
|
-
import { Menu as MenuPrimitive } from '@base-ui/react/menu';
|
|
36
|
-
import { AnimatePresence, motion } from 'motion/react';
|
|
37
|
-
|
|
38
|
-
import {
|
|
39
|
-
Highlight,
|
|
40
|
-
HighlightItem,
|
|
41
|
-
} from '@/react-ui/primitives/Highlight';
|
|
42
|
-
import { getStrictContext } from '@/react-ui/lib/get-strict-context';
|
|
43
|
-
import { useControlledState } from '@/react-ui/hooks/State/UseControlledState';
|
|
44
|
-
import { useDataState } from '@/react-ui/hooks/State/UseDataState';
|
|
45
|
-
import { cn } from '@/react-ui/lib/utils';
|
|
46
|
-
import { menuStyles } from './Menu.styles';
|
|
47
|
-
|
|
48
|
-
import type {
|
|
49
|
-
MenuActiveValueContextType,
|
|
50
|
-
MenuContextType,
|
|
51
|
-
IMenuProps,
|
|
52
|
-
IMenuTriggerProps,
|
|
53
|
-
IMenuPortalProps,
|
|
54
|
-
IMenuGroupProps,
|
|
55
|
-
IMenuGroupLabelProps,
|
|
56
|
-
IMenuSubmenuProps,
|
|
57
|
-
IMenuSubmenuTriggerProps,
|
|
58
|
-
IMenuHighlightProps,
|
|
59
|
-
IMenuHighlightItemProps,
|
|
60
|
-
IMenuPositionerProps,
|
|
61
|
-
IMenuPopupProps,
|
|
62
|
-
IMenuItemProps,
|
|
63
|
-
IMenuCheckboxItemProps,
|
|
64
|
-
IMenuCheckboxItemIndicatorProps,
|
|
65
|
-
IMenuRadioGroupProps,
|
|
66
|
-
IMenuRadioItemProps,
|
|
67
|
-
IMenuRadioItemIndicatorProps,
|
|
68
|
-
IMenuShortcutProps,
|
|
69
|
-
IMenuArrowProps,
|
|
70
|
-
IMenuSeparatorProps,
|
|
71
|
-
} from './Menu.types';
|
|
72
|
-
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// Context
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
|
|
77
|
-
const [MenuActiveValueProvider, useMenuActiveValue] =
|
|
78
|
-
getStrictContext<MenuActiveValueContextType>('MenuActiveValueContext');
|
|
79
|
-
|
|
80
|
-
const [MenuProvider, useMenu] =
|
|
81
|
-
getStrictContext<MenuContextType>('MenuContext');
|
|
82
|
-
|
|
83
|
-
// ---------------------------------------------------------------------------
|
|
84
|
-
// Menu (Root)
|
|
85
|
-
// ---------------------------------------------------------------------------
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Root Menu component -- provides open/close state and highlighted-value context.
|
|
89
|
-
* Wraps base-ui Menu.Root with controlled state management.
|
|
90
|
-
*
|
|
91
|
-
* @param open - Controlled open state
|
|
92
|
-
* @param defaultOpen - Uncontrolled initial open state
|
|
93
|
-
* @param onOpenChange - Callback when open state changes
|
|
94
|
-
* @param slots - Partial class overrides per slot
|
|
95
|
-
* @param config - Menu behavior / animation configuration
|
|
96
|
-
*
|
|
97
|
-
* @example
|
|
98
|
-
* ```tsx
|
|
99
|
-
* <Menu slots={{ popup: 'bg-zinc-900' }}>
|
|
100
|
-
* <MenuTrigger>Actions</MenuTrigger>
|
|
101
|
-
* <MenuPortal>...</MenuPortal>
|
|
102
|
-
* </Menu>
|
|
103
|
-
* ```
|
|
104
|
-
*/
|
|
105
|
-
function Menu({ slots, config, ...props }: IMenuProps) {
|
|
106
|
-
const [isOpen, setIsOpen] = useControlledState({
|
|
107
|
-
value: props?.open,
|
|
108
|
-
defaultValue: props?.defaultOpen,
|
|
109
|
-
onChange: props?.onOpenChange,
|
|
110
|
-
});
|
|
111
|
-
const [highlightedValue, setHighlightedValue] = React.useState<string | null>(
|
|
112
|
-
null,
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
return (
|
|
116
|
-
<MenuActiveValueProvider value={{ highlightedValue, setHighlightedValue }}>
|
|
117
|
-
<MenuProvider value={{ isOpen, setIsOpen }}>
|
|
118
|
-
<MenuPrimitive.Root
|
|
119
|
-
data-slot="menu"
|
|
120
|
-
{...props}
|
|
121
|
-
onOpenChange={setIsOpen}
|
|
122
|
-
/>
|
|
123
|
-
</MenuProvider>
|
|
124
|
-
</MenuActiveValueProvider>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// ---------------------------------------------------------------------------
|
|
129
|
-
// MenuTrigger
|
|
130
|
-
// ---------------------------------------------------------------------------
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* MenuTrigger -- the interactive element that toggles the menu open/closed.
|
|
134
|
-
* Renders a base-ui Menu.Trigger with the `trigger` slot classes.
|
|
135
|
-
*
|
|
136
|
-
* @param slots - Partial class overrides per slot
|
|
137
|
-
* @param className - Additional class names
|
|
138
|
-
*
|
|
139
|
-
* @example
|
|
140
|
-
* ```tsx
|
|
141
|
-
* <MenuTrigger className="rounded-md px-3 py-1.5">
|
|
142
|
-
* Open Menu
|
|
143
|
-
* </MenuTrigger>
|
|
144
|
-
* ```
|
|
145
|
-
*/
|
|
146
|
-
function MenuTrigger({ slots, className, ...props }: IMenuTriggerProps) {
|
|
147
|
-
return (
|
|
148
|
-
<MenuPrimitive.Trigger
|
|
149
|
-
data-slot="menu-trigger"
|
|
150
|
-
className={cn(menuStyles.trigger, slots?.trigger, className)}
|
|
151
|
-
{...props}
|
|
152
|
-
/>
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// ---------------------------------------------------------------------------
|
|
157
|
-
// MenuPortal
|
|
158
|
-
// ---------------------------------------------------------------------------
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* MenuPortal -- wraps menu content in a portal with AnimatePresence.
|
|
162
|
-
* Internally keeps the portal mounted and uses AnimatePresence for
|
|
163
|
-
* smooth enter/exit transitions of children.
|
|
164
|
-
*
|
|
165
|
-
* @example
|
|
166
|
-
* ```tsx
|
|
167
|
-
* <MenuPortal>
|
|
168
|
-
* <MenuPositioner>
|
|
169
|
-
* <MenuPopup>...</MenuPopup>
|
|
170
|
-
* </MenuPositioner>
|
|
171
|
-
* </MenuPortal>
|
|
172
|
-
* ```
|
|
173
|
-
*/
|
|
174
|
-
function MenuPortal(props: IMenuPortalProps) {
|
|
175
|
-
const { isOpen } = useMenu();
|
|
176
|
-
|
|
177
|
-
return (
|
|
178
|
-
<AnimatePresence>
|
|
179
|
-
{isOpen && (
|
|
180
|
-
<MenuPrimitive.Portal keepMounted data-slot="menu-portal" {...props} />
|
|
181
|
-
)}
|
|
182
|
-
</AnimatePresence>
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// ---------------------------------------------------------------------------
|
|
187
|
-
// MenuGroup
|
|
188
|
-
// ---------------------------------------------------------------------------
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* MenuGroup -- logical grouping of related menu items.
|
|
192
|
-
* Renders a base-ui Menu.Group with the `group` slot classes.
|
|
193
|
-
*
|
|
194
|
-
* @param slots - Partial class overrides per slot
|
|
195
|
-
* @param className - Additional class names
|
|
196
|
-
*
|
|
197
|
-
* @example
|
|
198
|
-
* ```tsx
|
|
199
|
-
* <MenuGroup>
|
|
200
|
-
* <MenuGroupLabel>Editing</MenuGroupLabel>
|
|
201
|
-
* <MenuItem id="cut">Cut</MenuItem>
|
|
202
|
-
* <MenuItem id="copy">Copy</MenuItem>
|
|
203
|
-
* </MenuGroup>
|
|
204
|
-
* ```
|
|
205
|
-
*/
|
|
206
|
-
function MenuGroup({ slots, className, ...props }: IMenuGroupProps) {
|
|
207
|
-
return (
|
|
208
|
-
<MenuPrimitive.Group
|
|
209
|
-
data-slot="menu-group"
|
|
210
|
-
className={cn(menuStyles.group, slots?.group, className)}
|
|
211
|
-
{...props}
|
|
212
|
-
/>
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// ---------------------------------------------------------------------------
|
|
217
|
-
// MenuGroupLabel
|
|
218
|
-
// ---------------------------------------------------------------------------
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* MenuGroupLabel -- heading text for a MenuGroup.
|
|
222
|
-
* Renders a base-ui Menu.GroupLabel with the `groupLabel` slot classes.
|
|
223
|
-
*
|
|
224
|
-
* @param slots - Partial class overrides per slot
|
|
225
|
-
* @param className - Additional class names
|
|
226
|
-
*
|
|
227
|
-
* @example
|
|
228
|
-
* ```tsx
|
|
229
|
-
* <MenuGroupLabel className="text-xs font-medium uppercase tracking-wider">
|
|
230
|
-
* Navigation
|
|
231
|
-
* </MenuGroupLabel>
|
|
232
|
-
* ```
|
|
233
|
-
*/
|
|
234
|
-
function MenuGroupLabel({ slots, className, ...props }: IMenuGroupLabelProps) {
|
|
235
|
-
return (
|
|
236
|
-
<MenuPrimitive.GroupLabel
|
|
237
|
-
data-slot="menu-group-label"
|
|
238
|
-
className={cn(menuStyles.groupLabel, slots?.groupLabel, className)}
|
|
239
|
-
{...props}
|
|
240
|
-
/>
|
|
241
|
-
);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// ---------------------------------------------------------------------------
|
|
245
|
-
// MenuSubmenu
|
|
246
|
-
// ---------------------------------------------------------------------------
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* MenuSubmenu -- a nested sub-menu with its own open/close state.
|
|
250
|
-
* Wraps base-ui Menu.SubmenuRoot and provides a scoped MenuProvider.
|
|
251
|
-
*
|
|
252
|
-
* @param open - Controlled open state
|
|
253
|
-
* @param defaultOpen - Uncontrolled initial open state
|
|
254
|
-
* @param onOpenChange - Callback when open state changes
|
|
255
|
-
*
|
|
256
|
-
* @example
|
|
257
|
-
* ```tsx
|
|
258
|
-
* <MenuSubmenu>
|
|
259
|
-
* <MenuSubmenuTrigger>More Actions</MenuSubmenuTrigger>
|
|
260
|
-
* <MenuPortal>
|
|
261
|
-
* <MenuPositioner>
|
|
262
|
-
* <MenuPopup>
|
|
263
|
-
* <MenuItem id="archive">Archive</MenuItem>
|
|
264
|
-
* </MenuPopup>
|
|
265
|
-
* </MenuPositioner>
|
|
266
|
-
* </MenuPortal>
|
|
267
|
-
* </MenuSubmenu>
|
|
268
|
-
* ```
|
|
269
|
-
*/
|
|
270
|
-
function MenuSubmenu(props: IMenuSubmenuProps) {
|
|
271
|
-
const [isOpen, setIsOpen] = useControlledState({
|
|
272
|
-
value: props?.open,
|
|
273
|
-
defaultValue: props?.defaultOpen,
|
|
274
|
-
onChange: props?.onOpenChange,
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
return (
|
|
278
|
-
<MenuProvider value={{ isOpen, setIsOpen }}>
|
|
279
|
-
<MenuPrimitive.SubmenuRoot
|
|
280
|
-
data-slot="menu-submenu"
|
|
281
|
-
{...props}
|
|
282
|
-
onOpenChange={setIsOpen}
|
|
283
|
-
/>
|
|
284
|
-
</MenuProvider>
|
|
285
|
-
);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// ---------------------------------------------------------------------------
|
|
289
|
-
// MenuSubmenuTrigger
|
|
290
|
-
// ---------------------------------------------------------------------------
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* MenuSubmenuTrigger -- the item that opens a submenu on hover/focus.
|
|
294
|
-
* Tracks its own highlighted state via useDataState for highlight integration.
|
|
295
|
-
*
|
|
296
|
-
* @param label - Accessible label for the trigger
|
|
297
|
-
* @param id - Unique identifier used for highlight tracking
|
|
298
|
-
* @param disabled - Whether the trigger is disabled
|
|
299
|
-
* @param slots - Partial class overrides per slot
|
|
300
|
-
* @param className - Additional class names
|
|
301
|
-
*
|
|
302
|
-
* @example
|
|
303
|
-
* ```tsx
|
|
304
|
-
* <MenuSubmenuTrigger id="more" label="More actions">
|
|
305
|
-
* More...
|
|
306
|
-
* </MenuSubmenuTrigger>
|
|
307
|
-
* ```
|
|
308
|
-
*/
|
|
309
|
-
function MenuSubmenuTrigger({
|
|
310
|
-
label,
|
|
311
|
-
id,
|
|
312
|
-
nativeButton,
|
|
313
|
-
slots,
|
|
314
|
-
className,
|
|
315
|
-
...props
|
|
316
|
-
}: IMenuSubmenuTriggerProps) {
|
|
317
|
-
const { setHighlightedValue } = useMenuActiveValue();
|
|
318
|
-
const [, highlightedRef] = useDataState<HTMLDivElement>(
|
|
319
|
-
'highlighted',
|
|
320
|
-
undefined,
|
|
321
|
-
(value) => {
|
|
322
|
-
if (value === true) {
|
|
323
|
-
const el = highlightedRef.current;
|
|
324
|
-
const v = el?.dataset.value || el?.id || null;
|
|
325
|
-
if (v) setHighlightedValue(v);
|
|
326
|
-
}
|
|
327
|
-
},
|
|
328
|
-
);
|
|
329
|
-
|
|
330
|
-
return (
|
|
331
|
-
<MenuPrimitive.SubmenuTrigger
|
|
332
|
-
ref={highlightedRef}
|
|
333
|
-
label={label}
|
|
334
|
-
id={id}
|
|
335
|
-
nativeButton={nativeButton}
|
|
336
|
-
data-slot="menu-submenu-trigger"
|
|
337
|
-
className={cn(menuStyles.submenuTrigger, slots?.submenuTrigger, className)}
|
|
338
|
-
{...(props as any)}
|
|
339
|
-
/>
|
|
340
|
-
);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
// ---------------------------------------------------------------------------
|
|
344
|
-
// MenuHighlight
|
|
345
|
-
// ---------------------------------------------------------------------------
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* MenuHighlight -- animated background that follows the currently
|
|
349
|
-
* focused/highlighted menu item. Wraps the Highlight primitive with
|
|
350
|
-
* menu-specific defaults (spring transition, no click activation).
|
|
351
|
-
*
|
|
352
|
-
* @param transition - Motion transition config (default: spring 350/35)
|
|
353
|
-
* @param animateOnHover - Whether to activate on hover
|
|
354
|
-
* @param slots - Partial class overrides per slot
|
|
355
|
-
* @param className - Additional class names
|
|
356
|
-
*
|
|
357
|
-
* @example
|
|
358
|
-
* ```tsx
|
|
359
|
-
* <MenuHighlight className="rounded-md bg-white/10" />
|
|
360
|
-
* ```
|
|
361
|
-
*/
|
|
362
|
-
function MenuHighlight({
|
|
363
|
-
transition = { type: 'spring', stiffness: 350, damping: 35 },
|
|
364
|
-
slots,
|
|
365
|
-
className,
|
|
366
|
-
...props
|
|
367
|
-
}: IMenuHighlightProps) {
|
|
368
|
-
const { highlightedValue } = useMenuActiveValue();
|
|
369
|
-
|
|
370
|
-
return (
|
|
371
|
-
<Highlight
|
|
372
|
-
data-slot="menu-highlight"
|
|
373
|
-
click={false}
|
|
374
|
-
controlledItems
|
|
375
|
-
transition={transition}
|
|
376
|
-
value={highlightedValue}
|
|
377
|
-
className={cn(menuStyles.highlight, slots?.highlight, className)}
|
|
378
|
-
{...props}
|
|
379
|
-
/>
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// ---------------------------------------------------------------------------
|
|
384
|
-
// MenuHighlightItem
|
|
385
|
-
// ---------------------------------------------------------------------------
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* MenuHighlightItem -- wraps a MenuItem for highlight position tracking.
|
|
389
|
-
* Must be placed inside a MenuHighlight context.
|
|
390
|
-
*
|
|
391
|
-
* @param slots - Partial class overrides per slot
|
|
392
|
-
*
|
|
393
|
-
* @example
|
|
394
|
-
* ```tsx
|
|
395
|
-
* <MenuHighlight className="rounded bg-white/10">
|
|
396
|
-
* <MenuHighlightItem>
|
|
397
|
-
* <MenuItem id="edit">Edit</MenuItem>
|
|
398
|
-
* </MenuHighlightItem>
|
|
399
|
-
* </MenuHighlight>
|
|
400
|
-
* ```
|
|
401
|
-
*/
|
|
402
|
-
function MenuHighlightItem({ slots, ...props }: IMenuHighlightItemProps) {
|
|
403
|
-
return <HighlightItem data-slot="menu-highlight-item" {...props} />;
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// ---------------------------------------------------------------------------
|
|
407
|
-
// MenuPositioner
|
|
408
|
-
// ---------------------------------------------------------------------------
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* MenuPositioner -- positions the popup relative to the trigger element.
|
|
412
|
-
* Thin wrapper over base-ui Menu.Positioner.
|
|
413
|
-
*
|
|
414
|
-
* @param sideOffset - Gap between trigger and popup
|
|
415
|
-
* @param align - Alignment along the trigger edge
|
|
416
|
-
*
|
|
417
|
-
* @example
|
|
418
|
-
* ```tsx
|
|
419
|
-
* <MenuPositioner sideOffset={8} align="start">
|
|
420
|
-
* <MenuPopup>...</MenuPopup>
|
|
421
|
-
* </MenuPositioner>
|
|
422
|
-
* ```
|
|
423
|
-
*/
|
|
424
|
-
function MenuPositioner(props: IMenuPositionerProps) {
|
|
425
|
-
return <MenuPrimitive.Positioner data-slot="menu-positioner" {...props} />;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// ---------------------------------------------------------------------------
|
|
429
|
-
// MenuPopup
|
|
430
|
-
// ---------------------------------------------------------------------------
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* MenuPopup -- the visible flyout surface containing menu items.
|
|
434
|
-
* Uses Motion for animated entrance (scale + opacity) and exit.
|
|
435
|
-
*
|
|
436
|
-
* @param transition - Motion transition config (default: 0.2s duration)
|
|
437
|
-
* @param slots - Partial class overrides per slot
|
|
438
|
-
* @param className - Additional class names
|
|
439
|
-
* @param style - Inline styles merged with will-change hint
|
|
440
|
-
*
|
|
441
|
-
* @example
|
|
442
|
-
* ```tsx
|
|
443
|
-
* <MenuPopup className="min-w-[180px] rounded-lg border bg-zinc-900 p-1 shadow-xl">
|
|
444
|
-
* <MenuItem id="edit">Edit</MenuItem>
|
|
445
|
-
* <MenuItem id="delete">Delete</MenuItem>
|
|
446
|
-
* </MenuPopup>
|
|
447
|
-
* ```
|
|
448
|
-
*/
|
|
449
|
-
function MenuPopup({
|
|
450
|
-
finalFocus,
|
|
451
|
-
id,
|
|
452
|
-
transition = { duration: 0.2 },
|
|
453
|
-
style,
|
|
454
|
-
slots,
|
|
455
|
-
className,
|
|
456
|
-
...props
|
|
457
|
-
}: IMenuPopupProps) {
|
|
458
|
-
return (
|
|
459
|
-
<MenuPrimitive.Popup
|
|
460
|
-
finalFocus={finalFocus}
|
|
461
|
-
id={id}
|
|
462
|
-
render={
|
|
463
|
-
<motion.div
|
|
464
|
-
key="menu-popup"
|
|
465
|
-
data-slot="menu-popup"
|
|
466
|
-
initial={{ opacity: 0, scale: 0.95 }}
|
|
467
|
-
animate={{ opacity: 1, scale: 1 }}
|
|
468
|
-
exit={{ opacity: 0, scale: 0.95 }}
|
|
469
|
-
transition={transition}
|
|
470
|
-
style={{ willChange: 'opacity, transform', ...style }}
|
|
471
|
-
className={cn(menuStyles.popup, slots?.popup, className)}
|
|
472
|
-
{...(props as any)}
|
|
473
|
-
/>
|
|
474
|
-
}
|
|
475
|
-
/>
|
|
476
|
-
);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// ---------------------------------------------------------------------------
|
|
480
|
-
// MenuItem
|
|
481
|
-
// ---------------------------------------------------------------------------
|
|
482
|
-
|
|
483
|
-
/**
|
|
484
|
-
* MenuItem -- a single actionable row within the menu.
|
|
485
|
-
* Tracks highlight state via useDataState for animated highlight integration.
|
|
486
|
-
*
|
|
487
|
-
* @param id - Unique identifier, also used as highlight tracking value
|
|
488
|
-
* @param label - Accessible label
|
|
489
|
-
* @param disabled - Whether the item is disabled
|
|
490
|
-
* @param closeOnClick - Close menu when this item is clicked
|
|
491
|
-
* @param slots - Partial class overrides per slot
|
|
492
|
-
* @param className - Additional class names
|
|
493
|
-
*
|
|
494
|
-
* @example
|
|
495
|
-
* ```tsx
|
|
496
|
-
* <MenuItem id="edit" label="Edit document">
|
|
497
|
-
* <PencilIcon className="mr-2 size-4" />
|
|
498
|
-
* Edit
|
|
499
|
-
* <MenuShortcut>Ctrl+E</MenuShortcut>
|
|
500
|
-
* </MenuItem>
|
|
501
|
-
* ```
|
|
502
|
-
*/
|
|
503
|
-
function MenuItem({
|
|
504
|
-
disabled,
|
|
505
|
-
label,
|
|
506
|
-
closeOnClick,
|
|
507
|
-
nativeButton,
|
|
508
|
-
id,
|
|
509
|
-
slots,
|
|
510
|
-
className,
|
|
511
|
-
...props
|
|
512
|
-
}: IMenuItemProps) {
|
|
513
|
-
const { setHighlightedValue } = useMenuActiveValue();
|
|
514
|
-
const [, highlightedRef] = useDataState<HTMLDivElement>(
|
|
515
|
-
'highlighted',
|
|
516
|
-
undefined,
|
|
517
|
-
(value) => {
|
|
518
|
-
if (value === true) {
|
|
519
|
-
const el = highlightedRef.current;
|
|
520
|
-
const v = el?.dataset.value || el?.id || null;
|
|
521
|
-
if (v) setHighlightedValue(v);
|
|
522
|
-
}
|
|
523
|
-
},
|
|
524
|
-
);
|
|
525
|
-
|
|
526
|
-
return (
|
|
527
|
-
<MenuPrimitive.Item
|
|
528
|
-
ref={highlightedRef}
|
|
529
|
-
label={label}
|
|
530
|
-
closeOnClick={closeOnClick}
|
|
531
|
-
nativeButton={nativeButton}
|
|
532
|
-
disabled={disabled}
|
|
533
|
-
id={id}
|
|
534
|
-
data-slot="menu-item"
|
|
535
|
-
className={cn(menuStyles.item, slots?.item, className)}
|
|
536
|
-
{...(props as any)}
|
|
537
|
-
/>
|
|
538
|
-
);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
// ---------------------------------------------------------------------------
|
|
542
|
-
// MenuCheckboxItem
|
|
543
|
-
// ---------------------------------------------------------------------------
|
|
544
|
-
|
|
545
|
-
/**
|
|
546
|
-
* MenuCheckboxItem -- a toggleable checkbox item within the menu.
|
|
547
|
-
* Tracks highlight state for animated highlight integration.
|
|
548
|
-
*
|
|
549
|
-
* @param checked - Controlled checked state
|
|
550
|
-
* @param defaultChecked - Uncontrolled initial checked state
|
|
551
|
-
* @param onCheckedChange - Callback when checked state changes
|
|
552
|
-
* @param disabled - Whether the item is disabled
|
|
553
|
-
* @param slots - Partial class overrides per slot
|
|
554
|
-
* @param className - Additional class names
|
|
555
|
-
*
|
|
556
|
-
* @example
|
|
557
|
-
* ```tsx
|
|
558
|
-
* <MenuCheckboxItem checked={showGrid} onCheckedChange={setShowGrid}>
|
|
559
|
-
* <MenuCheckboxItemIndicator>
|
|
560
|
-
* <CheckIcon />
|
|
561
|
-
* </MenuCheckboxItemIndicator>
|
|
562
|
-
* Show Grid
|
|
563
|
-
* </MenuCheckboxItem>
|
|
564
|
-
* ```
|
|
565
|
-
*/
|
|
566
|
-
function MenuCheckboxItem({
|
|
567
|
-
label,
|
|
568
|
-
defaultChecked,
|
|
569
|
-
checked,
|
|
570
|
-
onCheckedChange,
|
|
571
|
-
disabled,
|
|
572
|
-
closeOnClick,
|
|
573
|
-
nativeButton,
|
|
574
|
-
id,
|
|
575
|
-
slots,
|
|
576
|
-
className,
|
|
577
|
-
...props
|
|
578
|
-
}: IMenuCheckboxItemProps) {
|
|
579
|
-
const { setHighlightedValue } = useMenuActiveValue();
|
|
580
|
-
const [, highlightedRef] = useDataState<HTMLDivElement>(
|
|
581
|
-
'highlighted',
|
|
582
|
-
undefined,
|
|
583
|
-
(value) => {
|
|
584
|
-
if (value === true) {
|
|
585
|
-
const el = highlightedRef.current;
|
|
586
|
-
const v = el?.dataset.value || el?.id || null;
|
|
587
|
-
if (v) setHighlightedValue(v);
|
|
588
|
-
}
|
|
589
|
-
},
|
|
590
|
-
);
|
|
591
|
-
|
|
592
|
-
return (
|
|
593
|
-
<MenuPrimitive.CheckboxItem
|
|
594
|
-
ref={highlightedRef}
|
|
595
|
-
label={label}
|
|
596
|
-
checked={checked}
|
|
597
|
-
defaultChecked={defaultChecked}
|
|
598
|
-
onCheckedChange={onCheckedChange}
|
|
599
|
-
disabled={disabled}
|
|
600
|
-
closeOnClick={closeOnClick}
|
|
601
|
-
nativeButton={nativeButton}
|
|
602
|
-
id={id}
|
|
603
|
-
data-slot="menu-checkbox-item"
|
|
604
|
-
className={cn(menuStyles.checkboxItem, slots?.checkboxItem, className)}
|
|
605
|
-
{...props}
|
|
606
|
-
/>
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
// ---------------------------------------------------------------------------
|
|
611
|
-
// MenuCheckboxItemIndicator
|
|
612
|
-
// ---------------------------------------------------------------------------
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
* MenuCheckboxItemIndicator -- the visual check/indeterminate icon.
|
|
616
|
-
* Renders via a motion.div for animated enter/exit transitions.
|
|
617
|
-
*
|
|
618
|
-
* @param keepMounted - Keep in DOM when unchecked (for exit animations)
|
|
619
|
-
*
|
|
620
|
-
* @example
|
|
621
|
-
* ```tsx
|
|
622
|
-
* <MenuCheckboxItemIndicator
|
|
623
|
-
* initial={{ opacity: 0, scale: 0.8 }}
|
|
624
|
-
* animate={{ opacity: 1, scale: 1 }}
|
|
625
|
-
* >
|
|
626
|
-
* <CheckIcon className="size-4" />
|
|
627
|
-
* </MenuCheckboxItemIndicator>
|
|
628
|
-
* ```
|
|
629
|
-
*/
|
|
630
|
-
function MenuCheckboxItemIndicator({
|
|
631
|
-
keepMounted,
|
|
632
|
-
...props
|
|
633
|
-
}: IMenuCheckboxItemIndicatorProps) {
|
|
634
|
-
return (
|
|
635
|
-
<MenuPrimitive.CheckboxItemIndicator
|
|
636
|
-
data-slot="menu-checkbox-item-indicator"
|
|
637
|
-
keepMounted={keepMounted}
|
|
638
|
-
render={
|
|
639
|
-
<motion.div data-slot="menu-checkbox-item-indicator" {...(props as any)} />
|
|
640
|
-
}
|
|
641
|
-
/>
|
|
642
|
-
);
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
// ---------------------------------------------------------------------------
|
|
646
|
-
// MenuRadioGroup
|
|
647
|
-
// ---------------------------------------------------------------------------
|
|
648
|
-
|
|
649
|
-
/**
|
|
650
|
-
* MenuRadioGroup -- groups radio items for single-selection within a menu.
|
|
651
|
-
* Wraps base-ui Menu.RadioGroup.
|
|
652
|
-
*
|
|
653
|
-
* @param value - Controlled selected value
|
|
654
|
-
* @param defaultValue - Uncontrolled initial selected value
|
|
655
|
-
* @param onValueChange - Callback when selection changes
|
|
656
|
-
*
|
|
657
|
-
* @example
|
|
658
|
-
* ```tsx
|
|
659
|
-
* <MenuRadioGroup value={sortBy} onValueChange={setSortBy}>
|
|
660
|
-
* <MenuRadioItem value="name">Name</MenuRadioItem>
|
|
661
|
-
* <MenuRadioItem value="date">Date</MenuRadioItem>
|
|
662
|
-
* <MenuRadioItem value="size">Size</MenuRadioItem>
|
|
663
|
-
* </MenuRadioGroup>
|
|
664
|
-
* ```
|
|
665
|
-
*/
|
|
666
|
-
function MenuRadioGroup(props: IMenuRadioGroupProps) {
|
|
667
|
-
return <MenuPrimitive.RadioGroup data-slot="menu-radio-group" {...props} />;
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
// ---------------------------------------------------------------------------
|
|
671
|
-
// MenuRadioItem
|
|
672
|
-
// ---------------------------------------------------------------------------
|
|
673
|
-
|
|
674
|
-
/**
|
|
675
|
-
* MenuRadioItem -- a single option within a MenuRadioGroup.
|
|
676
|
-
* Tracks highlight state for animated highlight integration.
|
|
677
|
-
*
|
|
678
|
-
* @param value - The value this item represents
|
|
679
|
-
* @param disabled - Whether the item is disabled
|
|
680
|
-
* @param label - Accessible label
|
|
681
|
-
* @param slots - Partial class overrides per slot
|
|
682
|
-
* @param className - Additional class names
|
|
683
|
-
*
|
|
684
|
-
* @example
|
|
685
|
-
* ```tsx
|
|
686
|
-
* <MenuRadioItem value="name">
|
|
687
|
-
* <MenuRadioItemIndicator>
|
|
688
|
-
* <DotIcon />
|
|
689
|
-
* </MenuRadioItemIndicator>
|
|
690
|
-
* Sort by Name
|
|
691
|
-
* </MenuRadioItem>
|
|
692
|
-
* ```
|
|
693
|
-
*/
|
|
694
|
-
function MenuRadioItem({
|
|
695
|
-
value,
|
|
696
|
-
disabled,
|
|
697
|
-
label,
|
|
698
|
-
closeOnClick,
|
|
699
|
-
nativeButton,
|
|
700
|
-
id,
|
|
701
|
-
slots,
|
|
702
|
-
className,
|
|
703
|
-
...props
|
|
704
|
-
}: IMenuRadioItemProps) {
|
|
705
|
-
const { setHighlightedValue } = useMenuActiveValue();
|
|
706
|
-
const [, highlightedRef] = useDataState<HTMLDivElement>(
|
|
707
|
-
'highlighted',
|
|
708
|
-
undefined,
|
|
709
|
-
(value) => {
|
|
710
|
-
if (value === true) {
|
|
711
|
-
const el = highlightedRef.current;
|
|
712
|
-
const v = el?.dataset.value || el?.id || null;
|
|
713
|
-
if (v) setHighlightedValue(v);
|
|
714
|
-
}
|
|
715
|
-
},
|
|
716
|
-
);
|
|
717
|
-
|
|
718
|
-
return (
|
|
719
|
-
<MenuPrimitive.RadioItem
|
|
720
|
-
ref={highlightedRef}
|
|
721
|
-
value={value}
|
|
722
|
-
disabled={disabled}
|
|
723
|
-
label={label}
|
|
724
|
-
closeOnClick={closeOnClick}
|
|
725
|
-
nativeButton={nativeButton}
|
|
726
|
-
id={id}
|
|
727
|
-
data-slot="menu-radio-item"
|
|
728
|
-
className={cn(menuStyles.radioItem, slots?.radioItem, className)}
|
|
729
|
-
{...props}
|
|
730
|
-
/>
|
|
731
|
-
);
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
// ---------------------------------------------------------------------------
|
|
735
|
-
// MenuRadioItemIndicator
|
|
736
|
-
// ---------------------------------------------------------------------------
|
|
737
|
-
|
|
738
|
-
/**
|
|
739
|
-
* MenuRadioItemIndicator -- the selection dot/icon for a radio item.
|
|
740
|
-
* Renders via a motion.div for animated enter/exit transitions.
|
|
741
|
-
*
|
|
742
|
-
* @param keepMounted - Keep in DOM when unselected (for exit animations)
|
|
743
|
-
*
|
|
744
|
-
* @example
|
|
745
|
-
* ```tsx
|
|
746
|
-
* <MenuRadioItemIndicator
|
|
747
|
-
* initial={{ opacity: 0 }}
|
|
748
|
-
* animate={{ opacity: 1 }}
|
|
749
|
-
* >
|
|
750
|
-
* <DotFilledIcon className="size-4" />
|
|
751
|
-
* </MenuRadioItemIndicator>
|
|
752
|
-
* ```
|
|
753
|
-
*/
|
|
754
|
-
function MenuRadioItemIndicator({
|
|
755
|
-
keepMounted,
|
|
756
|
-
...props
|
|
757
|
-
}: IMenuRadioItemIndicatorProps) {
|
|
758
|
-
return (
|
|
759
|
-
<MenuPrimitive.RadioItemIndicator
|
|
760
|
-
data-slot="menu-radio-item-indicator"
|
|
761
|
-
keepMounted={keepMounted}
|
|
762
|
-
render={<motion.div data-slot="menu-radio-item-indicator" {...(props as any)} />}
|
|
763
|
-
/>
|
|
764
|
-
);
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
// ---------------------------------------------------------------------------
|
|
768
|
-
// MenuShortcut
|
|
769
|
-
// ---------------------------------------------------------------------------
|
|
770
|
-
|
|
771
|
-
/**
|
|
772
|
-
* MenuShortcut -- displays a keyboard shortcut hint aligned to the right.
|
|
773
|
-
* Renders a plain `<span>` with the `shortcut` slot classes.
|
|
774
|
-
*
|
|
775
|
-
* @param slots - Partial class overrides per slot
|
|
776
|
-
* @param className - Additional class names
|
|
777
|
-
*
|
|
778
|
-
* @example
|
|
779
|
-
* ```tsx
|
|
780
|
-
* <MenuItem id="copy">
|
|
781
|
-
* Copy
|
|
782
|
-
* <MenuShortcut>Ctrl+C</MenuShortcut>
|
|
783
|
-
* </MenuItem>
|
|
784
|
-
* ```
|
|
785
|
-
*/
|
|
786
|
-
function MenuShortcut({ slots, className, ...props }: IMenuShortcutProps) {
|
|
787
|
-
return (
|
|
788
|
-
<span
|
|
789
|
-
data-slot="menu-shortcut"
|
|
790
|
-
className={cn(menuStyles.shortcut, slots?.shortcut, className)}
|
|
791
|
-
{...props}
|
|
792
|
-
/>
|
|
793
|
-
);
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
// ---------------------------------------------------------------------------
|
|
797
|
-
// MenuArrow
|
|
798
|
-
// ---------------------------------------------------------------------------
|
|
799
|
-
|
|
800
|
-
/**
|
|
801
|
-
* MenuArrow -- the directional caret/arrow on the popup edge.
|
|
802
|
-
* Wraps base-ui Menu.Arrow.
|
|
803
|
-
*
|
|
804
|
-
* @example
|
|
805
|
-
* ```tsx
|
|
806
|
-
* <MenuPopup>
|
|
807
|
-
* <MenuArrow className="fill-zinc-800" />
|
|
808
|
-
* <MenuItem id="edit">Edit</MenuItem>
|
|
809
|
-
* </MenuPopup>
|
|
810
|
-
* ```
|
|
811
|
-
*/
|
|
812
|
-
function MenuArrow(props: IMenuArrowProps) {
|
|
813
|
-
return <MenuPrimitive.Arrow data-slot="menu-arrow" {...props} />;
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
// ---------------------------------------------------------------------------
|
|
817
|
-
// MenuSeparator
|
|
818
|
-
// ---------------------------------------------------------------------------
|
|
819
|
-
|
|
820
|
-
/**
|
|
821
|
-
* MenuSeparator -- a horizontal divider between menu items or groups.
|
|
822
|
-
* Renders a base-ui Menu.Separator with the `separator` slot classes.
|
|
823
|
-
*
|
|
824
|
-
* @param slots - Partial class overrides per slot
|
|
825
|
-
* @param className - Additional class names
|
|
826
|
-
*
|
|
827
|
-
* @example
|
|
828
|
-
* ```tsx
|
|
829
|
-
* <MenuItem id="edit">Edit</MenuItem>
|
|
830
|
-
* <MenuSeparator className="my-1 h-px bg-white/10" />
|
|
831
|
-
* <MenuItem id="delete">Delete</MenuItem>
|
|
832
|
-
* ```
|
|
833
|
-
*/
|
|
834
|
-
function MenuSeparator({ slots, className, ...props }: IMenuSeparatorProps) {
|
|
835
|
-
return (
|
|
836
|
-
<MenuPrimitive.Separator
|
|
837
|
-
data-slot="menu-separator"
|
|
838
|
-
className={cn(menuStyles.separator, slots?.separator, className)}
|
|
839
|
-
{...props}
|
|
840
|
-
/>
|
|
841
|
-
);
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
// ---------------------------------------------------------------------------
|
|
845
|
-
// Exports
|
|
846
|
-
// ---------------------------------------------------------------------------
|
|
847
|
-
|
|
848
|
-
export {
|
|
849
|
-
Menu,
|
|
850
|
-
MenuTrigger,
|
|
851
|
-
MenuPortal,
|
|
852
|
-
MenuPositioner,
|
|
853
|
-
MenuPopup,
|
|
854
|
-
MenuArrow,
|
|
855
|
-
MenuItem,
|
|
856
|
-
MenuCheckboxItem,
|
|
857
|
-
MenuCheckboxItemIndicator,
|
|
858
|
-
MenuRadioGroup,
|
|
859
|
-
MenuRadioItem,
|
|
860
|
-
MenuRadioItemIndicator,
|
|
861
|
-
MenuGroup,
|
|
862
|
-
MenuGroupLabel,
|
|
863
|
-
MenuSeparator,
|
|
864
|
-
MenuShortcut,
|
|
865
|
-
MenuHighlight,
|
|
866
|
-
MenuHighlightItem,
|
|
867
|
-
MenuSubmenu,
|
|
868
|
-
MenuSubmenuTrigger,
|
|
869
|
-
useMenuActiveValue,
|
|
870
|
-
useMenu,
|
|
871
|
-
};
|
|
872
|
-
|
|
873
|
-
// Re-export all types
|
|
874
|
-
export type {
|
|
875
|
-
IMenuProps,
|
|
876
|
-
IMenuTriggerProps,
|
|
877
|
-
IMenuPortalProps,
|
|
878
|
-
IMenuPositionerProps,
|
|
879
|
-
IMenuPopupProps,
|
|
880
|
-
IMenuArrowProps,
|
|
881
|
-
IMenuItemProps,
|
|
882
|
-
IMenuCheckboxItemProps,
|
|
883
|
-
IMenuCheckboxItemIndicatorProps,
|
|
884
|
-
IMenuRadioItemProps,
|
|
885
|
-
IMenuRadioItemIndicatorProps,
|
|
886
|
-
IMenuRadioGroupProps,
|
|
887
|
-
IMenuGroupProps,
|
|
888
|
-
IMenuGroupLabelProps,
|
|
889
|
-
IMenuSeparatorProps,
|
|
890
|
-
IMenuShortcutProps,
|
|
891
|
-
IMenuHighlightProps,
|
|
892
|
-
IMenuHighlightItemProps,
|
|
893
|
-
IMenuSubmenuProps,
|
|
894
|
-
IMenuSubmenuTriggerProps,
|
|
895
|
-
IMenuConfig,
|
|
896
|
-
MenuActiveValueContextType,
|
|
897
|
-
MenuContextType,
|
|
898
|
-
} from './Menu.types';
|
|
899
|
-
|
|
900
|
-
export type { MenuSlot } from './Menu.styles';
|