aural-ui 3.0.7 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1199
  2. package/dist/components/avatar/Avatar.stories.tsx +235 -237
  3. package/dist/components/badge/Badge.stories.tsx +379 -116
  4. package/dist/components/banner/Banner.stories.tsx +445 -391
  5. package/dist/components/breadcrumb/Breadcrumb.stories.tsx +453 -199
  6. package/dist/components/button/Button.stories.tsx +585 -230
  7. package/dist/components/button/index.tsx +7 -7
  8. package/dist/components/card/Card.stories.tsx +619 -301
  9. package/dist/components/char-count/CharCount.stories.tsx +350 -248
  10. package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
  11. package/dist/components/chip/Chip.stories.tsx +362 -168
  12. package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -620
  13. package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
  14. package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
  15. package/dist/components/command/Command.stories.tsx +533 -856
  16. package/dist/components/dialog/Dialog.stories.tsx +505 -949
  17. package/dist/components/divider/Divider.stories.tsx +265 -502
  18. package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
  19. package/dist/components/drawer/Drawer.stories.tsx +659 -993
  20. package/dist/components/drawer/index.tsx +3 -3
  21. package/dist/components/dropdown/Dropdown.stories.tsx +643 -1018
  22. package/dist/components/form/Form.stories.tsx +560 -274
  23. package/dist/components/helper-text/HelperText.stories.tsx +199 -200
  24. package/dist/components/hover-card/HoverCard.stories.tsx +318 -1221
  25. package/dist/components/icon-button/IconButton.stories.tsx +837 -194
  26. package/dist/components/if-else/if-else.stories.tsx +370 -83
  27. package/dist/components/input/Input.stories.tsx +436 -368
  28. package/dist/components/label/Label.stories.tsx +156 -154
  29. package/dist/components/list/List.stories.tsx +485 -822
  30. package/dist/components/marquee/Marquee.stories.tsx +356 -694
  31. package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -410
  32. package/dist/components/overlay/Overlay.stories.tsx +452 -818
  33. package/dist/components/overlay/index.tsx +4 -4
  34. package/dist/components/pagination/Pagination.stories.tsx +721 -210
  35. package/dist/components/popover/Popover.stories.tsx +484 -873
  36. package/dist/components/radio/Radio.stories.tsx +432 -124
  37. package/dist/components/resizable/Resizable.stories.tsx +496 -752
  38. package/dist/components/scroll-area/ScrollArea.stories.tsx +384 -1006
  39. package/dist/components/search/Search.stories.tsx +314 -575
  40. package/dist/components/select/Select.stories.tsx +684 -787
  41. package/dist/components/sheet/Sheet.stories.tsx +671 -936
  42. package/dist/components/skelton/Skelton.stories.tsx +230 -764
  43. package/dist/components/slider/Slider.stories.tsx +384 -737
  44. package/dist/components/stepper/Stepper.stories.tsx +371 -514
  45. package/dist/components/switch/Switch.stories.tsx +461 -208
  46. package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
  47. package/dist/components/table/Table.stories.tsx +770 -914
  48. package/dist/components/tabs/Tabs.stories.tsx +459 -1400
  49. package/dist/components/tag/Tag.stories.tsx +714 -542
  50. package/dist/components/textarea/TextArea.stories.tsx +621 -562
  51. package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -148
  52. package/dist/components/toast/Toast.stories.tsx +452 -1333
  53. package/dist/components/toggle/Toggle.stories.tsx +488 -909
  54. package/dist/components/tooltip/Tooltip.stories.tsx +344 -1372
  55. package/dist/components/typography/Typography.stories.tsx +406 -89
  56. package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
  57. package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
  58. package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
  59. package/dist/icons/Icons.stories.tsx +0 -12
  60. package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +226 -1013
  61. package/dist/icons/alert-icon/AlertIcon.stories.tsx +109 -929
  62. package/dist/icons/all-icons.tsx +124 -87
  63. package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +140 -971
  64. package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +148 -888
  65. package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +135 -1019
  66. package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +137 -953
  67. package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +138 -997
  68. package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +136 -942
  69. package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +148 -1092
  70. package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +146 -1211
  71. package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +126 -615
  72. package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +144 -1164
  73. package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +167 -985
  74. package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +122 -1179
  75. package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +124 -1168
  76. package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +119 -850
  77. package/dist/icons/camera-icon/CameraIcon.stories.tsx +112 -1213
  78. package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +117 -934
  79. package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +160 -961
  80. package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +163 -961
  81. package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +144 -942
  82. package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +129 -966
  83. package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +147 -964
  84. package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +145 -975
  85. package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +150 -1142
  86. package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +114 -461
  87. package/dist/icons/coin-icon/CoinIcon.stories.tsx +124 -1322
  88. package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +117 -1318
  89. package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +114 -903
  90. package/dist/icons/command-icon/CommandIcon.stories.tsx +127 -1042
  91. package/dist/icons/copy-icon/CopyIcon.stories.tsx +123 -962
  92. package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +147 -999
  93. package/dist/icons/cross-icon/CrossIcon.stories.tsx +139 -960
  94. package/dist/icons/download-icon/DownloadIcon.stories.tsx +126 -820
  95. package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +124 -1031
  96. package/dist/icons/email-icon/EmailIcon.stories.tsx +115 -936
  97. package/dist/icons/expand-icon/ExpandIcon.stories.tsx +112 -1111
  98. package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +144 -1025
  99. package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +143 -1036
  100. package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +127 -1011
  101. package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +126 -1056
  102. package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +125 -614
  103. package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +119 -1050
  104. package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +169 -989
  105. package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +115 -1145
  106. package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +115 -1122
  107. package/dist/icons/globe-icon/GlobeIcon.stories.tsx +130 -313
  108. package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +145 -940
  109. package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +119 -1174
  110. package/dist/icons/head-icon/HeadIcon.stories.tsx +111 -916
  111. package/dist/icons/heart-icon/HeartIcon.stories.tsx +120 -1019
  112. package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +119 -683
  113. package/dist/icons/image-icon/ImageIcon.stories.tsx +105 -1121
  114. package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +111 -1192
  115. package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +136 -1256
  116. package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +159 -962
  117. package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +161 -1385
  118. package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +124 -972
  119. package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +119 -948
  120. package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +119 -942
  121. package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +108 -1215
  122. package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +154 -1517
  123. package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +110 -1188
  124. package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +119 -678
  125. package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +123 -1184
  126. package/dist/icons/message-icon/MessageIcon.stories.tsx +114 -538
  127. package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +116 -1158
  128. package/dist/icons/moon-icon/MoonIcon.stories.tsx +120 -536
  129. package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +109 -1184
  130. package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +115 -1134
  131. package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +119 -971
  132. package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +111 -1100
  133. package/dist/icons/notes-icon/NotesIcon.stories.tsx +119 -1101
  134. package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +109 -1111
  135. package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +122 -684
  136. package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +113 -954
  137. package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +112 -877
  138. package/dist/icons/pause-icon/PauseIcon.stories.tsx +113 -1000
  139. package/dist/icons/pencil-icon/PencilIcon.stories.tsx +115 -1070
  140. package/dist/icons/phone-icon/PhoneIcon.stories.tsx +115 -978
  141. package/dist/icons/plus-icon/PlusIcon.stories.tsx +106 -1093
  142. package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +107 -829
  143. package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +102 -469
  144. package/dist/icons/search-icon/SearchIcon.stories.tsx +111 -1124
  145. package/dist/icons/setting-icon/SettingIcon.stories.tsx +107 -970
  146. package/dist/icons/share-icon/ShareIcon.stories.tsx +120 -1025
  147. package/dist/icons/shield-icon/ShieldIcon.stories.tsx +117 -931
  148. package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +137 -1104
  149. package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +172 -982
  150. package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +164 -983
  151. package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +105 -958
  152. package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +158 -580
  153. package/dist/icons/spinner-gradient-icon/index.tsx +6 -1
  154. package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +158 -587
  155. package/dist/icons/spinner-solid-icon/index.tsx +6 -1
  156. package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +146 -682
  157. package/dist/icons/spinner-solid-neutral-icon/index.tsx +1 -1
  158. package/dist/icons/star-icon/StarIcon.stories.tsx +124 -904
  159. package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +112 -964
  160. package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +116 -852
  161. package/dist/icons/sun-icon/SunIcon.stories.tsx +120 -831
  162. package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +116 -950
  163. package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +123 -980
  164. package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +156 -1427
  165. package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +146 -1142
  166. package/dist/icons/tick-icon/TickIcon.stories.tsx +145 -1276
  167. package/dist/icons/trash-icon/TrashIcon.stories.tsx +108 -933
  168. package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +157 -1402
  169. package/dist/icons/upload-icon/UploadIcon.stories.tsx +115 -889
  170. package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +118 -984
  171. package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +125 -1049
  172. package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +123 -1356
  173. package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +110 -1171
  174. package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +112 -1093
  175. package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +115 -1087
  176. package/dist/icons/warning-icon/WarningIcon.stories.tsx +122 -1046
  177. package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +161 -936
  178. package/dist/index.cjs +84 -84
  179. package/dist/index.js +84 -84
  180. package/dist/styles/aural-all-theme.css +1222 -0
  181. package/dist/styles/{aural-theme.css → aural-dark-theme.css} +15 -3
  182. package/dist/styles/aural-light-theme.css +1047 -0
  183. package/package.json +1 -1
@@ -1,6 +1,8 @@
1
1
  import React from "react"
2
2
  import type { Meta, StoryObj } from "@storybook/react-vite"
3
3
 
4
+ import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
5
+
4
6
  import { Slider } from "."
5
7
 
6
8
  const meta: Meta<typeof Slider> = {
@@ -8,126 +10,29 @@ const meta: Meta<typeof Slider> = {
8
10
  component: Slider,
9
11
  parameters: {
10
12
  layout: "centered",
11
- backgrounds: {
12
- default: "dark",
13
- values: [
14
- { name: "dark", value: "#0a0a0a" },
15
- { name: "light", value: "#ffffff" },
16
- ],
17
- },
18
13
  docs: {
19
14
  description: {
20
- component: `
21
- # Slider Component
22
-
23
- A customizable range slider component built with Radix UI primitives and design system integration.
24
-
25
- ## Features
26
-
27
- - **Multiple Variants**: Default, primary, secondary, positive, warning, and info variants
28
- - **Size Options**: Small (sm), medium (md), and large (lg) sizes
29
- - **Orientation Support**: Horizontal and vertical orientations
30
- - **Range & Single Value**: Support for both single value and range selection
31
- - **Label Display**: Configurable thumb labels with custom text or values
32
- - **Align Thumb**: Optional thumb alignment
33
- - **Accessibility**: Built with Radix UI for keyboard navigation and screen reader support
34
- - **Custom Styling**: Flexible class override system for complete customization
35
- - **Touch Support**: Touch-friendly interaction on mobile devices
36
- - **Design System**: Integrated with FM design tokens
37
-
38
- ## Anatomy
39
-
40
- ### Core Components
41
- - **SliderRoot**: Main container with orientation and interaction handling
42
- - **SliderTrack**: Background track element
43
- - **SliderRange**: Active range/progress indicator
44
- - **SliderThumb**: Interactive handle(s) for value selection with optional labels
45
-
46
- ## Props Interface
47
-
48
- \`\`\`tsx
49
- interface SliderProps extends React.ComponentProps<typeof SliderPrimitive.Root> {
50
- variant?: "default" | "primary" | "secondary" | "positive" | "warning" | "info"
51
- size?: "sm" | "md" | "lg"
52
- showLabel?: boolean // Show/hide thumb labels
53
- label?: string // Custom label text (overrides value display)
54
- alignThumb?: "bottom" | "top" | "center" // align thumb alignment
55
- classes?: {
56
- root?: string // Override root container styles
57
- track?: string // Override track background styles
58
- range?: string // Override active range styles
59
- thumb?: string // Override thumb handle styles
60
- }
61
- }
62
- \`\`\`
63
-
64
- ## New Features
65
-
66
- ### Label Display
67
- - **showLabel**: Toggle thumb label visibility (default: true)
68
- - **label**: Custom text to display instead of values
69
- - **Value Display**: Automatic value display when no custom label provided
70
-
71
- ### Align Thumb
72
- - **alignThumb**: Optional centered positioning for thumbs
73
- - **Track Alignment**: Conditional styling for track-thumb alignment
74
-
75
- ### Enhanced Styling
76
- - **classes**: Granular style overrides for all sub-components
77
- - **Variant Support**: Consistent variant styling across track, range, and thumbs
78
- - **Size Variants**: Responsive sizing for different use cases
79
-
80
- ## Usage Examples
81
-
82
- ### Basic with Labels
83
- \`\`\`tsx
84
- <Slider
85
- defaultValue={[50]}
86
- showLabel={true}
87
- max={100}
88
- min={0}
89
- />
90
- \`\`\`
91
-
92
- ### Custom Label Text
93
- \`\`\`tsx
94
- <Slider
95
- defaultValue={[75]}
96
- label="Volume"
97
- showLabel={true}
98
- />
99
- \`\`\`
100
-
101
- ### Without Labels
102
- \`\`\`tsx
103
- <Slider
104
- defaultValue={[30]}
105
- showLabel={false}
106
- />
107
- \`\`\`
108
-
109
- ### Align Thumb
110
- \`\`\`tsx
111
- <Slider
112
- defaultValue={[60]}
113
- alignThumb={"top"}
114
- />
115
- \`\`\`
116
-
117
- ### Custom Styling Classes
118
- \`\`\`tsx
119
- <Slider
120
- defaultValue={[45]}
121
- classes={{
122
- root: "custom-root-class",
123
- track: "bg-red-100",
124
- range: "bg-red-500",
125
- thumb: "bg-red-600 ring-red-200"
126
- }}
127
- />
128
- \`\`\`
129
- `,
15
+ component:
16
+ "A customizable range slider built on Radix UI primitives. Supports six color variants, three sizes, horizontal/vertical orientations, single and dual-thumb range mode, optional thumb labels, and configurable thumb alignment.",
130
17
  },
18
+ page: () => (
19
+ <AuralComponentDocsPage
20
+ features={[
21
+ {
22
+ title: "6 Color Variants",
23
+ description: "Default to info",
24
+ },
25
+ {
26
+ title: "Range Mode",
27
+ description: "Single or dual thumb",
28
+ },
29
+ {
30
+ title: "Thumb Labels",
31
+ description: "Optional value display",
32
+ },
33
+ ]}
34
+ />
35
+ ),
131
36
  },
132
37
  },
133
38
  tags: ["autodocs"],
@@ -142,34 +47,34 @@ interface SliderProps extends React.ComponentProps<typeof SliderPrimitive.Root>
142
47
  "warning",
143
48
  "info",
144
49
  ],
145
- description: "Visual variant of the slider",
50
+ description: "Color variant applied to the track range and thumb",
146
51
  },
147
52
  size: {
148
53
  control: "select",
149
54
  options: ["sm", "md", "lg"],
150
- description: "Size of the slider track and thumb",
55
+ description: "Track thickness and thumb size",
151
56
  },
152
57
  showLabel: {
153
58
  control: "boolean",
154
- description: "Show or hide thumb labels",
59
+ description: "Show or hide the value label on the thumb",
155
60
  },
156
61
  label: {
157
62
  control: "text",
158
- description: "Custom label text (overrides value display)",
63
+ description: "Custom label text overrides numeric value display",
159
64
  },
160
65
  alignThumb: {
161
66
  control: "select",
162
- options: ["bottom", "top", "center"],
163
- description: "Thumb alignment",
67
+ options: ["bottom", "center", "top"],
68
+ description: "Thumb vertical alignment relative to the track",
164
69
  },
165
70
  orientation: {
166
71
  control: "select",
167
72
  options: ["horizontal", "vertical"],
168
- description: "Orientation of the slider",
73
+ description: "Track orientation",
169
74
  },
170
75
  disabled: {
171
76
  control: "boolean",
172
- description: "Whether the slider is disabled",
77
+ description: "Disables interaction",
173
78
  },
174
79
  min: {
175
80
  control: "number",
@@ -181,7 +86,7 @@ interface SliderProps extends React.ComponentProps<typeof SliderPrimitive.Root>
181
86
  },
182
87
  step: {
183
88
  control: "number",
184
- description: "Step increment",
89
+ description: "Step increment between values",
185
90
  },
186
91
  },
187
92
  }
@@ -189,689 +94,431 @@ interface SliderProps extends React.ComponentProps<typeof SliderPrimitive.Root>
189
94
  export default meta
190
95
  type Story = StoryObj<typeof Slider>
191
96
 
192
- // 1. Default Slider
193
- export const Default: Story = {
97
+ // ─── 1. Playground ────────────────────────────────────────────────────────────
98
+
99
+ export const Playground: Story = {
194
100
  args: {
195
101
  defaultValue: [50],
102
+ variant: "primary",
103
+ size: "md",
104
+ showLabel: true,
105
+ alignThumb: "bottom",
196
106
  min: 0,
197
107
  max: 100,
198
- showLabel: true,
199
108
  },
200
109
  render: (args) => (
201
- <div className="w-80 p-8">
202
- <div className="mb-4">
203
- <h3 className="mb-2 text-lg font-medium text-white">Default Slider</h3>
204
- <p className="text-fm-secondary text-sm">
205
- Basic slider with default styling and value labels
206
- </p>
207
- </div>
110
+ <div className="w-full max-w-sm space-y-4">
208
111
  <Slider {...args} />
209
- </div>
210
- ),
211
- }
212
-
213
- // 2. Label Variants
214
- export const LabelVariants: Story = {
215
- render: () => (
216
- <div className="w-80 space-y-6 p-8">
217
- <div className="mb-6">
218
- <h3 className="mb-2 text-lg font-medium text-white">Label Options</h3>
219
- <p className="text-fm-secondary text-sm">
220
- Different ways to display thumb labels
221
- </p>
222
- </div>
223
-
224
- <div className="space-y-6">
225
- <div>
226
- <label className="mb-2 block text-sm font-medium text-white">
227
- With Value Labels (Default)
228
- </label>
229
- <Slider defaultValue={[60]} variant="primary" showLabel={true} />
230
- </div>
231
-
232
- <div>
233
- <label className="mb-2 block text-sm font-medium text-white">
234
- Custom Label Text
235
- </label>
236
- <Slider
237
- defaultValue={[75]}
238
- variant="positive"
239
- showLabel={true}
240
- label="High"
241
- />
242
- </div>
243
-
244
- <div>
245
- <label className="mb-2 block text-sm font-medium text-white">
246
- Without Labels
247
- </label>
248
- <Slider defaultValue={[40]} variant="warning" showLabel={false} />
249
- </div>
250
-
251
- <div>
252
- <label className="mb-2 block text-sm font-medium text-white">
253
- Range with Custom Labels
254
- </label>
255
- <Slider
256
- defaultValue={[25, 75]}
257
- variant="info"
258
- showLabel={true}
259
- label="Range"
260
- />
261
- </div>
112
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
113
+ <code
114
+ className="text-fm-secondary text-fm-md leading-fm-md"
115
+ style={{ fontFamily: "var(--font-fm-mono)" }}
116
+ >
117
+ {`<Slider variant="${args.variant}" size="${args.size}" showLabel={${args.showLabel}} alignThumb="${args.alignThumb}" />`}
118
+ </code>
262
119
  </div>
263
120
  </div>
264
121
  ),
122
+ parameters: {
123
+ docs: {
124
+ description: {
125
+ story:
126
+ "Use the controls panel in the sidebar to explore variant, size, label, and alignment options.",
127
+ },
128
+ },
129
+ },
265
130
  }
266
131
 
267
- // 3. All Variants with Labels
268
- export const Variants: Story = {
269
- render: () => (
270
- <div className="w-80 space-y-6 p-8">
271
- <div className="mb-6">
272
- <h3 className="mb-2 text-lg font-medium text-white">Slider Variants</h3>
273
- <p className="text-fm-secondary text-sm">
274
- Different color variants with value labels
275
- </p>
276
- </div>
132
+ // ─── 2. All Variants ──────────────────────────────────────────────────────────
277
133
 
134
+ export const AllVariants: Story = {
135
+ render: () => (
136
+ <div className="space-y-8">
278
137
  <div className="space-y-4">
279
- <div>
280
- <label className="mb-2 block text-sm font-medium text-white">
281
- Default
282
- </label>
283
- <Slider defaultValue={[40]} variant="default" showLabel={true} />
284
- </div>
285
-
286
- <div>
287
- <label className="mb-2 block text-sm font-medium text-white">
288
- Primary
289
- </label>
290
- <Slider defaultValue={[60]} variant="primary" showLabel={true} />
291
- </div>
292
-
293
- <div>
294
- <label className="mb-2 block text-sm font-medium text-white">
295
- Secondary
296
- </label>
297
- <Slider defaultValue={[35]} variant="secondary" showLabel={true} />
298
- </div>
299
-
300
- <div>
301
- <label className="mb-2 block text-sm font-medium text-white">
302
- Positive
303
- </label>
304
- <Slider defaultValue={[80]} variant="positive" showLabel={true} />
305
- </div>
306
-
307
- <div>
308
- <label className="mb-2 block text-sm font-medium text-white">
309
- Warning
310
- </label>
311
- <Slider defaultValue={[25]} variant="warning" showLabel={true} />
312
- </div>
313
-
314
- <div>
315
- <label className="mb-2 block text-sm font-medium text-white">
316
- Info
317
- </label>
318
- <Slider defaultValue={[70]} variant="info" showLabel={true} />
319
- </div>
138
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
139
+ Variant × Size
140
+ </h4>
141
+ {(
142
+ [
143
+ { variant: "default", label: "Default", value: 40 },
144
+ { variant: "primary", label: "Primary", value: 60 },
145
+ { variant: "secondary", label: "Secondary", value: 35 },
146
+ { variant: "positive", label: "Positive", value: 80 },
147
+ { variant: "warning", label: "Warning", value: 25 },
148
+ { variant: "info", label: "Info", value: 70 },
149
+ ] as const
150
+ ).map(({ variant, label, value }) => (
151
+ <div key={variant} className="space-y-6">
152
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
153
+ {label}
154
+ </h4>
155
+ <div className="flex flex-wrap items-end gap-8">
156
+ <div className="min-w-40 space-y-2 text-center">
157
+ <Slider
158
+ defaultValue={[value]}
159
+ variant={variant}
160
+ size="sm"
161
+ showLabel
162
+ />
163
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
164
+ sm
165
+ </p>
166
+ </div>
167
+ <div className="min-w-40 space-y-2 text-center">
168
+ <Slider
169
+ defaultValue={[value]}
170
+ variant={variant}
171
+ size="md"
172
+ showLabel
173
+ />
174
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
175
+ md
176
+ </p>
177
+ </div>
178
+ <div className="min-w-40 space-y-2 text-center">
179
+ <Slider
180
+ defaultValue={[value]}
181
+ variant={variant}
182
+ size="lg"
183
+ showLabel
184
+ />
185
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
186
+ lg
187
+ </p>
188
+ </div>
189
+ </div>
190
+ </div>
191
+ ))}
320
192
  </div>
321
193
  </div>
322
194
  ),
195
+ parameters: {
196
+ layout: "padded",
197
+ docs: {
198
+ description: {
199
+ story:
200
+ "All six color variants (default, primary, secondary, positive, warning, info) shown at each size (sm, md, lg).",
201
+ },
202
+ },
203
+ },
323
204
  }
324
205
 
325
- // 4. Different Sizes with Labels
326
- export const Sizes: Story = {
327
- render: () => (
328
- <div className="w-80 space-y-6 p-8">
329
- <div className="mb-6">
330
- <h3 className="mb-2 text-lg font-medium text-white">Slider Sizes</h3>
331
- <p className="text-fm-secondary text-sm">
332
- Small, medium, and large size options with labels
333
- </p>
334
- </div>
335
-
336
- <div className="space-y-6">
337
- <div>
338
- <label className="mb-2 block text-sm font-medium text-white">
339
- Small (sm)
340
- </label>
341
- <Slider
342
- defaultValue={[30]}
343
- size="sm"
344
- variant="primary"
345
- showLabel={true}
346
- />
347
- </div>
348
-
349
- <div>
350
- <label className="mb-2 block text-sm font-medium text-white">
351
- Medium (md) - Default
352
- </label>
353
- <Slider
354
- defaultValue={[50]}
355
- size="md"
356
- variant="primary"
357
- showLabel={true}
358
- />
359
- </div>
206
+ // ─── 3. Configurations ────────────────────────────────────────────────────────
360
207
 
361
- <div>
362
- <label className="mb-2 block text-sm font-medium text-white">
363
- Large (lg)
364
- </label>
365
- <Slider
366
- defaultValue={[70]}
367
- size="lg"
368
- variant="primary"
369
- showLabel={true}
370
- />
371
- </div>
372
- </div>
373
- </div>
374
- ),
375
- }
376
-
377
- // 5. Align Thumb
378
- export const AlignThumb: Story = {
208
+ export const Configurations: Story = {
379
209
  render: () => (
380
- <div className="w-80 space-y-6 p-8">
381
- <div className="mb-6">
382
- <h3 className="mb-2 text-lg font-medium text-white">Align Thumb</h3>
383
- <p className="text-fm-secondary text-sm">
384
- Compare default, centered and top thumb alignment
385
- </p>
386
- </div>
387
-
388
- <div className="space-y-6">
389
- <div>
390
- <label className="mb-2 block text-sm font-medium text-white">
391
- Default alignment
392
- </label>
393
- <Slider
394
- defaultValue={[50]}
395
- variant="primary"
396
- alignThumb={"bottom"}
397
- showLabel={true}
398
- />
399
- </div>
400
-
401
- <div>
402
- <label className="mb-2 block text-sm font-medium text-white">
403
- Centered Thumb
404
- </label>
405
- <Slider
406
- defaultValue={[50]}
407
- variant="primary"
408
- alignThumb={"center"}
409
- showLabel={true}
410
- />
411
- </div>
412
-
413
- <div>
414
- <label className="mb-5 block text-sm font-medium text-white">
415
- Top Thumbs
416
- </label>
417
- <Slider
418
- defaultValue={[50]}
419
- variant="positive"
420
- alignThumb={"top"}
421
- showLabel={true}
422
- />
423
- </div>
424
- </div>
425
- </div>
426
- ),
427
- }
428
-
429
- // 6. Custom Labels
430
- export const CustomLabels: Story = {
431
- render: () => {
432
- const [volume, setVolume] = React.useState([75])
433
- const [quality, setQuality] = React.useState([3])
434
- const [temperature, setTemperature] = React.useState([22])
435
- const [mode, setMode] = React.useState([2])
436
-
437
- const getQualityLabel = (value: number) => {
438
- const labels = ["Low", "Medium", "High", "Ultra", "Max"]
439
- return labels[value - 1] || "Unknown"
440
- }
441
-
442
- const getModeLabel = (value: number) => {
443
- const modes = ["Eco", "Normal", "Performance", "Turbo"]
444
- return modes[value - 1] || "Unknown"
445
- }
446
-
447
- return (
448
- <div className="w-80 space-y-6 p-8">
449
- <div className="mb-6">
450
- <h3 className="mb-2 text-lg font-medium text-white">Custom Labels</h3>
451
- <p className="text-fm-secondary text-sm">
452
- Sliders with custom label text instead of values
453
- </p>
454
- </div>
455
-
456
- <div className="space-y-6">
457
- <div>
458
- <label className="mb-2 block text-sm font-medium text-white">
459
- Volume Control
460
- </label>
210
+ <div className="space-y-8">
211
+ <div className="space-y-4">
212
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
213
+ Thumb Alignment
214
+ </h4>
215
+ <div className="flex flex-wrap gap-8">
216
+ <div className="min-w-48 space-y-2 text-center">
461
217
  <Slider
462
- value={volume}
463
- onValueChange={setVolume}
218
+ defaultValue={[50]}
464
219
  variant="primary"
465
- label="Vol"
466
- showLabel={true}
220
+ alignThumb="bottom"
221
+ showLabel
467
222
  />
468
- <div className="text-fm-secondary mt-1 text-xs">
469
- Current: {volume[0]}%
470
- </div>
223
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
224
+ bottom (default)
225
+ </p>
471
226
  </div>
472
-
473
- <div>
474
- <label className="mb-2 block text-sm font-medium text-white">
475
- Quality Setting
476
- </label>
227
+ <div className="min-w-48 space-y-2 text-center">
477
228
  <Slider
478
- value={quality}
479
- onValueChange={setQuality}
480
- variant="info"
481
- min={1}
482
- max={5}
483
- step={1}
484
- label={getQualityLabel(quality[0])}
485
- showLabel={true}
229
+ defaultValue={[50]}
230
+ variant="primary"
231
+ alignThumb="center"
232
+ showLabel
486
233
  />
487
- <div className="text-fm-secondary mt-1 text-xs">
488
- Level: {quality[0]}/5
489
- </div>
234
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
235
+ center
236
+ </p>
490
237
  </div>
491
-
492
- <div>
493
- <label className="mb-2 block text-sm font-medium text-white">
494
- Temperature
495
- </label>
238
+ <div className="min-w-48 space-y-2 pt-5 text-center">
496
239
  <Slider
497
- value={temperature}
498
- onValueChange={setTemperature}
499
- variant="warning"
500
- min={16}
501
- max={30}
502
- label={`${temperature[0]}°C`}
503
- showLabel={true}
240
+ defaultValue={[50]}
241
+ variant="primary"
242
+ alignThumb="top"
243
+ showLabel
504
244
  />
245
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
246
+ top
247
+ </p>
505
248
  </div>
249
+ </div>
250
+ </div>
506
251
 
507
- <div>
508
- <label className="mb-2 block text-sm font-medium text-white">
509
- Performance Mode
510
- </label>
252
+ <div className="space-y-4">
253
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
254
+ Range Slider (Dual Thumbs)
255
+ </h4>
256
+ <div className="flex flex-wrap gap-8">
257
+ <div className="min-w-48 space-y-2 text-center">
258
+ <Slider defaultValue={[20, 80]} variant="primary" showLabel />
259
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
260
+ primary range
261
+ </p>
262
+ </div>
263
+ <div className="min-w-48 space-y-2 text-center">
264
+ <Slider defaultValue={[30, 70]} variant="positive" showLabel />
265
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
266
+ positive range
267
+ </p>
268
+ </div>
269
+ <div className="min-w-48 space-y-2 text-center">
511
270
  <Slider
512
- value={mode}
513
- onValueChange={setMode}
514
- variant="positive"
515
- min={1}
516
- max={4}
517
- step={1}
518
- label={getModeLabel(mode[0])}
519
- showLabel={true}
271
+ defaultValue={[10, 90]}
272
+ variant="info"
273
+ showLabel
274
+ label="Range"
520
275
  />
276
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
277
+ custom label range
278
+ </p>
521
279
  </div>
522
280
  </div>
523
281
  </div>
524
- )
525
- },
526
- }
527
-
528
- // 7. Range Slider with Custom Styling
529
- export const RangeSlider: Story = {
530
- render: () => {
531
- const [values, setValues] = React.useState([25, 75])
532
282
 
533
- return (
534
- <div className="w-80 p-8">
535
- <div className="mb-6">
536
- <h3 className="mb-2 text-lg font-medium text-white">Range Slider</h3>
537
- <p className="text-fm-secondary">
538
- Select a range with dual handles and labels
539
- </p>
540
- </div>
541
-
542
- <div className="space-y-4">
543
- <Slider
544
- value={values}
545
- onValueChange={setValues}
546
- variant="primary"
547
- min={0}
548
- max={100}
549
- showLabel={true}
550
- classes={{
551
- thumb: "rounded-lg",
552
- }}
553
- />
554
-
555
- <div className="text-fm-secondary flex justify-between text-sm">
556
- <span>Min: {values[0]}</span>
557
- <span>Max: {values[1]}</span>
283
+ <div className="space-y-4">
284
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
285
+ Vertical Orientation
286
+ </h4>
287
+ <div className="flex flex-wrap items-end gap-12">
288
+ <div className="space-y-2 text-center">
289
+ <div className="flex justify-center">
290
+ <Slider
291
+ orientation="vertical"
292
+ defaultValue={[60]}
293
+ variant="primary"
294
+ className="h-48"
295
+ showLabel
296
+ />
297
+ </div>
298
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
299
+ primary · vertical
300
+ </p>
558
301
  </div>
559
-
560
- <div className="bg-fm-surface-secondary/20 mt-4 rounded-lg p-3">
561
- <p className="text-fm-secondary text-sm">
562
- Selected range: {values[0]} - {values[1]} ({values[1] - values[0]}{" "}
563
- units)
302
+ <div className="space-y-2 text-center">
303
+ <div className="flex justify-center">
304
+ <Slider
305
+ orientation="vertical"
306
+ defaultValue={[80]}
307
+ variant="positive"
308
+ className="h-48"
309
+ showLabel={false}
310
+ />
311
+ </div>
312
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
313
+ positive · no label
314
+ </p>
315
+ </div>
316
+ <div className="space-y-2 text-center">
317
+ <div className="flex justify-center">
318
+ <Slider
319
+ orientation="vertical"
320
+ defaultValue={[30, 80]}
321
+ variant="info"
322
+ className="h-48"
323
+ showLabel
324
+ />
325
+ </div>
326
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
327
+ info · range
328
+ </p>
329
+ </div>
330
+ <div className="space-y-2 text-center">
331
+ <div className="flex justify-center">
332
+ <Slider
333
+ orientation="vertical"
334
+ defaultValue={[40]}
335
+ variant="warning"
336
+ className="h-48"
337
+ showLabel
338
+ label="Temp"
339
+ />
340
+ </div>
341
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
342
+ warning · custom label
564
343
  </p>
565
344
  </div>
566
345
  </div>
567
346
  </div>
568
- )
569
- },
570
- }
571
-
572
- // 8. Vertical Orientation with Labels
573
- export const VerticalSlider: Story = {
574
- render: () => (
575
- <div className="flex items-center justify-center gap-12 p-8">
576
- <div className="text-center">
577
- <h4 className="mb-4 text-sm font-medium text-white">With Labels</h4>
578
- <Slider
579
- orientation="vertical"
580
- defaultValue={[60]}
581
- variant="primary"
582
- className="h-64"
583
- showLabel={true}
584
- />
585
- </div>
586
-
587
- <div className="text-center">
588
- <h4 className="mb-4 text-sm font-medium text-white">Without Labels</h4>
589
- <Slider
590
- orientation="vertical"
591
- defaultValue={[80]}
592
- variant="positive"
593
- className="h-64"
594
- showLabel={false}
595
- />
596
- </div>
597
-
598
- <div className="text-center">
599
- <h4 className="mb-4 text-sm font-medium text-white">Custom Label</h4>
600
- <Slider
601
- orientation="vertical"
602
- defaultValue={[40]}
603
- variant="warning"
604
- className="h-64"
605
- showLabel={true}
606
- label="Temp"
607
- />
608
- </div>
609
347
 
610
- <div className="text-center">
611
- <h4 className="mb-4 text-sm font-medium text-white">Range</h4>
612
- <Slider
613
- orientation="vertical"
614
- defaultValue={[30, 80]}
615
- variant="info"
616
- className="h-64"
617
- showLabel={true}
618
- />
348
+ <div className="space-y-4">
349
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
350
+ Label Display
351
+ </h4>
352
+ <div className="flex flex-wrap gap-8">
353
+ <div className="min-w-48 space-y-2 text-center">
354
+ <Slider defaultValue={[60]} variant="primary" showLabel />
355
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
356
+ numeric value
357
+ </p>
358
+ </div>
359
+ <div className="min-w-48 space-y-2 text-center">
360
+ <Slider
361
+ defaultValue={[75]}
362
+ variant="positive"
363
+ showLabel
364
+ label="High"
365
+ />
366
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
367
+ custom text
368
+ </p>
369
+ </div>
370
+ <div className="min-w-48 space-y-2 text-center">
371
+ <Slider defaultValue={[40]} variant="warning" showLabel={false} />
372
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
373
+ no label
374
+ </p>
375
+ </div>
376
+ </div>
619
377
  </div>
620
378
  </div>
621
379
  ),
622
380
  parameters: {
623
- layout: "fullscreen",
381
+ layout: "padded",
382
+ docs: {
383
+ description: {
384
+ story:
385
+ "Configuration axes: thumb alignment (bottom/center/top), range mode with dual thumbs, vertical orientation, and label display options.",
386
+ },
387
+ },
624
388
  },
625
389
  }
626
390
 
627
- // 9. Custom Styling Classes
628
- export const CustomStyling: Story = {
629
- render: () => (
630
- <div className="w-80 space-y-6 p-8">
631
- <div className="mb-6">
632
- <h3 className="mb-2 text-lg font-medium text-white">Custom Styling</h3>
633
- <p className="text-fm-secondary text-sm">
634
- Override default styles with custom classes
635
- </p>
636
- </div>
637
-
638
- <div className="space-y-6">
639
- <div>
640
- <label className="mb-2 block text-sm font-medium text-white">
641
- Custom Track & Range
642
- </label>
643
- <Slider
644
- defaultValue={[40]}
645
- showLabel={true}
646
- classes={{
647
- track: "bg-purple-900/40 rounded-full",
648
- range:
649
- "bg-gradient-to-r from-purple-400 to-pink-400 rounded-full",
650
- }}
651
- />
652
- </div>
653
-
654
- <div>
655
- <label className="mb-2 block text-sm font-medium text-white">
656
- Custom Thumb Styling
657
- </label>
658
- <Slider
659
- defaultValue={[70]}
660
- variant="primary"
661
- showLabel={true}
662
- classes={{
663
- thumb:
664
- "bg-white text-gray-900 border-2 border-fm-primary-500 ring-fm-primary-200 rounded-full shadow-lg",
665
- }}
666
- />
667
- </div>
668
-
669
- <div>
670
- <label className="mb-2 block text-sm font-medium text-white">
671
- Gradient with Custom Root
672
- </label>
673
- <Slider
674
- defaultValue={[55]}
675
- showLabel={true}
676
- label="Style"
677
- classes={{
678
- root: "p-2 bg-gray-900/20 rounded-lg",
679
- range: "bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full",
680
- thumb:
681
- "bg-gradient-to-r from-cyan-400 to-blue-500 border-0 shadow-xl",
682
- }}
683
- />
684
- </div>
685
- </div>
686
- </div>
687
- ),
688
- }
391
+ // ─── 4. Interactive ───────────────────────────────────────────────────────────
689
392
 
690
- // 10. Complete Interactive Showcase
691
- export const CompleteShowcase: Story = {
393
+ export const Interactive: Story = {
692
394
  render: () => {
693
- const [settings, setSettings] = React.useState({
694
- volume: [80],
695
- brightness: [65],
696
- contrast: [50],
697
- temperature: [18, 24],
698
- quality: [4],
699
- mode: [2],
700
- })
701
-
702
- const updateSetting = (key: string, value: number[]) => {
703
- setSettings((prev) => ({ ...prev, [key]: value }))
704
- }
705
-
706
- const getQualityLabel = (value: number) => {
707
- const labels = ["Low", "Medium", "High", "Ultra", "Max"]
708
- return labels[value - 1] || "Unknown"
395
+ const [volume, setVolume] = React.useState([72])
396
+ const [brightness, setBrightness] = React.useState([55])
397
+
398
+ const getVolumeIcon = (v: number) => {
399
+ if (v === 0) return "Muted"
400
+ if (v < 33) return "Low"
401
+ if (v < 66) return "Mid"
402
+ return "High"
709
403
  }
710
404
 
711
- const getModeLabel = (value: number) => {
712
- const modes = ["Eco", "Normal", "Turbo"]
713
- return modes[value - 1] || "Unknown"
405
+ const getBrightnessLabel = (v: number) => {
406
+ if (v < 25) return "Dim"
407
+ if (v < 50) return "Low"
408
+ if (v < 75) return "Mid"
409
+ return "Bright"
714
410
  }
715
411
 
716
412
  return (
717
- <div className="w-96 space-y-8 p-8">
718
- <div className="mb-8">
719
- <h3 className="mb-2 text-xl font-bold text-white">System Settings</h3>
720
- <p className="text-fm-secondary">
721
- Comprehensive slider showcase with labels and custom styling
722
- </p>
723
- </div>
724
-
725
- {/* Audio Settings */}
726
- <div className="space-y-4">
727
- <h4 className="font-medium text-white">Audio</h4>
728
- <div className="space-y-3">
729
- <div className="flex items-center justify-between">
730
- <label className="text-fm-secondary text-sm">Volume</label>
731
- <span className="text-sm font-medium text-white">
732
- {settings.volume[0]}%
733
- </span>
734
- </div>
735
- <Slider
736
- value={settings.volume}
737
- onValueChange={(value) => updateSetting("volume", value)}
738
- variant="primary"
739
- size="md"
740
- showLabel={true}
741
- label="Vol"
742
- />
743
- </div>
744
- </div>
745
-
746
- {/* Display Settings */}
747
- <div className="space-y-4">
748
- <h4 className="font-medium text-white">Display</h4>
749
- <div className="space-y-4">
750
- <div className="space-y-2">
751
- <div className="flex items-center justify-between">
752
- <label className="text-fm-secondary text-sm">Brightness</label>
753
- <span className="text-sm font-medium text-white">
754
- {settings.brightness[0]}%
755
- </span>
413
+ <div className="w-full p-8">
414
+ <div className="mx-auto max-w-3xl space-y-6">
415
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
416
+ {/* Controls Panel */}
417
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-5 rounded-xl border p-5">
418
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
419
+ Presets
420
+ </p>
421
+ <div className="space-y-2">
422
+ {[
423
+ { label: "Silent", vol: 0, bright: 20 },
424
+ { label: "Quiet", vol: 25, bright: 40 },
425
+ { label: "Default", vol: 72, bright: 55 },
426
+ { label: "Party", vol: 100, bright: 90 },
427
+ ].map(({ label, vol, bright }) => (
428
+ <button
429
+ key={label}
430
+ onClick={() => {
431
+ setVolume([vol])
432
+ setBrightness([bright])
433
+ }}
434
+ className="border-fm-divider-secondary text-fm-secondary hover:bg-fm-surface-secondary hover:text-fm-primary font-fm-text text-fm-sm leading-fm-sm w-full rounded-lg border px-3 py-2 text-left transition-colors"
435
+ >
436
+ {label}
437
+ </button>
438
+ ))}
756
439
  </div>
757
- <Slider
758
- value={settings.brightness}
759
- onValueChange={(value) => updateSetting("brightness", value)}
760
- variant="warning"
761
- size="sm"
762
- showLabel={false}
763
- />
764
- </div>
765
-
766
- <div className="space-y-2">
767
- <div className="flex items-center justify-between">
768
- <label className="text-fm-secondary text-sm">Contrast</label>
769
- <span className="text-sm font-medium text-white">
770
- {settings.contrast[0]}%
771
- </span>
440
+ <div className="border-fm-divider-secondary border-t pt-4" />
441
+ <div className="space-y-1">
442
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
443
+ Live Values
444
+ </p>
445
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
446
+ Volume: {volume[0]}% · {getVolumeIcon(volume[0])}
447
+ </p>
448
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
449
+ Brightness: {brightness[0]}% ·{" "}
450
+ {getBrightnessLabel(brightness[0])}
451
+ </p>
772
452
  </div>
773
- <Slider
774
- value={settings.contrast}
775
- onValueChange={(value) => updateSetting("contrast", value)}
776
- variant="info"
777
- size="sm"
778
- showLabel={true}
779
- />
780
453
  </div>
781
- </div>
782
- </div>
783
-
784
- {/* Environment Settings */}
785
- <div className="space-y-4">
786
- <h4 className="font-medium text-white">Environment</h4>
787
- <div className="space-y-3">
788
- <div className="flex items-center justify-between">
789
- <label className="text-fm-secondary text-sm">
790
- Temperature Range
791
- </label>
792
- <span className="text-sm font-medium text-white">
793
- {settings.temperature[0]}° - {settings.temperature[1]}°C
794
- </span>
795
- </div>
796
- <Slider
797
- value={settings.temperature}
798
- onValueChange={(value) => updateSetting("temperature", value)}
799
- variant="positive"
800
- min={10}
801
- max={30}
802
- size="lg"
803
- showLabel={true}
804
- alignThumb={"center"}
805
- />
806
- </div>
807
- </div>
808
454
 
809
- {/* Quality Settings */}
810
- <div className="space-y-4">
811
- <h4 className="font-medium text-white">Performance</h4>
812
- <div className="space-y-4">
813
- <div className="space-y-2">
814
- <div className="flex items-center justify-between">
815
- <label className="text-fm-secondary text-sm">Quality</label>
816
- <span className="text-sm font-medium text-white">
817
- {getQualityLabel(settings.quality[0])}
818
- </span>
455
+ {/* Preview Stage */}
456
+ <div className="flex flex-col gap-3 lg:col-span-2">
457
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-8 rounded-xl border p-6">
458
+ <div className="space-y-3">
459
+ <div className="flex items-center justify-between">
460
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
461
+ Volume
462
+ </span>
463
+ <span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
464
+ {volume[0]}%
465
+ </span>
466
+ </div>
467
+ <Slider
468
+ value={volume}
469
+ onValueChange={setVolume}
470
+ variant="primary"
471
+ size="md"
472
+ showLabel
473
+ label="Vol"
474
+ min={0}
475
+ max={100}
476
+ />
477
+ </div>
478
+
479
+ <div className="space-y-3">
480
+ <div className="flex items-center justify-between">
481
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
482
+ Brightness
483
+ </span>
484
+ <span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
485
+ {brightness[0]}%
486
+ </span>
487
+ </div>
488
+ <Slider
489
+ value={brightness}
490
+ onValueChange={setBrightness}
491
+ variant="warning"
492
+ size="md"
493
+ showLabel
494
+ label="Lux"
495
+ min={0}
496
+ max={100}
497
+ />
498
+ </div>
819
499
  </div>
820
- <Slider
821
- value={settings.quality}
822
- onValueChange={(value) => updateSetting("quality", value)}
823
- variant="secondary"
824
- min={1}
825
- max={5}
826
- step={1}
827
- showLabel={true}
828
- label={getQualityLabel(settings.quality[0])}
829
- />
830
- </div>
831
500
 
832
- <div className="space-y-2">
833
- <div className="flex items-center justify-between">
834
- <label className="text-fm-secondary text-sm">Mode</label>
835
- <span className="text-sm font-medium text-white">
836
- {getModeLabel(settings.mode[0])}
837
- </span>
501
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
502
+ <code
503
+ className="text-fm-secondary text-fm-md leading-fm-md"
504
+ style={{ fontFamily: "var(--font-fm-mono)" }}
505
+ >
506
+ {`<Slider value={[${volume[0]}]} variant="primary" showLabel label="Vol" />`}
507
+ </code>
838
508
  </div>
839
- <Slider
840
- value={settings.mode}
841
- onValueChange={(value) => updateSetting("mode", value)}
842
- variant="positive"
843
- min={1}
844
- max={3}
845
- step={1}
846
- showLabel={true}
847
- label={getModeLabel(settings.mode[0])}
848
- classes={{
849
- thumb: "rounded-full shadow-lg",
850
- }}
851
- />
852
509
  </div>
853
510
  </div>
854
511
  </div>
855
-
856
- {/* Settings Summary */}
857
- <div className="bg-fm-surface-secondary/20 mt-8 rounded-lg p-4">
858
- <h5 className="mb-2 font-medium text-white">Current Settings</h5>
859
- <div className="text-fm-secondary space-y-1 text-sm">
860
- <div>Volume: {settings.volume[0]}%</div>
861
- <div>Brightness: {settings.brightness[0]}%</div>
862
- <div>Contrast: {settings.contrast[0]}%</div>
863
- <div>
864
- Temperature: {settings.temperature[0]}° -{" "}
865
- {settings.temperature[1]}°C
866
- </div>
867
- <div>Quality: {getQualityLabel(settings.quality[0])}</div>
868
- <div>Mode: {getModeLabel(settings.mode[0])}</div>
869
- </div>
870
- </div>
871
512
  </div>
872
513
  )
873
514
  },
874
515
  parameters: {
875
516
  layout: "fullscreen",
517
+ docs: {
518
+ description: {
519
+ story:
520
+ "Live volume and brightness sliders with preset buttons and real-time value display. Demonstrates controlled state and label customization.",
521
+ },
522
+ },
876
523
  },
877
524
  }