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.
Files changed (183) hide show
  1. package/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1199
  2. package/dist/components/avatar/Avatar.stories.tsx +235 -237
  3. package/dist/components/badge/Badge.stories.tsx +379 -116
  4. package/dist/components/banner/Banner.stories.tsx +445 -391
  5. package/dist/components/breadcrumb/Breadcrumb.stories.tsx +453 -199
  6. package/dist/components/button/Button.stories.tsx +585 -230
  7. package/dist/components/button/index.tsx +7 -7
  8. package/dist/components/card/Card.stories.tsx +619 -301
  9. package/dist/components/char-count/CharCount.stories.tsx +350 -248
  10. package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
  11. package/dist/components/chip/Chip.stories.tsx +362 -168
  12. package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -620
  13. package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
  14. package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
  15. package/dist/components/command/Command.stories.tsx +533 -856
  16. package/dist/components/dialog/Dialog.stories.tsx +505 -949
  17. package/dist/components/divider/Divider.stories.tsx +265 -502
  18. package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
  19. package/dist/components/drawer/Drawer.stories.tsx +659 -993
  20. package/dist/components/drawer/index.tsx +3 -3
  21. package/dist/components/dropdown/Dropdown.stories.tsx +643 -1018
  22. package/dist/components/form/Form.stories.tsx +560 -274
  23. package/dist/components/helper-text/HelperText.stories.tsx +199 -200
  24. package/dist/components/hover-card/HoverCard.stories.tsx +318 -1221
  25. package/dist/components/icon-button/IconButton.stories.tsx +837 -194
  26. package/dist/components/if-else/if-else.stories.tsx +370 -83
  27. package/dist/components/input/Input.stories.tsx +436 -368
  28. package/dist/components/label/Label.stories.tsx +156 -154
  29. package/dist/components/list/List.stories.tsx +485 -822
  30. package/dist/components/marquee/Marquee.stories.tsx +356 -694
  31. package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -410
  32. package/dist/components/overlay/Overlay.stories.tsx +452 -818
  33. package/dist/components/overlay/index.tsx +4 -4
  34. package/dist/components/pagination/Pagination.stories.tsx +721 -210
  35. package/dist/components/popover/Popover.stories.tsx +484 -873
  36. package/dist/components/radio/Radio.stories.tsx +432 -124
  37. package/dist/components/resizable/Resizable.stories.tsx +496 -752
  38. package/dist/components/scroll-area/ScrollArea.stories.tsx +384 -1006
  39. package/dist/components/search/Search.stories.tsx +314 -575
  40. package/dist/components/select/Select.stories.tsx +684 -787
  41. package/dist/components/sheet/Sheet.stories.tsx +671 -936
  42. package/dist/components/skelton/Skelton.stories.tsx +230 -764
  43. package/dist/components/slider/Slider.stories.tsx +384 -737
  44. package/dist/components/stepper/Stepper.stories.tsx +371 -514
  45. package/dist/components/switch/Switch.stories.tsx +461 -208
  46. package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
  47. package/dist/components/table/Table.stories.tsx +770 -914
  48. package/dist/components/tabs/Tabs.stories.tsx +459 -1400
  49. package/dist/components/tag/Tag.stories.tsx +714 -542
  50. package/dist/components/textarea/TextArea.stories.tsx +621 -562
  51. package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -148
  52. package/dist/components/toast/Toast.stories.tsx +452 -1333
  53. package/dist/components/toggle/Toggle.stories.tsx +488 -909
  54. package/dist/components/tooltip/Tooltip.stories.tsx +344 -1372
  55. package/dist/components/typography/Typography.stories.tsx +406 -89
  56. package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
  57. package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
  58. package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
  59. package/dist/icons/Icons.stories.tsx +0 -12
  60. package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +226 -1013
  61. package/dist/icons/alert-icon/AlertIcon.stories.tsx +109 -929
  62. package/dist/icons/all-icons.tsx +124 -87
  63. package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +140 -971
  64. package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +148 -888
  65. package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +135 -1019
  66. package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +137 -953
  67. package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +138 -997
  68. package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +136 -942
  69. package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +148 -1092
  70. package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +146 -1211
  71. package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +126 -615
  72. package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +144 -1164
  73. package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +167 -985
  74. package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +122 -1179
  75. package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +124 -1168
  76. package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +119 -850
  77. package/dist/icons/camera-icon/CameraIcon.stories.tsx +112 -1213
  78. package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +117 -934
  79. package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +160 -961
  80. package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +163 -961
  81. package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +144 -942
  82. package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +129 -966
  83. package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +147 -964
  84. package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +145 -975
  85. package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +150 -1142
  86. package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +114 -461
  87. package/dist/icons/coin-icon/CoinIcon.stories.tsx +124 -1322
  88. package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +117 -1318
  89. package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +114 -903
  90. package/dist/icons/command-icon/CommandIcon.stories.tsx +127 -1042
  91. package/dist/icons/copy-icon/CopyIcon.stories.tsx +123 -962
  92. package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +147 -999
  93. package/dist/icons/cross-icon/CrossIcon.stories.tsx +139 -960
  94. package/dist/icons/download-icon/DownloadIcon.stories.tsx +126 -820
  95. package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +124 -1031
  96. package/dist/icons/email-icon/EmailIcon.stories.tsx +115 -936
  97. package/dist/icons/expand-icon/ExpandIcon.stories.tsx +112 -1111
  98. package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +144 -1025
  99. package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +143 -1036
  100. package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +127 -1011
  101. package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +126 -1056
  102. package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +125 -614
  103. package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +119 -1050
  104. package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +169 -989
  105. package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +115 -1145
  106. package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +115 -1122
  107. package/dist/icons/globe-icon/GlobeIcon.stories.tsx +130 -313
  108. package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +145 -940
  109. package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +119 -1174
  110. package/dist/icons/head-icon/HeadIcon.stories.tsx +111 -916
  111. package/dist/icons/heart-icon/HeartIcon.stories.tsx +120 -1019
  112. package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +119 -683
  113. package/dist/icons/image-icon/ImageIcon.stories.tsx +105 -1121
  114. package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +111 -1192
  115. package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +136 -1256
  116. package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +159 -962
  117. package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +161 -1385
  118. package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +124 -972
  119. package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +119 -948
  120. package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +119 -942
  121. package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +108 -1215
  122. package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +154 -1517
  123. package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +110 -1188
  124. package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +119 -678
  125. package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +123 -1184
  126. package/dist/icons/message-icon/MessageIcon.stories.tsx +114 -538
  127. package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +116 -1158
  128. package/dist/icons/moon-icon/MoonIcon.stories.tsx +120 -536
  129. package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +109 -1184
  130. package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +115 -1134
  131. package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +119 -971
  132. package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +111 -1100
  133. package/dist/icons/notes-icon/NotesIcon.stories.tsx +119 -1101
  134. package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +109 -1111
  135. package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +122 -684
  136. package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +113 -954
  137. package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +112 -877
  138. package/dist/icons/pause-icon/PauseIcon.stories.tsx +113 -1000
  139. package/dist/icons/pencil-icon/PencilIcon.stories.tsx +115 -1070
  140. package/dist/icons/phone-icon/PhoneIcon.stories.tsx +115 -978
  141. package/dist/icons/plus-icon/PlusIcon.stories.tsx +106 -1093
  142. package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +107 -829
  143. package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +102 -469
  144. package/dist/icons/search-icon/SearchIcon.stories.tsx +111 -1124
  145. package/dist/icons/setting-icon/SettingIcon.stories.tsx +107 -970
  146. package/dist/icons/share-icon/ShareIcon.stories.tsx +120 -1025
  147. package/dist/icons/shield-icon/ShieldIcon.stories.tsx +117 -931
  148. package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +137 -1104
  149. package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +172 -982
  150. package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +164 -983
  151. package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +105 -958
  152. package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +158 -580
  153. package/dist/icons/spinner-gradient-icon/index.tsx +6 -1
  154. package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +158 -587
  155. package/dist/icons/spinner-solid-icon/index.tsx +6 -1
  156. package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +146 -682
  157. package/dist/icons/spinner-solid-neutral-icon/index.tsx +1 -1
  158. package/dist/icons/star-icon/StarIcon.stories.tsx +124 -904
  159. package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +112 -964
  160. package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +116 -852
  161. package/dist/icons/sun-icon/SunIcon.stories.tsx +120 -831
  162. package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +116 -950
  163. package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +123 -980
  164. package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +156 -1427
  165. package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +146 -1142
  166. package/dist/icons/tick-icon/TickIcon.stories.tsx +145 -1276
  167. package/dist/icons/trash-icon/TrashIcon.stories.tsx +108 -933
  168. package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +157 -1402
  169. package/dist/icons/upload-icon/UploadIcon.stories.tsx +115 -889
  170. package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +118 -984
  171. package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +125 -1049
  172. package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +123 -1356
  173. package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +110 -1171
  174. package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +112 -1093
  175. package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +115 -1087
  176. package/dist/icons/warning-icon/WarningIcon.stories.tsx +122 -1046
  177. package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +161 -936
  178. package/dist/index.cjs +84 -84
  179. package/dist/index.js +84 -84
  180. package/dist/styles/aural-all-theme.css +1222 -0
  181. package/dist/styles/{aural-theme.css → aural-dark-theme.css} +15 -3
  182. package/dist/styles/aural-light-theme.css +1047 -0
  183. 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
- CrossIcon,
7
+ CircleTickIcon,
8
+ DownloadIcon,
11
9
  EditBigIcon,
12
- EyeCloseIcon,
13
10
  EyeOpenIcon,
14
- FileChartIcon,
15
- ImageIcon,
11
+ FileTextIcon,
12
+ HeartIcon,
13
+ MaintenanceIcon,
14
+ MusicalNoteIcon,
16
15
  PlusIcon,
17
16
  SearchIcon,
18
- SiteLogoIcon,
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
- # Dropdown Menu Component
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
- // 1. Basic Dropdown Examples
137
- export const BasicDropdown: Story = {
81
+ // ─── Configurations ───────────────────────────────────────────────────────────
82
+
83
+ export const Configurations: Story = {
138
84
  render: () => (
139
85
  <div className="space-y-8">
140
- <div className="text-center">
141
- <h3 className="mb-2 font-medium text-white">Basic Dropdown Menus</h3>
142
- <p className="text-sm text-white/60">
143
- Simple dropdown menus with different trigger styles and grouped
144
- content
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 variant="outline" className="gap-2">
268
- <AlertIcon className="h-4 w-4" />
269
- Notifications
270
- <ChevronDownIcon className="h-4 w-4" />
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
- <DropdownMenuLabel>Email Preferences</DropdownMenuLabel>
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
- <DropdownMenuCheckboxItem
278
- checked={notifications}
279
- onCheckedChange={setNotifications}
280
- >
281
- System Notifications
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
- {/* Radio Group Menu */}
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 variant="outline" className="gap-2">
297
- Theme: {theme}
298
- <ChevronDownIcon className="h-4 w-4" />
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>Appearance</DropdownMenuLabel>
147
+ <DropdownMenuContent className="w-48">
148
+ <DropdownMenuLabel>Account</DropdownMenuLabel>
303
149
  <DropdownMenuSeparator />
304
150
  <DropdownMenuGroup>
305
- <DropdownMenuRadioGroup value={theme} onValueChange={setTheme}>
306
- <DropdownMenuRadioItem value="light">
307
- Light
308
- </DropdownMenuRadioItem>
309
- <DropdownMenuRadioItem value="dark">
310
- Dark
311
- </DropdownMenuRadioItem>
312
- <DropdownMenuRadioItem value="system">
313
- System
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
- return (
661
- <div className="space-y-8">
662
- <div className="text-center">
663
- <h3 className="mb-2 font-medium text-white">Complex Menu</h3>
664
- <p className="text-sm text-white/60">
665
- Full-featured dropdown menu with all component types and logical
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 &amp; Separators
170
+ </h4>
171
+ <div className="flex flex-wrap justify-center gap-4">
671
172
  <DropdownMenu>
672
173
  <DropdownMenuTrigger asChild>
673
- <Button variant="outline" className="gap-2">
674
- <AlertIcon className="h-4 w-4" />
675
- More Actions
676
- <ChevronDownIcon className="h-4 w-4" />
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-64">
680
- {/* Basic Actions Group */}
681
- <DropdownMenuLabel>Quick Actions</DropdownMenuLabel>
182
+ <DropdownMenuContent className="w-52">
183
+ <DropdownMenuLabel>File</DropdownMenuLabel>
682
184
  <DropdownMenuSeparator />
683
185
  <DropdownMenuGroup>
684
186
  <DropdownMenuItem>
685
- <EditBigIcon className="h-4 w-4" />
686
- Edit Item
687
- <DropdownMenuShortcut>⌘E</DropdownMenuShortcut>
187
+ <FileTextIcon />
188
+ New
189
+ <DropdownMenuShortcut>⌘N</DropdownMenuShortcut>
688
190
  </DropdownMenuItem>
689
191
  <DropdownMenuItem>
690
- <TickIcon className="h-4 w-4" />
691
- Duplicate
692
- <DropdownMenuShortcut>⌘D</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
- <ArrowRightIcon className="h-4 w-4" />
696
- Share
697
- <DropdownMenuShortcut>⌘⇧S</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
- <DropdownMenuSeparator />
702
-
703
- {/* Options Group */}
704
- <DropdownMenuLabel>Options</DropdownMenuLabel>
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
- checked={bookmarked}
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
- checked={notifications}
716
- onCheckedChange={setNotifications}
717
- >
718
- <AlertIcon className="h-4 w-4" />
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
- <DropdownMenuSeparator />
724
-
725
- {/* View Mode Group */}
726
- <DropdownMenuLabel>View Mode</DropdownMenuLabel>
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={viewMode}
731
- onValueChange={setViewMode}
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="list">
737
- List View
276
+ <DropdownMenuRadioItem value="alpha">
277
+ Alphabetical
738
278
  </DropdownMenuRadioItem>
739
- <DropdownMenuRadioItem value="card">
740
- Card View
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
- <DropdownMenuSeparator />
746
-
747
- {/* Collections Group */}
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
- <PlusIcon className="h-4 w-4" />
752
- Add to Collection
309
+ <AudioBarIcon />
310
+ Playlist
753
311
  </DropdownMenuSubTrigger>
754
312
  <DropdownMenuSubContent>
755
313
  <DropdownMenuGroup>
756
314
  <DropdownMenuItem>
757
- <FileChartIcon className="h-4 w-4" />
758
- Favorites
315
+ <MusicalNoteIcon />
316
+ Late Night Drive
759
317
  </DropdownMenuItem>
760
318
  <DropdownMenuItem>
761
- <FileChartIcon className="h-4 w-4" />
762
- Work Projects
319
+ <MusicalNoteIcon />
320
+ Focus Mode
763
321
  </DropdownMenuItem>
764
322
  <DropdownMenuItem>
765
- <FileChartIcon className="h-4 w-4" />
766
- Personal
323
+ <MusicalNoteIcon />
324
+ Morning Energy
767
325
  </DropdownMenuItem>
768
326
  </DropdownMenuGroup>
769
327
  <DropdownMenuSeparator />
770
328
  <DropdownMenuGroup>
771
329
  <DropdownMenuItem>
772
- <PlusIcon className="h-4 w-4" />
773
- Create New Collection
330
+ <PlusIcon />
331
+ New Playlist…
774
332
  </DropdownMenuItem>
775
333
  </DropdownMenuGroup>
776
334
  </DropdownMenuSubContent>
777
335
  </DropdownMenuSub>
778
- </DropdownMenuGroup>
779
-
780
- <DropdownMenuSeparator />
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
- {/* State Display */}
795
- <div className="text-center">
796
- <div className="inline-block rounded-lg border border-white/10 bg-white/5 p-4">
797
- <h4 className="mb-2 text-sm font-medium text-white">
798
- Current Settings
799
- </h4>
800
- <div className="space-y-1 text-xs text-white/60">
801
- <div>Bookmarked: {bookmarked ? "Yes" : "No"}</div>
802
- <div>Notifications: {notifications ? "Enabled" : "Disabled"}</div>
803
- <div>View Mode: {viewMode}</div>
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
- "Complex dropdown menu example showcasing all component features with proper logical grouping using DropdownMenuGroup for better organization and accessibility.",
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
- // 7. Positioning Examples
821
- export const PositioningExamples: Story = {
822
- render: () => (
823
- <div className="space-y-8">
824
- <div className="text-center">
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
- <div className="grid grid-cols-2 gap-8">
832
- {/* Top Row */}
833
- <div className="space-y-4">
834
- <h4 className="text-sm font-medium text-white/80">
835
- Alignment Options
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 gap-2">
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="outline" size="sm">
841
- Align Start
615
+ <Button variant="text" size="sm">
616
+ <VerticalMenuIcon />
842
617
  </Button>
843
618
  </DropdownMenuTrigger>
844
- <DropdownMenuContent align="start">
619
+ <DropdownMenuContent align="end" className="w-52">
845
620
  <DropdownMenuGroup>
846
- <DropdownMenuItem>Left aligned</DropdownMenuItem>
847
- <DropdownMenuItem>Content</DropdownMenuItem>
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
- </DropdownMenuContent>
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
- <DropdownMenuItem>Center aligned</DropdownMenuItem>
861
- <DropdownMenuItem>Content</DropdownMenuItem>
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
- </DropdownMenuContent>
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>Right aligned</DropdownMenuItem>
875
- <DropdownMenuItem>Content</DropdownMenuItem>
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
- {/* Bottom Row */}
883
- <div className="space-y-4">
884
- <h4 className="text-sm font-medium text-white/80">Side Offset</h4>
885
- <div className="flex gap-2">
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 variant="outline" size="sm">
889
- No Offset
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 sideOffset={0}>
708
+ <DropdownMenuContent align="end" className="w-52">
709
+ <DropdownMenuLabel>My Account</DropdownMenuLabel>
710
+ <DropdownMenuSeparator />
893
711
  <DropdownMenuGroup>
894
- <DropdownMenuItem>No spacing</DropdownMenuItem>
895
- <DropdownMenuItem>From trigger</DropdownMenuItem>
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
- </DropdownMenuContent>
898
- </DropdownMenu>
899
-
900
- <DropdownMenu>
901
- <DropdownMenuTrigger asChild>
902
- <Button variant="outline" size="sm">
903
- Default
904
- </Button>
905
- </DropdownMenuTrigger>
906
- <DropdownMenuContent>
727
+ <DropdownMenuSeparator />
728
+ <DropdownMenuGroup>
729
+ <DropdownMenuItem>
730
+ <SearchIcon />
731
+ Help &amp; Support
732
+ </DropdownMenuItem>
733
+ </DropdownMenuGroup>
734
+ <DropdownMenuSeparator />
907
735
  <DropdownMenuGroup>
908
- <DropdownMenuItem>Default spacing</DropdownMenuItem>
909
- <DropdownMenuItem>4px offset</DropdownMenuItem>
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 variant="outline" size="sm">
917
- Large Offset
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 sideOffset={12}>
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>Large spacing</DropdownMenuItem>
923
- <DropdownMenuItem>12px offset</DropdownMenuItem>
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
- </div>
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
- "Demonstration of DropdownArrow component showing how to add visual arrows that point from dropdown menus to their triggers. Includes basic usage, custom styling, and usage with sub-menus.",
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
  },