aural-ui 3.0.7 → 4.1.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/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1199
- package/dist/components/avatar/Avatar.stories.tsx +235 -237
- package/dist/components/badge/Badge.stories.tsx +379 -116
- package/dist/components/banner/Banner.stories.tsx +445 -391
- package/dist/components/breadcrumb/Breadcrumb.stories.tsx +453 -199
- package/dist/components/button/Button.stories.tsx +585 -230
- package/dist/components/button/index.tsx +7 -7
- package/dist/components/card/Card.stories.tsx +619 -301
- package/dist/components/char-count/CharCount.stories.tsx +350 -248
- package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
- package/dist/components/chip/Chip.stories.tsx +362 -168
- package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -620
- package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
- package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
- package/dist/components/command/Command.stories.tsx +533 -856
- package/dist/components/dialog/Dialog.stories.tsx +505 -949
- package/dist/components/divider/Divider.stories.tsx +265 -502
- package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
- package/dist/components/drawer/Drawer.stories.tsx +659 -993
- package/dist/components/drawer/index.tsx +3 -3
- package/dist/components/dropdown/Dropdown.stories.tsx +643 -1018
- package/dist/components/form/Form.stories.tsx +560 -274
- package/dist/components/helper-text/HelperText.stories.tsx +199 -200
- package/dist/components/hover-card/HoverCard.stories.tsx +318 -1221
- package/dist/components/icon-button/IconButton.stories.tsx +837 -194
- package/dist/components/if-else/if-else.stories.tsx +370 -83
- package/dist/components/input/Input.stories.tsx +436 -368
- package/dist/components/label/Label.stories.tsx +156 -154
- package/dist/components/list/List.stories.tsx +485 -822
- package/dist/components/marquee/Marquee.stories.tsx +356 -694
- package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -410
- package/dist/components/overlay/Overlay.stories.tsx +452 -818
- package/dist/components/overlay/index.tsx +4 -4
- package/dist/components/pagination/Pagination.stories.tsx +721 -210
- package/dist/components/popover/Popover.stories.tsx +484 -873
- package/dist/components/radio/Radio.stories.tsx +432 -124
- package/dist/components/resizable/Resizable.stories.tsx +496 -752
- package/dist/components/scroll-area/ScrollArea.stories.tsx +384 -1006
- package/dist/components/search/Search.stories.tsx +314 -575
- package/dist/components/select/Select.stories.tsx +684 -787
- package/dist/components/sheet/Sheet.stories.tsx +671 -936
- package/dist/components/skelton/Skelton.stories.tsx +230 -764
- package/dist/components/slider/Slider.stories.tsx +384 -737
- package/dist/components/stepper/Stepper.stories.tsx +371 -514
- package/dist/components/switch/Switch.stories.tsx +461 -208
- package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
- package/dist/components/table/Table.stories.tsx +770 -914
- package/dist/components/tabs/Tabs.stories.tsx +459 -1400
- package/dist/components/tag/Tag.stories.tsx +714 -542
- package/dist/components/textarea/TextArea.stories.tsx +621 -562
- package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -148
- package/dist/components/toast/Toast.stories.tsx +452 -1333
- package/dist/components/toggle/Toggle.stories.tsx +488 -909
- package/dist/components/tooltip/Tooltip.stories.tsx +344 -1372
- package/dist/components/typography/Typography.stories.tsx +406 -89
- package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
- package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
- package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
- package/dist/icons/Icons.stories.tsx +0 -12
- package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +226 -1013
- package/dist/icons/alert-icon/AlertIcon.stories.tsx +109 -929
- package/dist/icons/all-icons.tsx +124 -87
- package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +140 -971
- package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +148 -888
- package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +135 -1019
- package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +137 -953
- package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +138 -997
- package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +136 -942
- package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +148 -1092
- package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +146 -1211
- package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +126 -615
- package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +144 -1164
- package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +167 -985
- package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +122 -1179
- package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +124 -1168
- package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +119 -850
- package/dist/icons/camera-icon/CameraIcon.stories.tsx +112 -1213
- package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +117 -934
- package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +160 -961
- package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +163 -961
- package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +144 -942
- package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +129 -966
- package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +147 -964
- package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +145 -975
- package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +150 -1142
- package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +114 -461
- package/dist/icons/coin-icon/CoinIcon.stories.tsx +124 -1322
- package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +117 -1318
- package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +114 -903
- package/dist/icons/command-icon/CommandIcon.stories.tsx +127 -1042
- package/dist/icons/copy-icon/CopyIcon.stories.tsx +123 -962
- package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +147 -999
- package/dist/icons/cross-icon/CrossIcon.stories.tsx +139 -960
- package/dist/icons/download-icon/DownloadIcon.stories.tsx +126 -820
- package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +124 -1031
- package/dist/icons/email-icon/EmailIcon.stories.tsx +115 -936
- package/dist/icons/expand-icon/ExpandIcon.stories.tsx +112 -1111
- package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +144 -1025
- package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +143 -1036
- package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +127 -1011
- package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +126 -1056
- package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +125 -614
- package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +119 -1050
- package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +169 -989
- package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +115 -1145
- package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +115 -1122
- package/dist/icons/globe-icon/GlobeIcon.stories.tsx +130 -313
- package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +145 -940
- package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +119 -1174
- package/dist/icons/head-icon/HeadIcon.stories.tsx +111 -916
- package/dist/icons/heart-icon/HeartIcon.stories.tsx +120 -1019
- package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +119 -683
- package/dist/icons/image-icon/ImageIcon.stories.tsx +105 -1121
- package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +111 -1192
- package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +136 -1256
- package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +159 -962
- package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +161 -1385
- package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +124 -972
- package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +119 -948
- package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +119 -942
- package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +108 -1215
- package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +154 -1517
- package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +110 -1188
- package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +119 -678
- package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +123 -1184
- package/dist/icons/message-icon/MessageIcon.stories.tsx +114 -538
- package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +116 -1158
- package/dist/icons/moon-icon/MoonIcon.stories.tsx +120 -536
- package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +109 -1184
- package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +115 -1134
- package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +119 -971
- package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +111 -1100
- package/dist/icons/notes-icon/NotesIcon.stories.tsx +119 -1101
- package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +109 -1111
- package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +122 -684
- package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +113 -954
- package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +112 -877
- package/dist/icons/pause-icon/PauseIcon.stories.tsx +113 -1000
- package/dist/icons/pencil-icon/PencilIcon.stories.tsx +115 -1070
- package/dist/icons/phone-icon/PhoneIcon.stories.tsx +115 -978
- package/dist/icons/plus-icon/PlusIcon.stories.tsx +106 -1093
- package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +107 -829
- package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +102 -469
- package/dist/icons/search-icon/SearchIcon.stories.tsx +111 -1124
- package/dist/icons/setting-icon/SettingIcon.stories.tsx +107 -970
- package/dist/icons/share-icon/ShareIcon.stories.tsx +120 -1025
- package/dist/icons/shield-icon/ShieldIcon.stories.tsx +117 -931
- package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +137 -1104
- package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +172 -982
- package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +164 -983
- package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +105 -958
- package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +158 -580
- package/dist/icons/spinner-gradient-icon/index.tsx +6 -1
- package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +158 -587
- package/dist/icons/spinner-solid-icon/index.tsx +6 -1
- package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +146 -682
- package/dist/icons/spinner-solid-neutral-icon/index.tsx +1 -1
- package/dist/icons/star-icon/StarIcon.stories.tsx +124 -904
- package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +112 -964
- package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +116 -852
- package/dist/icons/sun-icon/SunIcon.stories.tsx +120 -831
- package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +116 -950
- package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +123 -980
- package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +156 -1427
- package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +146 -1142
- package/dist/icons/tick-icon/TickIcon.stories.tsx +145 -1276
- package/dist/icons/trash-icon/TrashIcon.stories.tsx +108 -933
- package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +157 -1402
- package/dist/icons/upload-icon/UploadIcon.stories.tsx +115 -889
- package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +118 -984
- package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +125 -1049
- package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +123 -1356
- package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +110 -1171
- package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +112 -1093
- package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +115 -1087
- package/dist/icons/warning-icon/WarningIcon.stories.tsx +122 -1046
- package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +161 -936
- package/dist/index.cjs +84 -84
- package/dist/index.js +84 -84
- package/dist/styles/aural-all-theme.css +1222 -0
- package/dist/styles/{aural-theme.css → aural-dark-theme.css} +15 -3
- package/dist/styles/aural-light-theme.css +1047 -0
- package/package.json +1 -1
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
import React, { useState } from "react"
|
|
2
2
|
import { Button } from "@components/button"
|
|
3
|
-
import { IconButton } from "@components/icon-button"
|
|
4
3
|
import {
|
|
5
|
-
AlertIcon,
|
|
6
4
|
AngleDownIcon,
|
|
7
|
-
ArrowRightIcon,
|
|
8
5
|
AudioBarIcon,
|
|
9
6
|
ChevronDownIcon,
|
|
10
|
-
|
|
7
|
+
CircleTickIcon,
|
|
8
|
+
DownloadIcon,
|
|
11
9
|
EditBigIcon,
|
|
12
|
-
EyeCloseIcon,
|
|
13
10
|
EyeOpenIcon,
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
FileTextIcon,
|
|
12
|
+
HeartIcon,
|
|
13
|
+
MaintenanceIcon,
|
|
14
|
+
MusicalNoteIcon,
|
|
16
15
|
PlusIcon,
|
|
17
16
|
SearchIcon,
|
|
18
|
-
|
|
17
|
+
ShareIcon,
|
|
18
|
+
StarIcon,
|
|
19
19
|
TickIcon,
|
|
20
20
|
TrashIcon,
|
|
21
21
|
UploadIcon,
|
|
22
|
+
VerticalMenuIcon,
|
|
22
23
|
} from "@icons/index"
|
|
23
24
|
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
24
25
|
|
|
26
|
+
import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
|
|
27
|
+
|
|
25
28
|
import {
|
|
26
|
-
DropdownArrow,
|
|
27
29
|
DropdownMenu,
|
|
28
30
|
DropdownMenuCheckboxItem,
|
|
29
31
|
DropdownMenuContent,
|
|
@@ -45,86 +47,29 @@ const meta: Meta<typeof DropdownMenu> = {
|
|
|
45
47
|
component: DropdownMenu,
|
|
46
48
|
parameters: {
|
|
47
49
|
layout: "centered",
|
|
48
|
-
backgrounds: {
|
|
49
|
-
default: "dark",
|
|
50
|
-
values: [
|
|
51
|
-
{ name: "dark", value: "#0a0a0a" },
|
|
52
|
-
{ name: "light", value: "#ffffff" },
|
|
53
|
-
],
|
|
54
|
-
},
|
|
55
50
|
docs: {
|
|
56
51
|
description: {
|
|
57
|
-
component:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
A comprehensive dropdown menu component system built on Radix UI with dark theme optimization and frosted glass effects.
|
|
61
|
-
|
|
62
|
-
## Features
|
|
63
|
-
|
|
64
|
-
- **Dark Theme Optimized**: Frosted glass background with gradient borders
|
|
65
|
-
- **Flexible Content**: Support for items, labels, separators, checkboxes, and radio groups
|
|
66
|
-
- **Nested Menus**: Sub-menu support with hover triggers
|
|
67
|
-
- **Icon Integration**: Built-in icon support with proper sizing and theming
|
|
68
|
-
- **Keyboard Navigation**: Full accessibility with arrow keys and shortcuts
|
|
69
|
-
- **Custom Styling**: Granular control via \`classes\` prop
|
|
70
|
-
- **Smooth Animations**: Direction-aware entrance/exit animations
|
|
71
|
-
- **Portal Rendering**: Proper z-index layering and positioning
|
|
72
|
-
- **Logical Grouping**: Use \`DropdownMenuGroup\` for semantic organization
|
|
73
|
-
|
|
74
|
-
## Component Structure
|
|
75
|
-
|
|
76
|
-
- **DropdownMenu**: Root container managing state
|
|
77
|
-
- **DropdownMenuTrigger**: Interactive element that opens the menu
|
|
78
|
-
- **DropdownMenuContent**: The floating menu panel with frosted glass effect
|
|
79
|
-
- **DropdownMenuItem**: Standard menu item with optional variants
|
|
80
|
-
- **DropdownMenuGroup**: Groups related menu items together
|
|
81
|
-
- **DropdownMenuLabel**: Section headers and labels
|
|
82
|
-
- **DropdownMenuSeparator**: Visual dividers between sections
|
|
83
|
-
- **DropdownMenuCheckboxItem**: Checkable items with indicators
|
|
84
|
-
- **DropdownMenuRadioGroup/RadioItem**: Radio button groups
|
|
85
|
-
- **DropdownMenuSub/SubTrigger/SubContent**: Nested sub-menus
|
|
86
|
-
- **DropdownMenuShortcut**: Keyboard shortcut display
|
|
87
|
-
|
|
88
|
-
## Usage Examples
|
|
89
|
-
|
|
90
|
-
### Basic Menu with Groups
|
|
91
|
-
\`\`\`tsx
|
|
92
|
-
<DropdownMenu>
|
|
93
|
-
<DropdownMenuTrigger asChild>
|
|
94
|
-
<Button>Open Menu</Button>
|
|
95
|
-
</DropdownMenuTrigger>
|
|
96
|
-
<DropdownMenuContent>
|
|
97
|
-
<DropdownMenuGroup>
|
|
98
|
-
<DropdownMenuItem>Edit</DropdownMenuItem>
|
|
99
|
-
<DropdownMenuItem>Copy</DropdownMenuItem>
|
|
100
|
-
</DropdownMenuGroup>
|
|
101
|
-
<DropdownMenuSeparator />
|
|
102
|
-
<DropdownMenuGroup>
|
|
103
|
-
<DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
|
|
104
|
-
</DropdownMenuGroup>
|
|
105
|
-
</DropdownMenuContent>
|
|
106
|
-
</DropdownMenu>
|
|
107
|
-
\`\`\`
|
|
108
|
-
|
|
109
|
-
### With Custom Styling
|
|
110
|
-
\`\`\`tsx
|
|
111
|
-
<DropdownMenuContent
|
|
112
|
-
classes={{
|
|
113
|
-
root: "bg-blue-900/20",
|
|
114
|
-
border: "bg-gradient-to-r from-blue-500 to-purple-500"
|
|
115
|
-
}}
|
|
116
|
-
>
|
|
117
|
-
<DropdownMenuItem
|
|
118
|
-
classes={{
|
|
119
|
-
root: "text-blue-400 hover:bg-blue-500/20"
|
|
120
|
-
}}
|
|
121
|
-
>
|
|
122
|
-
Custom Item
|
|
123
|
-
</DropdownMenuItem>
|
|
124
|
-
</DropdownMenuContent>
|
|
125
|
-
\`\`\`
|
|
126
|
-
`,
|
|
52
|
+
component:
|
|
53
|
+
"A comprehensive dropdown menu system built on Radix UI with a frosted-glass aesthetic and gradient top border. Supports standard items, checkboxes, radio groups, nested sub-menus, separators, keyboard shortcuts, and a destructive variant. All item types accept a `classes` prop for granular style overrides. Animations are direction-aware and the menu renders into a portal for correct z-index layering.",
|
|
127
54
|
},
|
|
55
|
+
page: () => (
|
|
56
|
+
<AuralComponentDocsPage
|
|
57
|
+
features={[
|
|
58
|
+
{
|
|
59
|
+
title: "Rich Item Types",
|
|
60
|
+
description: "Checkbox, radio, sub-menu",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
title: "Keyboard Shortcuts",
|
|
64
|
+
description: "Shortcut slot per item",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
title: "Destructive Variant",
|
|
68
|
+
description: "Red danger action style",
|
|
69
|
+
},
|
|
70
|
+
]}
|
|
71
|
+
/>
|
|
72
|
+
),
|
|
128
73
|
},
|
|
129
74
|
},
|
|
130
75
|
tags: ["autodocs"],
|
|
@@ -133,674 +78,497 @@ A comprehensive dropdown menu component system built on Radix UI with dark theme
|
|
|
133
78
|
export default meta
|
|
134
79
|
type Story = StoryObj<typeof DropdownMenu>
|
|
135
80
|
|
|
136
|
-
//
|
|
137
|
-
|
|
81
|
+
// ─── Configurations ───────────────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
export const Configurations: Story = {
|
|
138
84
|
render: () => (
|
|
139
85
|
<div className="space-y-8">
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
<
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
</p>
|
|
146
|
-
</div>
|
|
147
|
-
|
|
148
|
-
<div className="flex flex-wrap items-start justify-center gap-4">
|
|
149
|
-
{/* Basic Button Trigger */}
|
|
150
|
-
<DropdownMenu>
|
|
151
|
-
<DropdownMenuTrigger asChild>
|
|
152
|
-
<Button variant="outline" className="gap-2">
|
|
153
|
-
<SiteLogoIcon className="h-4 w-4" />
|
|
154
|
-
Options
|
|
155
|
-
<ChevronDownIcon className="h-4 w-4" />
|
|
156
|
-
</Button>
|
|
157
|
-
</DropdownMenuTrigger>
|
|
158
|
-
<DropdownMenuContent>
|
|
159
|
-
<DropdownMenuGroup>
|
|
160
|
-
<DropdownMenuItem>
|
|
161
|
-
<EditBigIcon className="h-4 w-4" />
|
|
162
|
-
Edit
|
|
163
|
-
</DropdownMenuItem>
|
|
164
|
-
<DropdownMenuItem>
|
|
165
|
-
<TickIcon className="h-4 w-4" />
|
|
166
|
-
Copy
|
|
167
|
-
</DropdownMenuItem>
|
|
168
|
-
</DropdownMenuGroup>
|
|
169
|
-
<DropdownMenuSeparator />
|
|
170
|
-
<DropdownMenuGroup>
|
|
171
|
-
<DropdownMenuItem variant="destructive">
|
|
172
|
-
<TrashIcon className="h-4 w-4" />
|
|
173
|
-
Delete
|
|
174
|
-
</DropdownMenuItem>
|
|
175
|
-
</DropdownMenuGroup>
|
|
176
|
-
</DropdownMenuContent>
|
|
177
|
-
</DropdownMenu>
|
|
178
|
-
|
|
179
|
-
{/* Icon Button Trigger */}
|
|
180
|
-
<DropdownMenu>
|
|
181
|
-
<DropdownMenuTrigger asChild>
|
|
182
|
-
<IconButton variant="ghost" icon={<AlertIcon />} label="" />
|
|
183
|
-
</DropdownMenuTrigger>
|
|
184
|
-
<DropdownMenuContent>
|
|
185
|
-
<DropdownMenuGroup>
|
|
186
|
-
<DropdownMenuItem>
|
|
187
|
-
<ArrowRightIcon className="h-4 w-4" />
|
|
188
|
-
Share
|
|
189
|
-
</DropdownMenuItem>
|
|
190
|
-
<DropdownMenuItem>
|
|
191
|
-
<TickIcon className="h-4 w-4" />
|
|
192
|
-
Favorite
|
|
193
|
-
</DropdownMenuItem>
|
|
194
|
-
<DropdownMenuItem>
|
|
195
|
-
<TickIcon className="h-4 w-4" />
|
|
196
|
-
Copy Link
|
|
197
|
-
</DropdownMenuItem>
|
|
198
|
-
</DropdownMenuGroup>
|
|
199
|
-
</DropdownMenuContent>
|
|
200
|
-
</DropdownMenu>
|
|
201
|
-
|
|
202
|
-
{/* User Menu */}
|
|
203
|
-
<DropdownMenu>
|
|
204
|
-
<DropdownMenuTrigger asChild>
|
|
205
|
-
<Button variant="text" className="gap-2">
|
|
206
|
-
<SiteLogoIcon className="h-4 w-4" />
|
|
207
|
-
Account
|
|
208
|
-
<ChevronDownIcon className="h-4 w-4" />
|
|
209
|
-
</Button>
|
|
210
|
-
</DropdownMenuTrigger>
|
|
211
|
-
<DropdownMenuContent align="end">
|
|
212
|
-
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
|
213
|
-
<DropdownMenuSeparator />
|
|
214
|
-
<DropdownMenuGroup>
|
|
215
|
-
<DropdownMenuItem>
|
|
216
|
-
<SiteLogoIcon className="h-4 w-4" />
|
|
217
|
-
Profile
|
|
218
|
-
</DropdownMenuItem>
|
|
219
|
-
<DropdownMenuItem>
|
|
220
|
-
<SiteLogoIcon className="h-4 w-4" />
|
|
221
|
-
Settings
|
|
222
|
-
</DropdownMenuItem>
|
|
223
|
-
</DropdownMenuGroup>
|
|
224
|
-
<DropdownMenuSeparator />
|
|
225
|
-
<DropdownMenuGroup>
|
|
226
|
-
<DropdownMenuItem variant="destructive">
|
|
227
|
-
<CrossIcon className="h-4 w-4" />
|
|
228
|
-
Log out
|
|
229
|
-
</DropdownMenuItem>
|
|
230
|
-
</DropdownMenuGroup>
|
|
231
|
-
</DropdownMenuContent>
|
|
232
|
-
</DropdownMenu>
|
|
233
|
-
</div>
|
|
234
|
-
</div>
|
|
235
|
-
),
|
|
236
|
-
parameters: {
|
|
237
|
-
docs: {
|
|
238
|
-
description: {
|
|
239
|
-
story:
|
|
240
|
-
"Basic dropdown menu examples with different trigger styles and grouped content using DropdownMenuGroup.",
|
|
241
|
-
},
|
|
242
|
-
},
|
|
243
|
-
},
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// 2. Interactive States
|
|
247
|
-
export const InteractiveStates: Story = {
|
|
248
|
-
render: () => {
|
|
249
|
-
const [notifications, setNotifications] = useState(true)
|
|
250
|
-
const [marketing, setMarketing] = useState(false)
|
|
251
|
-
const [theme, setTheme] = useState("dark")
|
|
252
|
-
|
|
253
|
-
return (
|
|
254
|
-
<div className="space-y-8">
|
|
255
|
-
<div className="text-center">
|
|
256
|
-
<h3 className="mb-2 font-medium text-white">Interactive States</h3>
|
|
257
|
-
<p className="text-sm text-white/60">
|
|
258
|
-
Checkboxes, radio groups, and stateful interactions with logical
|
|
259
|
-
grouping
|
|
260
|
-
</p>
|
|
261
|
-
</div>
|
|
262
|
-
|
|
86
|
+
{/* Basic item */}
|
|
87
|
+
<div className="space-y-3">
|
|
88
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
89
|
+
Basic Items
|
|
90
|
+
</h4>
|
|
263
91
|
<div className="flex flex-wrap justify-center gap-4">
|
|
264
|
-
{/* Checkbox Menu */}
|
|
265
92
|
<DropdownMenu>
|
|
266
93
|
<DropdownMenuTrigger asChild>
|
|
267
|
-
<Button
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
94
|
+
<Button
|
|
95
|
+
variant="outline"
|
|
96
|
+
innerClassName="flex items-center gap-2"
|
|
97
|
+
>
|
|
98
|
+
Options
|
|
99
|
+
<ChevronDownIcon className="size-4" />
|
|
271
100
|
</Button>
|
|
272
101
|
</DropdownMenuTrigger>
|
|
273
102
|
<DropdownMenuContent>
|
|
274
|
-
<
|
|
103
|
+
<DropdownMenuGroup>
|
|
104
|
+
<DropdownMenuItem>
|
|
105
|
+
<EditBigIcon />
|
|
106
|
+
Edit
|
|
107
|
+
</DropdownMenuItem>
|
|
108
|
+
<DropdownMenuItem>
|
|
109
|
+
<TickIcon />
|
|
110
|
+
Duplicate
|
|
111
|
+
</DropdownMenuItem>
|
|
112
|
+
<DropdownMenuItem>
|
|
113
|
+
<ShareIcon />
|
|
114
|
+
Share
|
|
115
|
+
<DropdownMenuShortcut>⌘⇧S</DropdownMenuShortcut>
|
|
116
|
+
</DropdownMenuItem>
|
|
117
|
+
</DropdownMenuGroup>
|
|
275
118
|
<DropdownMenuSeparator />
|
|
276
119
|
<DropdownMenuGroup>
|
|
277
|
-
<
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
</DropdownMenuCheckboxItem>
|
|
283
|
-
<DropdownMenuCheckboxItem
|
|
284
|
-
checked={marketing}
|
|
285
|
-
onCheckedChange={setMarketing}
|
|
286
|
-
>
|
|
287
|
-
Marketing Emails
|
|
288
|
-
</DropdownMenuCheckboxItem>
|
|
120
|
+
<DropdownMenuItem variant="destructive">
|
|
121
|
+
<TrashIcon />
|
|
122
|
+
Delete
|
|
123
|
+
<DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
|
|
124
|
+
</DropdownMenuItem>
|
|
289
125
|
</DropdownMenuGroup>
|
|
290
126
|
</DropdownMenuContent>
|
|
291
127
|
</DropdownMenu>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
292
130
|
|
|
293
|
-
|
|
131
|
+
{/* Inset items */}
|
|
132
|
+
<div className="space-y-3">
|
|
133
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
134
|
+
Inset Items
|
|
135
|
+
</h4>
|
|
136
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
294
137
|
<DropdownMenu>
|
|
295
138
|
<DropdownMenuTrigger asChild>
|
|
296
|
-
<Button
|
|
297
|
-
|
|
298
|
-
|
|
139
|
+
<Button
|
|
140
|
+
variant="outline"
|
|
141
|
+
innerClassName="flex items-center gap-2"
|
|
142
|
+
>
|
|
143
|
+
With Inset
|
|
144
|
+
<ChevronDownIcon className="size-4" />
|
|
299
145
|
</Button>
|
|
300
146
|
</DropdownMenuTrigger>
|
|
301
|
-
<DropdownMenuContent>
|
|
302
|
-
<DropdownMenuLabel>
|
|
147
|
+
<DropdownMenuContent className="w-48">
|
|
148
|
+
<DropdownMenuLabel>Account</DropdownMenuLabel>
|
|
303
149
|
<DropdownMenuSeparator />
|
|
304
150
|
<DropdownMenuGroup>
|
|
305
|
-
<
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
</DropdownMenuRadioItem>
|
|
315
|
-
</DropdownMenuRadioGroup>
|
|
151
|
+
<DropdownMenuItem inset>Profile</DropdownMenuItem>
|
|
152
|
+
<DropdownMenuItem inset>Settings</DropdownMenuItem>
|
|
153
|
+
<DropdownMenuItem inset>Billing</DropdownMenuItem>
|
|
154
|
+
</DropdownMenuGroup>
|
|
155
|
+
<DropdownMenuSeparator />
|
|
156
|
+
<DropdownMenuGroup>
|
|
157
|
+
<DropdownMenuItem inset variant="destructive">
|
|
158
|
+
Log out
|
|
159
|
+
</DropdownMenuItem>
|
|
316
160
|
</DropdownMenuGroup>
|
|
317
161
|
</DropdownMenuContent>
|
|
318
162
|
</DropdownMenu>
|
|
319
163
|
</div>
|
|
320
|
-
|
|
321
|
-
{/* State Display */}
|
|
322
|
-
<div className="text-center">
|
|
323
|
-
<div className="inline-block rounded-lg border border-white/10 bg-white/5 p-4">
|
|
324
|
-
<h4 className="mb-2 text-sm font-medium text-white">
|
|
325
|
-
Current State
|
|
326
|
-
</h4>
|
|
327
|
-
<div className="space-y-1 text-xs text-white/60">
|
|
328
|
-
<div>Notifications: {notifications ? "On" : "Off"}</div>
|
|
329
|
-
<div>Marketing: {marketing ? "On" : "Off"}</div>
|
|
330
|
-
<div>Theme: {theme}</div>
|
|
331
|
-
</div>
|
|
332
|
-
</div>
|
|
333
|
-
</div>
|
|
334
|
-
</div>
|
|
335
|
-
)
|
|
336
|
-
},
|
|
337
|
-
parameters: {
|
|
338
|
-
docs: {
|
|
339
|
-
description: {
|
|
340
|
-
story:
|
|
341
|
-
"Interactive dropdown menus with checkboxes, radio groups, and state management using proper grouping.",
|
|
342
|
-
},
|
|
343
|
-
},
|
|
344
|
-
},
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// 3. Nested Sub-menus
|
|
348
|
-
export const NestedMenus: Story = {
|
|
349
|
-
render: () => (
|
|
350
|
-
<div className="space-y-8">
|
|
351
|
-
<div className="text-center">
|
|
352
|
-
<h3 className="mb-2 font-medium text-white">Nested Sub-menus</h3>
|
|
353
|
-
<p className="text-sm text-white/60">
|
|
354
|
-
Multi-level menus with sub-menu navigation and logical grouping
|
|
355
|
-
</p>
|
|
356
|
-
</div>
|
|
357
|
-
|
|
358
|
-
<div className="flex justify-center">
|
|
359
|
-
<DropdownMenu>
|
|
360
|
-
<DropdownMenuTrigger asChild>
|
|
361
|
-
<Button variant="outline" className="gap-2">
|
|
362
|
-
<PlusIcon className="h-4 w-4" />
|
|
363
|
-
Create New
|
|
364
|
-
<ChevronDownIcon className="h-4 w-4" />
|
|
365
|
-
</Button>
|
|
366
|
-
</DropdownMenuTrigger>
|
|
367
|
-
<DropdownMenuContent>
|
|
368
|
-
<DropdownMenuLabel>Create</DropdownMenuLabel>
|
|
369
|
-
<DropdownMenuSeparator />
|
|
370
|
-
|
|
371
|
-
<DropdownMenuGroup>
|
|
372
|
-
<DropdownMenuSub>
|
|
373
|
-
<DropdownMenuSubTrigger>
|
|
374
|
-
<FileChartIcon className="h-4 w-4" />
|
|
375
|
-
Folder
|
|
376
|
-
</DropdownMenuSubTrigger>
|
|
377
|
-
<DropdownMenuSubContent>
|
|
378
|
-
<DropdownMenuGroup>
|
|
379
|
-
<DropdownMenuItem>
|
|
380
|
-
<FileChartIcon className="h-4 w-4" />
|
|
381
|
-
Project Folder
|
|
382
|
-
</DropdownMenuItem>
|
|
383
|
-
<DropdownMenuItem>
|
|
384
|
-
<FileChartIcon className="h-4 w-4" />
|
|
385
|
-
Asset Folder
|
|
386
|
-
</DropdownMenuItem>
|
|
387
|
-
<DropdownMenuItem>
|
|
388
|
-
<FileChartIcon className="h-4 w-4" />
|
|
389
|
-
Template Folder
|
|
390
|
-
</DropdownMenuItem>
|
|
391
|
-
</DropdownMenuGroup>
|
|
392
|
-
</DropdownMenuSubContent>
|
|
393
|
-
</DropdownMenuSub>
|
|
394
|
-
|
|
395
|
-
<DropdownMenuSub>
|
|
396
|
-
<DropdownMenuSubTrigger>
|
|
397
|
-
<FileChartIcon className="h-4 w-4" />
|
|
398
|
-
Document
|
|
399
|
-
</DropdownMenuSubTrigger>
|
|
400
|
-
<DropdownMenuSubContent>
|
|
401
|
-
<DropdownMenuGroup>
|
|
402
|
-
<DropdownMenuItem>
|
|
403
|
-
<FileChartIcon className="h-4 w-4" />
|
|
404
|
-
Text Document
|
|
405
|
-
</DropdownMenuItem>
|
|
406
|
-
<DropdownMenuItem>
|
|
407
|
-
<FileChartIcon className="h-4 w-4" />
|
|
408
|
-
Spreadsheet
|
|
409
|
-
</DropdownMenuItem>
|
|
410
|
-
<DropdownMenuItem>
|
|
411
|
-
<FileChartIcon className="h-4 w-4" />
|
|
412
|
-
Presentation
|
|
413
|
-
</DropdownMenuItem>
|
|
414
|
-
</DropdownMenuGroup>
|
|
415
|
-
<DropdownMenuSeparator />
|
|
416
|
-
<DropdownMenuGroup>
|
|
417
|
-
<DropdownMenuItem>
|
|
418
|
-
<ImageIcon className="h-4 w-4" />
|
|
419
|
-
From Template
|
|
420
|
-
</DropdownMenuItem>
|
|
421
|
-
</DropdownMenuGroup>
|
|
422
|
-
</DropdownMenuSubContent>
|
|
423
|
-
</DropdownMenuSub>
|
|
424
|
-
</DropdownMenuGroup>
|
|
425
|
-
|
|
426
|
-
<DropdownMenuSeparator />
|
|
427
|
-
<DropdownMenuGroup>
|
|
428
|
-
<DropdownMenuItem>
|
|
429
|
-
<UploadIcon className="h-4 w-4" />
|
|
430
|
-
Upload File
|
|
431
|
-
</DropdownMenuItem>
|
|
432
|
-
</DropdownMenuGroup>
|
|
433
|
-
</DropdownMenuContent>
|
|
434
|
-
</DropdownMenu>
|
|
435
|
-
</div>
|
|
436
|
-
</div>
|
|
437
|
-
),
|
|
438
|
-
parameters: {
|
|
439
|
-
docs: {
|
|
440
|
-
description: {
|
|
441
|
-
story:
|
|
442
|
-
"Nested dropdown menus with sub-menu triggers and multi-level navigation using DropdownMenuGroup for organization.",
|
|
443
|
-
},
|
|
444
|
-
},
|
|
445
|
-
},
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
// 4. Keyboard Shortcuts
|
|
449
|
-
export const KeyboardShortcuts: Story = {
|
|
450
|
-
render: () => (
|
|
451
|
-
<div className="space-y-8">
|
|
452
|
-
<div className="text-center">
|
|
453
|
-
<h3 className="mb-2 font-medium text-white">Keyboard Shortcuts</h3>
|
|
454
|
-
<p className="text-sm text-white/60">
|
|
455
|
-
Menu items with keyboard shortcut indicators and logical grouping
|
|
456
|
-
</p>
|
|
457
|
-
</div>
|
|
458
|
-
|
|
459
|
-
<div className="flex justify-center">
|
|
460
|
-
<DropdownMenu>
|
|
461
|
-
<DropdownMenuTrigger asChild>
|
|
462
|
-
<Button variant="outline" className="gap-2">
|
|
463
|
-
<EditBigIcon className="h-4 w-4" />
|
|
464
|
-
Edit Menu
|
|
465
|
-
<ChevronDownIcon className="h-4 w-4" />
|
|
466
|
-
</Button>
|
|
467
|
-
</DropdownMenuTrigger>
|
|
468
|
-
<DropdownMenuContent className="w-56">
|
|
469
|
-
<DropdownMenuLabel>Edit</DropdownMenuLabel>
|
|
470
|
-
<DropdownMenuSeparator />
|
|
471
|
-
|
|
472
|
-
<DropdownMenuGroup>
|
|
473
|
-
<DropdownMenuItem>
|
|
474
|
-
<EditBigIcon className="h-4 w-4" />
|
|
475
|
-
Undo
|
|
476
|
-
<DropdownMenuShortcut>⌘Z</DropdownMenuShortcut>
|
|
477
|
-
</DropdownMenuItem>
|
|
478
|
-
<DropdownMenuItem>
|
|
479
|
-
<EditBigIcon className="h-4 w-4" />
|
|
480
|
-
Redo
|
|
481
|
-
<DropdownMenuShortcut>⌘⇧Z</DropdownMenuShortcut>
|
|
482
|
-
</DropdownMenuItem>
|
|
483
|
-
</DropdownMenuGroup>
|
|
484
|
-
|
|
485
|
-
<DropdownMenuSeparator />
|
|
486
|
-
|
|
487
|
-
<DropdownMenuGroup>
|
|
488
|
-
<DropdownMenuItem>
|
|
489
|
-
<TickIcon className="h-4 w-4" />
|
|
490
|
-
Cut
|
|
491
|
-
<DropdownMenuShortcut>⌘X</DropdownMenuShortcut>
|
|
492
|
-
</DropdownMenuItem>
|
|
493
|
-
<DropdownMenuItem>
|
|
494
|
-
<TickIcon className="h-4 w-4" />
|
|
495
|
-
Copy
|
|
496
|
-
<DropdownMenuShortcut>⌘C</DropdownMenuShortcut>
|
|
497
|
-
</DropdownMenuItem>
|
|
498
|
-
<DropdownMenuItem>
|
|
499
|
-
<TickIcon className="h-4 w-4" />
|
|
500
|
-
Paste
|
|
501
|
-
<DropdownMenuShortcut>⌘V</DropdownMenuShortcut>
|
|
502
|
-
</DropdownMenuItem>
|
|
503
|
-
</DropdownMenuGroup>
|
|
504
|
-
|
|
505
|
-
<DropdownMenuSeparator />
|
|
506
|
-
|
|
507
|
-
<DropdownMenuGroup>
|
|
508
|
-
<DropdownMenuItem>
|
|
509
|
-
Select All
|
|
510
|
-
<DropdownMenuShortcut>⌘A</DropdownMenuShortcut>
|
|
511
|
-
</DropdownMenuItem>
|
|
512
|
-
<DropdownMenuItem>
|
|
513
|
-
<SearchIcon className="h-4 w-4" />
|
|
514
|
-
Find
|
|
515
|
-
<DropdownMenuShortcut>⌘F</DropdownMenuShortcut>
|
|
516
|
-
</DropdownMenuItem>
|
|
517
|
-
</DropdownMenuGroup>
|
|
518
|
-
</DropdownMenuContent>
|
|
519
|
-
</DropdownMenu>
|
|
520
|
-
</div>
|
|
521
|
-
</div>
|
|
522
|
-
),
|
|
523
|
-
parameters: {
|
|
524
|
-
docs: {
|
|
525
|
-
description: {
|
|
526
|
-
story:
|
|
527
|
-
"Dropdown menu with keyboard shortcut indicators for common actions, organized with DropdownMenuGroup.",
|
|
528
|
-
},
|
|
529
|
-
},
|
|
530
|
-
},
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
// 5. Custom Styling
|
|
534
|
-
export const CustomStyling: Story = {
|
|
535
|
-
render: () => (
|
|
536
|
-
<div className="space-y-8">
|
|
537
|
-
<div className="text-center">
|
|
538
|
-
<h3 className="mb-2 font-medium text-white">Custom Styling</h3>
|
|
539
|
-
<p className="text-sm text-white/60">
|
|
540
|
-
Dropdown menus with custom styling using the classes prop
|
|
541
|
-
</p>
|
|
542
|
-
</div>
|
|
543
|
-
|
|
544
|
-
<div className="flex flex-wrap justify-center gap-4">
|
|
545
|
-
{/* Blue Theme */}
|
|
546
|
-
<DropdownMenu>
|
|
547
|
-
<DropdownMenuTrigger asChild>
|
|
548
|
-
<Button>Blue Theme</Button>
|
|
549
|
-
</DropdownMenuTrigger>
|
|
550
|
-
<DropdownMenuContent
|
|
551
|
-
classes={{
|
|
552
|
-
root: "bg-blue-900/40 border-blue-500/20",
|
|
553
|
-
border: "bg-gradient-to-r from-blue-500 to-cyan-500",
|
|
554
|
-
}}
|
|
555
|
-
>
|
|
556
|
-
<DropdownMenuGroup>
|
|
557
|
-
<DropdownMenuItem
|
|
558
|
-
classes={{
|
|
559
|
-
root: "text-blue-200 hover:bg-blue-500/20 focus:bg-blue-500/20",
|
|
560
|
-
}}
|
|
561
|
-
>
|
|
562
|
-
<TickIcon className="h-4 w-4" />
|
|
563
|
-
Blue Item
|
|
564
|
-
</DropdownMenuItem>
|
|
565
|
-
<DropdownMenuItem
|
|
566
|
-
classes={{
|
|
567
|
-
root: "text-blue-200 hover:bg-blue-500/20 focus:bg-blue-500/20",
|
|
568
|
-
}}
|
|
569
|
-
>
|
|
570
|
-
<AudioBarIcon className="h-4 w-4" />
|
|
571
|
-
Another Item
|
|
572
|
-
</DropdownMenuItem>
|
|
573
|
-
</DropdownMenuGroup>
|
|
574
|
-
</DropdownMenuContent>
|
|
575
|
-
</DropdownMenu>
|
|
576
|
-
|
|
577
|
-
{/* Green Theme */}
|
|
578
|
-
<DropdownMenu>
|
|
579
|
-
<DropdownMenuTrigger asChild>
|
|
580
|
-
<Button>Green Theme</Button>
|
|
581
|
-
</DropdownMenuTrigger>
|
|
582
|
-
<DropdownMenuContent
|
|
583
|
-
classes={{
|
|
584
|
-
root: "bg-green-900/40 border-green-500/20",
|
|
585
|
-
border: "bg-gradient-to-r from-green-500 to-emerald-500",
|
|
586
|
-
}}
|
|
587
|
-
>
|
|
588
|
-
<DropdownMenuGroup>
|
|
589
|
-
<DropdownMenuItem
|
|
590
|
-
classes={{
|
|
591
|
-
root: "text-green-200 hover:bg-green-500/20 focus:bg-green-500/20",
|
|
592
|
-
}}
|
|
593
|
-
>
|
|
594
|
-
<TickIcon className="h-4 w-4" />
|
|
595
|
-
Green Item
|
|
596
|
-
</DropdownMenuItem>
|
|
597
|
-
<DropdownMenuItem
|
|
598
|
-
classes={{
|
|
599
|
-
root: "text-green-200 hover:bg-green-500/20 focus:bg-green-500/20",
|
|
600
|
-
}}
|
|
601
|
-
>
|
|
602
|
-
<AudioBarIcon className="h-4 w-4" />
|
|
603
|
-
Success Action
|
|
604
|
-
</DropdownMenuItem>
|
|
605
|
-
</DropdownMenuGroup>
|
|
606
|
-
</DropdownMenuContent>
|
|
607
|
-
</DropdownMenu>
|
|
608
|
-
|
|
609
|
-
{/* Purple Theme */}
|
|
610
|
-
<DropdownMenu>
|
|
611
|
-
<DropdownMenuTrigger asChild>
|
|
612
|
-
<Button>Purple Theme</Button>
|
|
613
|
-
</DropdownMenuTrigger>
|
|
614
|
-
<DropdownMenuContent
|
|
615
|
-
classes={{
|
|
616
|
-
root: "bg-purple-900/40 border-purple-500/20",
|
|
617
|
-
border: "bg-gradient-to-r from-purple-500 to-pink-500",
|
|
618
|
-
}}
|
|
619
|
-
>
|
|
620
|
-
<DropdownMenuGroup>
|
|
621
|
-
<DropdownMenuItem
|
|
622
|
-
classes={{
|
|
623
|
-
root: "text-purple-200 hover:bg-purple-500/20 focus:bg-purple-500/20",
|
|
624
|
-
}}
|
|
625
|
-
>
|
|
626
|
-
<TickIcon className="h-4 w-4" />
|
|
627
|
-
Purple Item
|
|
628
|
-
</DropdownMenuItem>
|
|
629
|
-
<DropdownMenuItem
|
|
630
|
-
classes={{
|
|
631
|
-
root: "text-purple-200 hover:bg-purple-500/20 focus:bg-purple-500/20",
|
|
632
|
-
}}
|
|
633
|
-
>
|
|
634
|
-
<AudioBarIcon className="h-4 w-4" />
|
|
635
|
-
Creative Action
|
|
636
|
-
</DropdownMenuItem>
|
|
637
|
-
</DropdownMenuGroup>
|
|
638
|
-
</DropdownMenuContent>
|
|
639
|
-
</DropdownMenu>
|
|
640
164
|
</div>
|
|
641
|
-
</div>
|
|
642
|
-
),
|
|
643
|
-
parameters: {
|
|
644
|
-
docs: {
|
|
645
|
-
description: {
|
|
646
|
-
story:
|
|
647
|
-
"Custom styled dropdown menus using the classes prop for theme variations with logical grouping.",
|
|
648
|
-
},
|
|
649
|
-
},
|
|
650
|
-
},
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// 6. Complex Menu Example
|
|
654
|
-
export const ComplexMenu: Story = {
|
|
655
|
-
render: () => {
|
|
656
|
-
const [bookmarked, setBookmarked] = useState(false)
|
|
657
|
-
const [notifications, setNotifications] = useState(true)
|
|
658
|
-
const [viewMode, setViewMode] = useState("grid")
|
|
659
165
|
|
|
660
|
-
|
|
661
|
-
<div className="space-y-
|
|
662
|
-
<
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
grouping
|
|
667
|
-
</p>
|
|
668
|
-
</div>
|
|
669
|
-
|
|
670
|
-
<div className="flex justify-center">
|
|
166
|
+
{/* Group + separator */}
|
|
167
|
+
<div className="space-y-3">
|
|
168
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
169
|
+
Groups & Separators
|
|
170
|
+
</h4>
|
|
171
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
671
172
|
<DropdownMenu>
|
|
672
173
|
<DropdownMenuTrigger asChild>
|
|
673
|
-
<Button
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
174
|
+
<Button
|
|
175
|
+
variant="outline"
|
|
176
|
+
innerClassName="flex items-center gap-2"
|
|
177
|
+
>
|
|
178
|
+
Grouped
|
|
179
|
+
<ChevronDownIcon className="size-4" />
|
|
677
180
|
</Button>
|
|
678
181
|
</DropdownMenuTrigger>
|
|
679
|
-
<DropdownMenuContent className="w-
|
|
680
|
-
|
|
681
|
-
<DropdownMenuLabel>Quick Actions</DropdownMenuLabel>
|
|
182
|
+
<DropdownMenuContent className="w-52">
|
|
183
|
+
<DropdownMenuLabel>File</DropdownMenuLabel>
|
|
682
184
|
<DropdownMenuSeparator />
|
|
683
185
|
<DropdownMenuGroup>
|
|
684
186
|
<DropdownMenuItem>
|
|
685
|
-
<
|
|
686
|
-
|
|
687
|
-
<DropdownMenuShortcut>⌘
|
|
187
|
+
<FileTextIcon />
|
|
188
|
+
New
|
|
189
|
+
<DropdownMenuShortcut>⌘N</DropdownMenuShortcut>
|
|
688
190
|
</DropdownMenuItem>
|
|
689
191
|
<DropdownMenuItem>
|
|
690
|
-
<
|
|
691
|
-
|
|
692
|
-
<DropdownMenuShortcut>⌘
|
|
192
|
+
<UploadIcon />
|
|
193
|
+
Upload
|
|
194
|
+
<DropdownMenuShortcut>⌘U</DropdownMenuShortcut>
|
|
693
195
|
</DropdownMenuItem>
|
|
196
|
+
</DropdownMenuGroup>
|
|
197
|
+
<DropdownMenuSeparator />
|
|
198
|
+
<DropdownMenuLabel>Edit</DropdownMenuLabel>
|
|
199
|
+
<DropdownMenuSeparator />
|
|
200
|
+
<DropdownMenuGroup>
|
|
694
201
|
<DropdownMenuItem>
|
|
695
|
-
<
|
|
696
|
-
|
|
697
|
-
<DropdownMenuShortcut
|
|
202
|
+
<EditBigIcon />
|
|
203
|
+
Rename
|
|
204
|
+
<DropdownMenuShortcut>⌘R</DropdownMenuShortcut>
|
|
205
|
+
</DropdownMenuItem>
|
|
206
|
+
<DropdownMenuItem>
|
|
207
|
+
<DownloadIcon />
|
|
208
|
+
Download
|
|
209
|
+
<DropdownMenuShortcut>⌘D</DropdownMenuShortcut>
|
|
698
210
|
</DropdownMenuItem>
|
|
699
211
|
</DropdownMenuGroup>
|
|
212
|
+
</DropdownMenuContent>
|
|
213
|
+
</DropdownMenu>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
700
216
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
217
|
+
{/* Checkbox items */}
|
|
218
|
+
<div className="space-y-3">
|
|
219
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
220
|
+
Checkbox Items
|
|
221
|
+
</h4>
|
|
222
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
223
|
+
<DropdownMenu>
|
|
224
|
+
<DropdownMenuTrigger asChild>
|
|
225
|
+
<Button
|
|
226
|
+
variant="outline"
|
|
227
|
+
innerClassName="flex items-center gap-2"
|
|
228
|
+
>
|
|
229
|
+
Preferences
|
|
230
|
+
<ChevronDownIcon className="size-4" />
|
|
231
|
+
</Button>
|
|
232
|
+
</DropdownMenuTrigger>
|
|
233
|
+
<DropdownMenuContent>
|
|
234
|
+
<DropdownMenuLabel>Display</DropdownMenuLabel>
|
|
705
235
|
<DropdownMenuSeparator />
|
|
706
236
|
<DropdownMenuGroup>
|
|
707
|
-
<DropdownMenuCheckboxItem
|
|
708
|
-
|
|
709
|
-
onCheckedChange={setBookmarked}
|
|
710
|
-
>
|
|
711
|
-
<TickIcon className="h-4 w-4" />
|
|
712
|
-
Bookmark
|
|
237
|
+
<DropdownMenuCheckboxItem checked>
|
|
238
|
+
Show artwork
|
|
713
239
|
</DropdownMenuCheckboxItem>
|
|
714
|
-
<DropdownMenuCheckboxItem
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
>
|
|
718
|
-
|
|
719
|
-
Enable Notifications
|
|
240
|
+
<DropdownMenuCheckboxItem checked={false}>
|
|
241
|
+
Show lyrics
|
|
242
|
+
</DropdownMenuCheckboxItem>
|
|
243
|
+
<DropdownMenuCheckboxItem checked>
|
|
244
|
+
Show queue
|
|
720
245
|
</DropdownMenuCheckboxItem>
|
|
721
246
|
</DropdownMenuGroup>
|
|
247
|
+
</DropdownMenuContent>
|
|
248
|
+
</DropdownMenu>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
722
251
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
252
|
+
{/* Radio items */}
|
|
253
|
+
<div className="space-y-3">
|
|
254
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
255
|
+
Radio Items
|
|
256
|
+
</h4>
|
|
257
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
258
|
+
<DropdownMenu>
|
|
259
|
+
<DropdownMenuTrigger asChild>
|
|
260
|
+
<Button
|
|
261
|
+
variant="outline"
|
|
262
|
+
innerClassName="flex items-center gap-2"
|
|
263
|
+
>
|
|
264
|
+
Sort by
|
|
265
|
+
<AngleDownIcon className="size-4" />
|
|
266
|
+
</Button>
|
|
267
|
+
</DropdownMenuTrigger>
|
|
268
|
+
<DropdownMenuContent>
|
|
269
|
+
<DropdownMenuLabel>Sort Order</DropdownMenuLabel>
|
|
727
270
|
<DropdownMenuSeparator />
|
|
728
271
|
<DropdownMenuGroup>
|
|
729
|
-
<DropdownMenuRadioGroup
|
|
730
|
-
value=
|
|
731
|
-
|
|
732
|
-
>
|
|
733
|
-
<DropdownMenuRadioItem value="grid">
|
|
734
|
-
Grid View
|
|
272
|
+
<DropdownMenuRadioGroup value="recent">
|
|
273
|
+
<DropdownMenuRadioItem value="recent">
|
|
274
|
+
Most Recent
|
|
735
275
|
</DropdownMenuRadioItem>
|
|
736
|
-
<DropdownMenuRadioItem value="
|
|
737
|
-
|
|
276
|
+
<DropdownMenuRadioItem value="alpha">
|
|
277
|
+
Alphabetical
|
|
738
278
|
</DropdownMenuRadioItem>
|
|
739
|
-
<DropdownMenuRadioItem value="
|
|
740
|
-
|
|
279
|
+
<DropdownMenuRadioItem value="plays">
|
|
280
|
+
Most Played
|
|
741
281
|
</DropdownMenuRadioItem>
|
|
742
282
|
</DropdownMenuRadioGroup>
|
|
743
283
|
</DropdownMenuGroup>
|
|
284
|
+
</DropdownMenuContent>
|
|
285
|
+
</DropdownMenu>
|
|
286
|
+
</div>
|
|
287
|
+
</div>
|
|
744
288
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
289
|
+
{/* Sub-menus */}
|
|
290
|
+
<div className="space-y-3">
|
|
291
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
292
|
+
Nested Sub-menu
|
|
293
|
+
</h4>
|
|
294
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
295
|
+
<DropdownMenu>
|
|
296
|
+
<DropdownMenuTrigger asChild>
|
|
297
|
+
<Button
|
|
298
|
+
variant="outline"
|
|
299
|
+
innerClassName="flex items-center gap-2"
|
|
300
|
+
>
|
|
301
|
+
<PlusIcon className="size-4" />
|
|
302
|
+
Add to…
|
|
303
|
+
</Button>
|
|
304
|
+
</DropdownMenuTrigger>
|
|
305
|
+
<DropdownMenuContent>
|
|
748
306
|
<DropdownMenuGroup>
|
|
749
307
|
<DropdownMenuSub>
|
|
750
308
|
<DropdownMenuSubTrigger>
|
|
751
|
-
<
|
|
752
|
-
|
|
309
|
+
<AudioBarIcon />
|
|
310
|
+
Playlist
|
|
753
311
|
</DropdownMenuSubTrigger>
|
|
754
312
|
<DropdownMenuSubContent>
|
|
755
313
|
<DropdownMenuGroup>
|
|
756
314
|
<DropdownMenuItem>
|
|
757
|
-
<
|
|
758
|
-
|
|
315
|
+
<MusicalNoteIcon />
|
|
316
|
+
Late Night Drive
|
|
759
317
|
</DropdownMenuItem>
|
|
760
318
|
<DropdownMenuItem>
|
|
761
|
-
<
|
|
762
|
-
|
|
319
|
+
<MusicalNoteIcon />
|
|
320
|
+
Focus Mode
|
|
763
321
|
</DropdownMenuItem>
|
|
764
322
|
<DropdownMenuItem>
|
|
765
|
-
<
|
|
766
|
-
|
|
323
|
+
<MusicalNoteIcon />
|
|
324
|
+
Morning Energy
|
|
767
325
|
</DropdownMenuItem>
|
|
768
326
|
</DropdownMenuGroup>
|
|
769
327
|
<DropdownMenuSeparator />
|
|
770
328
|
<DropdownMenuGroup>
|
|
771
329
|
<DropdownMenuItem>
|
|
772
|
-
<PlusIcon
|
|
773
|
-
|
|
330
|
+
<PlusIcon />
|
|
331
|
+
New Playlist…
|
|
774
332
|
</DropdownMenuItem>
|
|
775
333
|
</DropdownMenuGroup>
|
|
776
334
|
</DropdownMenuSubContent>
|
|
777
335
|
</DropdownMenuSub>
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
{/* Danger Group */}
|
|
783
|
-
<DropdownMenuGroup>
|
|
784
|
-
<DropdownMenuItem variant="destructive">
|
|
785
|
-
<TrashIcon className="h-4 w-4" />
|
|
786
|
-
Delete Item
|
|
787
|
-
<DropdownMenuShortcut>⌘⌫</DropdownMenuShortcut>
|
|
336
|
+
<DropdownMenuItem>
|
|
337
|
+
<AudioBarIcon />
|
|
338
|
+
Queue
|
|
339
|
+
<DropdownMenuShortcut>⌘Q</DropdownMenuShortcut>
|
|
788
340
|
</DropdownMenuItem>
|
|
789
341
|
</DropdownMenuGroup>
|
|
790
342
|
</DropdownMenuContent>
|
|
791
343
|
</DropdownMenu>
|
|
792
344
|
</div>
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
),
|
|
348
|
+
parameters: {
|
|
349
|
+
docs: {
|
|
350
|
+
description: {
|
|
351
|
+
story:
|
|
352
|
+
"All item type configurations displayed in separate labeled groups: basic items with keyboard shortcuts, inset items, group+separator layouts, checkbox items, radio items, and a nested sub-menu trigger. Each section can be opened independently to inspect how that item type renders.",
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// ─── Interactive ──────────────────────────────────────────────────────────────
|
|
359
|
+
|
|
360
|
+
export const Interactive: Story = {
|
|
361
|
+
render: () => {
|
|
362
|
+
const [showArtwork, setShowArtwork] = useState(true)
|
|
363
|
+
const [showLyrics, setShowLyrics] = useState(false)
|
|
364
|
+
const [showQueue, setShowQueue] = useState(true)
|
|
365
|
+
const [audioQuality, setAudioQuality] = useState("high")
|
|
366
|
+
const [sortOrder, setSortOrder] = useState("recent")
|
|
367
|
+
const [lastAction, setLastAction] = useState<string | null>(null)
|
|
368
|
+
|
|
369
|
+
const qualityLabels: Record<string, string> = {
|
|
370
|
+
low: "Normal (96 kbps)",
|
|
371
|
+
high: "High (320 kbps)",
|
|
372
|
+
lossless: "Lossless (FLAC)",
|
|
373
|
+
}
|
|
374
|
+
const sortLabels: Record<string, string> = {
|
|
375
|
+
recent: "Most Recent",
|
|
376
|
+
alpha: "Alphabetical",
|
|
377
|
+
plays: "Most Played",
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return (
|
|
381
|
+
<div className="w-full p-8">
|
|
382
|
+
<div className="mx-auto max-w-3xl space-y-6">
|
|
383
|
+
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
|
384
|
+
{/* Controls panel */}
|
|
385
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-5 rounded-xl border p-5">
|
|
386
|
+
<p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
|
|
387
|
+
Live State
|
|
388
|
+
</p>
|
|
389
|
+
|
|
390
|
+
<div className="space-y-2">
|
|
391
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
392
|
+
Display Toggles
|
|
393
|
+
</p>
|
|
394
|
+
<div className="space-y-1">
|
|
395
|
+
{[
|
|
396
|
+
{ label: "Artwork", value: showArtwork },
|
|
397
|
+
{ label: "Lyrics", value: showLyrics },
|
|
398
|
+
{ label: "Queue", value: showQueue },
|
|
399
|
+
].map(({ label, value }) => (
|
|
400
|
+
<div key={label} className="flex justify-between">
|
|
401
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
402
|
+
{label}
|
|
403
|
+
</span>
|
|
404
|
+
<span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
|
|
405
|
+
{value ? "On" : "Off"}
|
|
406
|
+
</span>
|
|
407
|
+
</div>
|
|
408
|
+
))}
|
|
409
|
+
</div>
|
|
410
|
+
</div>
|
|
411
|
+
|
|
412
|
+
<div className="border-fm-divider-secondary border-t pt-4" />
|
|
413
|
+
|
|
414
|
+
<div className="space-y-1">
|
|
415
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
416
|
+
Audio Quality
|
|
417
|
+
</p>
|
|
418
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
419
|
+
{qualityLabels[audioQuality]}
|
|
420
|
+
</p>
|
|
421
|
+
</div>
|
|
422
|
+
|
|
423
|
+
<div className="space-y-1">
|
|
424
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
425
|
+
Sort Order
|
|
426
|
+
</p>
|
|
427
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
428
|
+
{sortLabels[sortOrder]}
|
|
429
|
+
</p>
|
|
430
|
+
</div>
|
|
431
|
+
|
|
432
|
+
<div className="border-fm-divider-secondary border-t pt-4" />
|
|
433
|
+
|
|
434
|
+
<div className="space-y-1">
|
|
435
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
436
|
+
Last Action
|
|
437
|
+
</p>
|
|
438
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md truncate font-medium">
|
|
439
|
+
{lastAction ?? "—"}
|
|
440
|
+
</p>
|
|
441
|
+
</div>
|
|
442
|
+
</div>
|
|
793
443
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
444
|
+
{/* Preview stage */}
|
|
445
|
+
<div className="flex flex-col gap-4 lg:col-span-2">
|
|
446
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
447
|
+
{/* Checkbox preferences */}
|
|
448
|
+
<DropdownMenu>
|
|
449
|
+
<DropdownMenuTrigger asChild>
|
|
450
|
+
<Button
|
|
451
|
+
variant="outline"
|
|
452
|
+
innerClassName="flex items-center gap-2"
|
|
453
|
+
>
|
|
454
|
+
Display
|
|
455
|
+
<ChevronDownIcon className="size-4" />
|
|
456
|
+
</Button>
|
|
457
|
+
</DropdownMenuTrigger>
|
|
458
|
+
<DropdownMenuContent>
|
|
459
|
+
<DropdownMenuLabel>Display Options</DropdownMenuLabel>
|
|
460
|
+
<DropdownMenuSeparator />
|
|
461
|
+
<DropdownMenuGroup>
|
|
462
|
+
<DropdownMenuCheckboxItem
|
|
463
|
+
checked={showArtwork}
|
|
464
|
+
onCheckedChange={(v) => {
|
|
465
|
+
setShowArtwork(v)
|
|
466
|
+
setLastAction(`Show Artwork → ${v ? "On" : "Off"}`)
|
|
467
|
+
}}
|
|
468
|
+
>
|
|
469
|
+
Show Artwork
|
|
470
|
+
</DropdownMenuCheckboxItem>
|
|
471
|
+
<DropdownMenuCheckboxItem
|
|
472
|
+
checked={showLyrics}
|
|
473
|
+
onCheckedChange={(v) => {
|
|
474
|
+
setShowLyrics(v)
|
|
475
|
+
setLastAction(`Show Lyrics → ${v ? "On" : "Off"}`)
|
|
476
|
+
}}
|
|
477
|
+
>
|
|
478
|
+
Show Lyrics
|
|
479
|
+
</DropdownMenuCheckboxItem>
|
|
480
|
+
<DropdownMenuCheckboxItem
|
|
481
|
+
checked={showQueue}
|
|
482
|
+
onCheckedChange={(v) => {
|
|
483
|
+
setShowQueue(v)
|
|
484
|
+
setLastAction(`Show Queue → ${v ? "On" : "Off"}`)
|
|
485
|
+
}}
|
|
486
|
+
>
|
|
487
|
+
Show Queue
|
|
488
|
+
</DropdownMenuCheckboxItem>
|
|
489
|
+
</DropdownMenuGroup>
|
|
490
|
+
</DropdownMenuContent>
|
|
491
|
+
</DropdownMenu>
|
|
492
|
+
|
|
493
|
+
{/* Radio — audio quality */}
|
|
494
|
+
<DropdownMenu>
|
|
495
|
+
<DropdownMenuTrigger asChild>
|
|
496
|
+
<Button
|
|
497
|
+
variant="outline"
|
|
498
|
+
innerClassName="flex items-center gap-2"
|
|
499
|
+
>
|
|
500
|
+
Quality: {qualityLabels[audioQuality].split(" ")[0]}
|
|
501
|
+
<AngleDownIcon className="size-4" />
|
|
502
|
+
</Button>
|
|
503
|
+
</DropdownMenuTrigger>
|
|
504
|
+
<DropdownMenuContent>
|
|
505
|
+
<DropdownMenuLabel>Audio Quality</DropdownMenuLabel>
|
|
506
|
+
<DropdownMenuSeparator />
|
|
507
|
+
<DropdownMenuGroup>
|
|
508
|
+
<DropdownMenuRadioGroup
|
|
509
|
+
value={audioQuality}
|
|
510
|
+
onValueChange={(v) => {
|
|
511
|
+
setAudioQuality(v)
|
|
512
|
+
setLastAction(`Quality → ${qualityLabels[v]}`)
|
|
513
|
+
}}
|
|
514
|
+
>
|
|
515
|
+
<DropdownMenuRadioItem value="low">
|
|
516
|
+
Normal (96 kbps)
|
|
517
|
+
</DropdownMenuRadioItem>
|
|
518
|
+
<DropdownMenuRadioItem value="high">
|
|
519
|
+
High (320 kbps)
|
|
520
|
+
</DropdownMenuRadioItem>
|
|
521
|
+
<DropdownMenuRadioItem value="lossless">
|
|
522
|
+
Lossless (FLAC)
|
|
523
|
+
</DropdownMenuRadioItem>
|
|
524
|
+
</DropdownMenuRadioGroup>
|
|
525
|
+
</DropdownMenuGroup>
|
|
526
|
+
</DropdownMenuContent>
|
|
527
|
+
</DropdownMenu>
|
|
528
|
+
|
|
529
|
+
{/* Radio — sort order */}
|
|
530
|
+
<DropdownMenu>
|
|
531
|
+
<DropdownMenuTrigger asChild>
|
|
532
|
+
<Button
|
|
533
|
+
variant="outline"
|
|
534
|
+
innerClassName="flex items-center gap-2"
|
|
535
|
+
>
|
|
536
|
+
Sort
|
|
537
|
+
<AngleDownIcon className="size-4" />
|
|
538
|
+
</Button>
|
|
539
|
+
</DropdownMenuTrigger>
|
|
540
|
+
<DropdownMenuContent>
|
|
541
|
+
<DropdownMenuLabel>Sort Library By</DropdownMenuLabel>
|
|
542
|
+
<DropdownMenuSeparator />
|
|
543
|
+
<DropdownMenuGroup>
|
|
544
|
+
<DropdownMenuRadioGroup
|
|
545
|
+
value={sortOrder}
|
|
546
|
+
onValueChange={(v) => {
|
|
547
|
+
setSortOrder(v)
|
|
548
|
+
setLastAction(`Sort → ${sortLabels[v]}`)
|
|
549
|
+
}}
|
|
550
|
+
>
|
|
551
|
+
<DropdownMenuRadioItem value="recent">
|
|
552
|
+
Most Recent
|
|
553
|
+
</DropdownMenuRadioItem>
|
|
554
|
+
<DropdownMenuRadioItem value="alpha">
|
|
555
|
+
Alphabetical
|
|
556
|
+
</DropdownMenuRadioItem>
|
|
557
|
+
<DropdownMenuRadioItem value="plays">
|
|
558
|
+
Most Played
|
|
559
|
+
</DropdownMenuRadioItem>
|
|
560
|
+
</DropdownMenuRadioGroup>
|
|
561
|
+
</DropdownMenuGroup>
|
|
562
|
+
</DropdownMenuContent>
|
|
563
|
+
</DropdownMenu>
|
|
564
|
+
</div>
|
|
565
|
+
|
|
566
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
|
|
567
|
+
<code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">
|
|
568
|
+
Checkbox and radio selections update state immediately — open
|
|
569
|
+
the left panel to see live values.
|
|
570
|
+
</code>
|
|
571
|
+
</div>
|
|
804
572
|
</div>
|
|
805
573
|
</div>
|
|
806
574
|
</div>
|
|
@@ -811,399 +579,256 @@ export const ComplexMenu: Story = {
|
|
|
811
579
|
docs: {
|
|
812
580
|
description: {
|
|
813
581
|
story:
|
|
814
|
-
"
|
|
582
|
+
"Stateful dropdown story demonstrating live checkbox and radio item selection. Three separate menus manage display toggle preferences, audio quality (radio single-select), and library sort order (radio single-select). The left panel reflects every state change in real time so the interaction loop is visible without opening browser DevTools.",
|
|
815
583
|
},
|
|
816
584
|
},
|
|
817
585
|
},
|
|
818
586
|
}
|
|
819
587
|
|
|
820
|
-
//
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
<h3 className="mb-2 font-medium text-white">Positioning Examples</h3>
|
|
826
|
-
<p className="text-sm text-white/60">
|
|
827
|
-
Different positioning and alignment options with grouped content
|
|
828
|
-
</p>
|
|
829
|
-
</div>
|
|
588
|
+
// ─── UseCases ─────────────────────────────────────────────────────────────────
|
|
589
|
+
|
|
590
|
+
export const UseCases: Story = {
|
|
591
|
+
render: () => {
|
|
592
|
+
const [liked, setLiked] = useState(false)
|
|
830
593
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
594
|
+
return (
|
|
595
|
+
<div className="mx-auto max-w-3xl space-y-8 p-8">
|
|
596
|
+
{/* 1 — Track action menu */}
|
|
597
|
+
<div className="space-y-3">
|
|
598
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
599
|
+
Track Action Menu
|
|
836
600
|
</h4>
|
|
837
|
-
<div className="flex
|
|
601
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary flex items-center justify-between rounded-xl border p-4">
|
|
602
|
+
<div className="flex items-center gap-3">
|
|
603
|
+
<div className="bg-fm-surface-tertiary size-10 shrink-0 rounded-lg" />
|
|
604
|
+
<div className="space-y-0.5">
|
|
605
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
606
|
+
Midnight Echoes
|
|
607
|
+
</p>
|
|
608
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
609
|
+
Luna Vex · 4:12
|
|
610
|
+
</p>
|
|
611
|
+
</div>
|
|
612
|
+
</div>
|
|
838
613
|
<DropdownMenu>
|
|
839
614
|
<DropdownMenuTrigger asChild>
|
|
840
|
-
<Button variant="
|
|
841
|
-
|
|
615
|
+
<Button variant="text" size="sm">
|
|
616
|
+
<VerticalMenuIcon />
|
|
842
617
|
</Button>
|
|
843
618
|
</DropdownMenuTrigger>
|
|
844
|
-
<DropdownMenuContent align="
|
|
619
|
+
<DropdownMenuContent align="end" className="w-52">
|
|
845
620
|
<DropdownMenuGroup>
|
|
846
|
-
<DropdownMenuItem>
|
|
847
|
-
|
|
621
|
+
<DropdownMenuItem>
|
|
622
|
+
<AudioBarIcon />
|
|
623
|
+
Add to Queue
|
|
624
|
+
<DropdownMenuShortcut>⌘Q</DropdownMenuShortcut>
|
|
625
|
+
</DropdownMenuItem>
|
|
626
|
+
<DropdownMenuItem onSelect={() => setLiked((v) => !v)}>
|
|
627
|
+
<HeartIcon />
|
|
628
|
+
{liked ? "Unlike Track" : "Like Track"}
|
|
629
|
+
<DropdownMenuShortcut>⌘L</DropdownMenuShortcut>
|
|
630
|
+
</DropdownMenuItem>
|
|
848
631
|
</DropdownMenuGroup>
|
|
849
|
-
|
|
850
|
-
</DropdownMenu>
|
|
851
|
-
|
|
852
|
-
<DropdownMenu>
|
|
853
|
-
<DropdownMenuTrigger asChild>
|
|
854
|
-
<Button variant="outline" size="sm">
|
|
855
|
-
Align Center
|
|
856
|
-
</Button>
|
|
857
|
-
</DropdownMenuTrigger>
|
|
858
|
-
<DropdownMenuContent align="center">
|
|
632
|
+
<DropdownMenuSeparator />
|
|
859
633
|
<DropdownMenuGroup>
|
|
860
|
-
<
|
|
861
|
-
|
|
634
|
+
<DropdownMenuSub>
|
|
635
|
+
<DropdownMenuSubTrigger>
|
|
636
|
+
<MusicalNoteIcon />
|
|
637
|
+
Add to Playlist
|
|
638
|
+
</DropdownMenuSubTrigger>
|
|
639
|
+
<DropdownMenuSubContent>
|
|
640
|
+
<DropdownMenuGroup>
|
|
641
|
+
<DropdownMenuItem>
|
|
642
|
+
<CircleTickIcon />
|
|
643
|
+
Late Night Drive
|
|
644
|
+
</DropdownMenuItem>
|
|
645
|
+
<DropdownMenuItem>
|
|
646
|
+
<CircleTickIcon />
|
|
647
|
+
Focus Mode
|
|
648
|
+
</DropdownMenuItem>
|
|
649
|
+
<DropdownMenuItem>
|
|
650
|
+
<CircleTickIcon />
|
|
651
|
+
Morning Energy
|
|
652
|
+
</DropdownMenuItem>
|
|
653
|
+
</DropdownMenuGroup>
|
|
654
|
+
<DropdownMenuSeparator />
|
|
655
|
+
<DropdownMenuGroup>
|
|
656
|
+
<DropdownMenuItem>
|
|
657
|
+
<PlusIcon />
|
|
658
|
+
New Playlist…
|
|
659
|
+
</DropdownMenuItem>
|
|
660
|
+
</DropdownMenuGroup>
|
|
661
|
+
</DropdownMenuSubContent>
|
|
662
|
+
</DropdownMenuSub>
|
|
663
|
+
<DropdownMenuItem>
|
|
664
|
+
<ShareIcon />
|
|
665
|
+
Share Track
|
|
666
|
+
<DropdownMenuShortcut>⌘⇧S</DropdownMenuShortcut>
|
|
667
|
+
</DropdownMenuItem>
|
|
668
|
+
<DropdownMenuItem>
|
|
669
|
+
<DownloadIcon />
|
|
670
|
+
Download Offline
|
|
671
|
+
<DropdownMenuShortcut>⌘D</DropdownMenuShortcut>
|
|
672
|
+
</DropdownMenuItem>
|
|
862
673
|
</DropdownMenuGroup>
|
|
863
|
-
|
|
864
|
-
</DropdownMenu>
|
|
865
|
-
|
|
866
|
-
<DropdownMenu>
|
|
867
|
-
<DropdownMenuTrigger asChild>
|
|
868
|
-
<Button variant="outline" size="sm">
|
|
869
|
-
Align End
|
|
870
|
-
</Button>
|
|
871
|
-
</DropdownMenuTrigger>
|
|
872
|
-
<DropdownMenuContent align="end">
|
|
674
|
+
<DropdownMenuSeparator />
|
|
873
675
|
<DropdownMenuGroup>
|
|
874
|
-
<DropdownMenuItem
|
|
875
|
-
|
|
676
|
+
<DropdownMenuItem variant="destructive">
|
|
677
|
+
<TrashIcon />
|
|
678
|
+
Remove from Library
|
|
679
|
+
</DropdownMenuItem>
|
|
876
680
|
</DropdownMenuGroup>
|
|
877
681
|
</DropdownMenuContent>
|
|
878
682
|
</DropdownMenu>
|
|
879
683
|
</div>
|
|
684
|
+
{liked && (
|
|
685
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm text-center">
|
|
686
|
+
Track liked — heart state toggles via the menu above.
|
|
687
|
+
</p>
|
|
688
|
+
)}
|
|
880
689
|
</div>
|
|
881
690
|
|
|
882
|
-
{/*
|
|
883
|
-
<div className="space-y-
|
|
884
|
-
<h4 className="text-
|
|
885
|
-
|
|
691
|
+
{/* 2 — User account menu */}
|
|
692
|
+
<div className="space-y-3">
|
|
693
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
694
|
+
User Account Menu
|
|
695
|
+
</h4>
|
|
696
|
+
<div className="flex justify-center">
|
|
886
697
|
<DropdownMenu>
|
|
887
698
|
<DropdownMenuTrigger asChild>
|
|
888
|
-
<Button
|
|
889
|
-
|
|
699
|
+
<Button
|
|
700
|
+
variant="outline"
|
|
701
|
+
innerClassName="flex items-center gap-2"
|
|
702
|
+
>
|
|
703
|
+
<div className="bg-fm-surface-tertiary size-6 rounded-full" />
|
|
704
|
+
Alex Rivera
|
|
705
|
+
<ChevronDownIcon className="size-4" />
|
|
890
706
|
</Button>
|
|
891
707
|
</DropdownMenuTrigger>
|
|
892
|
-
<DropdownMenuContent
|
|
708
|
+
<DropdownMenuContent align="end" className="w-52">
|
|
709
|
+
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
|
710
|
+
<DropdownMenuSeparator />
|
|
893
711
|
<DropdownMenuGroup>
|
|
894
|
-
<DropdownMenuItem>
|
|
895
|
-
|
|
712
|
+
<DropdownMenuItem>
|
|
713
|
+
<EyeOpenIcon />
|
|
714
|
+
View Profile
|
|
715
|
+
<DropdownMenuShortcut>⌘P</DropdownMenuShortcut>
|
|
716
|
+
</DropdownMenuItem>
|
|
717
|
+
<DropdownMenuItem>
|
|
718
|
+
<StarIcon />
|
|
719
|
+
Subscription
|
|
720
|
+
</DropdownMenuItem>
|
|
721
|
+
<DropdownMenuItem>
|
|
722
|
+
<MaintenanceIcon />
|
|
723
|
+
Settings
|
|
724
|
+
<DropdownMenuShortcut>⌘,</DropdownMenuShortcut>
|
|
725
|
+
</DropdownMenuItem>
|
|
896
726
|
</DropdownMenuGroup>
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
</DropdownMenuTrigger>
|
|
906
|
-
<DropdownMenuContent>
|
|
727
|
+
<DropdownMenuSeparator />
|
|
728
|
+
<DropdownMenuGroup>
|
|
729
|
+
<DropdownMenuItem>
|
|
730
|
+
<SearchIcon />
|
|
731
|
+
Help & Support
|
|
732
|
+
</DropdownMenuItem>
|
|
733
|
+
</DropdownMenuGroup>
|
|
734
|
+
<DropdownMenuSeparator />
|
|
907
735
|
<DropdownMenuGroup>
|
|
908
|
-
<DropdownMenuItem
|
|
909
|
-
|
|
736
|
+
<DropdownMenuItem variant="destructive">
|
|
737
|
+
Log Out
|
|
738
|
+
<DropdownMenuShortcut>⌘⇧Q</DropdownMenuShortcut>
|
|
739
|
+
</DropdownMenuItem>
|
|
910
740
|
</DropdownMenuGroup>
|
|
911
741
|
</DropdownMenuContent>
|
|
912
742
|
</DropdownMenu>
|
|
743
|
+
</div>
|
|
744
|
+
</div>
|
|
913
745
|
|
|
746
|
+
{/* 3 — Settings context menu */}
|
|
747
|
+
<div className="space-y-3">
|
|
748
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
749
|
+
Settings Context Menu
|
|
750
|
+
</h4>
|
|
751
|
+
<div className="flex justify-center">
|
|
914
752
|
<DropdownMenu>
|
|
915
753
|
<DropdownMenuTrigger asChild>
|
|
916
|
-
<Button
|
|
917
|
-
|
|
754
|
+
<Button
|
|
755
|
+
variant="outline"
|
|
756
|
+
innerClassName="flex items-center gap-2"
|
|
757
|
+
>
|
|
758
|
+
<MaintenanceIcon className="size-4" />
|
|
759
|
+
Settings
|
|
760
|
+
<AngleDownIcon className="size-4" />
|
|
918
761
|
</Button>
|
|
919
762
|
</DropdownMenuTrigger>
|
|
920
|
-
<DropdownMenuContent
|
|
763
|
+
<DropdownMenuContent className="w-56">
|
|
764
|
+
<DropdownMenuLabel>Application</DropdownMenuLabel>
|
|
765
|
+
<DropdownMenuSeparator />
|
|
766
|
+
<DropdownMenuGroup>
|
|
767
|
+
<DropdownMenuSub>
|
|
768
|
+
<DropdownMenuSubTrigger>
|
|
769
|
+
<AudioBarIcon />
|
|
770
|
+
Audio Settings
|
|
771
|
+
</DropdownMenuSubTrigger>
|
|
772
|
+
<DropdownMenuSubContent>
|
|
773
|
+
<DropdownMenuGroup>
|
|
774
|
+
<DropdownMenuItem>
|
|
775
|
+
Equaliser
|
|
776
|
+
<DropdownMenuShortcut>⌘E</DropdownMenuShortcut>
|
|
777
|
+
</DropdownMenuItem>
|
|
778
|
+
<DropdownMenuItem>Crossfade</DropdownMenuItem>
|
|
779
|
+
<DropdownMenuItem>Normalisation</DropdownMenuItem>
|
|
780
|
+
</DropdownMenuGroup>
|
|
781
|
+
</DropdownMenuSubContent>
|
|
782
|
+
</DropdownMenuSub>
|
|
783
|
+
<DropdownMenuSub>
|
|
784
|
+
<DropdownMenuSubTrigger>
|
|
785
|
+
<MusicalNoteIcon />
|
|
786
|
+
Library Settings
|
|
787
|
+
</DropdownMenuSubTrigger>
|
|
788
|
+
<DropdownMenuSubContent>
|
|
789
|
+
<DropdownMenuGroup>
|
|
790
|
+
<DropdownMenuItem>
|
|
791
|
+
<UploadIcon />
|
|
792
|
+
Import Music
|
|
793
|
+
</DropdownMenuItem>
|
|
794
|
+
<DropdownMenuItem>
|
|
795
|
+
<EditBigIcon />
|
|
796
|
+
Manage Storage
|
|
797
|
+
</DropdownMenuItem>
|
|
798
|
+
</DropdownMenuGroup>
|
|
799
|
+
</DropdownMenuSubContent>
|
|
800
|
+
</DropdownMenuSub>
|
|
801
|
+
</DropdownMenuGroup>
|
|
802
|
+
<DropdownMenuSeparator />
|
|
921
803
|
<DropdownMenuGroup>
|
|
922
|
-
<DropdownMenuItem>
|
|
923
|
-
|
|
804
|
+
<DropdownMenuItem>
|
|
805
|
+
<FileTextIcon />
|
|
806
|
+
Privacy Policy
|
|
807
|
+
</DropdownMenuItem>
|
|
808
|
+
<DropdownMenuItem>
|
|
809
|
+
<ShareIcon />
|
|
810
|
+
Terms of Service
|
|
811
|
+
</DropdownMenuItem>
|
|
812
|
+
</DropdownMenuGroup>
|
|
813
|
+
<DropdownMenuSeparator />
|
|
814
|
+
<DropdownMenuGroup>
|
|
815
|
+
<DropdownMenuItem variant="destructive">
|
|
816
|
+
<TrashIcon />
|
|
817
|
+
Reset All Settings
|
|
818
|
+
</DropdownMenuItem>
|
|
924
819
|
</DropdownMenuGroup>
|
|
925
820
|
</DropdownMenuContent>
|
|
926
821
|
</DropdownMenu>
|
|
927
822
|
</div>
|
|
928
823
|
</div>
|
|
929
824
|
</div>
|
|
930
|
-
|
|
931
|
-
),
|
|
932
|
-
parameters: {
|
|
933
|
-
docs: {
|
|
934
|
-
description: {
|
|
935
|
-
story:
|
|
936
|
-
"Examples of different positioning options including alignment and offset configurations with proper content grouping.",
|
|
937
|
-
},
|
|
938
|
-
},
|
|
939
|
-
},
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
// 8. Grouping Showcase
|
|
943
|
-
export const GroupingShowcase: Story = {
|
|
944
|
-
render: () => (
|
|
945
|
-
<div className="space-y-8">
|
|
946
|
-
<div className="text-center">
|
|
947
|
-
<h3 className="mb-2 font-medium text-white">
|
|
948
|
-
DropdownMenuGroup Showcase
|
|
949
|
-
</h3>
|
|
950
|
-
<p className="text-sm text-white/60">
|
|
951
|
-
Demonstrating logical grouping for better organization and
|
|
952
|
-
accessibility
|
|
953
|
-
</p>
|
|
954
|
-
</div>
|
|
955
|
-
|
|
956
|
-
<div className="flex justify-center">
|
|
957
|
-
<DropdownMenu>
|
|
958
|
-
<DropdownMenuTrigger asChild>
|
|
959
|
-
<Button variant="outline" className="gap-2">
|
|
960
|
-
<SiteLogoIcon className="h-4 w-4" />
|
|
961
|
-
Grouped Menu
|
|
962
|
-
<AngleDownIcon className="h-4 w-4" />
|
|
963
|
-
</Button>
|
|
964
|
-
</DropdownMenuTrigger>
|
|
965
|
-
<DropdownMenuContent className="w-56">
|
|
966
|
-
{/* File Operations Group */}
|
|
967
|
-
<DropdownMenuLabel>File Operations</DropdownMenuLabel>
|
|
968
|
-
<DropdownMenuSeparator />
|
|
969
|
-
<DropdownMenuGroup>
|
|
970
|
-
<DropdownMenuItem>
|
|
971
|
-
<FileChartIcon className="h-4 w-4" />
|
|
972
|
-
New File
|
|
973
|
-
<DropdownMenuShortcut>⌘N</DropdownMenuShortcut>
|
|
974
|
-
</DropdownMenuItem>
|
|
975
|
-
<DropdownMenuItem>
|
|
976
|
-
<UploadIcon className="h-4 w-4" />
|
|
977
|
-
Upload
|
|
978
|
-
<DropdownMenuShortcut>⌘U</DropdownMenuShortcut>
|
|
979
|
-
</DropdownMenuItem>
|
|
980
|
-
<DropdownMenuItem>
|
|
981
|
-
<ImageIcon className="h-4 w-4" />
|
|
982
|
-
Import
|
|
983
|
-
<DropdownMenuShortcut>⌘I</DropdownMenuShortcut>
|
|
984
|
-
</DropdownMenuItem>
|
|
985
|
-
</DropdownMenuGroup>
|
|
986
|
-
|
|
987
|
-
<DropdownMenuSeparator />
|
|
988
|
-
|
|
989
|
-
{/* View Options Group */}
|
|
990
|
-
<DropdownMenuLabel>View Options</DropdownMenuLabel>
|
|
991
|
-
<DropdownMenuSeparator />
|
|
992
|
-
<DropdownMenuGroup>
|
|
993
|
-
<DropdownMenuItem>
|
|
994
|
-
<EyeOpenIcon className="h-4 w-4" />
|
|
995
|
-
Show Hidden Files
|
|
996
|
-
</DropdownMenuItem>
|
|
997
|
-
<DropdownMenuItem>
|
|
998
|
-
<EyeCloseIcon className="h-4 w-4" />
|
|
999
|
-
Hide Preview
|
|
1000
|
-
</DropdownMenuItem>
|
|
1001
|
-
<DropdownMenuItem>
|
|
1002
|
-
<SearchIcon className="h-4 w-4" />
|
|
1003
|
-
Search
|
|
1004
|
-
<DropdownMenuShortcut>⌘F</DropdownMenuShortcut>
|
|
1005
|
-
</DropdownMenuItem>
|
|
1006
|
-
</DropdownMenuGroup>
|
|
1007
|
-
|
|
1008
|
-
<DropdownMenuSeparator />
|
|
1009
|
-
|
|
1010
|
-
{/* Settings Group */}
|
|
1011
|
-
<DropdownMenuLabel>Settings</DropdownMenuLabel>
|
|
1012
|
-
<DropdownMenuSeparator />
|
|
1013
|
-
<DropdownMenuGroup>
|
|
1014
|
-
<DropdownMenuItem>
|
|
1015
|
-
<SiteLogoIcon className="h-4 w-4" />
|
|
1016
|
-
Preferences
|
|
1017
|
-
<DropdownMenuShortcut>⌘,</DropdownMenuShortcut>
|
|
1018
|
-
</DropdownMenuItem>
|
|
1019
|
-
<DropdownMenuItem>
|
|
1020
|
-
<SiteLogoIcon className="h-4 w-4" />
|
|
1021
|
-
Account
|
|
1022
|
-
</DropdownMenuItem>
|
|
1023
|
-
</DropdownMenuGroup>
|
|
1024
|
-
|
|
1025
|
-
<DropdownMenuSeparator />
|
|
1026
|
-
|
|
1027
|
-
{/* Danger Zone Group */}
|
|
1028
|
-
<DropdownMenuGroup>
|
|
1029
|
-
<DropdownMenuItem variant="destructive">
|
|
1030
|
-
<CrossIcon className="h-4 w-4" />
|
|
1031
|
-
Reset All Settings
|
|
1032
|
-
</DropdownMenuItem>
|
|
1033
|
-
</DropdownMenuGroup>
|
|
1034
|
-
</DropdownMenuContent>
|
|
1035
|
-
</DropdownMenu>
|
|
1036
|
-
</div>
|
|
1037
|
-
</div>
|
|
1038
|
-
),
|
|
1039
|
-
parameters: {
|
|
1040
|
-
docs: {
|
|
1041
|
-
description: {
|
|
1042
|
-
story:
|
|
1043
|
-
"Showcase of DropdownMenuGroup component demonstrating how to logically group related menu items for better organization, navigation, and accessibility. Each group represents a semantic category of actions.",
|
|
1044
|
-
},
|
|
1045
|
-
},
|
|
825
|
+
)
|
|
1046
826
|
},
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
// 9. Arrow Showcase
|
|
1050
|
-
export const ArrowShowcase: Story = {
|
|
1051
|
-
render: () => (
|
|
1052
|
-
<div className="space-y-8">
|
|
1053
|
-
<div className="text-center">
|
|
1054
|
-
<h3 className="mb-2 font-medium text-white">DropdownArrow Showcase</h3>
|
|
1055
|
-
<p className="text-sm text-white/60">
|
|
1056
|
-
Dropdown menus with arrow pointers for better visual connection to
|
|
1057
|
-
triggers
|
|
1058
|
-
</p>
|
|
1059
|
-
</div>
|
|
1060
|
-
|
|
1061
|
-
<div className="flex flex-wrap justify-center gap-8">
|
|
1062
|
-
{/* Basic Arrow */}
|
|
1063
|
-
<div className="space-y-4">
|
|
1064
|
-
<h4 className="text-center text-sm font-medium text-white/80">
|
|
1065
|
-
Basic Arrow
|
|
1066
|
-
</h4>
|
|
1067
|
-
<DropdownMenu>
|
|
1068
|
-
<DropdownMenuTrigger asChild>
|
|
1069
|
-
<Button variant="outline" className="gap-2">
|
|
1070
|
-
<SiteLogoIcon className="h-4 w-4" />
|
|
1071
|
-
With Arrow
|
|
1072
|
-
<ChevronDownIcon className="h-4 w-4" />
|
|
1073
|
-
</Button>
|
|
1074
|
-
</DropdownMenuTrigger>
|
|
1075
|
-
<DropdownMenuContent>
|
|
1076
|
-
<DropdownArrow className="h-4 w-6" />
|
|
1077
|
-
<DropdownMenuGroup>
|
|
1078
|
-
<DropdownMenuItem>
|
|
1079
|
-
<EditBigIcon className="h-4 w-4" />
|
|
1080
|
-
Edit Item
|
|
1081
|
-
</DropdownMenuItem>
|
|
1082
|
-
<DropdownMenuItem>
|
|
1083
|
-
<TickIcon className="h-4 w-4" />
|
|
1084
|
-
Copy Item
|
|
1085
|
-
</DropdownMenuItem>
|
|
1086
|
-
<DropdownMenuItem>
|
|
1087
|
-
<ArrowRightIcon className="h-4 w-4" />
|
|
1088
|
-
Share Item
|
|
1089
|
-
</DropdownMenuItem>
|
|
1090
|
-
</DropdownMenuGroup>
|
|
1091
|
-
</DropdownMenuContent>
|
|
1092
|
-
</DropdownMenu>
|
|
1093
|
-
</div>
|
|
1094
|
-
|
|
1095
|
-
{/* Custom Styled Arrow */}
|
|
1096
|
-
<div className="space-y-4">
|
|
1097
|
-
<h4 className="text-center text-sm font-medium text-white/80">
|
|
1098
|
-
Custom Styled Arrow
|
|
1099
|
-
</h4>
|
|
1100
|
-
<DropdownMenu>
|
|
1101
|
-
<DropdownMenuTrigger asChild>
|
|
1102
|
-
<Button>
|
|
1103
|
-
<AlertIcon className="h-4 w-4" />
|
|
1104
|
-
Blue Theme
|
|
1105
|
-
<AngleDownIcon className="h-4 w-4" />
|
|
1106
|
-
</Button>
|
|
1107
|
-
</DropdownMenuTrigger>
|
|
1108
|
-
<DropdownMenuContent
|
|
1109
|
-
classes={{
|
|
1110
|
-
root: "bg-blue-900/40 border-blue-500/20",
|
|
1111
|
-
border: "bg-gradient-to-r from-blue-500 to-cyan-500",
|
|
1112
|
-
}}
|
|
1113
|
-
>
|
|
1114
|
-
<DropdownArrow className="h-4 w-6 fill-blue-900" />
|
|
1115
|
-
<DropdownMenuGroup>
|
|
1116
|
-
<DropdownMenuItem
|
|
1117
|
-
classes={{
|
|
1118
|
-
root: "text-blue-200 hover:bg-blue-500/20 focus:bg-blue-500/20",
|
|
1119
|
-
}}
|
|
1120
|
-
>
|
|
1121
|
-
<TickIcon className="h-4 w-4" />
|
|
1122
|
-
Blue Action
|
|
1123
|
-
</DropdownMenuItem>
|
|
1124
|
-
<DropdownMenuItem
|
|
1125
|
-
classes={{
|
|
1126
|
-
root: "text-blue-200 hover:bg-blue-500/20 focus:bg-blue-500/20",
|
|
1127
|
-
}}
|
|
1128
|
-
>
|
|
1129
|
-
<AudioBarIcon className="h-4 w-4" />
|
|
1130
|
-
Another Action
|
|
1131
|
-
</DropdownMenuItem>
|
|
1132
|
-
</DropdownMenuGroup>
|
|
1133
|
-
</DropdownMenuContent>
|
|
1134
|
-
</DropdownMenu>
|
|
1135
|
-
</div>
|
|
1136
|
-
|
|
1137
|
-
{/* Arrow with Sub-menu */}
|
|
1138
|
-
<div className="space-y-4">
|
|
1139
|
-
<h4 className="text-center text-sm font-medium text-white/80">
|
|
1140
|
-
Arrow with Sub-menu
|
|
1141
|
-
</h4>
|
|
1142
|
-
<DropdownMenu>
|
|
1143
|
-
<DropdownMenuTrigger asChild>
|
|
1144
|
-
<Button variant="text" className="gap-2">
|
|
1145
|
-
<PlusIcon className="h-4 w-4" />
|
|
1146
|
-
Create Menu
|
|
1147
|
-
<ChevronDownIcon className="h-4 w-4" />
|
|
1148
|
-
</Button>
|
|
1149
|
-
</DropdownMenuTrigger>
|
|
1150
|
-
<DropdownMenuContent>
|
|
1151
|
-
<DropdownArrow className="fill-fm-surface-frosted h-4 w-6" />
|
|
1152
|
-
<DropdownMenuLabel>Create New</DropdownMenuLabel>
|
|
1153
|
-
<DropdownMenuSeparator />
|
|
1154
|
-
<DropdownMenuGroup>
|
|
1155
|
-
<DropdownMenuItem>
|
|
1156
|
-
<FileChartIcon className="h-4 w-4" />
|
|
1157
|
-
New Document
|
|
1158
|
-
</DropdownMenuItem>
|
|
1159
|
-
<DropdownMenuSub>
|
|
1160
|
-
<DropdownMenuSubTrigger>
|
|
1161
|
-
<ImageIcon className="h-4 w-4" />
|
|
1162
|
-
Import From
|
|
1163
|
-
</DropdownMenuSubTrigger>
|
|
1164
|
-
<DropdownMenuSubContent>
|
|
1165
|
-
<DropdownArrow className="fill-fm-surface-frosted h-4 w-4" />
|
|
1166
|
-
<DropdownMenuGroup>
|
|
1167
|
-
<DropdownMenuItem>
|
|
1168
|
-
<UploadIcon className="h-4 w-4" />
|
|
1169
|
-
Local File
|
|
1170
|
-
</DropdownMenuItem>
|
|
1171
|
-
<DropdownMenuItem>
|
|
1172
|
-
<ArrowRightIcon className="h-4 w-4" />
|
|
1173
|
-
URL
|
|
1174
|
-
</DropdownMenuItem>
|
|
1175
|
-
<DropdownMenuItem>
|
|
1176
|
-
<SiteLogoIcon className="h-4 w-4" />
|
|
1177
|
-
Cloud Service
|
|
1178
|
-
</DropdownMenuItem>
|
|
1179
|
-
</DropdownMenuGroup>
|
|
1180
|
-
</DropdownMenuSubContent>
|
|
1181
|
-
</DropdownMenuSub>
|
|
1182
|
-
</DropdownMenuGroup>
|
|
1183
|
-
</DropdownMenuContent>
|
|
1184
|
-
</DropdownMenu>
|
|
1185
|
-
</div>
|
|
1186
|
-
</div>
|
|
1187
|
-
|
|
1188
|
-
<div className="text-center">
|
|
1189
|
-
<div className="inline-block max-w-lg rounded-lg border border-white/10 bg-white/5 p-4">
|
|
1190
|
-
<h4 className="mb-2 text-sm font-medium text-white">Arrow Usage</h4>
|
|
1191
|
-
<p className="text-xs leading-relaxed text-white/60">
|
|
1192
|
-
The DropdownArrow component creates a visual pointer from the menu
|
|
1193
|
-
to its trigger. It automatically inherits the menu's background
|
|
1194
|
-
color and can be customized with the className prop. Use it to
|
|
1195
|
-
improve the visual connection between triggers and their associated
|
|
1196
|
-
menus.
|
|
1197
|
-
</p>
|
|
1198
|
-
</div>
|
|
1199
|
-
</div>
|
|
1200
|
-
</div>
|
|
1201
|
-
),
|
|
1202
827
|
parameters: {
|
|
1203
828
|
docs: {
|
|
1204
829
|
description: {
|
|
1205
830
|
story:
|
|
1206
|
-
"
|
|
831
|
+
"Three product-realistic use cases in one export: (1) a track action menu attached to a track row — add to queue, like/unlike (stateful), add to playlist via sub-menu, share, download, remove; (2) a user account menu in a top-nav context with profile, subscription, settings, and log-out; (3) a settings context menu with nested sub-menus for audio and library configuration plus a destructive reset option.",
|
|
1207
832
|
},
|
|
1208
833
|
},
|
|
1209
834
|
},
|