aural-ui 4.2.5 → 4.4.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 (30) hide show
  1. package/dist/components/aspect-ratio/AspectRatio.stories.tsx +4 -4
  2. package/dist/components/badge/Badge.stories.tsx +3 -3
  3. package/dist/components/button/Button.stories.tsx +288 -366
  4. package/dist/components/button/index.tsx +3 -43
  5. package/dist/components/card/Card.stories.tsx +2 -2
  6. package/dist/components/card/index.tsx +1 -1
  7. package/dist/components/clamp-lines/index.tsx +0 -1
  8. package/dist/components/drawer/index.tsx +1 -1
  9. package/dist/components/hover-card/HoverCard.stories.tsx +7 -7
  10. package/dist/components/marquee/Marquee.stories.tsx +2 -6
  11. package/dist/components/otp-inputs/OtpInputs.stories.tsx +1 -1
  12. package/dist/components/popover/Popover.stories.tsx +1 -1
  13. package/dist/components/slider/index.tsx +1 -6
  14. package/dist/components/table/Table.stories.tsx +4 -4
  15. package/dist/components/toggle/Toggle.stories.tsx +4 -4
  16. package/dist/components/tooltip/index.tsx +1 -2
  17. package/dist/components/typography/Typography.stories.tsx +7 -19
  18. package/dist/components/typography/index.tsx +0 -2
  19. package/dist/fonts/LabGrotesque-Medium.ttf +0 -0
  20. package/dist/icons/all-icons.tsx +9 -7
  21. package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +3 -3
  22. package/dist/index.cjs +86 -86
  23. package/dist/index.js +86 -86
  24. package/package.json +4 -4
  25. package/dist/fonts/LabGrotesqueTRIAL-Bold.otf +0 -0
  26. package/dist/fonts/LabGrotesqueTRIAL-Light.otf +0 -0
  27. package/dist/fonts/LabGrotesqueTRIAL-Medium.otf +0 -0
  28. package/dist/fonts/LabGrotesqueTRIAL-Regular.otf +0 -0
  29. package/dist/fonts/PPSupplySans-Regular (1).otf +0 -0
  30. package/dist/fonts/PPSupplySans-Ultralight.otf +0 -0
@@ -2,6 +2,8 @@ import React from "react"
2
2
  import {
3
3
  CircularPlayIcon,
4
4
  HeartIcon,
5
+ PlusIcon,
6
+ SearchIcon,
5
7
  SettingIcon,
6
8
  SkipBackwardIcon,
7
9
  SkipForwardIcon,
@@ -21,22 +23,22 @@ const meta: Meta<typeof Button> = {
21
23
  docs: {
22
24
  description: {
23
25
  component:
24
- "A versatile button component with six visual variants (primary, secondary, outline, text, chip, chipActive), three sizes, optional noise texture, icon slots, and tooltip support. Built with CVA for composable, type-safe variant management.",
26
+ "A versatile button component with six visual variants (primary, secondary, outline, text, chip, chipActive), three sizes, left/right icon slots, and optional tooltip support via the withTooltip HOC. Noise texture is applied automatically per variant.",
25
27
  },
26
28
  page: () => (
27
29
  <AuralComponentDocsPage
28
30
  features={[
29
31
  {
30
32
  title: "6 Visual Variants",
31
- description: "From primary to chip",
33
+ description: "Primary to chipActive",
32
34
  },
33
35
  {
34
- title: "Noise Texture",
35
- description: "4 levels of grain",
36
+ title: "Icon Slots",
37
+ description: "Left and right icons",
36
38
  },
37
39
  {
38
- title: "Icon Slots & Tooltip",
39
- description: "Left, right, tooltip",
40
+ title: "Tooltip Support",
41
+ description: "Built-in via withTooltip",
40
42
  },
41
43
  ]}
42
44
  />
@@ -44,13 +46,6 @@ const meta: Meta<typeof Button> = {
44
46
  },
45
47
  },
46
48
  tags: ["autodocs"],
47
- args: {
48
- variant: "primary",
49
- size: "md",
50
- noise: "medium",
51
- isDisabled: false,
52
- children: "Click me",
53
- },
54
49
  argTypes: {
55
50
  variant: {
56
51
  control: { type: "select" },
@@ -62,25 +57,28 @@ const meta: Meta<typeof Button> = {
62
57
  "chip",
63
58
  "chipActive",
64
59
  ],
60
+ description: "Visual style of the button",
65
61
  },
66
62
  size: {
67
63
  control: { type: "select" },
68
64
  options: ["sm", "md", "lg"],
69
- },
70
- noise: {
71
- control: { type: "select" },
72
- options: ["none", "low", "medium", "strong"],
65
+ description: "Button size",
73
66
  },
74
67
  isDisabled: {
75
68
  control: { type: "boolean" },
69
+ description: "Disables the button",
76
70
  },
77
- leftIcon: {
78
- control: { type: "boolean" },
79
- },
80
- rightIcon: {
81
- control: { type: "boolean" },
71
+ children: {
72
+ control: { type: "text" },
73
+ description: "Button label",
82
74
  },
83
75
  },
76
+ args: {
77
+ variant: "primary",
78
+ size: "md",
79
+ isDisabled: false,
80
+ children: "Click me",
81
+ },
84
82
  }
85
83
 
86
84
  export default meta
@@ -89,18 +87,11 @@ type Story = StoryObj<typeof Button>
89
87
  // ─── 1. Playground ────────────────────────────────────────────────────────────
90
88
 
91
89
  export const Playground: Story = {
92
- args: {
93
- variant: "primary",
94
- size: "md",
95
- noise: "medium",
96
- isDisabled: false,
97
- children: "Click me",
98
- },
99
90
  render: (args) => (
100
91
  <div className="flex w-full max-w-sm flex-col items-center space-y-4">
101
92
  <Button {...args} />
102
93
  <div className="border-fm-divider-secondary bg-fm-surface-secondary w-full rounded-lg border px-4 py-3">
103
- <code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">{`<Button variant="${args.variant}" size="${args.size}" noise="${args.noise}"${args.isDisabled ? " isDisabled" : ""}>${args.children}</Button>`}</code>
94
+ <code className="text-fm-secondary text-fm-md leading-fm-md font-[var(--font-fm-mono)]">{`<Button variant="${args.variant}" size="${args.size}"${args.isDisabled ? " isDisabled" : ""}>${args.children}</Button>`}</code>
104
95
  </div>
105
96
  </div>
106
97
  ),
@@ -108,7 +99,7 @@ export const Playground: Story = {
108
99
  docs: {
109
100
  description: {
110
101
  story:
111
- "Use the controls panel in the sidebar to explore all Button props. The code snippet below the button updates live to reflect the current configuration.",
102
+ "Use the sidebar controls to explore all Button props. The code snippet below updates live.",
112
103
  },
113
104
  },
114
105
  },
@@ -124,179 +115,22 @@ export const AllVariants: Story = {
124
115
  Variants
125
116
  </h4>
126
117
  <div className="flex flex-wrap items-end gap-4">
127
- <div className="space-y-2 text-center">
128
- <Button variant="primary" noise="medium">
129
- Primary
130
- </Button>
131
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
132
- Primary
133
- </p>
134
- </div>
135
- <div className="space-y-2 text-center">
136
- <Button variant="secondary">Secondary</Button>
137
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
138
- Secondary
139
- </p>
140
- </div>
141
- <div className="space-y-2 text-center">
142
- <Button variant="outline" noise="none">
143
- Outline
144
- </Button>
145
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
146
- Outline
147
- </p>
148
- </div>
149
- <div className="space-y-2 text-center">
150
- <Button variant="text" noise="none">
151
- Text
152
- </Button>
153
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
154
- Text
155
- </p>
156
- </div>
157
- <div className="space-y-2 text-center">
158
- <Button variant="chip" noise="none">
159
- Chip
160
- </Button>
161
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
162
- Chip
163
- </p>
164
- </div>
165
- <div className="space-y-2 text-center">
166
- <Button variant="chipActive" noise="medium">
167
- Chip Active
168
- </Button>
169
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
170
- Chip Active
171
- </p>
172
- </div>
173
- </div>
174
- </div>
175
-
176
- <div className="space-y-4">
177
- <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
178
- Sizes
179
- </h4>
180
- <div className="flex flex-wrap items-end gap-4">
181
- <div className="space-y-2 text-center">
182
- <Button variant="primary" size="sm" noise="medium">
183
- Small
184
- </Button>
185
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
186
- Small (sm)
187
- </p>
188
- </div>
189
- <div className="space-y-2 text-center">
190
- <Button variant="primary" size="md" noise="medium">
191
- Medium
192
- </Button>
193
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
194
- Medium (md)
195
- </p>
196
- </div>
197
- <div className="space-y-2 text-center">
198
- <Button variant="primary" size="lg" noise="medium">
199
- Large
200
- </Button>
201
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
202
- Large (lg)
203
- </p>
204
- </div>
205
- </div>
206
- </div>
207
-
208
- <div className="space-y-4">
209
- <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
210
- Noise Levels (Primary)
211
- </h4>
212
- <div className="flex flex-wrap items-end gap-4">
213
- <div className="space-y-2 text-center">
214
- <Button variant="primary" noise="none">
215
- None
216
- </Button>
217
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
218
- None
219
- </p>
220
- </div>
221
- <div className="space-y-2 text-center">
222
- <Button variant="primary" noise="low">
223
- Low
224
- </Button>
225
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
226
- Low
227
- </p>
228
- </div>
229
- <div className="space-y-2 text-center">
230
- <Button variant="primary" noise="medium">
231
- Medium
232
- </Button>
233
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
234
- Medium
235
- </p>
236
- </div>
237
- <div className="space-y-2 text-center">
238
- <Button variant="primary" noise="strong">
239
- Strong
240
- </Button>
241
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
242
- Strong
243
- </p>
244
- </div>
245
- </div>
246
- </div>
247
-
248
- <div className="space-y-4">
249
- <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
250
- Noise Levels (Secondary)
251
- </h4>
252
- <div className="flex flex-wrap items-end gap-4">
253
- <div className="space-y-2 text-center">
254
- <Button variant="secondary" noise="none">
255
- None
256
- </Button>
257
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
258
- None
259
- </p>
260
- </div>
261
- <div className="space-y-2 text-center">
262
- <Button variant="secondary" noise="low">
263
- Low
264
- </Button>
265
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
266
- Low
267
- </p>
268
- </div>
269
- <div className="space-y-2 text-center">
270
- <Button variant="secondary" noise="medium">
271
- Medium
272
- </Button>
273
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
274
- Medium
275
- </p>
276
- </div>
277
- <div className="space-y-2 text-center">
278
- <Button variant="secondary" noise="strong">
279
- Strong
280
- </Button>
281
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
282
- Strong
283
- </p>
284
- </div>
285
- </div>
286
- </div>
287
-
288
- <div className="space-y-4">
289
- <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
290
- Chip — Noise Levels
291
- </h4>
292
- <div className="flex flex-wrap items-end gap-4">
293
- {(["none", "low", "medium", "strong"] as const).map((noise) => (
294
- <div key={noise} className="space-y-2 text-center">
295
- <Button variant="chip" noise={noise}>
296
- {noise.charAt(0).toUpperCase() + noise.slice(1)}
118
+ {(
119
+ [
120
+ "primary",
121
+ "secondary",
122
+ "outline",
123
+ "text",
124
+ "chip",
125
+ "chipActive",
126
+ ] as const
127
+ ).map((variant) => (
128
+ <div key={variant} className="space-y-2 text-center">
129
+ <Button variant={variant}>
130
+ {variant.charAt(0).toUpperCase() + variant.slice(1)}
297
131
  </Button>
298
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm capitalize">
299
- {noise}
132
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
133
+ {variant}
300
134
  </p>
301
135
  </div>
302
136
  ))}
@@ -305,16 +139,16 @@ export const AllVariants: Story = {
305
139
 
306
140
  <div className="space-y-4">
307
141
  <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
308
- Chip Active Noise Levels
142
+ SizesPrimary
309
143
  </h4>
310
- <div className="flex flex-wrap items-end gap-4">
311
- {(["none", "low", "medium", "strong"] as const).map((noise) => (
312
- <div key={noise} className="space-y-2 text-center">
313
- <Button variant="chipActive" noise={noise}>
314
- {noise.charAt(0).toUpperCase() + noise.slice(1)}
144
+ <div className="flex flex-wrap items-end gap-6">
145
+ {(["sm", "md", "lg"] as const).map((size) => (
146
+ <div key={size} className="space-y-2 text-center">
147
+ <Button variant="primary" size={size}>
148
+ Button
315
149
  </Button>
316
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm capitalize">
317
- {noise}
150
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
151
+ {size}
318
152
  </p>
319
153
  </div>
320
154
  ))}
@@ -323,13 +157,13 @@ export const AllVariants: Story = {
323
157
 
324
158
  <div className="space-y-4">
325
159
  <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
326
- Chip vs Chip Active — Sizes
160
+ Chip vs Chip Active — All Sizes
327
161
  </h4>
328
162
  <div className="flex flex-wrap items-end gap-6">
329
163
  {(["sm", "md", "lg"] as const).map((size) => (
330
- <div key={size} className="space-y-3">
164
+ <div key={size} className="flex flex-col items-center gap-3">
331
165
  <div className="space-y-2 text-center">
332
- <Button variant="chip" size={size} noise="medium">
166
+ <Button variant="chip" size={size}>
333
167
  Chip
334
168
  </Button>
335
169
  <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
@@ -337,7 +171,7 @@ export const AllVariants: Story = {
337
171
  </p>
338
172
  </div>
339
173
  <div className="space-y-2 text-center">
340
- <Button variant="chipActive" size={size} noise="medium">
174
+ <Button variant="chipActive" size={size}>
341
175
  Chip Active
342
176
  </Button>
343
177
  <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
@@ -354,7 +188,7 @@ export const AllVariants: Story = {
354
188
  docs: {
355
189
  description: {
356
190
  story:
357
- "All six variants, three sizes, all four noise levels on primary and secondary, and a full chip/chipActive noise and size breakdown.",
191
+ "All six variants at default size, a size comparison for the primary variant, and a chip vs chipActive breakdown across all three sizes.",
358
192
  },
359
193
  },
360
194
  },
@@ -370,125 +204,225 @@ export const States: Story = {
370
204
  Disabled — All Variants
371
205
  </h4>
372
206
  <div className="flex flex-wrap items-end gap-4">
373
- <div className="space-y-2 text-center">
374
- <Button variant="primary" isDisabled>
375
- Primary
376
- </Button>
377
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
378
- Primary
379
- </p>
380
- </div>
381
- <div className="space-y-2 text-center">
382
- <Button variant="secondary" isDisabled>
383
- Secondary
384
- </Button>
385
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
386
- Secondary
387
- </p>
388
- </div>
389
- <div className="space-y-2 text-center">
390
- <Button variant="outline" isDisabled>
391
- Outline
392
- </Button>
393
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
394
- Outline
395
- </p>
396
- </div>
397
- <div className="space-y-2 text-center">
398
- <Button variant="text" isDisabled>
399
- Text
400
- </Button>
401
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
402
- Text
403
- </p>
404
- </div>
405
- <div className="space-y-2 text-center">
406
- <Button variant="chip" isDisabled>
407
- Chip
408
- </Button>
409
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
410
- Chip
411
- </p>
412
- </div>
413
- <div className="space-y-2 text-center">
414
- <Button variant="chipActive" isDisabled>
415
- Chip Active
416
- </Button>
417
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
418
- Chip Active
419
- </p>
420
- </div>
207
+ {(
208
+ [
209
+ "primary",
210
+ "secondary",
211
+ "outline",
212
+ "text",
213
+ "chip",
214
+ "chipActive",
215
+ ] as const
216
+ ).map((variant) => (
217
+ <div key={variant} className="space-y-2 text-center">
218
+ <Button variant={variant} isDisabled>
219
+ {variant.charAt(0).toUpperCase() + variant.slice(1)}
220
+ </Button>
221
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
222
+ {variant}
223
+ </p>
224
+ </div>
225
+ ))}
421
226
  </div>
422
227
  </div>
423
228
 
424
229
  <div className="space-y-4">
425
230
  <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
426
- Disabled with Noise
231
+ Enabled vs Disabled
427
232
  </h4>
428
- <div className="flex flex-wrap items-end gap-4">
429
- <div className="space-y-2 text-center">
430
- <Button variant="primary" noise="strong" isDisabled>
431
- Primary
432
- </Button>
433
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
434
- Primary + strong noise
435
- </p>
436
- </div>
437
- <div className="space-y-2 text-center">
438
- <Button variant="secondary" noise="medium" isDisabled>
439
- Secondary
440
- </Button>
441
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
442
- Secondary + medium noise
443
- </p>
444
- </div>
445
- <div className="space-y-2 text-center">
446
- <Button variant="chipActive" noise="low" isDisabled>
447
- Chip Active
448
- </Button>
449
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
450
- Chip Active + low noise
451
- </p>
452
- </div>
233
+ <div className="flex flex-wrap items-end gap-8">
234
+ {(
235
+ [
236
+ "primary",
237
+ "secondary",
238
+ "outline",
239
+ "text",
240
+ "chip",
241
+ "chipActive",
242
+ ] as const
243
+ ).map((variant) => (
244
+ <div key={variant} className="flex flex-col items-center gap-3">
245
+ <div className="space-y-2 text-center">
246
+ <Button variant={variant}>Enabled</Button>
247
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
248
+ {variant} · enabled
249
+ </p>
250
+ </div>
251
+ <div className="space-y-2 text-center">
252
+ <Button variant={variant} isDisabled>
253
+ Disabled
254
+ </Button>
255
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
256
+ {variant} · disabled
257
+ </p>
258
+ </div>
259
+ </div>
260
+ ))}
453
261
  </div>
454
262
  </div>
263
+ </div>
264
+ ),
265
+ parameters: {
266
+ docs: {
267
+ description: {
268
+ story:
269
+ "Disabled state across all six variants, and an enabled/disabled comparison for primary, secondary, and outline.",
270
+ },
271
+ },
272
+ },
273
+ }
455
274
 
456
- <div className="space-y-4">
457
- <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
458
- Enabled vs Disabled
459
- </h4>
460
- <div className="flex flex-wrap items-end gap-6">
461
- <div className="space-y-2 text-center">
462
- <Button variant="primary" noise="medium">
463
- Enabled
464
- </Button>
465
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
466
- Enabled
467
- </p>
468
- </div>
469
- <div className="space-y-2 text-center">
470
- <Button variant="primary" noise="medium" isDisabled>
471
- Disabled
472
- </Button>
473
- <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
474
- Disabled
475
- </p>
275
+ // ─── 4. Interactive ───────────────────────────────────────────────────────────
276
+
277
+ export const Interactive: Story = {
278
+ render: function InteractiveStory() {
279
+ const [variant, setVariant] = React.useState<
280
+ "primary" | "secondary" | "outline" | "text" | "chip" | "chipActive"
281
+ >("primary")
282
+ const [size, setSize] = React.useState<"sm" | "md" | "lg">("md")
283
+ const [showLeftIcon, setShowLeftIcon] = React.useState(false)
284
+ const [showRightIcon, setShowRightIcon] = React.useState(false)
285
+ const [isDisabled, setIsDisabled] = React.useState(false)
286
+
287
+ const variants = [
288
+ "primary",
289
+ "secondary",
290
+ "outline",
291
+ "text",
292
+ "chip",
293
+ "chipActive",
294
+ ] as const
295
+ const sizes = ["sm", "md", "lg"] as const
296
+
297
+ const code = `<Button
298
+ variant="${variant}"
299
+ size="${size}"${isDisabled ? "\n isDisabled" : ""}${showLeftIcon ? "\n leftIcon={<StarIcon />}" : ""}${showRightIcon ? "\n rightIcon={<PlusIcon />}" : ""}
300
+ >
301
+ Get Started
302
+ </Button>`
303
+
304
+ return (
305
+ <div className="w-full p-8">
306
+ <div className="mx-auto max-w-3xl space-y-6">
307
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
308
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-5 rounded-xl border p-5">
309
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
310
+ Variant
311
+ </p>
312
+ <div className="flex flex-col gap-2">
313
+ {variants.map((v) => (
314
+ <button
315
+ key={v}
316
+ onClick={() => setVariant(v)}
317
+ className={`font-fm-text text-fm-sm leading-fm-sm rounded-lg px-3 py-2 text-left transition-colors ${
318
+ variant === v
319
+ ? "bg-fm-surface-primary text-fm-primary font-medium"
320
+ : "text-fm-secondary hover:text-fm-primary"
321
+ }`}
322
+ >
323
+ {v}
324
+ </button>
325
+ ))}
326
+ </div>
327
+
328
+ <div className="border-fm-divider-secondary border-t pt-4" />
329
+
330
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
331
+ Size
332
+ </p>
333
+ <div className="flex gap-2">
334
+ {sizes.map((s) => (
335
+ <button
336
+ key={s}
337
+ onClick={() => setSize(s)}
338
+ className={`font-fm-text text-fm-sm leading-fm-sm rounded-lg px-3 py-2 transition-colors ${
339
+ size === s
340
+ ? "bg-fm-surface-primary text-fm-primary font-medium"
341
+ : "text-fm-secondary hover:text-fm-primary"
342
+ }`}
343
+ >
344
+ {s}
345
+ </button>
346
+ ))}
347
+ </div>
348
+
349
+ <div className="border-fm-divider-secondary border-t pt-4" />
350
+
351
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
352
+ Options
353
+ </p>
354
+ <div className="flex flex-col gap-2">
355
+ <label className="flex cursor-pointer items-center gap-2">
356
+ <input
357
+ type="checkbox"
358
+ checked={showLeftIcon}
359
+ onChange={(e) => setShowLeftIcon(e.target.checked)}
360
+ className="accent-fm-primary"
361
+ />
362
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
363
+ Left icon
364
+ </span>
365
+ </label>
366
+ <label className="flex cursor-pointer items-center gap-2">
367
+ <input
368
+ type="checkbox"
369
+ checked={showRightIcon}
370
+ onChange={(e) => setShowRightIcon(e.target.checked)}
371
+ className="accent-fm-primary"
372
+ />
373
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
374
+ Right icon
375
+ </span>
376
+ </label>
377
+ <label className="flex cursor-pointer items-center gap-2">
378
+ <input
379
+ type="checkbox"
380
+ checked={isDisabled}
381
+ onChange={(e) => setIsDisabled(e.target.checked)}
382
+ className="accent-fm-primary"
383
+ />
384
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
385
+ Disabled
386
+ </span>
387
+ </label>
388
+ </div>
389
+ </div>
390
+
391
+ <div className="flex flex-col gap-6 lg:col-span-2">
392
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary flex min-h-40 items-center justify-center rounded-xl border p-8">
393
+ <Button
394
+ variant={variant}
395
+ size={size}
396
+ isDisabled={isDisabled}
397
+ leftIcon={showLeftIcon ? <StarIcon /> : undefined}
398
+ rightIcon={showRightIcon ? <PlusIcon /> : undefined}
399
+ >
400
+ Get Started
401
+ </Button>
402
+ </div>
403
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
404
+ <code className="text-fm-secondary text-fm-sm leading-fm-lg font-[var(--font-fm-mono)] whitespace-pre">
405
+ {code}
406
+ </code>
407
+ </div>
408
+ </div>
476
409
  </div>
477
410
  </div>
478
411
  </div>
479
- </div>
480
- ),
412
+ )
413
+ },
481
414
  parameters: {
415
+ layout: "fullscreen",
482
416
  docs: {
483
417
  description: {
484
418
  story:
485
- "Disabled state applied across all six variants, with and without noise. Compare enabled and disabled appearances side-by-side.",
419
+ "Configure variant, size, icon slots, and disabled state in the left panel. The live preview and code snippet update instantly.",
486
420
  },
487
421
  },
488
422
  },
489
423
  }
490
424
 
491
- // ─── 4. Use Cases ─────────────────────────────────────────────────────────────
425
+ // ─── 5. Use Cases ─────────────────────────────────────────────────────────────
492
426
 
493
427
  export const UseCases: Story = {
494
428
  render: () => (
@@ -501,12 +435,7 @@ export const UseCases: Story = {
501
435
  <Button variant="secondary" size="sm">
502
436
  <SkipBackwardIcon className="h-4 w-4" />
503
437
  </Button>
504
- <Button
505
- variant="primary"
506
- noise="strong"
507
- size="lg"
508
- leftIcon={<CircularPlayIcon />}
509
- >
438
+ <Button variant="primary" size="lg" leftIcon={<CircularPlayIcon />}>
510
439
  Play Now
511
440
  </Button>
512
441
  <Button variant="secondary" size="sm">
@@ -523,26 +452,21 @@ export const UseCases: Story = {
523
452
  Subscription CTA
524
453
  </h4>
525
454
  <div className="border-fm-divider-secondary bg-fm-surface-secondary flex flex-col items-center gap-4 rounded-xl border p-6">
526
- <p className="text-fm-primary font-fm-text text-fm-lg leading-fm-xl font-semibold">
455
+ <p className="text-fm-primary font-fm-text text-fm-lg leading-fm-xl font-medium">
527
456
  Unlock Premium Audio
528
457
  </p>
529
458
  <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl max-w-xs text-center">
530
459
  Get lossless streaming, offline downloads, and exclusive content.
531
460
  </p>
532
461
  <div className="flex flex-wrap justify-center gap-3">
533
- <Button
534
- variant="primary"
535
- noise="medium"
536
- size="lg"
537
- leftIcon={<StarIcon />}
538
- >
462
+ <Button variant="primary" size="lg" leftIcon={<StarIcon />}>
539
463
  Start Free Trial
540
464
  </Button>
541
- <Button variant="outline" noise="none" size="lg">
465
+ <Button variant="outline" size="lg">
542
466
  Learn More
543
467
  </Button>
544
468
  </div>
545
- <Button variant="text" noise="none" size="sm">
469
+ <Button variant="text" size="sm">
546
470
  Not now
547
471
  </Button>
548
472
  </div>
@@ -575,7 +499,7 @@ export const UseCases: Story = {
575
499
  <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
576
500
  Equalizer
577
501
  </p>
578
- <Button variant="chipActive" size="sm" noise="low">
502
+ <Button variant="chipActive" size="sm">
579
503
  Active
580
504
  </Button>
581
505
  </div>
@@ -587,27 +511,16 @@ export const UseCases: Story = {
587
511
  Genre Filter Chips
588
512
  </h4>
589
513
  <div className="border-fm-divider-secondary bg-fm-surface-secondary flex flex-wrap gap-2 rounded-xl border p-6">
590
- <Button variant="chipActive" size="sm" noise="medium">
514
+ <Button variant="chipActive" size="sm">
591
515
  All
592
516
  </Button>
593
- <Button variant="chip" size="sm">
594
- Hip-Hop
595
- </Button>
596
- <Button variant="chip" size="sm">
597
- Electronic
598
- </Button>
599
- <Button variant="chip" size="sm">
600
- Jazz
601
- </Button>
602
- <Button variant="chip" size="sm">
603
- Classical
604
- </Button>
605
- <Button variant="chip" size="sm">
606
- Rock
607
- </Button>
608
- <Button variant="chip" size="sm">
609
- Pop
610
- </Button>
517
+ {["Hip-Hop", "Electronic", "Jazz", "Classical", "Rock", "Pop"].map(
518
+ (genre) => (
519
+ <Button key={genre} variant="chip" size="sm">
520
+ {genre}
521
+ </Button>
522
+ )
523
+ )}
611
524
  </div>
612
525
  </div>
613
526
 
@@ -617,41 +530,50 @@ export const UseCases: Story = {
617
530
  </h4>
618
531
  <div className="border-fm-divider-secondary bg-fm-surface-secondary flex flex-wrap items-center justify-center gap-4 rounded-xl border p-6">
619
532
  <Button
620
- tooltip="Primary medium noise, tooltip above"
533
+ tooltip="Play your library"
621
534
  tooltipContentProps={{
622
- align: "center",
623
535
  side: "top",
624
- sideOffset: 10,
536
+ align: "center",
537
+ sideOffset: 8,
625
538
  }}
626
- noise="medium"
539
+ leftIcon={<CircularPlayIcon />}
627
540
  >
628
- Primary
541
+ Play
629
542
  </Button>
630
543
  <Button
631
544
  variant="secondary"
632
- tooltip="Secondary tooltip below"
545
+ tooltip="Add to favourites"
633
546
  tooltipContentProps={{
634
- align: "center",
635
547
  side: "bottom",
636
- sideOffset: 10,
548
+ align: "center",
549
+ sideOffset: 8,
637
550
  }}
551
+ leftIcon={<HeartIcon />}
638
552
  >
639
- Secondary
553
+ Favourite
640
554
  </Button>
641
555
  <Button
642
556
  variant="outline"
643
- tooltip="Outline no noise, tooltip above"
557
+ tooltip="Search your library"
644
558
  tooltipContentProps={{
645
- align: "center",
646
559
  side: "top",
647
- sideOffset: 10,
560
+ align: "center",
561
+ sideOffset: 8,
648
562
  }}
649
- noise="none"
563
+ leftIcon={<SearchIcon />}
650
564
  >
651
- Outline
565
+ Search
652
566
  </Button>
653
- <Button variant="text" tooltip="Text — tooltip on hover" noise="none">
654
- Text
567
+ <Button
568
+ variant="text"
569
+ tooltip="Opens account settings"
570
+ tooltipContentProps={{
571
+ side: "top",
572
+ align: "center",
573
+ sideOffset: 8,
574
+ }}
575
+ >
576
+ Settings
655
577
  </Button>
656
578
  </div>
657
579
  </div>
@@ -662,7 +584,7 @@ export const UseCases: Story = {
662
584
  docs: {
663
585
  description: {
664
586
  story:
665
- "Realistic audio-app scenarios: player playback controls, subscription upgrade CTA, settings panel actions, and genre filter chip row.",
587
+ "Realistic audio-app scenarios: player controls, subscription CTA, settings panel, genre chip filter, and tooltip integration.",
666
588
  },
667
589
  },
668
590
  },