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