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
@@ -4,18 +4,16 @@ import { Button } from "@components/button"
4
4
  import { Checkbox } from "@components/checkbox"
5
5
  import Input from "@components/input"
6
6
  import { Label } from "@components/label"
7
- import {
8
- Select,
9
- SelectContent,
10
- SelectItem,
11
- SelectTrigger,
12
- SelectValue,
13
- } from "@components/select"
14
- import Textarea from "@components/textarea"
15
- import { CrossIcon } from "@icons/cross-icon"
16
- import { EditBigIcon } from "@icons/edit-big-icon"
7
+ import { ChevronRightIcon } from "@icons/chevron-right-icon"
8
+ import { MaintenanceIcon } from "@icons/maintenance-icon"
9
+ import { MusicalNoteIcon } from "@icons/musical-note-icon"
10
+ import { SearchIcon } from "@icons/search-icon"
11
+ import { SiteLogoIcon } from "@icons/site-logo-icon"
12
+ import { TickCircleIcon } from "@icons/tick-circle-icon"
17
13
  import type { Meta, StoryObj } from "@storybook/react-vite"
18
14
 
15
+ import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
16
+
19
17
  import {
20
18
  Drawer,
21
19
  DrawerClose,
@@ -27,194 +25,50 @@ import {
27
25
  DrawerTrigger,
28
26
  } from "."
29
27
 
30
- const meta: Meta<typeof DrawerContent> = {
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ const meta: Meta<any> = {
31
30
  title: "Components/UI/Drawer",
32
31
  component: Drawer,
33
32
  parameters: {
34
33
  layout: "centered",
35
- backgrounds: {
36
- default: "dark",
37
- values: [
38
- { name: "dark", value: "#0a0a0a" },
39
- { name: "light", value: "#ffffff" },
40
- ],
41
- },
42
34
  docs: {
43
35
  description: {
44
- component: `
45
- # Drawer Component
46
-
47
- A slide-out drawer component built on Vaul primitives with support for multiple directions, smooth animations, customizable content sections, and enhanced accessibility features.
48
-
49
- ## Features
50
-
51
- - **Multiple Directions**: Top, bottom, left, and right slide directions
52
- - **Multiple Variants**: Neutral and gradient styles with custom styling
53
- - **Custom Overlays**: Configurable opacity, glass effect, and noise texture
54
- - **Smooth Animations**: Fade in/out animations for overlay and content with customizable duration
55
- - **Accessible**: Full keyboard navigation, screen reader support, and focus management
56
- - **Flexible Content**: Header, footer, and body sections with custom styling
57
- - **Portal Rendering**: Renders outside normal DOM hierarchy for proper layering
58
- - **Focus Management**: Automatic focus trapping and restoration
59
- - **Responsive Design**: Adapts to different screen sizes with mobile-first approach
60
- - **Drag Support**: Built-in drag gestures for intuitive interaction
61
- - **Nested Support**: Support for nested drawers with proper z-index management
62
-
63
- ## Directions
64
-
65
- The drawer can slide from different directions using the \`direction\` prop:
66
-
67
- - **Bottom** (default): Slides up from the bottom - ideal for mobile navigation
68
- - **Top**: Slides down from the top - useful for notifications or quick actions
69
- - **Left**: Slides in from the left - perfect for navigation menus
70
- - **Right**: Slides in from the right - great for settings or detail panels
71
-
72
- ## Usage Examples
73
-
74
- ### Basic Drawer with Direction Configuration
75
- \`\`\`tsx
76
- import { Drawer, DrawerContent, DrawerTrigger } from '@/components/drawer'
77
-
78
- // Bottom drawer (default)
79
- <Drawer>
80
- <DrawerTrigger asChild>
81
- <Button>Open Bottom Drawer</Button>
82
- </DrawerTrigger>
83
- <DrawerContent>
84
- Content slides up from bottom
85
- </DrawerContent>
86
- </Drawer>
87
-
88
- // Top drawer
89
- <Drawer>
90
- <DrawerTrigger asChild>
91
- <Button>Open Top Drawer</Button>
92
- </DrawerTrigger>
93
- <DrawerContent>
94
- Content slides down from top
95
- </DrawerContent>
96
- </Drawer>
97
-
98
- // Left drawer
99
- <Drawer>
100
- <DrawerTrigger asChild>
101
- <Button>Open Left Drawer</Button>
102
- </DrawerTrigger>
103
- <DrawerContent>
104
- Content slides in from left
105
- </DrawerContent>
106
- </Drawer>
107
-
108
- // Right drawer
109
- <Drawer>
110
- <DrawerTrigger asChild>
111
- <Button>Open Right Drawer</Button>
112
- </DrawerTrigger>
113
- <DrawerContent>
114
- Content slides in from right
115
- </DrawerContent>
116
- </Drawer>
117
-
118
- ### Drawer with Custom Overlay Effects
119
- \`\`\`tsx
120
- <Drawer>
121
- <DrawerTrigger asChild>
122
- <Button>Open Drawer with Custom Overlay</Button>
123
- </DrawerTrigger>
124
- <DrawerContent
125
- noise="high"
126
- opacity="medium"
127
- glass="low"
128
- >
129
- Content with custom overlay effects
130
- </DrawerContent>
131
- </Drawer>
132
- \`\`\`
133
-
134
- ### Overlay Configuration
135
-
136
- The drawer supports configurable overlay effects through the \`opacity\`, \`glass\`, and \`noise\` props:
137
-
138
- - **opacity**: Controls background dimming level
139
- - \`"high"\` - Strong dimming (80%)
140
- - \`"medium"\` - Balanced dimming (60%) - default
141
- - \`"low"\` - Subtle dimming (40%)
142
- - \`"none"\` - No dimming (100% coverage)
143
-
144
- - **glass**: Controls backdrop blur effect
145
- - \`"high"\` - Strong blur effect
146
- - \`"medium"\` - Balanced blur effect
147
- - \`"low"\` - Subtle blur effect - default
148
- - \`"none"\` - No blur effect
149
-
150
- - **noise**: Controls texture overlay
151
- - \`"high"\` - Strong texture pattern
152
- - \`"medium"\` - Balanced texture pattern
153
- - \`"low"\` - Subtle texture pattern - default
154
- - \`"none"\` - No texture pattern
155
-
156
- ### Usage Examples
157
-
158
- \`\`\`tsx
159
- // High opacity with glass effect
160
- <DrawerContent opacity="high" glass="medium" noise="low">
161
- Content with strong background dimming
162
- </DrawerContent>
163
-
164
- // Subtle overlay with texture
165
- <DrawerContent opacity="low" glass="none" noise="high">
166
- Content with subtle dimming and strong texture
167
- </DrawerContent>
168
-
169
- // No overlay effects
170
- <DrawerContent opacity="none" glass="none" noise="none">
171
- Content without any overlay effects
172
- </DrawerContent>
173
- \`\`\`
174
- \`\`\`
175
-
176
- ### Drawer with Form Elements
177
- \`\`\`tsx
178
- <Drawer>
179
- <DrawerTrigger asChild>
180
- <Button>Open Form Drawer</Button>
181
- </DrawerTrigger>
182
- <DrawerContent>
183
- <DrawerHeader>
184
- <DrawerTitle>Contact Form</DrawerTitle>
185
- <DrawerDescription>Fill out the form below to get in touch.</DrawerDescription>
186
- </DrawerHeader>
187
- <div className="space-y-4 p-4">
188
- <Input placeholder="Name" />
189
- <Input placeholder="Email" type="email" />
190
- <Textarea placeholder="Message" rows={4} />
191
- </div>
192
- <DrawerFooter>
193
- <Button>Submit</Button>
194
- <DrawerClose asChild>
195
- <Button variant="outline">Cancel</Button>
196
- </DrawerClose>
197
- </DrawerFooter>
198
- </DrawerContent>
199
- </Drawer>
200
- \`\`\`
201
- `,
36
+ component:
37
+ "A slide-out drawer built on Vaul primitives. Supports four slide directions, neutral and gradient variants, configurable glass/noise overlays, an optional swipe handle, and an optional backdrop overlay — ideal for mobile navigation, settings panels, and contextual actions.",
202
38
  },
39
+ page: () => (
40
+ <AuralComponentDocsPage
41
+ features={[
42
+ {
43
+ title: "4 Slide Directions",
44
+ description: "Top, bottom, left, right",
45
+ },
46
+ {
47
+ title: "Glass & Noise Overlay",
48
+ description: "Blur and grain levels",
49
+ },
50
+ {
51
+ title: "Swipe Handle",
52
+ description: "Optional pill indicator",
53
+ },
54
+ ]}
55
+ />
56
+ ),
203
57
  },
204
58
  },
205
59
  argTypes: {
206
60
  variant: {
207
61
  control: { type: "select" },
208
62
  options: ["neutral", "gradient"],
209
- description: "Drawer variant for different use cases",
63
+ description: "Visual style variant",
210
64
  },
211
65
  showOverlay: {
212
66
  control: { type: "boolean" },
213
- description: "Whether to show the overlay backdrop",
67
+ description: "Whether to render the backdrop overlay",
214
68
  },
215
69
  showSwipeButton: {
216
70
  control: { type: "boolean" },
217
- description: "Whether to show the swipe indicator button",
71
+ description: "Show swipe indicator handle (bottom drawers only)",
218
72
  },
219
73
  opacity: {
220
74
  control: { type: "select" },
@@ -224,12 +78,12 @@ The drawer supports configurable overlay effects through the \`opacity\`, \`glas
224
78
  glass: {
225
79
  control: { type: "select" },
226
80
  options: ["high", "medium", "low", "none"],
227
- description: "Overlay glass effect level",
81
+ description: "Overlay glass blur intensity",
228
82
  },
229
83
  noise: {
230
84
  control: { type: "select" },
231
85
  options: ["high", "medium", "low", "none"],
232
- description: "Overlay noise texture level",
86
+ description: "Overlay noise texture intensity",
233
87
  },
234
88
  },
235
89
  tags: ["autodocs"],
@@ -238,33 +92,28 @@ The drawer supports configurable overlay effects through the \`opacity\`, \`glas
238
92
  export default meta
239
93
  type Story = StoryObj<typeof Drawer>
240
94
 
241
- // 1. Direction Examples
242
- export const DirectionExamples: Story = {
95
+ // ─── Configurations ────────────────────────────────────────────────────────────
96
+
97
+ export const Configurations: Story = {
243
98
  render: () => {
244
- const DirectionDrawer = ({ direction, title, description }: any) => {
245
- return (
99
+ const DirDrawer = ({ direction, label, description }: any) => (
100
+ <div className="space-y-2 text-center">
246
101
  <Drawer direction={direction}>
247
102
  <DrawerTrigger asChild>
248
103
  <Button variant="outline" size="sm">
249
- {title}
104
+ {label}
250
105
  </Button>
251
106
  </DrawerTrigger>
252
107
  <DrawerContent>
253
108
  <DrawerHeader>
254
- <DrawerTitle>{title}</DrawerTitle>
109
+ <DrawerTitle>{label} Drawer</DrawerTitle>
255
110
  <DrawerDescription>{description}</DrawerDescription>
256
111
  </DrawerHeader>
257
- <div className="p-2 py-4">
258
- <div className="rounded-lg border border-white/10 bg-white/5 p-3">
259
- <div className="space-y-1 text-xs text-white/60">
260
- <div>
261
- Direction: <span className="text-white">{direction}</span>
262
- </div>
263
- <div>
264
- Content:{" "}
265
- <span className="text-white">Slides from {direction}</span>
266
- </div>
267
- </div>
112
+ <div className="p-4">
113
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
114
+ <code className="text-fm-secondary text-fm-sm leading-fm-sm font-(--font-fm-mono)">
115
+ direction="{direction}"
116
+ </code>
268
117
  </div>
269
118
  </div>
270
119
  <DrawerFooter>
@@ -274,73 +123,202 @@ export const DirectionExamples: Story = {
274
123
  </DrawerFooter>
275
124
  </DrawerContent>
276
125
  </Drawer>
277
- )
278
- }
126
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
127
+ {label}
128
+ </p>
129
+ </div>
130
+ )
131
+
132
+ const OverlayDrawer = ({ label, opacity, glass, noise }: any) => (
133
+ <div className="space-y-2 text-center">
134
+ <Drawer direction="bottom">
135
+ <DrawerTrigger asChild>
136
+ <Button variant="outline" size="sm">
137
+ {label}
138
+ </Button>
139
+ </DrawerTrigger>
140
+ <DrawerContent opacity={opacity} glass={glass} noise={noise}>
141
+ <DrawerHeader>
142
+ <DrawerTitle>{label}</DrawerTitle>
143
+ <DrawerDescription>Overlay configuration demo.</DrawerDescription>
144
+ </DrawerHeader>
145
+ <div className="p-4">
146
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
147
+ <code className="text-fm-secondary text-fm-sm leading-fm-sm font-(--font-fm-mono)">
148
+ {opacity ? `opacity="${opacity}"` : ""}
149
+ {glass ? ` glass="${glass}"` : ""}
150
+ {noise ? ` noise="${noise}"` : ""}
151
+ </code>
152
+ </div>
153
+ </div>
154
+ <DrawerFooter>
155
+ <DrawerClose asChild>
156
+ <Button>Close</Button>
157
+ </DrawerClose>
158
+ </DrawerFooter>
159
+ </DrawerContent>
160
+ </Drawer>
161
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
162
+ {label}
163
+ </p>
164
+ </div>
165
+ )
279
166
 
280
167
  return (
281
168
  <div className="space-y-8">
282
- <div className="text-center">
283
- <h3 className="mb-2 font-medium text-white">Drawer Directions</h3>
284
- <p className="text-sm text-white/60">
285
- Explore different slide directions for various use cases
286
- </p>
169
+ {/* All four directions */}
170
+ <div className="space-y-3">
171
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
172
+ Slide Directions
173
+ </h4>
174
+ <div className="flex flex-wrap gap-6">
175
+ <DirDrawer
176
+ direction="bottom"
177
+ label="Bottom"
178
+ description="Slides up from the bottom — default for mobile."
179
+ />
180
+ <DirDrawer
181
+ direction="top"
182
+ label="Top"
183
+ description="Slides down from the top — ideal for notifications."
184
+ />
185
+ <DirDrawer
186
+ direction="left"
187
+ label="Left"
188
+ description="Slides in from the left — navigation menus."
189
+ />
190
+ <DirDrawer
191
+ direction="right"
192
+ label="Right"
193
+ description="Slides in from the right — settings panels."
194
+ />
195
+ </div>
287
196
  </div>
288
197
 
289
- <div className="space-y-6">
290
- {/* Bottom Direction */}
291
- <div className="space-y-4">
292
- <h4 className="text-sm font-medium text-white/80">
293
- Bottom Direction (Default)
294
- </h4>
295
- <div className="flex flex-wrap gap-2">
296
- <DirectionDrawer
297
- direction="bottom"
298
- title="Bottom Drawer"
299
- description="Slides up from the bottom - ideal for mobile navigation"
300
- />
198
+ {/* Variant styles */}
199
+ <div className="space-y-3">
200
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
201
+ Variant Styles
202
+ </h4>
203
+ <div className="flex flex-wrap gap-6">
204
+ <div className="space-y-2 text-center">
205
+ <Drawer direction="bottom">
206
+ <DrawerTrigger asChild>
207
+ <Button variant="outline" size="sm">
208
+ Neutral
209
+ </Button>
210
+ </DrawerTrigger>
211
+ <DrawerContent variant="neutral">
212
+ <DrawerHeader>
213
+ <DrawerTitle>Neutral Variant</DrawerTitle>
214
+ <DrawerDescription>
215
+ Frosted glass surface with backdrop blur.
216
+ </DrawerDescription>
217
+ </DrawerHeader>
218
+ <DrawerFooter>
219
+ <DrawerClose asChild>
220
+ <Button>Close</Button>
221
+ </DrawerClose>
222
+ </DrawerFooter>
223
+ </DrawerContent>
224
+ </Drawer>
225
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
226
+ Neutral
227
+ </p>
301
228
  </div>
302
- </div>
303
229
 
304
- {/* Top Direction */}
305
- <div className="space-y-4">
306
- <h4 className="text-sm font-medium text-white/80">Top Direction</h4>
307
- <div className="flex flex-wrap gap-2">
308
- <DirectionDrawer
309
- direction="top"
310
- title="Top Drawer"
311
- description="Slides down from the top - useful for notifications"
312
- />
230
+ <div className="space-y-2 text-center">
231
+ <Drawer direction="bottom">
232
+ <DrawerTrigger asChild>
233
+ <Button variant="outline" size="sm">
234
+ Gradient
235
+ </Button>
236
+ </DrawerTrigger>
237
+ <DrawerContent variant="gradient">
238
+ <DrawerHeader>
239
+ <DrawerTitle>Gradient Variant</DrawerTitle>
240
+ <DrawerDescription>
241
+ Surface primary with a white gradient overlay.
242
+ </DrawerDescription>
243
+ </DrawerHeader>
244
+ <DrawerFooter>
245
+ <DrawerClose asChild>
246
+ <Button>Close</Button>
247
+ </DrawerClose>
248
+ </DrawerFooter>
249
+ </DrawerContent>
250
+ </Drawer>
251
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
252
+ Gradient
253
+ </p>
313
254
  </div>
314
- </div>
315
255
 
316
- {/* Left Direction */}
317
- <div className="space-y-4">
318
- <h4 className="text-sm font-medium text-white/80">
319
- Left Direction
320
- </h4>
321
- <div className="flex flex-wrap gap-2">
322
- <DirectionDrawer
323
- direction="left"
324
- title="Left Drawer"
325
- description="Slides in from the left - perfect for navigation menus"
326
- />
256
+ <div className="space-y-2 text-center">
257
+ <Drawer direction="bottom">
258
+ <DrawerTrigger asChild>
259
+ <Button variant="outline" size="sm">
260
+ Swipe handle
261
+ </Button>
262
+ </DrawerTrigger>
263
+ <DrawerContent showSwipeButton>
264
+ <DrawerHeader>
265
+ <DrawerTitle>Swipe Handle</DrawerTitle>
266
+ <DrawerDescription>
267
+ Pill handle appears at the top of bottom drawers.
268
+ </DrawerDescription>
269
+ </DrawerHeader>
270
+ <DrawerFooter>
271
+ <DrawerClose asChild>
272
+ <Button>Close</Button>
273
+ </DrawerClose>
274
+ </DrawerFooter>
275
+ </DrawerContent>
276
+ </Drawer>
277
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
278
+ Swipe button
279
+ </p>
327
280
  </div>
328
- </div>
329
281
 
330
- {/* Right Direction */}
331
- <div className="space-y-4">
332
- <h4 className="text-sm font-medium text-white/80">
333
- Right Direction
334
- </h4>
335
- <div className="flex flex-wrap gap-2">
336
- <DirectionDrawer
337
- direction="right"
338
- title="Right Drawer"
339
- description="Slides in from the right - great for settings panels"
340
- />
282
+ <div className="space-y-2 text-center">
283
+ <Drawer direction="bottom">
284
+ <DrawerTrigger asChild>
285
+ <Button variant="outline" size="sm">
286
+ No overlay
287
+ </Button>
288
+ </DrawerTrigger>
289
+ <DrawerContent showOverlay={false}>
290
+ <DrawerHeader>
291
+ <DrawerTitle>No Overlay</DrawerTitle>
292
+ <DrawerDescription>
293
+ Drawer without the backdrop overlay.
294
+ </DrawerDescription>
295
+ </DrawerHeader>
296
+ <DrawerFooter>
297
+ <DrawerClose asChild>
298
+ <Button>Close</Button>
299
+ </DrawerClose>
300
+ </DrawerFooter>
301
+ </DrawerContent>
302
+ </Drawer>
303
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
304
+ No overlay
305
+ </p>
341
306
  </div>
342
307
  </div>
343
308
  </div>
309
+
310
+ {/* Glass / noise options */}
311
+ <div className="space-y-3">
312
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
313
+ Glass &amp; Noise Overlay Options
314
+ </h4>
315
+ <div className="flex flex-wrap gap-6">
316
+ <OverlayDrawer label="Low opacity" opacity="low" />
317
+ <OverlayDrawer label="High opacity" opacity="high" />
318
+ <OverlayDrawer label="High glass" glass="high" />
319
+ <OverlayDrawer label="Noise texture" noise="medium" />
320
+ </div>
321
+ </div>
344
322
  </div>
345
323
  )
346
324
  },
@@ -348,597 +326,456 @@ export const DirectionExamples: Story = {
348
326
  docs: {
349
327
  description: {
350
328
  story:
351
- "Comprehensive showcase of all drawer direction options with descriptions of their use cases.",
329
+ "Comparison of all four slide directions, both visual variants, swipe handle, overlay toggle, and glass/noise overlay options.",
352
330
  },
353
331
  },
354
332
  },
355
333
  }
356
334
 
357
- // 6. Basic Drawer
358
- export const Basic: Story = {
359
- render: () => (
360
- <Drawer>
361
- <DrawerTrigger asChild>
362
- <Button>Open Drawer</Button>
363
- </DrawerTrigger>
364
- <DrawerContent>
365
- <DrawerHeader>
366
- <DrawerTitle>Basic Drawer</DrawerTitle>
367
- <DrawerDescription>
368
- This is a basic drawer example with header, content, and footer.
369
- </DrawerDescription>
370
- </DrawerHeader>
371
- <p className="p-4 text-sm">
372
- This is the main content area of the drawer. You can put any content
373
- here.
374
- </p>
375
- <DrawerFooter>
376
- <Button>Save Changes</Button>
377
- <DrawerClose asChild>
378
- <Button variant="outline">Cancel</Button>
379
- </DrawerClose>
380
- </DrawerFooter>
381
- </DrawerContent>
382
- </Drawer>
383
- ),
384
- parameters: {
385
- docs: {
386
- description: {
387
- story:
388
- "Basic drawer example demonstrating the fundamental structure with header, content, and footer sections.",
389
- },
390
- },
391
- },
392
- }
393
- // 2. Form Drawer with Select Components
394
- export const FormDrawer: Story = {
335
+ // ─── Interactive ───────────────────────────────────────────────────────────────
336
+
337
+ export const Interactive: Story = {
395
338
  render: () => {
396
- const [formData, setFormData] = useState({
397
- name: "",
398
- email: "",
399
- category: "",
400
- priority: "",
401
- message: "",
402
- newsletter: false,
403
- })
339
+ const InteractiveDemo = () => {
340
+ const [direction, setDirection] = useState<
341
+ "top" | "bottom" | "left" | "right"
342
+ >("bottom")
343
+ const [variant, setVariant] = useState<"neutral" | "gradient">("neutral")
344
+ const [opacity, setOpacity] = useState<
345
+ "high" | "medium" | "low" | "none"
346
+ >("medium")
347
+ const [glass, setGlass] = useState<"high" | "medium" | "low" | "none">(
348
+ "none"
349
+ )
350
+ const [noise, setNoise] = useState<"high" | "medium" | "low" | "none">(
351
+ "none"
352
+ )
353
+ const [showSwipeButton, setShowSwipeButton] = useState(false)
354
+ const [name, setName] = useState("")
355
+ const [email, setEmail] = useState("")
356
+ const [submitted, setSubmitted] = useState(false)
357
+
358
+ const directions = ["bottom", "top", "left", "right"] as const
359
+ const variants = ["neutral", "gradient"] as const
360
+ const levels = ["none", "low", "medium", "high"] as const
361
+
362
+ const btnCls = (active: boolean) =>
363
+ `font-fm-text text-fm-sm leading-fm-sm rounded px-2 py-1 outline-none transition-colors ${
364
+ active
365
+ ? "bg-fm-surface-contrast text-fm-contrast"
366
+ : "bg-fm-surface-secondary text-fm-secondary hover:text-fm-primary"
367
+ }`
404
368
 
405
- const handleSubmit = (e: React.FormEvent) => {
406
- e.preventDefault()
407
- console.log("Form submitted:", formData)
408
- }
369
+ return (
370
+ <div className="w-full p-8">
371
+ <div className="mx-auto max-w-3xl space-y-6">
372
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
373
+ {/* Controls panel */}
374
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-5 rounded-xl border p-5">
375
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
376
+ Configuration
377
+ </p>
378
+
379
+ <div className="space-y-2">
380
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
381
+ Direction
382
+ </p>
383
+ <div className="flex flex-wrap gap-1">
384
+ {directions.map((d) => (
385
+ <button
386
+ key={d}
387
+ onClick={() => setDirection(d)}
388
+ className={btnCls(direction === d)}
389
+ >
390
+ {d}
391
+ </button>
392
+ ))}
393
+ </div>
394
+ </div>
409
395
 
410
- return (
411
- <Drawer>
412
- <DrawerTrigger asChild>
413
- <Button className="gap-2">
414
- <EditBigIcon className="h-4 w-4" />
415
- Contact Form
416
- </Button>
417
- </DrawerTrigger>
418
- <DrawerContent>
419
- <DrawerHeader>
420
- <DrawerTitle>Contact Form</DrawerTitle>
421
- <DrawerDescription>
422
- Fill out the form below to get in touch with us.
423
- </DrawerDescription>
424
- </DrawerHeader>
425
- <form onSubmit={handleSubmit} className="space-y-4 overflow-auto p-4">
426
- <div className="space-y-2">
427
- <Label htmlFor="name">Name</Label>
428
- <Input
429
- id="name"
430
- value={formData.name}
431
- onChange={(e) =>
432
- setFormData({ ...formData, name: e.target.value })
433
- }
434
- placeholder="Enter your name"
435
- />
436
- </div>
437
- <div className="space-y-2">
438
- <Label htmlFor="email">Email</Label>
439
- <Input
440
- id="email"
441
- type="email"
442
- value={formData.email}
443
- onChange={(e) =>
444
- setFormData({ ...formData, email: e.target.value })
445
- }
446
- placeholder="Enter your email"
447
- />
448
- </div>
449
- <div className="space-y-2">
450
- <Label htmlFor="category">Category</Label>
451
- <Select
452
- value={formData.category}
453
- onValueChange={(value) =>
454
- setFormData({ ...formData, category: value })
455
- }
456
- >
457
- <SelectTrigger>
458
- <SelectValue placeholder="Select a category" />
459
- </SelectTrigger>
460
- <SelectContent>
461
- <SelectItem value="general">General Inquiry</SelectItem>
462
- <SelectItem value="support">Technical Support</SelectItem>
463
- <SelectItem value="sales">Sales Question</SelectItem>
464
- <SelectItem value="feedback">Feedback</SelectItem>
465
- </SelectContent>
466
- </Select>
467
- </div>
468
- <div className="space-y-2">
469
- <Label htmlFor="priority">Priority</Label>
470
- <Select
471
- value={formData.priority}
472
- onValueChange={(value) =>
473
- setFormData({ ...formData, priority: value })
474
- }
475
- >
476
- <SelectTrigger>
477
- <SelectValue placeholder="Select priority level" />
478
- </SelectTrigger>
479
- <SelectContent>
480
- <SelectItem value="low">Low</SelectItem>
481
- <SelectItem value="medium">Medium</SelectItem>
482
- <SelectItem value="high">High</SelectItem>
483
- <SelectItem value="urgent">Urgent</SelectItem>
484
- </SelectContent>
485
- </Select>
486
- </div>
487
- <div className="space-y-2">
488
- <Label htmlFor="message">Message</Label>
489
- <Textarea
490
- id="message"
491
- value={formData.message}
492
- onChange={(e) =>
493
- setFormData({ ...formData, message: e.target.value })
494
- }
495
- placeholder="Enter your message"
496
- rows={4}
497
- />
498
- </div>
499
- <div className="flex items-center space-x-2">
500
- <Checkbox
501
- id="newsletter"
502
- checked={formData.newsletter}
503
- onCheckedChange={(checked) =>
504
- setFormData({ ...formData, newsletter: !!checked })
505
- }
506
- />
507
- <Label htmlFor="newsletter" className="text-sm">
508
- Subscribe to newsletter
509
- </Label>
510
- </div>
511
- </form>
512
- <DrawerFooter>
513
- <Button
514
- disabled={!formData.name || !formData.email || !formData.message}
515
- onClick={handleSubmit}
516
- >
517
- Submit
518
- </Button>
519
- <DrawerClose asChild>
520
- <Button variant="outline">Cancel</Button>
521
- </DrawerClose>
522
- </DrawerFooter>
523
- </DrawerContent>
524
- </Drawer>
525
- )
526
- },
527
- parameters: {
528
- docs: {
529
- description: {
530
- story:
531
- "Form drawer with select components instead of native select tags, demonstrating proper form handling and validation.",
532
- },
533
- },
534
- },
535
- }
396
+ <div className="border-fm-divider-secondary border-t pt-4" />
536
397
 
537
- // 3. Settings Drawer with Select Components
538
- export const SettingsDrawer: Story = {
539
- render: () => {
540
- const [settings, setSettings] = useState({
541
- theme: "dark",
542
- notifications: "important",
543
- language: "en",
544
- timezone: "utc",
545
- })
398
+ <div className="space-y-2">
399
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
400
+ Variant
401
+ </p>
402
+ <div className="flex flex-wrap gap-1">
403
+ {variants.map((v) => (
404
+ <button
405
+ key={v}
406
+ onClick={() => setVariant(v)}
407
+ className={btnCls(variant === v)}
408
+ >
409
+ {v}
410
+ </button>
411
+ ))}
412
+ </div>
413
+ </div>
546
414
 
547
- return (
548
- <Drawer>
549
- <DrawerTrigger asChild>
550
- <Button>Open Settings</Button>
551
- </DrawerTrigger>
552
- <DrawerContent>
553
- <DrawerHeader>
554
- <DrawerTitle>Settings</DrawerTitle>
555
- <DrawerDescription>
556
- Configure your application preferences.
557
- </DrawerDescription>
558
- </DrawerHeader>
559
- <div className="space-y-6 overflow-auto p-4">
560
- <div className="space-y-4">
561
- <h3 className="text-sm font-medium">Appearance</h3>
562
- <div className="space-y-2">
563
- <Label htmlFor="theme">Theme</Label>
564
- <Select
565
- value={settings.theme}
566
- onValueChange={(value) =>
567
- setSettings({ ...settings, theme: value })
568
- }
569
- >
570
- <SelectTrigger>
571
- <SelectValue />
572
- </SelectTrigger>
573
- <SelectContent>
574
- <SelectItem value="light">Light</SelectItem>
575
- <SelectItem value="dark">Dark</SelectItem>
576
- <SelectItem value="system">System</SelectItem>
577
- </SelectContent>
578
- </Select>
579
- </div>
580
- </div>
581
- <div className="space-y-4">
582
- <h3 className="text-sm font-medium">Notifications</h3>
583
- <div className="space-y-2">
584
- <Label htmlFor="notifications">Email Notifications</Label>
585
- <Select
586
- value={settings.notifications}
587
- onValueChange={(value) =>
588
- setSettings({ ...settings, notifications: value })
589
- }
590
- >
591
- <SelectTrigger>
592
- <SelectValue />
593
- </SelectTrigger>
594
- <SelectContent>
595
- <SelectItem value="all">All notifications</SelectItem>
596
- <SelectItem value="important">Important only</SelectItem>
597
- <SelectItem value="none">None</SelectItem>
598
- </SelectContent>
599
- </Select>
600
- </div>
601
- </div>
602
- <div className="space-y-4">
603
- <h3 className="text-sm font-medium">Regional</h3>
604
- <div className="space-y-2">
605
- <Label htmlFor="language">Language</Label>
606
- <Select
607
- value={settings.language}
608
- onValueChange={(value) =>
609
- setSettings({ ...settings, language: value })
610
- }
611
- >
612
- <SelectTrigger>
613
- <SelectValue />
614
- </SelectTrigger>
615
- <SelectContent>
616
- <SelectItem value="en">English</SelectItem>
617
- <SelectItem value="es">Spanish</SelectItem>
618
- <SelectItem value="fr">French</SelectItem>
619
- <SelectItem value="de">German</SelectItem>
620
- </SelectContent>
621
- </Select>
622
- </div>
623
- <div className="space-y-2">
624
- <Label htmlFor="timezone">Timezone</Label>
625
- <Select
626
- value={settings.timezone}
627
- onValueChange={(value) =>
628
- setSettings({ ...settings, timezone: value })
629
- }
630
- >
631
- <SelectTrigger>
632
- <SelectValue />
633
- </SelectTrigger>
634
- <SelectContent>
635
- <SelectItem value="utc">UTC</SelectItem>
636
- <SelectItem value="est">Eastern Time</SelectItem>
637
- <SelectItem value="pst">Pacific Time</SelectItem>
638
- <SelectItem value="gmt">GMT</SelectItem>
639
- </SelectContent>
640
- </Select>
641
- </div>
642
- </div>
643
- </div>
644
- <DrawerFooter>
645
- <Button onClick={() => console.log("Settings saved:", settings)}>
646
- Save Settings
647
- </Button>
648
- <DrawerClose asChild>
649
- <Button variant="outline">Cancel</Button>
650
- </DrawerClose>
651
- </DrawerFooter>
652
- </DrawerContent>
653
- </Drawer>
654
- )
655
- },
656
- parameters: {
657
- docs: {
658
- description: {
659
- story:
660
- "Settings drawer showcasing select components for configuration options with proper state management.",
661
- },
662
- },
663
- },
664
- }
415
+ <div className="border-fm-divider-secondary border-t pt-4" />
665
416
 
666
- // 4. Nested Drawers
667
- export const NestedDrawers: Story = {
668
- render: () => {
669
- const [isNestedOpen, setIsNestedOpen] = useState(false)
417
+ <div className="space-y-2">
418
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
419
+ Opacity
420
+ </p>
421
+ <div className="flex flex-wrap gap-1">
422
+ {levels.map((l) => (
423
+ <button
424
+ key={l}
425
+ onClick={() => setOpacity(l)}
426
+ className={btnCls(opacity === l)}
427
+ >
428
+ {l}
429
+ </button>
430
+ ))}
431
+ </div>
432
+ </div>
670
433
 
671
- return (
672
- <Drawer>
673
- <DrawerTrigger asChild>
674
- <Button>Open Parent Drawer</Button>
675
- </DrawerTrigger>
676
- <DrawerContent>
677
- <DrawerHeader>
678
- <DrawerTitle>Parent Drawer</DrawerTitle>
679
- <DrawerDescription>
680
- This drawer contains a nested drawer example.
681
- </DrawerDescription>
682
- </DrawerHeader>
683
- <div className="space-y-4 p-4">
684
- <p className="text-muted-foreground text-sm">
685
- This is the parent drawer content.
686
- </p>
687
- <Drawer open={isNestedOpen} onOpenChange={setIsNestedOpen}>
688
- <DrawerTrigger asChild>
689
- <Button variant="outline">Open Nested Drawer</Button>
690
- </DrawerTrigger>
691
- <DrawerContent>
692
- <DrawerHeader>
693
- <DrawerTitle>Nested Drawer</DrawerTitle>
694
- <DrawerDescription>
695
- This is a nested drawer within the parent drawer.
696
- </DrawerDescription>
697
- </DrawerHeader>
698
- <div className="p-4">
699
- <p className="text-muted-foreground text-sm">
700
- Nested drawer content goes here.
434
+ <div className="space-y-2">
435
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
436
+ Glass
437
+ </p>
438
+ <div className="flex flex-wrap gap-1">
439
+ {levels.map((l) => (
440
+ <button
441
+ key={l}
442
+ onClick={() => setGlass(l)}
443
+ className={btnCls(glass === l)}
444
+ >
445
+ {l}
446
+ </button>
447
+ ))}
448
+ </div>
449
+ </div>
450
+
451
+ <div className="space-y-2">
452
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
453
+ Noise
701
454
  </p>
455
+ <div className="flex flex-wrap gap-1">
456
+ {levels.map((l) => (
457
+ <button
458
+ key={l}
459
+ onClick={() => setNoise(l)}
460
+ className={btnCls(noise === l)}
461
+ >
462
+ {l}
463
+ </button>
464
+ ))}
465
+ </div>
702
466
  </div>
703
- <DrawerFooter>
704
- <Button onClick={() => setIsNestedOpen(false)}>
705
- Close Nested
706
- </Button>
707
- <DrawerClose asChild>
708
- <Button variant="outline">Cancel</Button>
709
- </DrawerClose>
710
- </DrawerFooter>
711
- </DrawerContent>
712
- </Drawer>
713
- </div>
714
- <DrawerFooter>
715
- <Button>Save</Button>
716
- <DrawerClose asChild>
717
- <Button variant="outline">Close Parent</Button>
718
- </DrawerClose>
719
- </DrawerFooter>
720
- </DrawerContent>
721
- </Drawer>
722
- )
723
- },
724
- parameters: {
725
- docs: {
726
- description: {
727
- story:
728
- "Nested drawer example demonstrating proper modal stacking and z-index management.",
729
- },
730
- },
731
- },
732
- }
733
467
 
734
- // 5. Custom Close Button
735
- export const CustomCloseButton: Story = {
736
- render: () => (
737
- <Drawer>
738
- <DrawerTrigger asChild>
739
- <Button>Open Drawer with Custom Close</Button>
740
- </DrawerTrigger>
741
- <DrawerContent>
742
- <DrawerHeader>
743
- <div className="flex items-center justify-between">
744
- <div className="flex-1 text-center">
745
- <DrawerTitle>Custom Close Button</DrawerTitle>
746
- <DrawerDescription>
747
- This drawer has a custom close button in the header.
748
- </DrawerDescription>
468
+ <div className="border-fm-divider-secondary border-t pt-4" />
469
+
470
+ <div className="flex items-center gap-2">
471
+ <Checkbox
472
+ id="swipe-btn"
473
+ checked={showSwipeButton}
474
+ onCheckedChange={(c) => setShowSwipeButton(!!c)}
475
+ />
476
+ <Label
477
+ htmlFor="swipe-btn"
478
+ className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm"
479
+ >
480
+ Swipe handle
481
+ </Label>
482
+ </div>
483
+ </div>
484
+
485
+ {/* Preview stage */}
486
+ <div className="flex flex-col gap-3 lg:col-span-2">
487
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary flex min-h-48 flex-col items-center justify-center gap-4 rounded-xl border p-8">
488
+ {submitted && (
489
+ <div className="border-fm-divider-positive bg-fm-surface-positive-sec rounded-lg border px-4 py-2">
490
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
491
+ Form submitted for{" "}
492
+ <span className="text-fm-primary font-medium">
493
+ {name}
494
+ </span>
495
+ </p>
496
+ </div>
497
+ )}
498
+
499
+ <Drawer direction={direction}>
500
+ <DrawerTrigger asChild>
501
+ <Button onClick={() => setSubmitted(false)}>
502
+ Open Drawer
503
+ </Button>
504
+ </DrawerTrigger>
505
+ <DrawerContent
506
+ variant={variant}
507
+ opacity={opacity}
508
+ glass={glass}
509
+ noise={noise}
510
+ showSwipeButton={showSwipeButton}
511
+ >
512
+ <DrawerHeader>
513
+ <DrawerTitle>Quick Contact</DrawerTitle>
514
+ <DrawerDescription>
515
+ Fill out the form to send a message.
516
+ </DrawerDescription>
517
+ </DrawerHeader>
518
+
519
+ <div className="space-y-4 p-4">
520
+ <div className="space-y-2">
521
+ <Label htmlFor="drawer-name">Name</Label>
522
+ <Input
523
+ id="drawer-name"
524
+ placeholder="Your name"
525
+ value={name}
526
+ onChange={(e) => setName(e.target.value)}
527
+ />
528
+ </div>
529
+ <div className="space-y-2">
530
+ <Label htmlFor="drawer-email">Email</Label>
531
+ <Input
532
+ id="drawer-email"
533
+ type="email"
534
+ placeholder="your@email.com"
535
+ value={email}
536
+ onChange={(e) => setEmail(e.target.value)}
537
+ />
538
+ </div>
539
+ </div>
540
+
541
+ <DrawerFooter>
542
+ <DrawerClose asChild>
543
+ <Button
544
+ disabled={!name || !email}
545
+ onClick={() => setSubmitted(true)}
546
+ >
547
+ Submit
548
+ </Button>
549
+ </DrawerClose>
550
+ <DrawerClose asChild>
551
+ <Button variant="outline">Cancel</Button>
552
+ </DrawerClose>
553
+ </DrawerFooter>
554
+ </DrawerContent>
555
+ </Drawer>
556
+ </div>
557
+
558
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
559
+ <code className="text-fm-secondary text-fm-sm leading-fm-sm font-(--font-fm-mono)">
560
+ {`<Drawer direction="${direction}"><DrawerContent variant="${variant}" opacity="${opacity}" glass="${glass}" noise="${noise}" showSwipeButton={${showSwipeButton}} />`}
561
+ </code>
562
+ </div>
563
+ </div>
749
564
  </div>
750
- <DrawerClose asChild>
751
- <Button variant="text" size="sm" className="ml-4">
752
- <CrossIcon className="h-4 w-4" />
753
- </Button>
754
- </DrawerClose>
755
565
  </div>
756
- </DrawerHeader>
566
+ </div>
567
+ )
568
+ }
757
569
 
758
- <DrawerFooter>
759
- <Button>Confirm</Button>
760
- <DrawerClose asChild>
761
- <Button variant="outline">Cancel</Button>
762
- </DrawerClose>
763
- </DrawerFooter>
764
- </DrawerContent>
765
- </Drawer>
766
- ),
570
+ return <InteractiveDemo />
571
+ },
767
572
  parameters: {
768
573
  docs: {
769
574
  description: {
770
575
  story:
771
- "Drawer with custom close button positioned in the header for enhanced user experience.",
576
+ "Live configurator select direction, variant, overlay settings, and swipe handle, then open the drawer and submit the form inside to see state feedback.",
772
577
  },
773
578
  },
774
579
  },
775
580
  }
776
581
 
777
- // 6. Accessibility Example
778
- export const AccessibilityExample: Story = {
582
+ // ─── UseCases ─────────────────────────────────────────────────────────────────
583
+
584
+ export const UseCases: Story = {
779
585
  render: () => {
780
- return (
781
- <Drawer>
782
- <DrawerTrigger asChild>
783
- <Button>Accessible Drawer Demo</Button>
784
- </DrawerTrigger>
785
- <DrawerContent>
786
- <DrawerHeader>
787
- <DrawerTitle>Accessibility Features</DrawerTitle>
788
- <DrawerDescription>
789
- This drawer demonstrates proper accessibility implementation.
790
- </DrawerDescription>
791
- </DrawerHeader>
586
+ // Track actions bottom drawer
587
+ const TrackActionsDrawer = () => {
588
+ const [liked, setLiked] = useState(false)
589
+ const [queued, setQueued] = useState(false)
792
590
 
793
- <div className="space-y-4 overflow-auto p-4">
794
- <div className="rounded-lg border border-white/10 bg-white/5 p-4">
795
- <h4 className="mb-2 font-medium text-white">
796
- Keyboard Navigation
797
- </h4>
798
- <ul className="space-y-1 text-sm text-white/80">
799
- <li>
800
- <kbd className="rounded bg-white/10 px-1">Tab</kbd> -
801
- Navigate between elements
802
- </li>
803
- <li>
804
- • <kbd className="rounded bg-white/10 px-1">Escape</kbd> -
805
- Close drawer
806
- </li>
807
- <li>
808
- • <kbd className="rounded bg-white/10 px-1">Enter</kbd> -
809
- Activate buttons
810
- </li>
811
- <li>
812
- • <kbd className="rounded bg-white/10 px-1">Space</kbd> -
813
- Activate buttons
814
- </li>
815
- </ul>
816
- </div>
591
+ return (
592
+ <Drawer direction="bottom">
593
+ <DrawerTrigger asChild>
594
+ <Button variant="outline" size="sm">
595
+ Track actions
596
+ </Button>
597
+ </DrawerTrigger>
598
+ <DrawerContent showSwipeButton>
599
+ <DrawerHeader>
600
+ <DrawerTitle>Midnight Drive</DrawerTitle>
601
+ <DrawerDescription>Lo-fi Chill · 3:42</DrawerDescription>
602
+ </DrawerHeader>
817
603
 
818
- <div className="rounded-lg border border-white/10 bg-white/5 p-4">
819
- <h4 className="mb-2 font-medium text-white">Focus Management</h4>
820
- <ul className="space-y-1 text-sm text-white/80">
821
- <li>• Automatic focus trapping within drawer</li>
822
- <li>• Focus restoration when drawer closes</li>
823
- <li>• Proper focus order for all interactive elements</li>
824
- <li>• Screen reader announcements for state changes</li>
825
- </ul>
604
+ <div className="space-y-1 p-4">
605
+ {[
606
+ {
607
+ label: liked ? "Remove from Liked" : "Like this track",
608
+ icon: TickCircleIcon,
609
+ action: () => setLiked((v) => !v),
610
+ active: liked,
611
+ },
612
+ {
613
+ label: queued ? "Remove from queue" : "Add to queue",
614
+ icon: MusicalNoteIcon,
615
+ action: () => setQueued((v) => !v),
616
+ active: queued,
617
+ },
618
+ {
619
+ label: "Go to artist",
620
+ icon: ChevronRightIcon,
621
+ action: () => {},
622
+ active: false,
623
+ },
624
+ {
625
+ label: "Share",
626
+ icon: SearchIcon,
627
+ action: () => {},
628
+ active: false,
629
+ },
630
+ ].map((item) => (
631
+ <button
632
+ key={item.label}
633
+ onClick={item.action}
634
+ className={`flex w-full items-center gap-3 rounded-lg px-3 py-3 text-left transition-colors ${
635
+ item.active
636
+ ? "bg-fm-surface-positive-sec text-fm-primary"
637
+ : "text-fm-primary hover:bg-fm-surface-secondary"
638
+ }`}
639
+ >
640
+ <item.icon className="text-fm-secondary h-5 w-5 shrink-0" />
641
+ <span className="font-fm-text text-fm-md leading-fm-md">
642
+ {item.label}
643
+ </span>
644
+ </button>
645
+ ))}
826
646
  </div>
827
647
 
828
- <div className="rounded-lg border border-white/10 bg-white/5 p-4">
829
- <h4 className="mb-2 font-medium text-white">Drag Support</h4>
830
- <ul className="space-y-1 text-sm text-white/80">
831
- <li>• Drag to close functionality</li>
832
- <li>• Smooth animations during drag</li>
833
- <li>• Haptic feedback on mobile devices</li>
834
- <li>• Proper gesture recognition</li>
835
- </ul>
836
- </div>
837
- </div>
648
+ <DrawerFooter>
649
+ <DrawerClose asChild>
650
+ <Button variant="outline">Close</Button>
651
+ </DrawerClose>
652
+ </DrawerFooter>
653
+ </DrawerContent>
654
+ </Drawer>
655
+ )
656
+ }
838
657
 
839
- <DrawerFooter>
840
- <DrawerClose asChild>
841
- <Button>Close Drawer</Button>
842
- </DrawerClose>
843
- </DrawerFooter>
844
- </DrawerContent>
845
- </Drawer>
846
- )
847
- },
848
- parameters: {
849
- docs: {
850
- description: {
851
- story:
852
- "Comprehensive accessibility example showcasing keyboard navigation, focus management, and drag support features.",
853
- },
854
- },
855
- },
856
- }
658
+ // Side navigation drawer
659
+ const NavDrawer = () => {
660
+ const [active, setActive] = useState("Home")
661
+ const items = [
662
+ { label: "Home", icon: SiteLogoIcon },
663
+ { label: "Search", icon: SearchIcon },
664
+ { label: "Library", icon: MusicalNoteIcon },
665
+ { label: "Settings", icon: MaintenanceIcon },
666
+ ]
857
667
 
858
- // 7. Drawer without Overlay
859
- export const DrawerWithoutOverlay: Story = {
860
- render: () => (
861
- <div>
862
- <Drawer>
863
- <DrawerTrigger asChild>
864
- <Button className="relative z-10">Open Drawer (No Overlay)</Button>
865
- </DrawerTrigger>
866
- <DrawerContent showOverlay={false}>
867
- <DrawerHeader>
868
- <DrawerTitle>Drawer Without Overlay</DrawerTitle>
869
- <DrawerDescription>
870
- This drawer opens without a backdrop overlay, allowing background
871
- content to remain visible.
872
- </DrawerDescription>
873
- </DrawerHeader>
874
- <DrawerFooter>
875
- <Button>Apply Changes</Button>
876
- <DrawerClose asChild>
877
- <Button variant="outline">Cancel</Button>
878
- </DrawerClose>
879
- </DrawerFooter>
880
- </DrawerContent>
881
- </Drawer>
882
- </div>
883
- ),
884
- parameters: {
885
- docs: {
886
- description: {
887
- story:
888
- "Drawer example with `showOverlay={false}` demonstrating how to create non-modal drawer interactions that don't obscure background content.",
889
- },
890
- },
891
- },
892
- }
668
+ return (
669
+ <Drawer direction="left">
670
+ <DrawerTrigger asChild>
671
+ <Button variant="outline" size="sm">
672
+ Side navigation
673
+ </Button>
674
+ </DrawerTrigger>
675
+ <DrawerContent>
676
+ <DrawerHeader>
677
+ <DrawerTitle>Navigation</DrawerTitle>
678
+ <DrawerDescription>Main app navigation</DrawerDescription>
679
+ </DrawerHeader>
680
+
681
+ <nav className="space-y-1 p-4">
682
+ {items.map((item) => (
683
+ <button
684
+ key={item.label}
685
+ onClick={() => setActive(item.label)}
686
+ className={`flex w-full items-center gap-3 rounded-lg px-3 py-3 text-left transition-colors ${
687
+ active === item.label
688
+ ? "bg-fm-surface-info-sec text-fm-primary"
689
+ : "text-fm-primary hover:bg-fm-surface-secondary"
690
+ }`}
691
+ >
692
+ <item.icon className="text-fm-secondary h-5 w-5 shrink-0" />
693
+ <span className="font-fm-text text-fm-md leading-fm-md">
694
+ {item.label}
695
+ </span>
696
+ </button>
697
+ ))}
698
+ </nav>
699
+
700
+ <DrawerFooter>
701
+ <DrawerClose asChild>
702
+ <Button variant="outline">Close</Button>
703
+ </DrawerClose>
704
+ </DrawerFooter>
705
+ </DrawerContent>
706
+ </Drawer>
707
+ )
708
+ }
709
+
710
+ // Settings panel drawer
711
+ const SettingsDrawer = () => {
712
+ const [autoplay, setAutoplay] = useState(true)
713
+ const [notifications, setNotifications] = useState(false)
714
+ const [hq, setHq] = useState(true)
893
715
 
894
- // 8. Overlay Variations
895
- export const OverlayVariations: Story = {
896
- render: () => {
897
- const OverlayDrawer = ({
898
- opacity,
899
- glass,
900
- noise,
901
- title,
902
- description,
903
- }: any) => {
904
716
  return (
905
- <Drawer>
717
+ <Drawer direction="right">
906
718
  <DrawerTrigger asChild>
907
719
  <Button variant="outline" size="sm">
908
- {title}
720
+ Settings panel
909
721
  </Button>
910
722
  </DrawerTrigger>
911
- <DrawerContent
912
- opacity={opacity}
913
- glass={glass}
914
- noise={noise}
915
- variant="neutral"
916
- >
723
+ <DrawerContent>
917
724
  <DrawerHeader>
918
- <DrawerTitle>{title}</DrawerTitle>
919
- <DrawerDescription>{description}</DrawerDescription>
725
+ <DrawerTitle>Playback Settings</DrawerTitle>
726
+ <DrawerDescription>
727
+ Configure your listening experience
728
+ </DrawerDescription>
920
729
  </DrawerHeader>
921
- <div className="py-4">
922
- <div className="grid grid-cols-2 gap-2 text-xs text-white/60">
923
- <div>
924
- Opacity:{" "}
925
- <span className="text-white">{opacity || "default"}</span>
926
- </div>
927
- <div>
928
- Glass:{" "}
929
- <span className="text-white">{glass || "default"}</span>
930
- </div>
931
- <div>
932
- Noise: <span className="text-white">{noise || "none"}</span>
730
+
731
+ <div className="space-y-5 p-4">
732
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
733
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm mb-3 font-semibold tracking-widest uppercase">
734
+ Playback
735
+ </p>
736
+ <div className="space-y-3">
737
+ {[
738
+ { label: "Autoplay", value: autoplay, set: setAutoplay },
739
+ { label: "High quality audio", value: hq, set: setHq },
740
+ ].map((s) => (
741
+ <div
742
+ key={s.label}
743
+ className="flex items-center justify-between"
744
+ >
745
+ <span className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
746
+ {s.label}
747
+ </span>
748
+ <Checkbox
749
+ checked={s.value}
750
+ onCheckedChange={(c) => s.set(!!c)}
751
+ />
752
+ </div>
753
+ ))}
933
754
  </div>
934
- <div>
935
- Variant: <span className="text-white">neutral</span>
755
+ </div>
756
+
757
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
758
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm mb-3 font-semibold tracking-widest uppercase">
759
+ Notifications
760
+ </p>
761
+ <div className="flex items-center justify-between">
762
+ <span className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
763
+ Push notifications
764
+ </span>
765
+ <Checkbox
766
+ checked={notifications}
767
+ onCheckedChange={(c) => setNotifications(!!c)}
768
+ />
936
769
  </div>
937
770
  </div>
938
771
  </div>
772
+
939
773
  <DrawerFooter>
940
774
  <DrawerClose asChild>
941
- <Button>Close</Button>
775
+ <Button>Save</Button>
776
+ </DrawerClose>
777
+ <DrawerClose asChild>
778
+ <Button variant="outline">Cancel</Button>
942
779
  </DrawerClose>
943
780
  </DrawerFooter>
944
781
  </DrawerContent>
@@ -947,174 +784,39 @@ export const OverlayVariations: Story = {
947
784
  }
948
785
 
949
786
  return (
950
- <div className="space-y-8">
951
- <div className="text-center">
952
- <h3 className="mb-2 font-medium text-white">Overlay Variations</h3>
953
- <p className="text-sm text-white/60">
954
- Different overlay effects for various visual styles
787
+ <div className="mx-auto max-w-3xl space-y-8 p-8">
788
+ <div className="space-y-3">
789
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
790
+ Mobile Bottom Drawer — Track Actions
791
+ </h4>
792
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-xl">
793
+ A bottom sheet presenting contextual actions for the currently
794
+ playing track. Includes a swipe handle and stateful like/queue
795
+ toggles.
955
796
  </p>
797
+ <TrackActionsDrawer />
956
798
  </div>
957
799
 
958
- <div className="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-4">
959
- <OverlayDrawer
960
- opacity="low"
961
- title="Low Opacity"
962
- description="Subtle background dimming (40%)"
963
- />
964
- <OverlayDrawer
965
- opacity="medium"
966
- title="Medium Opacity"
967
- description="Balanced background dimming (60%)"
968
- />
969
- <OverlayDrawer
970
- opacity="high"
971
- title="High Opacity"
972
- description="Strong background dimming (80%)"
973
- />
974
- <OverlayDrawer
975
- opacity="none"
976
- title="Full Opacity"
977
- description="Complete background coverage (100%)"
978
- />
979
- <OverlayDrawer
980
- glass="low"
981
- title="Low Glass"
982
- description="Subtle backdrop blur effect"
983
- />
984
- <OverlayDrawer
985
- glass="medium"
986
- title="Medium Glass"
987
- description="Balanced backdrop blur effect"
988
- />
989
- <OverlayDrawer
990
- glass="high"
991
- title="High Glass"
992
- description="Strong backdrop blur effect"
993
- />
994
- <OverlayDrawer
995
- noise="low"
996
- title="Low Noise"
997
- description="Subtle texture pattern"
998
- />
999
- <OverlayDrawer
1000
- noise="medium"
1001
- title="Medium Noise"
1002
- description="Balanced texture pattern"
1003
- />
1004
- <OverlayDrawer
1005
- noise="high"
1006
- title="High Noise"
1007
- description="Strong texture pattern"
1008
- />
1009
- <OverlayDrawer
1010
- opacity="medium"
1011
- glass="medium"
1012
- noise="medium"
1013
- title="Balanced"
1014
- description="All effects at medium level"
1015
- />
1016
- </div>
1017
- </div>
1018
- )
1019
- },
1020
- parameters: {
1021
- docs: {
1022
- description: {
1023
- story:
1024
- "Showcase of different overlay configurations demonstrating various opacity, glass, and noise effects.",
1025
- },
1026
- },
1027
- },
1028
- }
1029
-
1030
- // 9. Variant Examples
1031
- export const VariantExamples: Story = {
1032
- render: () => {
1033
- return (
1034
- <div className="space-y-8">
1035
- <div className="text-center">
1036
- <h3 className="mb-2 font-medium text-white">Drawer Variants</h3>
1037
- <p className="text-sm text-white/60">
1038
- Compare the neutral (default) and gradient variants
800
+ <div className="space-y-3">
801
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
802
+ Side Navigation Drawer
803
+ </h4>
804
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-xl">
805
+ A left-side navigation drawer for switching between primary app
806
+ sections. Active item is highlighted.
1039
807
  </p>
808
+ <NavDrawer />
1040
809
  </div>
1041
810
 
1042
- <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
1043
- <div className="space-y-4">
1044
- <h4 className="text-center font-medium text-white">
1045
- Neutral Variant (Default)
1046
- </h4>
1047
- <Drawer>
1048
- <DrawerTrigger asChild>
1049
- <Button variant="outline" className="w-full">
1050
- Open Neutral Drawer
1051
- </Button>
1052
- </DrawerTrigger>
1053
- <DrawerContent variant="neutral">
1054
- <DrawerHeader>
1055
- <DrawerTitle>Neutral Variant</DrawerTitle>
1056
- <DrawerDescription>
1057
- This is the default neutral variant with frosted glass
1058
- background and border.
1059
- </DrawerDescription>
1060
- </DrawerHeader>
1061
- <div className="py-4">
1062
- <div className="rounded-lg border border-white/10 bg-white/5 p-4">
1063
- <h5 className="mb-2 font-medium text-white">Features:</h5>
1064
- <ul className="space-y-1 text-sm text-white/70">
1065
- <li>• Frosted glass background</li>
1066
- <li>• Subtle border</li>
1067
- <li>• Backdrop blur effect</li>
1068
- <li>• Semi-transparent appearance</li>
1069
- </ul>
1070
- </div>
1071
- </div>
1072
- <DrawerFooter>
1073
- <DrawerClose asChild>
1074
- <Button>Close</Button>
1075
- </DrawerClose>
1076
- </DrawerFooter>
1077
- </DrawerContent>
1078
- </Drawer>
1079
- </div>
1080
-
1081
- <div className="space-y-4">
1082
- <h4 className="text-center font-medium text-white">
1083
- Gradient Variant
1084
- </h4>
1085
- <Drawer>
1086
- <DrawerTrigger asChild>
1087
- <Button variant="outline" className="w-full">
1088
- Open Gradient Drawer
1089
- </Button>
1090
- </DrawerTrigger>
1091
- <DrawerContent variant="gradient">
1092
- <DrawerHeader>
1093
- <DrawerTitle>Gradient Variant</DrawerTitle>
1094
- <DrawerDescription>
1095
- This is the gradient variant with white gradient background
1096
- and no border.
1097
- </DrawerDescription>
1098
- </DrawerHeader>
1099
- <div className="py-4">
1100
- <div className="rounded-lg border border-white/10 bg-white/5 p-4">
1101
- <h5 className="mb-2 font-medium text-white">Features:</h5>
1102
- <ul className="space-y-1 text-sm text-white/70">
1103
- <li>• White gradient background</li>
1104
- <li>• No border</li>
1105
- <li>• Clean, modern appearance</li>
1106
- <li>• Solid background effect</li>
1107
- </ul>
1108
- </div>
1109
- </div>
1110
- <DrawerFooter>
1111
- <DrawerClose asChild>
1112
- <Button>Close</Button>
1113
- </DrawerClose>
1114
- </DrawerFooter>
1115
- </DrawerContent>
1116
- </Drawer>
1117
- </div>
811
+ <div className="space-y-3">
812
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
813
+ Settings Panel Drawer
814
+ </h4>
815
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-xl">
816
+ A right-side settings panel that groups playback and notification
817
+ preferences with interactive checkboxes.
818
+ </p>
819
+ <SettingsDrawer />
1118
820
  </div>
1119
821
  </div>
1120
822
  )
@@ -1123,43 +825,7 @@ export const VariantExamples: Story = {
1123
825
  docs: {
1124
826
  description: {
1125
827
  story:
1126
- "Simple comparison of the two drawer variants: neutral (default) with frosted glass background and gradient with white gradient background.",
1127
- },
1128
- },
1129
- },
1130
- }
1131
-
1132
- export const DrawerWithSwipeButton: Story = {
1133
- render: () => (
1134
- <div>
1135
- <Drawer>
1136
- <DrawerTrigger asChild>
1137
- <Button className="relative z-10">
1138
- Open Drawer (With Swipe button)
1139
- </Button>
1140
- </DrawerTrigger>
1141
- <DrawerContent showSwipeButton={true}>
1142
- <DrawerHeader>
1143
- <DrawerTitle>Drawer with Swipe button</DrawerTitle>
1144
- <DrawerDescription>
1145
- This drawer opens with a swipe button.
1146
- </DrawerDescription>
1147
- </DrawerHeader>
1148
- <DrawerFooter>
1149
- <Button>Apply Changes</Button>
1150
- <DrawerClose asChild>
1151
- <Button variant="outline">Cancel</Button>
1152
- </DrawerClose>
1153
- </DrawerFooter>
1154
- </DrawerContent>
1155
- </Drawer>
1156
- </div>
1157
- ),
1158
- parameters: {
1159
- docs: {
1160
- description: {
1161
- story:
1162
- "Drawer example with `showSwipeButton={true}` showing a swipe indicator button",
828
+ "Three realistic product scenarios: a mobile bottom track-actions sheet, a left-side app navigation drawer, and a right-side settings panel.",
1163
829
  },
1164
830
  },
1165
831
  },