aural-ui 4.0.1 → 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 (174) hide show
  1. package/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1228
  2. package/dist/components/avatar/Avatar.stories.tsx +219 -235
  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/card/Card.stories.tsx +619 -301
  8. package/dist/components/char-count/CharCount.stories.tsx +350 -248
  9. package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
  10. package/dist/components/chip/Chip.stories.tsx +362 -168
  11. package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -636
  12. package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
  13. package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
  14. package/dist/components/command/Command.stories.tsx +530 -867
  15. package/dist/components/dialog/Dialog.stories.tsx +501 -950
  16. package/dist/components/divider/Divider.stories.tsx +264 -527
  17. package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
  18. package/dist/components/drawer/Drawer.stories.tsx +659 -1023
  19. package/dist/components/dropdown/Dropdown.stories.tsx +643 -1028
  20. package/dist/components/form/Form.stories.tsx +560 -274
  21. package/dist/components/helper-text/HelperText.stories.tsx +199 -200
  22. package/dist/components/hover-card/HoverCard.stories.tsx +318 -1254
  23. package/dist/components/icon-button/IconButton.stories.tsx +837 -194
  24. package/dist/components/if-else/if-else.stories.tsx +370 -83
  25. package/dist/components/input/Input.stories.tsx +436 -368
  26. package/dist/components/label/Label.stories.tsx +156 -154
  27. package/dist/components/list/List.stories.tsx +484 -835
  28. package/dist/components/marquee/Marquee.stories.tsx +356 -712
  29. package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -422
  30. package/dist/components/overlay/Overlay.stories.tsx +452 -824
  31. package/dist/components/pagination/Pagination.stories.tsx +721 -210
  32. package/dist/components/popover/Popover.stories.tsx +481 -896
  33. package/dist/components/radio/Radio.stories.tsx +432 -124
  34. package/dist/components/resizable/Resizable.stories.tsx +495 -799
  35. package/dist/components/scroll-area/ScrollArea.stories.tsx +383 -1059
  36. package/dist/components/search/Search.stories.tsx +312 -595
  37. package/dist/components/select/Select.stories.tsx +684 -789
  38. package/dist/components/sheet/Sheet.stories.tsx +671 -950
  39. package/dist/components/skelton/Skelton.stories.tsx +230 -764
  40. package/dist/components/slider/Slider.stories.tsx +383 -760
  41. package/dist/components/stepper/Stepper.stories.tsx +371 -514
  42. package/dist/components/switch/Switch.stories.tsx +461 -208
  43. package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
  44. package/dist/components/table/Table.stories.tsx +770 -916
  45. package/dist/components/tabs/Tabs.stories.tsx +458 -1455
  46. package/dist/components/tag/Tag.stories.tsx +714 -542
  47. package/dist/components/textarea/TextArea.stories.tsx +621 -562
  48. package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -154
  49. package/dist/components/toast/Toast.stories.tsx +452 -1339
  50. package/dist/components/toggle/Toggle.stories.tsx +488 -931
  51. package/dist/components/tooltip/Tooltip.stories.tsx +344 -1388
  52. package/dist/components/typography/Typography.stories.tsx +406 -89
  53. package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
  54. package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
  55. package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
  56. package/dist/icons/Icons.stories.tsx +0 -12
  57. package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +223 -1060
  58. package/dist/icons/alert-icon/AlertIcon.stories.tsx +106 -968
  59. package/dist/icons/all-icons.tsx +37 -16
  60. package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +137 -1010
  61. package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +145 -935
  62. package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +132 -1046
  63. package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +134 -986
  64. package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +135 -1028
  65. package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +133 -971
  66. package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +145 -1123
  67. package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +143 -1252
  68. package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +123 -632
  69. package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +141 -1223
  70. package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +164 -1018
  71. package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +121 -1236
  72. package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +121 -1213
  73. package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +116 -893
  74. package/dist/icons/camera-icon/CameraIcon.stories.tsx +109 -1254
  75. package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +114 -975
  76. package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +157 -994
  77. package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +160 -992
  78. package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +140 -970
  79. package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +126 -993
  80. package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +144 -987
  81. package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +141 -1007
  82. package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +147 -1187
  83. package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +110 -476
  84. package/dist/icons/coin-icon/CoinIcon.stories.tsx +120 -1364
  85. package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +113 -1360
  86. package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +111 -942
  87. package/dist/icons/command-icon/CommandIcon.stories.tsx +124 -1087
  88. package/dist/icons/copy-icon/CopyIcon.stories.tsx +119 -996
  89. package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +144 -1046
  90. package/dist/icons/cross-icon/CrossIcon.stories.tsx +136 -999
  91. package/dist/icons/download-icon/DownloadIcon.stories.tsx +123 -857
  92. package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +121 -1080
  93. package/dist/icons/email-icon/EmailIcon.stories.tsx +112 -979
  94. package/dist/icons/expand-icon/ExpandIcon.stories.tsx +109 -1146
  95. package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +141 -1068
  96. package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +140 -1081
  97. package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +124 -1050
  98. package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +123 -1091
  99. package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +122 -633
  100. package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +116 -1087
  101. package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +166 -1020
  102. package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +112 -1182
  103. package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +112 -1155
  104. package/dist/icons/globe-icon/GlobeIcon.stories.tsx +127 -325
  105. package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +142 -985
  106. package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +116 -1217
  107. package/dist/icons/head-icon/HeadIcon.stories.tsx +108 -953
  108. package/dist/icons/heart-icon/HeartIcon.stories.tsx +117 -1060
  109. package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +116 -716
  110. package/dist/icons/image-icon/ImageIcon.stories.tsx +102 -1164
  111. package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +108 -1233
  112. package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +133 -1289
  113. package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +155 -1012
  114. package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +158 -1438
  115. package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +121 -1011
  116. package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +116 -981
  117. package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +116 -979
  118. package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +105 -1252
  119. package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +151 -1554
  120. package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +107 -1227
  121. package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +116 -707
  122. package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +119 -1226
  123. package/dist/icons/message-icon/MessageIcon.stories.tsx +111 -557
  124. package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +112 -1198
  125. package/dist/icons/moon-icon/MoonIcon.stories.tsx +117 -557
  126. package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +106 -1235
  127. package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +112 -1185
  128. package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +116 -1012
  129. package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +108 -1137
  130. package/dist/icons/notes-icon/NotesIcon.stories.tsx +116 -1138
  131. package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +106 -1146
  132. package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +119 -719
  133. package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +110 -999
  134. package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +109 -912
  135. package/dist/icons/pause-icon/PauseIcon.stories.tsx +110 -1041
  136. package/dist/icons/pencil-icon/PencilIcon.stories.tsx +112 -1109
  137. package/dist/icons/phone-icon/PhoneIcon.stories.tsx +112 -1023
  138. package/dist/icons/plus-icon/PlusIcon.stories.tsx +103 -1132
  139. package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +104 -870
  140. package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +99 -476
  141. package/dist/icons/search-icon/SearchIcon.stories.tsx +108 -1161
  142. package/dist/icons/setting-icon/SettingIcon.stories.tsx +104 -1009
  143. package/dist/icons/share-icon/ShareIcon.stories.tsx +117 -1064
  144. package/dist/icons/shield-icon/ShieldIcon.stories.tsx +114 -974
  145. package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +134 -1160
  146. package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +169 -1017
  147. package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +161 -1016
  148. package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +102 -1001
  149. package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +155 -593
  150. package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +155 -608
  151. package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +142 -712
  152. package/dist/icons/star-icon/StarIcon.stories.tsx +120 -946
  153. package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +109 -1013
  154. package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +113 -891
  155. package/dist/icons/sun-icon/SunIcon.stories.tsx +117 -864
  156. package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +113 -989
  157. package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +120 -1027
  158. package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +153 -1476
  159. package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +143 -1187
  160. package/dist/icons/tick-icon/TickIcon.stories.tsx +142 -1322
  161. package/dist/icons/trash-icon/TrashIcon.stories.tsx +105 -970
  162. package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +154 -1457
  163. package/dist/icons/upload-icon/UploadIcon.stories.tsx +112 -930
  164. package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +115 -1019
  165. package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +122 -1092
  166. package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +120 -1401
  167. package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +107 -1212
  168. package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +109 -1122
  169. package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +112 -1124
  170. package/dist/icons/warning-icon/WarningIcon.stories.tsx +119 -1083
  171. package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +158 -983
  172. package/dist/index.cjs +1 -1
  173. package/dist/index.js +1 -1
  174. package/package.json +1 -1
@@ -1,6 +1,8 @@
1
1
  import * as 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 { Stepper } from "."
5
7
 
6
8
  const meta: Meta<typeof Stepper> = {
@@ -8,52 +10,63 @@ const meta: Meta<typeof Stepper> = {
8
10
  component: Stepper,
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
15
  component:
21
- "A flexible stepper component that guides users through a multi-step process. Supports both automatic step generation and custom composition patterns with clickable navigation.",
16
+ "A multi-step progress indicator that guides users through sequential flows. Supports four color variants, horizontal and vertical orientations, three sizes, step labels, and clickable navigation with optional keyboard support.",
22
17
  },
18
+ page: () => (
19
+ <AuralComponentDocsPage
20
+ features={[
21
+ {
22
+ title: "4 Color Variants",
23
+ description: "Primary to warning",
24
+ },
25
+ {
26
+ title: "H & V Orientations",
27
+ description: "Horizontal or vertical",
28
+ },
29
+ {
30
+ title: "Clickable Steps",
31
+ description: "onStepClick navigation",
32
+ },
33
+ ]}
34
+ />
35
+ ),
23
36
  },
24
37
  },
25
38
  tags: ["autodocs"],
26
39
  argTypes: {
27
40
  steps: {
28
41
  control: { type: "number", min: 1, max: 10 },
29
- description: "Number of steps to generate automatically",
42
+ description: "Number of steps to render automatically",
30
43
  },
31
44
  activeStep: {
32
45
  control: { type: "number", min: 0, max: 9 },
33
- description: "Currently active step (0-indexed)",
46
+ description: "Currently active step index (0-based)",
34
47
  },
35
48
  variant: {
36
49
  control: { type: "select" },
37
50
  options: ["primary", "positive", "negative", "warning"],
38
- description: "Visual variant of the stepper",
51
+ description: "Color variant applied to active and completed steps",
39
52
  },
40
53
  orientation: {
41
54
  control: { type: "select" },
42
55
  options: ["horizontal", "vertical"],
43
- description: "Layout orientation",
56
+ description: "Layout orientation of the step list",
44
57
  },
45
58
  size: {
46
59
  control: { type: "select" },
47
60
  options: ["sm", "md", "lg"],
48
- description: "Size of the step indicators",
61
+ description: "Size of the step indicator circles",
49
62
  },
50
63
  stepLabels: {
51
64
  control: { type: "object" },
52
- description: "Array of labels for each step",
65
+ description: "Array of label strings for each step",
53
66
  },
54
67
  onStepClick: {
55
68
  action: "stepClicked",
56
- description: "Callback function when a step is clicked",
69
+ description: "Callback fired when a clickable step is selected",
57
70
  },
58
71
  },
59
72
  }
@@ -61,586 +74,430 @@ const meta: Meta<typeof Stepper> = {
61
74
  export default meta
62
75
  type Story = StoryObj<typeof Stepper>
63
76
 
64
- // Basic Examples
65
- export const Default: Story = {
66
- args: {
67
- steps: 4,
68
- activeStep: 1,
69
- variant: "primary",
70
- orientation: "horizontal",
71
- size: "md",
72
- className: "text-fm-primary w-[600px]",
73
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
74
- },
75
- }
77
+ // ─── 1. Playground ────────────────────────────────────────────────────────────
76
78
 
77
- export const WithLabels: Story = {
79
+ export const Playground: Story = {
78
80
  args: {
79
81
  steps: 4,
80
82
  activeStep: 1,
81
83
  variant: "primary",
82
84
  orientation: "horizontal",
83
85
  size: "md",
84
- className: "text-fm-primary w-[600px]",
85
- stepLabels: ["Account", "Profile", "Payment", "Confirmation"],
86
- },
87
- }
88
-
89
- export const Completed: Story = {
90
- args: {
91
- steps: 4,
92
- activeStep: 4,
93
- variant: "primary",
94
- orientation: "horizontal",
95
- size: "md",
96
- className: "text-fm-primary w-[600px]",
97
- stepLabels: ["Account", "Profile", "Payment", "Confirmation"],
98
- },
99
- }
100
-
101
- // Clickable Examples
102
- export const ClickableBasic: Story = {
103
- render: () => {
104
- const [activeStep, setActiveStep] = React.useState(1)
105
-
106
- return (
107
- <div className="space-y-4">
108
- <div className="text-fm-primary text-sm">
109
- Click on any step to navigate. Current step: {activeStep + 1}
110
- </div>
111
- <Stepper
112
- steps={4}
113
- activeStep={activeStep}
114
- variant="primary"
115
- className="text-fm-primary w-[600px]"
116
- stepLabels={["Account", "Profile", "Payment", "Confirmation"]}
117
- onStepClick={(stepIndex) => setActiveStep(stepIndex)}
118
- />
86
+ stepLabels: ["Account", "Profile", "Payment", "Confirm"],
87
+ },
88
+ render: (args) => (
89
+ <div className="w-full max-w-xl space-y-4">
90
+ <Stepper {...args} className="text-fm-primary w-full" />
91
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
92
+ <code
93
+ className="text-fm-secondary text-fm-md leading-fm-md"
94
+ style={{ fontFamily: "var(--font-fm-mono)" }}
95
+ >
96
+ {`<Stepper steps={${args.steps}} activeStep={${args.activeStep}} variant="${args.variant}" size="${args.size}" orientation="${args.orientation}" />`}
97
+ </code>
119
98
  </div>
120
- )
121
- },
99
+ </div>
100
+ ),
122
101
  parameters: {
123
102
  docs: {
124
103
  description: {
125
104
  story:
126
- "Stepper with clickable steps. Users can click on any step to navigate directly.",
105
+ "Use the controls panel to explore steps count, active step index, variant, size, and orientation.",
127
106
  },
128
107
  },
129
108
  },
130
109
  }
131
110
 
132
- export const ClickableWithRestrictions: Story = {
133
- render: () => {
134
- const [activeStep, setActiveStep] = React.useState(0)
111
+ // ─── 2. All Variants ──────────────────────────────────────────────────────────
135
112
 
136
- const handleStepClick = (stepIndex: number) => {
137
- // Only allow navigation to completed steps or the next step
138
- if (stepIndex <= activeStep + 1) {
139
- setActiveStep(stepIndex)
140
- }
141
- }
142
-
143
- return (
144
- <div className="space-y-4">
145
- <div className="text-fm-primary text-sm">
146
- Click on completed steps or the next step to navigate. Current step:{" "}
147
- {activeStep + 1}
148
- </div>
149
- <Stepper
150
- steps={5}
151
- activeStep={activeStep}
152
- variant="primary"
153
- className="text-fm-primary w-[700px]"
154
- stepLabels={["Start", "Info", "Review", "Payment", "Complete"]}
155
- onStepClick={handleStepClick}
156
- />
157
- <div className="flex gap-2">
158
- <button
159
- onClick={() => setActiveStep(Math.max(0, activeStep - 1))}
160
- disabled={activeStep === 0}
161
- className="bg-fm-surface-tertiary text-fm-primary rounded px-3 py-1 text-sm disabled:opacity-50"
162
- >
163
- Previous
164
- </button>
165
- <button
166
- onClick={() => setActiveStep(Math.min(4, activeStep + 1))}
167
- disabled={activeStep === 4}
168
- className="bg-fm-surface-info text-fm-surface-primary rounded px-3 py-1 text-sm disabled:opacity-50"
169
- >
170
- Next
171
- </button>
113
+ export const AllVariants: Story = {
114
+ render: () => (
115
+ <div className="space-y-8">
116
+ {(
117
+ [
118
+ {
119
+ variant: "primary",
120
+ label: "Primary",
121
+ labels: ["Account", "Profile", "Payment", "Confirm"],
122
+ },
123
+ {
124
+ variant: "positive",
125
+ label: "Positive",
126
+ labels: ["Setup", "Configure", "Test", "Deploy"],
127
+ },
128
+ {
129
+ variant: "negative",
130
+ label: "Negative",
131
+ labels: ["Report", "Review", "Resolve", "Close"],
132
+ },
133
+ {
134
+ variant: "warning",
135
+ label: "Warning",
136
+ labels: ["Draft", "Validate", "Approve", "Publish"],
137
+ },
138
+ ] as const
139
+ ).map(({ variant, label, labels }) => (
140
+ <div key={variant} className="space-y-3">
141
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium capitalize">
142
+ {label}
143
+ </h4>
144
+ <div className="space-y-2 text-center">
145
+ <Stepper
146
+ steps={4}
147
+ activeStep={2}
148
+ variant={variant}
149
+ stepLabels={[...labels]}
150
+ className="text-fm-primary w-150"
151
+ />
152
+ </div>
172
153
  </div>
173
- </div>
174
- )
175
- },
154
+ ))}
155
+ </div>
156
+ ),
176
157
  parameters: {
158
+ layout: "padded",
177
159
  docs: {
178
160
  description: {
179
161
  story:
180
- "Stepper with navigation restrictions. Users can only click on completed steps or the immediate next step.",
162
+ "All four variants (primary, positive, negative, warning) shown with step labels at active step 3 displaying completed, active, and inactive states simultaneously.",
181
163
  },
182
164
  },
183
165
  },
184
166
  }
185
167
 
186
- export const ClickableVertical: Story = {
187
- render: () => {
188
- const [activeStep, setActiveStep] = React.useState(1)
168
+ // ─── 2. Sizes ─────────────────────────────────────────────────────────────────
189
169
 
190
- return (
191
- <div className="flex gap-8">
192
- <div className="space-y-4">
193
- <div className="text-fm-primary text-sm">
194
- Vertical clickable stepper
195
- </div>
170
+ export const Sizes: Story = {
171
+ render: () => (
172
+ <div className="space-y-8">
173
+ <div className="flex flex-wrap items-end justify-center gap-8">
174
+ <div className="space-y-3 text-center">
196
175
  <Stepper
197
- steps={4}
198
- activeStep={activeStep}
199
- variant="positive"
200
- orientation="vertical"
201
- className="text-fm-primary h-[400px]"
202
- stepLabels={["Setup", "Configure", "Test", "Deploy"]}
203
- onStepClick={(stepIndex) => setActiveStep(stepIndex)}
176
+ steps={3}
177
+ activeStep={1}
178
+ variant="primary"
179
+ size="sm"
180
+ stepLabels={["Start", "Middle", "End"]}
181
+ className="text-fm-primary w-80"
204
182
  />
183
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
184
+ Small (sm)
185
+ </p>
205
186
  </div>
206
- <div className="bg-fm-surface-secondary min-w-[300px] rounded-lg p-4">
207
- <h3 className="text-fm-primary mb-2 font-semibold">Step Content</h3>
208
- <p className="text-fm-secondary text-sm">
209
- Content for step:{" "}
210
- {["Setup", "Configure", "Test", "Deploy"][activeStep] ||
211
- "Completed"}
187
+ <div className="space-y-3 text-center">
188
+ <Stepper
189
+ steps={3}
190
+ activeStep={1}
191
+ variant="primary"
192
+ size="md"
193
+ stepLabels={["Start", "Middle", "End"]}
194
+ className="text-fm-primary w-80"
195
+ />
196
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
197
+ Medium (md) — default
198
+ </p>
199
+ </div>
200
+ <div className="space-y-3 text-center">
201
+ <Stepper
202
+ steps={3}
203
+ activeStep={1}
204
+ variant="primary"
205
+ size="lg"
206
+ stepLabels={["Start", "Middle", "End"]}
207
+ className="text-fm-primary w-80"
208
+ />
209
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
210
+ Large (lg)
212
211
  </p>
213
212
  </div>
214
213
  </div>
215
- )
216
- },
217
- parameters: {
218
- layout: "padded",
219
- docs: {
220
- description: {
221
- story: "Vertical orientation stepper with clickable navigation.",
222
- },
223
- },
224
- },
225
- }
226
214
 
227
- export const ClickableCompound: Story = {
228
- render: () => {
229
- const [activeStep, setActiveStep] = React.useState(0)
230
- const steps = ["Personal", "Address", "Payment", "Review"]
231
-
232
- return (
233
- <div className="space-y-6">
234
- <Stepper
235
- variant="primary"
236
- activeStep={activeStep}
237
- onStepClick={(stepIndex) => setActiveStep(stepIndex)}
238
- >
239
- {steps.map((step, index) => (
240
- <Stepper.Step
241
- key={index}
242
- index={index}
243
- label={step}
244
- isLast={index === steps.length - 1}
245
- />
246
- ))}
247
-
248
- <Stepper.Content>
249
- <div className="bg-fm-surface-secondary min-h-[200px] rounded-lg p-6">
250
- <h3 className="mb-4 text-lg font-semibold">
251
- {steps[activeStep]} Information
252
- </h3>
253
- <p className="text-fm-secondary mb-6">
254
- Please fill out your {steps[activeStep].toLowerCase()}{" "}
255
- information below.
215
+ <div className="space-y-4">
216
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
217
+ Size × Variant
218
+ </h4>
219
+ <div className="flex flex-wrap items-center gap-8">
220
+ {(["sm", "md", "lg"] as const).map((size) => (
221
+ <div key={size} className="space-y-3 text-center">
222
+ <Stepper
223
+ steps={4}
224
+ activeStep={2}
225
+ variant="positive"
226
+ size={size}
227
+ className="text-fm-primary w-72"
228
+ />
229
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
230
+ positive · {size}
256
231
  </p>
257
-
258
- <div className="flex gap-4">
259
- <button
260
- onClick={() => setActiveStep(Math.max(0, activeStep - 1))}
261
- disabled={activeStep === 0}
262
- className="bg-fm-surface-tertiary text-fm-primary rounded px-4 py-2 disabled:opacity-50"
263
- >
264
- Previous
265
- </button>
266
- <button
267
- onClick={() =>
268
- setActiveStep(Math.min(steps.length - 1, activeStep + 1))
269
- }
270
- disabled={activeStep === steps.length - 1}
271
- className="bg-fm-surface-info text-fm-surface-primary rounded px-4 py-2 disabled:opacity-50"
272
- >
273
- {activeStep === steps.length - 1 ? "Complete" : "Next"}
274
- </button>
275
- </div>
276
232
  </div>
277
- </Stepper.Content>
278
- </Stepper>
233
+ ))}
234
+ </div>
279
235
  </div>
280
- )
281
- },
236
+ </div>
237
+ ),
282
238
  parameters: {
283
239
  layout: "padded",
284
240
  docs: {
285
241
  description: {
286
242
  story:
287
- "Compound component pattern with clickable steps and integrated content area.",
243
+ "Three indicator sizes (sm, md, lg) compared side by side with labels, plus a size × variant cross-axis row.",
288
244
  },
289
245
  },
290
246
  },
291
247
  }
292
248
 
293
- export const ClickableAllVariants: Story = {
294
- render: () => {
295
- const [activeSteps, setActiveSteps] = React.useState({
296
- primary: 1,
297
- positive: 2,
298
- negative: 0,
299
- warning: 3,
300
- })
249
+ // ─── 3. Configurations ────────────────────────────────────────────────────────
250
+
251
+ export const Configurations: Story = {
252
+ render: () => (
253
+ <div className="space-y-10">
254
+ <div className="space-y-4">
255
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
256
+ Horizontal Orientation
257
+ </h4>
258
+ <div className="space-y-3 text-center">
259
+ <Stepper
260
+ steps={4}
261
+ activeStep={2}
262
+ variant="primary"
263
+ orientation="horizontal"
264
+ stepLabels={["Account", "Profile", "Payment", "Confirm"]}
265
+ className="text-fm-primary w-150"
266
+ />
267
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
268
+ horizontal (default)
269
+ </p>
270
+ </div>
271
+ </div>
301
272
 
302
- const handleStepClick = (
303
- variant: keyof typeof activeSteps,
304
- stepIndex: number
305
- ) => {
306
- setActiveSteps((prev) => ({
307
- ...prev,
308
- [variant]: stepIndex,
309
- }))
310
- }
273
+ <div className="space-y-4">
274
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
275
+ Vertical Orientation
276
+ </h4>
277
+ <div className="flex flex-wrap gap-10">
278
+ <div className="space-y-3 text-center">
279
+ <Stepper
280
+ steps={4}
281
+ activeStep={2}
282
+ variant="primary"
283
+ orientation="vertical"
284
+ stepLabels={["Account", "Profile", "Payment", "Confirm"]}
285
+ className="text-fm-primary h-48"
286
+ />
287
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
288
+ primary · vertical
289
+ </p>
290
+ </div>
291
+ <div className="space-y-3 text-center">
292
+ <Stepper
293
+ steps={4}
294
+ activeStep={1}
295
+ variant="positive"
296
+ orientation="vertical"
297
+ stepLabels={["Setup", "Configure", "Test", "Deploy"]}
298
+ className="text-fm-primary h-48"
299
+ />
300
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
301
+ positive · vertical
302
+ </p>
303
+ </div>
304
+ <div className="space-y-3 text-center">
305
+ <Stepper
306
+ steps={4}
307
+ activeStep={3}
308
+ variant="warning"
309
+ orientation="vertical"
310
+ stepLabels={["Draft", "Review", "Approve", "Publish"]}
311
+ className="text-fm-primary h-48"
312
+ />
313
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
314
+ warning · vertical
315
+ </p>
316
+ </div>
317
+ </div>
318
+ </div>
311
319
 
312
- return (
313
- <div className="text-fm-primary space-y-8">
314
- {(["primary", "positive", "negative", "warning"] as const).map(
315
- (variant) => (
316
- <div key={variant} className="space-y-2">
317
- <h4 className="text-sm font-medium capitalize">
318
- {variant} - Active Step: {activeSteps[variant] + 1}
319
- </h4>
320
+ <div className="space-y-4">
321
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
322
+ Progress States
323
+ </h4>
324
+ <div className="space-y-4">
325
+ {[
326
+ { active: 0, label: "Step 1 active (all inactive)" },
327
+ { active: 1, label: "Step 2 active (1 completed)" },
328
+ { active: 3, label: "Step 4 active (3 completed)" },
329
+ { active: 4, label: "All completed" },
330
+ ].map(({ active, label }) => (
331
+ <div key={active} className="space-y-2">
332
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
333
+ {label}
334
+ </p>
320
335
  <Stepper
321
336
  steps={4}
322
- activeStep={activeSteps[variant]}
323
- variant={variant}
324
- stepLabels={["Step 1", "Step 2", "Step 3", "Step 4"]}
325
- onStepClick={(stepIndex) => handleStepClick(variant, stepIndex)}
337
+ activeStep={active}
338
+ variant="primary"
339
+ stepLabels={["Start", "Build", "Test", "Ship"]}
340
+ className="text-fm-primary w-125"
326
341
  />
327
342
  </div>
328
- )
329
- )}
330
- </div>
331
- )
332
- },
333
- parameters: {
334
- layout: "padded",
335
- docs: {
336
- description: {
337
- story:
338
- "All variants with clickable functionality to demonstrate different visual styles.",
339
- },
340
- },
341
- },
342
- }
343
-
344
- export const ClickableWithKeyboard: Story = {
345
- render: () => {
346
- const [activeStep, setActiveStep] = React.useState(1)
347
-
348
- return (
349
- <div className="space-y-4">
350
- <div className="bg-fm-surface-warning-sec text-fm-warning rounded-lg p-4 text-sm">
351
- <strong>Keyboard Navigation:</strong>
352
- <ul className="mt-2 space-y-1">
353
- <li>• Use Tab to focus on clickable steps</li>
354
- <li>• Press Enter or Space to navigate to a step</li>
355
- <li>• Use mouse click for direct navigation</li>
356
- </ul>
357
- </div>
358
- <Stepper
359
- steps={5}
360
- activeStep={activeStep}
361
- variant="primary"
362
- className="text-fm-primary w-[700px]"
363
- stepLabels={["Start", "Personal", "Details", "Review", "Finish"]}
364
- onStepClick={(stepIndex) => setActiveStep(stepIndex)}
365
- aria-label="Registration process stepper"
366
- />
367
- <div className="text-fm-primary text-sm">
368
- Current step: {activeStep + 1} of 5
343
+ ))}
369
344
  </div>
370
345
  </div>
371
- )
372
- },
346
+ </div>
347
+ ),
373
348
  parameters: {
349
+ layout: "padded",
374
350
  docs: {
375
351
  description: {
376
352
  story:
377
- "Demonstrates keyboard accessibility features for clickable steps. Focus management and ARIA labels provide screen reader support.",
353
+ "Horizontal vs vertical orientation comparison, plus a full sweep of progress states from step 1 through all-completed.",
378
354
  },
379
355
  },
380
356
  },
381
357
  }
382
358
 
383
- // Variant Examples
384
- export const PrimaryVariant: Story = {
385
- args: {
386
- steps: 4,
387
- activeStep: 2,
388
- variant: "primary",
389
- className: "text-fm-primary w-[600px]",
390
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
391
- },
392
- }
359
+ // ─── 4. Interactive ───────────────────────────────────────────────────────────
393
360
 
394
- export const PositiveVariant: Story = {
395
- args: {
396
- steps: 4,
397
- activeStep: 2,
398
- variant: "positive",
399
- className: "text-fm-primary w-[600px]",
400
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
401
- },
402
- }
403
-
404
- export const NegativeVariant: Story = {
405
- args: {
406
- steps: 4,
407
- activeStep: 2,
408
- variant: "negative",
409
- className: "text-fm-primary w-[600px]",
410
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
411
- },
412
- }
413
-
414
- export const WarningVariant: Story = {
415
- args: {
416
- steps: 4,
417
- activeStep: 2,
418
- variant: "warning",
419
- className: "text-fm-primary w-[600px]",
420
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
421
- },
422
- }
423
-
424
- // Size Examples
425
- export const SmallSize: Story = {
426
- args: {
427
- steps: 4,
428
- activeStep: 2,
429
- variant: "primary",
430
- className: "text-fm-primary w-[600px]",
431
- size: "sm",
432
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
433
- },
434
- }
435
-
436
- export const MediumSize: Story = {
437
- args: {
438
- steps: 4,
439
- activeStep: 2,
440
- variant: "primary",
441
- size: "md",
442
- className: "text-fm-primary w-[600px]",
443
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
444
- },
445
- }
446
-
447
- export const LargeSize: Story = {
448
- args: {
449
- steps: 4,
450
- activeStep: 2,
451
- variant: "primary",
452
- size: "lg",
453
- className: "text-fm-primary w-[600px]",
454
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
455
- },
456
- }
457
-
458
- // Orientation Examples
459
- export const HorizontalOrientation: Story = {
460
- args: {
461
- steps: 4,
462
- activeStep: 2,
463
- variant: "primary",
464
- orientation: "horizontal",
465
- className: "text-fm-primary w-[600px]",
466
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
467
- },
468
- }
469
-
470
- export const VerticalOrientation: Story = {
471
- args: {
472
- steps: 4,
473
- activeStep: 2,
474
- variant: "primary",
475
- orientation: "vertical",
476
- stepLabels: ["Step 1", "Step 2", "Step 3", "Step 4"],
477
- className: "text-fm-primary h-[400px]",
478
- },
479
- parameters: {
480
- layout: "padded",
481
- },
482
- }
483
-
484
- // Interactive Example
485
361
  export const Interactive: Story = {
486
362
  render: () => {
487
- const [activeStep, setActiveStep] = React.useState(0)
488
363
  const steps = [
489
- "Account Setup",
490
- "Personal Info",
491
- "Preferences",
492
- "Review",
493
- "Complete",
364
+ {
365
+ label: "Account Setup",
366
+ description:
367
+ "Create your account credentials and verify your email address.",
368
+ },
369
+ {
370
+ label: "Profile Info",
371
+ description:
372
+ "Add your display name, bio, and profile photo to personalise your experience.",
373
+ },
374
+ {
375
+ label: "Preferences",
376
+ description:
377
+ "Choose your music genres, languages, and notification settings.",
378
+ },
379
+ {
380
+ label: "Review",
381
+ description:
382
+ "Confirm all your details before we activate your account.",
383
+ },
384
+ {
385
+ label: "Complete",
386
+ description:
387
+ "Your account is ready. Start discovering music tailored to you.",
388
+ },
494
389
  ]
495
390
 
391
+ const [activeStep, setActiveStep] = React.useState(0)
392
+ const isComplete = activeStep >= steps.length
393
+
496
394
  return (
497
- <div className="space-y-8">
498
- <Stepper activeStep={activeStep}>
499
- {steps.map((step, index) => (
500
- <Stepper.Step
501
- key={index}
502
- index={index}
503
- label={step}
504
- isLast={index === steps.length - 1}
505
- />
506
- ))}
507
- <Stepper.Content>
508
- <div className="bg-fm-surface-secondary min-h-[200px] rounded-lg p-6">
509
- <h3 className="mb-4 text-lg font-semibold">
510
- {steps[activeStep] || "Completed!"}
511
- </h3>
512
- <p className="text-fm-secondary mb-6">
513
- {activeStep < steps.length
514
- ? `This is the content for ${steps[activeStep]}`
515
- : "All steps completed successfully!"}
395
+ <div className="w-full p-8">
396
+ <div className="mx-auto max-w-3xl space-y-6">
397
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
398
+ {/* Controls Panel */}
399
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-5 rounded-xl border p-5">
400
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
401
+ Jump to Step
516
402
  </p>
517
-
518
- <div className="flex gap-4">
519
- <button
520
- onClick={() => setActiveStep(Math.max(0, activeStep - 1))}
521
- disabled={activeStep === 0}
522
- className="bg-fm-surface-tertiary text-fm-primary rounded px-4 py-2 disabled:opacity-50"
523
- >
524
- Previous
525
- </button>
526
- <button
527
- onClick={() =>
528
- setActiveStep(Math.min(steps.length, activeStep + 1))
529
- }
530
- disabled={activeStep >= steps.length}
531
- className="bg-fm-surface-info text-fm-surface-primary rounded px-4 py-2 disabled:opacity-50"
532
- >
533
- {activeStep === steps.length - 1 ? "Complete" : "Next"}
534
- </button>
403
+ <div className="space-y-2">
404
+ {steps.map((step, index) => (
405
+ <button
406
+ key={index}
407
+ onClick={() => setActiveStep(index)}
408
+ className={[
409
+ "font-fm-text text-fm-sm leading-fm-sm w-full rounded-lg border px-3 py-2 text-left transition-colors",
410
+ activeStep === index
411
+ ? "border-fm-divider-brand-secondary bg-fm-surface-secondary text-fm-primary"
412
+ : "border-fm-divider-secondary text-fm-secondary hover:text-fm-primary hover:border-fm-divider-secondary",
413
+ ].join(" ")}
414
+ >
415
+ {index + 1}. {step.label}
416
+ </button>
417
+ ))}
535
418
  </div>
419
+ <div className="border-fm-divider-secondary border-t pt-4" />
420
+ <button
421
+ onClick={() => setActiveStep(0)}
422
+ className="border-fm-divider-secondary text-fm-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"
423
+ >
424
+ Reset
425
+ </button>
536
426
  </div>
537
- </Stepper.Content>
538
- </Stepper>
539
- </div>
540
- )
541
- },
542
- parameters: {
543
- layout: "padded",
544
- },
545
- }
546
-
547
- // Custom Composition Example
548
- export const CustomComposition: Story = {
549
- render: () => (
550
- <Stepper variant="primary" activeStep={1}>
551
- <Stepper.Step index={0} label="Start" />
552
- <Stepper.Step index={1} label="Progress" />
553
- <Stepper.Step index={2} label="Finish" isLast />
554
-
555
- <Stepper.Content>
556
- <div className="bg-fm-surface-secondary rounded-lg p-4">
557
- <p>Custom content area with flexible composition</p>
558
- </div>
559
- </Stepper.Content>
560
- </Stepper>
561
- ),
562
- parameters: {
563
- layout: "padded",
564
- },
565
- }
566
-
567
- // All Variants Showcase
568
- export const AllVariants: Story = {
569
- render: () => (
570
- <div className="text-fm-primary space-y-8">
571
- {(["primary", "positive", "negative", "warning"] as const).map(
572
- (variant) => (
573
- <div key={variant} className="space-y-2">
574
- <h4 className="text-sm font-medium capitalize">{variant}</h4>
575
- <Stepper
576
- steps={4}
577
- activeStep={2}
578
- variant={variant}
579
- stepLabels={["Step 1", "Step 2", "Step 3", "Step 4"]}
580
- />
581
- </div>
582
- )
583
- )}
584
- </div>
585
- ),
586
- parameters: {
587
- layout: "padded",
588
- },
589
- }
590
-
591
- // Progressive States Example
592
- export const ProgressiveStates: Story = {
593
- render: () => {
594
- const steps = ["Not Started", "In Progress", "Completed"]
595
427
 
596
- return (
597
- <div className="text-fm-primary space-y-8">
598
- {[0, 1, 2, 3].map((activeStep) => (
599
- <div key={activeStep} className="space-y-2">
600
- <h4 className="text-sm font-medium">
601
- Active Step: {activeStep}{" "}
602
- {activeStep === 3 ? "(All Complete)" : ""}
603
- </h4>
604
- <Stepper
605
- steps={3}
606
- activeStep={activeStep}
607
- variant="primary"
608
- stepLabels={steps}
609
- />
428
+ {/* Preview Stage */}
429
+ <div className="flex flex-col gap-4 lg:col-span-2">
430
+ <Stepper
431
+ activeStep={activeStep}
432
+ onStepClick={(i) => setActiveStep(i)}
433
+ variant="primary"
434
+ className="text-fm-primary w-full"
435
+ >
436
+ {steps.map((step, index) => (
437
+ <Stepper.Step
438
+ key={index}
439
+ index={index}
440
+ label={step.label}
441
+ isLast={index === steps.length - 1}
442
+ />
443
+ ))}
444
+ <Stepper.Content>
445
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary min-h-44 rounded-xl border p-6">
446
+ {isComplete ? (
447
+ <div className="space-y-2">
448
+ <p className="text-fm-primary font-fm-brand text-fm-lg leading-fm-xl font-semibold">
449
+ All done!
450
+ </p>
451
+ <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
452
+ All steps completed successfully.
453
+ </p>
454
+ </div>
455
+ ) : (
456
+ <div className="space-y-2">
457
+ <p className="text-fm-primary font-fm-brand text-fm-lg leading-fm-xl font-semibold">
458
+ {steps[activeStep].label}
459
+ </p>
460
+ <p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
461
+ {steps[activeStep].description}
462
+ </p>
463
+ </div>
464
+ )}
465
+ <div className="mt-6 flex gap-3">
466
+ <button
467
+ onClick={() =>
468
+ setActiveStep(Math.max(0, activeStep - 1))
469
+ }
470
+ disabled={activeStep === 0}
471
+ className="border-fm-divider-secondary text-fm-secondary hover:text-fm-primary font-fm-text text-fm-sm leading-fm-sm rounded-lg border px-4 py-2 transition-colors disabled:opacity-40"
472
+ >
473
+ Previous
474
+ </button>
475
+ <button
476
+ onClick={() =>
477
+ setActiveStep(Math.min(steps.length, activeStep + 1))
478
+ }
479
+ disabled={isComplete}
480
+ className="bg-fm-surface-info-sec text-fm-info-sec font-fm-text text-fm-sm leading-fm-sm rounded-lg px-4 py-2 transition-opacity disabled:opacity-40"
481
+ >
482
+ {activeStep === steps.length - 1 ? "Finish" : "Next"}
483
+ </button>
484
+ </div>
485
+ </div>
486
+ </Stepper.Content>
487
+ </Stepper>
488
+ </div>
610
489
  </div>
611
- ))}
490
+ </div>
612
491
  </div>
613
492
  )
614
493
  },
615
494
  parameters: {
616
- layout: "padded",
617
- },
618
- }
619
-
620
- // Vertical with Content Example
621
- export const VerticalWithContent: Story = {
622
- render: () => (
623
- <div className="text-fm-primary">
624
- <Stepper
625
- steps={4}
626
- activeStep={2}
627
- variant="primary"
628
- orientation="vertical"
629
- stepLabels={["Account", "Profile", "Settings", "Review"]}
630
- className="h-[800px]"
631
- >
632
- <Stepper.Content>
633
- <div className="bg-fm-surface-secondary text-fm-secondary rounded-lg p-6">
634
- <h3 className="mb-4 text-lg font-semibold">
635
- Settings Configuration
636
- </h3>
637
- <p>Configure your account settings and preferences.</p>
638
- </div>
639
- </Stepper.Content>
640
- </Stepper>
641
- </div>
642
- ),
643
- parameters: {
644
- layout: "padded",
495
+ layout: "fullscreen",
496
+ docs: {
497
+ description: {
498
+ story:
499
+ "Clickable wizard with five steps, step content panels, Previous/Next buttons, and a jump-to-step sidebar. Demonstrates compound component usage with Stepper.Step and Stepper.Content.",
500
+ },
501
+ },
645
502
  },
646
503
  }