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,142 +1,66 @@
1
- import React from "react"
1
+ import React, { useState } from "react"
2
2
  import {
3
3
  AlertIcon,
4
4
  EditBigIcon,
5
5
  EyeCloseIcon,
6
6
  EyeOpenIcon,
7
7
  FileChartIcon,
8
- PlusIcon,
8
+ MoonIcon,
9
+ PauseIcon,
9
10
  SearchIcon,
11
+ SkipBackwardIcon,
12
+ SkipForwardIcon,
10
13
  TickCircleIcon,
11
14
  TrashIcon,
15
+ VolumeFullIcon,
12
16
  } from "@icons/index"
13
17
  import type { Meta, StoryObj } from "@storybook/react-vite"
14
18
 
19
+ import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
20
+
15
21
  import { Toggle } from "."
16
22
 
17
23
  const meta: Meta<typeof Toggle> = {
18
24
  title: "Components/UI/Toggle",
19
25
  component: Toggle,
26
+ tags: ["autodocs"],
20
27
  parameters: {
21
28
  layout: "centered",
22
- backgrounds: {
23
- default: "dark",
24
- values: [
25
- { name: "dark", value: "#0a0a0a" },
26
- { name: "light", value: "#ffffff" },
27
- ],
28
- },
29
29
  docs: {
30
30
  description: {
31
- component: `
32
- # Toggle Component
33
-
34
- A flexible toggle button component built on top of Radix UI's Toggle primitive, providing on/off state management with visual feedback.
35
-
36
- ## Features
37
-
38
- - **State Management**: Built-in pressed/unpressed state handling
39
- - **Keyboard Accessible**: Full keyboard navigation support
40
- - **Multiple Variants**: Default and outline styles
41
- - **Size Options**: Small, default, and large sizes
42
- - **Icon Support**: Automatic icon sizing and styling
43
- - **Disabled State**: Proper disabled state handling
44
- - **Focus Management**: Clear focus indicators
45
- - **ARIA Support**: Proper accessibility attributes
46
-
47
- ## Variants
48
-
49
- ### Default
50
- - **default**: Transparent background with accent highlighting
51
- - **outline**: Border style with shadow and hover effects
52
-
53
- ### Sizes
54
- - **sm**: Small (32px height, compact padding)
55
- - **default**: Standard (36px height, balanced padding)
56
- - **lg**: Large (40px height, generous padding)
57
-
58
- ## Usage Examples
59
-
60
- ### Basic Toggle
61
- \`\`\`tsx
62
- <Toggle aria-label="Toggle bold">
63
- Bold
64
- </Toggle>
65
- \`\`\`
66
-
67
- ### With Icon
68
- \`\`\`tsx
69
- <Toggle aria-label="Toggle notifications">
70
- <AlertIcon />
71
- Notifications
72
- </Toggle>
73
- \`\`\`
74
-
75
- ### Icon Only
76
- \`\`\`tsx
77
- <Toggle aria-label="Toggle visibility">
78
- <EyeOpenIcon />
79
- </Toggle>
80
- \`\`\`
81
-
82
- ### Controlled State
83
- \`\`\`tsx
84
- const [pressed, setPressed] = useState(false)
85
-
86
- <Toggle
87
- pressed={pressed}
88
- onPressedChange={setPressed}
89
- aria-label="Toggle feature"
90
- >
91
- Feature
92
- </Toggle>
93
- \`\`\`
94
-
95
- ### Different Variants
96
- \`\`\`tsx
97
- <Toggle variant="outline" size="sm">
98
- Small Outline
99
- </Toggle>
100
- \`\`\`
101
-
102
- ## Accessibility
103
-
104
- - **ARIA Label**: Always provide \`aria-label\` for screen readers
105
- - **Keyboard Navigation**: Spacebar and Enter toggle state
106
- - **Focus Indicators**: Clear visual focus ring
107
- - **State Announcement**: Screen readers announce pressed state
108
- - **Semantic HTML**: Uses proper button semantics
109
-
110
- ## States
111
-
112
- - **Default**: Unpressed/off state
113
- - **Pressed**: Pressed/on state with accent styling
114
- - **Hover**: Subtle background change on hover
115
- - **Focus**: Clear focus ring for keyboard navigation
116
- - **Disabled**: Reduced opacity and no interaction
117
-
118
- ## Best Practices
119
-
120
- - Always provide descriptive \`aria-label\` attributes
121
- - Use consistent toggle patterns throughout your app
122
- - Consider using icons to enhance visual clarity
123
- - Test with keyboard navigation and screen readers
124
- - Provide visual feedback for state changes
125
- `,
31
+ component:
32
+ "A stateful toggle button built on Radix UI's Toggle primitive. Supports three visual variants (default, outline, filled), three sizes (sm, default, lg), pressed/unpressed states, disabled state, and icon or text content.",
126
33
  },
34
+ page: () => (
35
+ <AuralComponentDocsPage
36
+ features={[
37
+ {
38
+ title: "3 Variants",
39
+ description: "Default, outline, filled",
40
+ },
41
+ {
42
+ title: "Pressed State",
43
+ description: "Controlled or uncontrolled",
44
+ },
45
+ {
46
+ title: "Icon or Text",
47
+ description: "Flexible content slot",
48
+ },
49
+ ]}
50
+ />
51
+ ),
127
52
  },
128
53
  },
129
- tags: ["autodocs"],
130
54
  argTypes: {
131
55
  variant: {
132
56
  control: "select",
133
- options: ["default", "outline"],
57
+ options: ["default", "outline", "filled"],
134
58
  description: "Visual style variant",
135
59
  },
136
60
  size: {
137
61
  control: "select",
138
62
  options: ["sm", "default", "lg"],
139
- description: "Size of the toggle button",
63
+ description: "Size of the toggle",
140
64
  },
141
65
  pressed: {
142
66
  control: "boolean",
@@ -146,174 +70,178 @@ const [pressed, setPressed] = useState(false)
146
70
  control: "boolean",
147
71
  description: "Disabled state",
148
72
  },
149
- className: {
150
- control: "text",
151
- description: "Additional CSS classes",
152
- },
153
73
  },
154
74
  }
155
75
 
156
76
  export default meta
157
77
  type Story = StoryObj<typeof Toggle>
158
78
 
159
- // 1. Basic Toggle
160
- export const Basic: Story = {
79
+ // ─── 1. Playground ────────────────────────────────────────────────────────────
80
+
81
+ export const Playground: Story = {
161
82
  args: {
162
- children: "Toggle me",
163
- "aria-label": "Toggle basic example",
83
+ children: "Toggle",
84
+ variant: "default",
85
+ size: "default",
86
+ "aria-label": "Playground toggle",
164
87
  },
88
+ render: (args) => (
89
+ <div className="w-full max-w-sm space-y-4">
90
+ <div className="flex justify-center">
91
+ <Toggle {...args} />
92
+ </div>
93
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
94
+ <code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">{`<Toggle variant="${args.variant}" size="${args.size}">${args.children}</Toggle>`}</code>
95
+ </div>
96
+ </div>
97
+ ),
165
98
  parameters: {
166
99
  docs: {
167
100
  description: {
168
- story: "A simple toggle button with text content.",
101
+ story:
102
+ "Adjust variant, size, pressed, and disabled using the controls panel in the sidebar.",
169
103
  },
170
104
  },
171
105
  },
172
106
  }
173
107
 
174
- // 2. Variants
175
- export const Variants: Story = {
176
- render: () => (
177
- <div className="flex flex-col gap-8 p-8">
178
- <h3 className="text-center text-lg font-medium text-white">
179
- Toggle Variants
180
- </h3>
108
+ // ─── 2. All Variants ──────────────────────────────────────────────────────────
181
109
 
182
- <div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
183
- {/* Default Variant */}
184
- <div className="space-y-4">
185
- <h4 className="text-sm font-medium text-white/70">Default Variant</h4>
186
- <div className="flex flex-wrap gap-4">
187
- <Toggle aria-label="Default unpressed">Default</Toggle>
188
- <Toggle defaultPressed aria-label="Default pressed">
189
- Pressed
110
+ export const AllVariants: Story = {
111
+ render: () => (
112
+ <div className="space-y-8">
113
+ {/* Default variant × sizes */}
114
+ <div className="space-y-4">
115
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
116
+ Default variant all sizes
117
+ </h4>
118
+ <div className="flex flex-wrap items-end gap-4">
119
+ <div className="space-y-2 text-center">
120
+ <Toggle size="sm" aria-label="Default small">
121
+ Small
190
122
  </Toggle>
191
- <Toggle disabled aria-label="Default disabled">
192
- Disabled
123
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
124
+ sm
125
+ </p>
126
+ </div>
127
+ <div className="space-y-2 text-center">
128
+ <Toggle size="default" aria-label="Default default">
129
+ Default
193
130
  </Toggle>
131
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
132
+ default
133
+ </p>
134
+ </div>
135
+ <div className="space-y-2 text-center">
136
+ <Toggle size="lg" aria-label="Default large">
137
+ Large
138
+ </Toggle>
139
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
140
+ lg
141
+ </p>
194
142
  </div>
195
143
  </div>
144
+ </div>
196
145
 
197
- {/* Outline Variant */}
198
- <div className="space-y-4">
199
- <h4 className="text-sm font-medium text-white/70">Outline Variant</h4>
200
- <div className="flex flex-wrap gap-4">
201
- <Toggle variant="outline" aria-label="Outline unpressed">
202
- Outline
146
+ {/* Outline variant × sizes */}
147
+ <div className="space-y-4">
148
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
149
+ Outline variant all sizes
150
+ </h4>
151
+ <div className="flex flex-wrap items-end gap-4">
152
+ <div className="space-y-2 text-center">
153
+ <Toggle variant="outline" size="sm" aria-label="Outline small">
154
+ Small
203
155
  </Toggle>
156
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
157
+ sm
158
+ </p>
159
+ </div>
160
+ <div className="space-y-2 text-center">
204
161
  <Toggle
205
162
  variant="outline"
206
- defaultPressed
207
- aria-label="Outline pressed"
163
+ size="default"
164
+ aria-label="Outline default"
208
165
  >
209
- Pressed
210
- </Toggle>
211
- <Toggle variant="outline" disabled aria-label="Outline disabled">
212
- Disabled
166
+ Default
213
167
  </Toggle>
168
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
169
+ default
170
+ </p>
214
171
  </div>
215
- </div>
216
-
217
- {/* Filled Variant */}
218
- <div className="space-y-4">
219
- <h4 className="text-sm font-medium text-white/70">Filled Variant</h4>
220
- <div className="flex flex-wrap gap-4">
221
- <Toggle variant="filled" aria-label="Filled unpressed">
222
- Filled
223
- </Toggle>
224
- <Toggle variant="filled" defaultPressed aria-label="Filled pressed">
225
- Pressed
226
- </Toggle>
227
- <Toggle variant="filled" disabled aria-label="Filled disabled">
228
- Disabled
172
+ <div className="space-y-2 text-center">
173
+ <Toggle variant="outline" size="lg" aria-label="Outline large">
174
+ Large
229
175
  </Toggle>
176
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
177
+ lg
178
+ </p>
230
179
  </div>
231
180
  </div>
232
181
  </div>
233
- </div>
234
- ),
235
- parameters: {
236
- docs: {
237
- description: {
238
- story:
239
- "Different visual variants showing default and outline styles in various states.",
240
- },
241
- },
242
- },
243
- }
244
-
245
- // 3. Sizes
246
- export const Sizes: Story = {
247
- render: () => (
248
- <div className="space-y-8 p-8">
249
- <h3 className="text-center text-lg font-medium text-white">
250
- Toggle Sizes
251
- </h3>
252
-
253
- <div className="space-y-6">
254
- {/* Size Comparison */}
255
- <div className="space-y-4">
256
- <h4 className="text-center text-sm font-medium text-white/70">
257
- Size Comparison
258
- </h4>
259
- <div className="flex items-center justify-center gap-4">
260
- <div className="flex flex-col items-center gap-2">
261
- <Toggle size="sm" aria-label="Small toggle">
262
- Small
263
- </Toggle>
264
- <span className="text-xs text-white/60">Small (32px)</span>
265
- </div>
266
- <div className="flex flex-col items-center gap-2">
267
- <Toggle size="default" aria-label="Default toggle">
268
- Default
269
- </Toggle>
270
- <span className="text-xs text-white/60">Default (36px)</span>
271
- </div>
272
- <div className="flex flex-col items-center gap-2">
273
- <Toggle size="lg" aria-label="Large toggle">
274
- Large
275
- </Toggle>
276
- <span className="text-xs text-white/60">Large (40px)</span>
277
- </div>
278
- </div>
279
- </div>
280
182
 
281
- {/* Sizes with Icons */}
282
- <div className="space-y-4">
283
- <h4 className="text-center text-sm font-medium text-white/70">
284
- With Icons
285
- </h4>
286
- <div className="flex items-center justify-center gap-4">
287
- <Toggle size="sm" aria-label="Small with icon">
288
- <AlertIcon />
183
+ {/* Filled variant × sizes */}
184
+ <div className="space-y-4">
185
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
186
+ Filled variant — all sizes
187
+ </h4>
188
+ <div className="flex flex-wrap items-end gap-4">
189
+ <div className="space-y-2 text-center">
190
+ <Toggle variant="filled" size="sm" aria-label="Filled small">
289
191
  Small
290
192
  </Toggle>
291
- <Toggle size="default" aria-label="Default with icon">
292
- <SearchIcon />
193
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
194
+ sm
195
+ </p>
196
+ </div>
197
+ <div className="space-y-2 text-center">
198
+ <Toggle variant="filled" size="default" aria-label="Filled default">
293
199
  Default
294
200
  </Toggle>
295
- <Toggle size="lg" aria-label="Large with icon">
296
- <EditBigIcon />
201
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
202
+ default
203
+ </p>
204
+ </div>
205
+ <div className="space-y-2 text-center">
206
+ <Toggle variant="filled" size="lg" aria-label="Filled large">
297
207
  Large
298
208
  </Toggle>
209
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
210
+ lg
211
+ </p>
299
212
  </div>
300
213
  </div>
214
+ </div>
301
215
 
302
- {/* Icon Only Sizes */}
303
- <div className="space-y-4">
304
- <h4 className="text-center text-sm font-medium text-white/70">
305
- Icon Only
306
- </h4>
307
- <div className="flex items-center justify-center gap-4">
308
- <Toggle size="sm" aria-label="Small icon only">
309
- <PlusIcon />
216
+ {/* Icon-only × all variants */}
217
+ <div className="space-y-4">
218
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
219
+ Icon-only — all variants
220
+ </h4>
221
+ <div className="flex flex-wrap items-center gap-4">
222
+ <div className="space-y-2 text-center">
223
+ <Toggle aria-label="Default icon only">
224
+ <SearchIcon />
310
225
  </Toggle>
311
- <Toggle size="default" aria-label="Default icon only">
226
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
227
+ default
228
+ </p>
229
+ </div>
230
+ <div className="space-y-2 text-center">
231
+ <Toggle variant="outline" aria-label="Outline icon only">
312
232
  <SearchIcon />
313
233
  </Toggle>
314
- <Toggle size="lg" aria-label="Large icon only">
315
- <EditBigIcon />
234
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
235
+ outline
236
+ </p>
237
+ </div>
238
+ <div className="space-y-2 text-center">
239
+ <Toggle variant="filled" aria-label="Filled icon only">
240
+ <SearchIcon />
316
241
  </Toggle>
242
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
243
+ filled
244
+ </p>
317
245
  </div>
318
246
  </div>
319
247
  </div>
@@ -323,393 +251,173 @@ export const Sizes: Story = {
323
251
  docs: {
324
252
  description: {
325
253
  story:
326
- "Different size options for toggles, including text, icon with text, and icon-only variants.",
254
+ "Full variant × size matrix for all three visual styles (default, outline, filled), plus icon-only instances across each variant.",
327
255
  },
328
256
  },
329
257
  },
330
258
  }
331
259
 
332
- // 4. Icon Toggles
333
- export const IconToggles: Story = {
334
- render: () => {
335
- const [notifications, setNotifications] = React.useState(false)
336
- const [visibility, setVisibility] = React.useState(false)
337
- const [completed, setCompleted] = React.useState(false)
338
-
339
- return (
340
- <div className="space-y-8 p-8">
341
- <h3 className="text-center text-lg font-medium text-white">
342
- Icon Toggles
343
- </h3>
260
+ // ─── 3. States ────────────────────────────────────────────────────────────────
344
261
 
345
- <div className="space-y-6">
346
- {/* Icon with Text */}
347
- <div className="space-y-4">
348
- <h4 className="text-center text-sm font-medium text-white/70">
349
- Icon with Text
350
- </h4>
351
- <div className="flex flex-wrap justify-center gap-4">
352
- <Toggle
353
- pressed={notifications}
354
- onPressedChange={setNotifications}
355
- aria-label="Toggle notifications"
356
- >
357
- <AlertIcon />
358
- Notifications
359
- </Toggle>
360
-
361
- <Toggle
362
- pressed={visibility}
363
- onPressedChange={setVisibility}
364
- aria-label="Toggle visibility"
365
- >
366
- {visibility ? <EyeOpenIcon /> : <EyeCloseIcon />}
367
- {visibility ? "Visible" : "Hidden"}
368
- </Toggle>
369
-
370
- <Toggle
371
- pressed={completed}
372
- onPressedChange={setCompleted}
373
- aria-label="Toggle completion"
374
- >
375
- <TickCircleIcon />
376
- Complete
377
- </Toggle>
378
- </div>
262
+ export const States: Story = {
263
+ render: () => (
264
+ <div className="space-y-8">
265
+ {/* Default variant states */}
266
+ <div className="space-y-4">
267
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
268
+ Default variant
269
+ </h4>
270
+ <div className="flex flex-wrap gap-4">
271
+ <div className="space-y-2 text-center">
272
+ <Toggle aria-label="Unpressed default">Unpressed</Toggle>
273
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
274
+ Unpressed
275
+ </p>
379
276
  </div>
380
-
381
- {/* Icon Only */}
382
- <div className="space-y-4">
383
- <h4 className="text-center text-sm font-medium text-white/70">
384
- Icon Only
385
- </h4>
386
- <div className="flex flex-wrap justify-center gap-4">
387
- <Toggle aria-label="Toggle search">
388
- <SearchIcon />
389
- </Toggle>
390
-
391
- <Toggle aria-label="Toggle edit mode">
392
- <EditBigIcon />
393
- </Toggle>
394
-
395
- <Toggle aria-label="Toggle charts">
396
- <FileChartIcon />
397
- </Toggle>
398
-
399
- <Toggle aria-label="Add to favorites" defaultPressed>
400
- <PlusIcon />
401
- </Toggle>
402
-
403
- <Toggle aria-label="Delete mode" variant="outline">
404
- <TrashIcon />
405
- </Toggle>
406
- </div>
277
+ <div className="space-y-2 text-center">
278
+ <Toggle defaultPressed aria-label="Pressed default">
279
+ Pressed
280
+ </Toggle>
281
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
282
+ Pressed
283
+ </p>
407
284
  </div>
408
-
409
- {/* Different Variants */}
410
- <div className="space-y-4">
411
- <h4 className="text-center text-sm font-medium text-white/70">
412
- Different Variants
413
- </h4>
414
- <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
415
- <div className="space-y-2">
416
- <span className="text-xs text-white/60">Default Variant</span>
417
- <div className="flex flex-wrap gap-2">
418
- <Toggle aria-label="Default alert">
419
- <AlertIcon />
420
- </Toggle>
421
- <Toggle defaultPressed aria-label="Default search">
422
- <SearchIcon />
423
- </Toggle>
424
- <Toggle aria-label="Default edit">
425
- <EditBigIcon />
426
- </Toggle>
427
- </div>
428
- </div>
429
-
430
- <div className="space-y-2">
431
- <span className="text-xs text-white/60">Outline Variant</span>
432
- <div className="flex flex-wrap gap-2">
433
- <Toggle variant="outline" aria-label="Outline alert">
434
- <AlertIcon />
435
- </Toggle>
436
- <Toggle
437
- variant="outline"
438
- defaultPressed
439
- aria-label="Outline search"
440
- >
441
- <SearchIcon />
442
- </Toggle>
443
- <Toggle variant="outline" aria-label="Outline edit">
444
- <EditBigIcon />
445
- </Toggle>
446
- </div>
447
- </div>
448
- </div>
285
+ <div className="space-y-2 text-center">
286
+ <Toggle disabled aria-label="Disabled default">
287
+ Disabled
288
+ </Toggle>
289
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
290
+ Disabled
291
+ </p>
449
292
  </div>
450
293
  </div>
451
294
  </div>
452
- )
453
- },
454
- parameters: {
455
- docs: {
456
- description: {
457
- story:
458
- "Icon-based toggles showing different configurations including dynamic icons and various states.",
459
- },
460
- },
461
- },
462
- }
463
295
 
464
- // 5. Interactive States
465
- export const InteractiveStates: Story = {
466
- render: () => {
467
- const [states, setStates] = React.useState({
468
- bold: false,
469
- italic: false,
470
- underline: false,
471
- notifications: true,
472
- autoSave: false,
473
- darkMode: true,
474
- })
475
-
476
- const updateState = (key: keyof typeof states) => {
477
- setStates((prev) => ({ ...prev, [key]: !prev[key] }))
478
- }
479
-
480
- return (
481
- <div className="space-y-8 p-8">
482
- <h3 className="text-center text-lg font-medium text-white">
483
- Interactive States
484
- </h3>
485
-
486
- <div className="space-y-6">
487
- {/* Text Formatting Toolbar */}
488
- <div className="space-y-4">
489
- <h4 className="text-center text-sm font-medium text-white/70">
490
- Text Formatting Toolbar
491
- </h4>
492
- <div className="flex justify-center">
493
- <div className="flex items-center gap-1 rounded-lg border border-white/10 bg-white/5 p-2">
494
- <Toggle
495
- size="sm"
496
- pressed={states.bold}
497
- onPressedChange={() => updateState("bold")}
498
- aria-label="Toggle bold"
499
- >
500
- <span className="font-bold">B</span>
501
- </Toggle>
502
- <Toggle
503
- size="sm"
504
- pressed={states.italic}
505
- onPressedChange={() => updateState("italic")}
506
- aria-label="Toggle italic"
507
- >
508
- <span className="italic">I</span>
509
- </Toggle>
510
- <Toggle
511
- size="sm"
512
- pressed={states.underline}
513
- onPressedChange={() => updateState("underline")}
514
- aria-label="Toggle underline"
515
- >
516
- <span className="underline">U</span>
517
- </Toggle>
518
- <div className="mx-2 h-6 w-px bg-white/20"></div>
519
- <Toggle size="sm" aria-label="Add item">
520
- <PlusIcon />
521
- </Toggle>
522
- <Toggle size="sm" aria-label="Search">
523
- <SearchIcon />
524
- </Toggle>
525
- </div>
526
- </div>
296
+ {/* Outline variant states */}
297
+ <div className="space-y-4">
298
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
299
+ Outline variant
300
+ </h4>
301
+ <div className="flex flex-wrap gap-4">
302
+ <div className="space-y-2 text-center">
303
+ <Toggle variant="outline" aria-label="Unpressed outline">
304
+ Unpressed
305
+ </Toggle>
306
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
307
+ Unpressed
308
+ </p>
527
309
  </div>
528
-
529
- {/* Settings Panel */}
530
- <div className="space-y-4">
531
- <h4 className="text-center text-sm font-medium text-white/70">
532
- Settings Panel
533
- </h4>
534
- <div className="mx-auto max-w-xs space-y-3">
535
- <div className="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-3">
536
- <div className="flex items-center gap-3">
537
- <AlertIcon className="h-4 w-4 text-blue-400" />
538
- <span className="text-sm text-white">Notifications</span>
539
- </div>
540
- <Toggle
541
- size="sm"
542
- pressed={states.notifications}
543
- onPressedChange={() => updateState("notifications")}
544
- aria-label="Toggle notifications"
545
- />
546
- </div>
547
-
548
- <div className="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-3">
549
- <div className="flex items-center gap-3">
550
- <TickCircleIcon className="h-4 w-4 text-green-400" />
551
- <span className="text-sm text-white">Auto Save</span>
552
- </div>
553
- <Toggle
554
- size="sm"
555
- pressed={states.autoSave}
556
- onPressedChange={() => updateState("autoSave")}
557
- aria-label="Toggle auto save"
558
- />
559
- </div>
560
-
561
- <div className="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-3">
562
- <div className="flex items-center gap-3">
563
- <EyeOpenIcon className="h-4 w-4 text-purple-400" />
564
- <span className="text-sm text-white">Dark Mode</span>
565
- </div>
566
- <Toggle
567
- size="sm"
568
- pressed={states.darkMode}
569
- onPressedChange={() => updateState("darkMode")}
570
- aria-label="Toggle dark mode"
571
- />
572
- </div>
573
- </div>
310
+ <div className="space-y-2 text-center">
311
+ <Toggle
312
+ variant="outline"
313
+ defaultPressed
314
+ aria-label="Pressed outline"
315
+ >
316
+ Pressed
317
+ </Toggle>
318
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
319
+ Pressed
320
+ </p>
574
321
  </div>
575
-
576
- {/* State Display */}
577
- <div className="space-y-4">
578
- <h4 className="text-center text-sm font-medium text-white/70">
579
- Current States
580
- </h4>
581
- <div className="mx-auto max-w-md rounded-lg border border-white/10 bg-white/5 p-4">
582
- <div className="grid grid-cols-2 gap-2 text-xs">
583
- {Object.entries(states).map(([key, value]) => (
584
- <div key={key} className="flex justify-between">
585
- <span className="text-white/70 capitalize">{key}:</span>
586
- <span className={value ? "text-green-400" : "text-red-400"}>
587
- {value ? "ON" : "OFF"}
588
- </span>
589
- </div>
590
- ))}
591
- </div>
592
- </div>
322
+ <div className="space-y-2 text-center">
323
+ <Toggle variant="outline" disabled aria-label="Disabled outline">
324
+ Disabled
325
+ </Toggle>
326
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
327
+ Disabled
328
+ </p>
593
329
  </div>
594
330
  </div>
595
331
  </div>
596
- )
597
- },
598
- parameters: {
599
- docs: {
600
- description: {
601
- story:
602
- "Interactive examples showing toggles in real-world scenarios like toolbars and settings panels.",
603
- },
604
- },
605
- },
606
- }
607
332
 
608
- // 6. Accessibility Demo
609
- export const AccessibilityDemo: Story = {
610
- render: () => (
611
- <div className="space-y-8 p-8">
612
- <h3 className="text-center text-lg font-medium text-white">
613
- Accessibility Features
614
- </h3>
615
-
616
- <div className="space-y-6">
617
- <div className="rounded-lg border border-blue-500/30 bg-blue-900/10 p-4">
618
- <h4 className="mb-2 text-sm font-medium text-blue-300">
619
- Keyboard Navigation
620
- </h4>
621
- <p className="mb-2 text-xs text-blue-200/70">
622
- Try these keyboard interactions:
623
- </p>
624
- <ul className="space-y-1 text-xs text-blue-200/70">
625
- <li>
626
- <kbd className="rounded bg-white/10 px-1">Tab</kbd> to focus
627
- toggles
628
- </li>
629
- <li>
630
- <kbd className="rounded bg-white/10 px-1">Space</kbd> or{" "}
631
- <kbd className="rounded bg-white/10 px-1">Enter</kbd> to toggle
632
- state
633
- </li>
634
- <li>• Clear focus indicators show current position</li>
635
- <li>• Screen readers announce pressed state</li>
636
- </ul>
333
+ {/* Filled variant states */}
334
+ <div className="space-y-4">
335
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
336
+ Filled variant
337
+ </h4>
338
+ <div className="flex flex-wrap gap-4">
339
+ <div className="space-y-2 text-center">
340
+ <Toggle variant="filled" aria-label="Unpressed filled">
341
+ Unpressed
342
+ </Toggle>
343
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
344
+ Unpressed
345
+ </p>
346
+ </div>
347
+ <div className="space-y-2 text-center">
348
+ <Toggle variant="filled" defaultPressed aria-label="Pressed filled">
349
+ Pressed
350
+ </Toggle>
351
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
352
+ Pressed
353
+ </p>
354
+ </div>
355
+ <div className="space-y-2 text-center">
356
+ <Toggle variant="filled" disabled aria-label="Disabled filled">
357
+ Disabled
358
+ </Toggle>
359
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
360
+ Disabled
361
+ </p>
362
+ </div>
637
363
  </div>
364
+ </div>
638
365
 
639
- {/* Keyboard Accessible Examples */}
640
- <div className="space-y-4">
641
- <h4 className="text-sm font-medium text-white/70">
642
- Keyboard Accessible Toggles
643
- </h4>
644
- <div className="flex flex-wrap justify-center gap-4">
645
- <Toggle aria-label="Toggle feature A - currently off">
366
+ {/* Icon states */}
367
+ <div className="space-y-4">
368
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
369
+ Icon-only states
370
+ </h4>
371
+ <div className="flex flex-wrap gap-4">
372
+ <div className="space-y-2 text-center">
373
+ <Toggle aria-label="Alert unpressed">
646
374
  <AlertIcon />
647
- Feature A
648
375
  </Toggle>
649
-
650
- <Toggle defaultPressed aria-label="Toggle feature B - currently on">
651
- <TickCircleIcon />
652
- Feature B
376
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
377
+ Unpressed
378
+ </p>
379
+ </div>
380
+ <div className="space-y-2 text-center">
381
+ <Toggle defaultPressed aria-label="Alert pressed">
382
+ <AlertIcon />
653
383
  </Toggle>
654
-
384
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
385
+ Pressed
386
+ </p>
387
+ </div>
388
+ <div className="space-y-2 text-center">
389
+ <Toggle disabled aria-label="Alert disabled">
390
+ <AlertIcon />
391
+ </Toggle>
392
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
393
+ Disabled
394
+ </p>
395
+ </div>
396
+ <div className="space-y-2 text-center">
655
397
  <Toggle
656
398
  variant="outline"
657
- aria-label="Toggle visibility - show or hide content"
399
+ defaultPressed
400
+ aria-label="Trash pressed outline"
658
401
  >
659
- <EyeOpenIcon />
660
- Visibility
661
- </Toggle>
662
-
663
- <Toggle size="sm" aria-label="Toggle search mode">
664
- <SearchIcon />
402
+ <TrashIcon />
665
403
  </Toggle>
404
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
405
+ Pressed outline
406
+ </p>
666
407
  </div>
667
- </div>
668
-
669
- {/* ARIA Labels Demo */}
670
- <div className="space-y-4">
671
- <h4 className="text-sm font-medium text-white/70">
672
- ARIA Labels Best Practices
673
- </h4>
674
- <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
675
- <div className="space-y-3">
676
- <span className="text-xs text-white/60">Good Examples</span>
677
- <div className="space-y-2">
678
- <Toggle aria-label="Toggle notifications - receive alerts when new messages arrive">
679
- <AlertIcon />
680
- Notifications
681
- </Toggle>
682
- <Toggle aria-label="Toggle edit mode - switch between viewing and editing">
683
- <EditBigIcon />
684
- Edit Mode
685
- </Toggle>
686
- </div>
687
- </div>
688
-
689
- <div className="space-y-3">
690
- <span className="text-xs text-white/60">Code Examples</span>
691
- <div className="rounded border border-white/10 bg-white/5 p-3 font-mono text-xs text-white/80">
692
- <div>aria-label="Toggle notifications"</div>
693
- <div>aria-label="Show/hide password"</div>
694
- <div>aria-label="Enable dark mode"</div>
695
- </div>
696
- </div>
408
+ <div className="space-y-2 text-center">
409
+ <Toggle
410
+ variant="outline"
411
+ disabled
412
+ aria-label="Trash disabled outline"
413
+ >
414
+ <TrashIcon />
415
+ </Toggle>
416
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
417
+ Disabled outline
418
+ </p>
697
419
  </div>
698
420
  </div>
699
-
700
- <div className="rounded-lg border border-amber-500/30 bg-amber-900/10 p-4">
701
- <h4 className="mb-2 text-sm font-medium text-amber-300">
702
- Best Practices
703
- </h4>
704
- <ul className="space-y-1 text-xs text-amber-200/70">
705
- <li>• Always provide descriptive aria-label attributes</li>
706
- <li>• Include current state in label when helpful</li>
707
- <li>• Use consistent toggle patterns across your app</li>
708
- <li>• Test with screen readers and keyboard navigation</li>
709
- <li>• Ensure sufficient color contrast for all states</li>
710
- <li>• Provide visual feedback for state changes</li>
711
- </ul>
712
- </div>
713
421
  </div>
714
422
  </div>
715
423
  ),
@@ -717,365 +425,236 @@ export const AccessibilityDemo: Story = {
717
425
  docs: {
718
426
  description: {
719
427
  story:
720
- "Accessibility features including keyboard navigation, ARIA labels, and best practices for inclusive design.",
428
+ "Pressed, unpressed, and disabled states rendered for each variant. Disabled toggles suppress pointer events and render at reduced opacity.",
721
429
  },
722
430
  },
723
431
  },
724
432
  }
725
433
 
726
- // 7. Use Cases
727
- export const UseCases: Story = {
728
- render: () => {
729
- const [preferences, setPreferences] = React.useState({
730
- notifications: true,
731
- autoSave: false,
732
- showPreview: true,
733
- darkMode: true,
734
- })
434
+ // ─── 4. Interactive ───────────────────────────────────────────────────────────
735
435
 
736
- const [toolbar, setToolbar] = React.useState({
436
+ export const Interactive: Story = {
437
+ render: () => {
438
+ const [formatting, setFormatting] = useState({
737
439
  bold: false,
738
440
  italic: false,
739
- list: false,
441
+ underline: false,
740
442
  code: false,
741
443
  })
742
444
 
743
- const updatePreference = (key: keyof typeof preferences) => {
744
- setPreferences((prev) => ({ ...prev, [key]: !prev[key] }))
745
- }
445
+ const [playback, setPlayback] = useState({
446
+ shuffle: false,
447
+ repeat: false,
448
+ mute: false,
449
+ })
450
+
451
+ const [visibility, setVisibility] = useState(false)
452
+ const [done, setDone] = useState(false)
453
+
454
+ const toggleFormat = (key: keyof typeof formatting) =>
455
+ setFormatting((prev) => ({ ...prev, [key]: !prev[key] }))
746
456
 
747
- const updateToolbar = (key: keyof typeof toolbar) => {
748
- setToolbar((prev) => ({ ...prev, [key]: !prev[key] }))
749
- }
457
+ const togglePlayback = (key: keyof typeof playback) =>
458
+ setPlayback((prev) => ({ ...prev, [key]: !prev[key] }))
459
+
460
+ const activeFormats = Object.entries(formatting)
461
+ .filter(([, v]) => v)
462
+ .map(([k]) => k)
750
463
 
751
464
  return (
752
- <div className="space-y-8 p-8">
753
- <h3 className="text-center text-lg font-medium text-white">
754
- Real-world Use Cases
755
- </h3>
465
+ <div className="w-full p-8">
466
+ <div className="mx-auto max-w-3xl space-y-6">
467
+ <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
468
+ {/* Controls panel */}
469
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-5 rounded-xl border p-5">
470
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
471
+ Current State
472
+ </p>
473
+
474
+ <div className="space-y-2">
475
+ <p className="text-fm-secondary font-fm-text text-fm-xs leading-fm-xs tracking-wider uppercase">
476
+ Active formats
477
+ </p>
478
+ <p className="text-fm-primary font-fm-brand text-fm-md leading-fm-md font-semibold">
479
+ {activeFormats.length === 0
480
+ ? "None"
481
+ : activeFormats.join(", ")}
482
+ </p>
483
+ </div>
484
+
485
+ <div className="border-fm-divider-secondary border-t pt-4" />
486
+
487
+ <div className="space-y-2">
488
+ <p className="text-fm-secondary font-fm-text text-fm-xs leading-fm-xs tracking-wider uppercase">
489
+ Playback
490
+ </p>
491
+ <div className="flex flex-col gap-1">
492
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
493
+ Shuffle:{" "}
494
+ <span className="font-semibold">
495
+ {playback.shuffle ? "ON" : "OFF"}
496
+ </span>
497
+ </p>
498
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
499
+ Repeat:{" "}
500
+ <span className="font-semibold">
501
+ {playback.repeat ? "ON" : "OFF"}
502
+ </span>
503
+ </p>
504
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
505
+ Mute:{" "}
506
+ <span className="font-semibold">
507
+ {playback.mute ? "ON" : "OFF"}
508
+ </span>
509
+ </p>
510
+ </div>
511
+ </div>
756
512
 
757
- <div className="space-y-8">
758
- {/* Editor Toolbar */}
759
- <div className="space-y-4">
760
- <h4 className="text-sm font-medium text-white/70">
761
- Editor Toolbar
762
- </h4>
763
- <div className="rounded-lg border border-white/10 bg-white/5 p-4">
764
- <div className="flex items-center gap-1">
765
- <Toggle
766
- size="sm"
767
- pressed={toolbar.bold}
768
- onPressedChange={() => updateToolbar("bold")}
769
- aria-label="Toggle bold formatting"
770
- >
771
- <span className="text-sm font-bold">B</span>
772
- </Toggle>
773
- <Toggle
774
- size="sm"
775
- pressed={toolbar.italic}
776
- onPressedChange={() => updateToolbar("italic")}
777
- aria-label="Toggle italic formatting"
778
- >
779
- <span className="text-sm italic">I</span>
780
- </Toggle>
781
- <div className="mx-2 h-4 w-px bg-white/20"></div>
782
- <Toggle
783
- size="sm"
784
- pressed={toolbar.list}
785
- onPressedChange={() => updateToolbar("list")}
786
- aria-label="Toggle bullet list"
787
- >
788
- • List
789
- </Toggle>
790
- <Toggle
791
- size="sm"
792
- pressed={toolbar.code}
793
- onPressedChange={() => updateToolbar("code")}
794
- aria-label="Toggle code formatting"
795
- >
796
- <span className="font-mono text-sm">&lt;/&gt;</span>
797
- </Toggle>
798
- <div className="mx-2 h-4 w-px bg-white/20"></div>
799
- <Toggle size="sm" aria-label="Insert image">
800
- <FileChartIcon />
801
- </Toggle>
802
- <Toggle size="sm" aria-label="Add link">
803
- <PlusIcon />
804
- </Toggle>
513
+ <div className="border-fm-divider-secondary border-t pt-4" />
514
+
515
+ <div className="space-y-2">
516
+ <p className="text-fm-secondary font-fm-text text-fm-xs leading-fm-xs tracking-wider uppercase">
517
+ Visibility
518
+ </p>
519
+ <p className="text-fm-primary font-fm-brand text-fm-md leading-fm-md font-semibold">
520
+ {visibility ? "Visible" : "Hidden"}
521
+ </p>
805
522
  </div>
806
523
  </div>
807
- </div>
808
524
 
809
- {/* User Preferences */}
810
- <div className="space-y-4">
811
- <h4 className="text-sm font-medium text-white/70">
812
- User Preferences
813
- </h4>
814
- <div className="grid grid-cols-1 gap-3 lg:grid-cols-2">
525
+ {/* Preview stage */}
526
+ <div className="flex flex-col gap-6 lg:col-span-2">
527
+ {/* Text formatting toolbar */}
815
528
  <div className="space-y-3">
816
- <div className="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-3">
817
- <div className="flex items-center gap-3">
818
- <AlertIcon className="h-4 w-4 text-blue-400" />
819
- <div>
820
- <div className="text-sm text-white">
821
- Push Notifications
822
- </div>
823
- <div className="text-xs text-white/60">
824
- Get notified of updates
825
- </div>
826
- </div>
827
- </div>
529
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
530
+ Text formatting toolbar
531
+ </h4>
532
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary inline-flex items-center gap-1 rounded-lg border p-2">
828
533
  <Toggle
829
- pressed={preferences.notifications}
830
- onPressedChange={() => updatePreference("notifications")}
831
- aria-label="Toggle push notifications"
832
- />
833
- </div>
834
-
835
- <div className="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-3">
836
- <div className="flex items-center gap-3">
837
- <TickCircleIcon className="h-4 w-4 text-green-400" />
838
- <div>
839
- <div className="text-sm text-white">Auto Save</div>
840
- <div className="text-xs text-white/60">
841
- Save changes automatically
842
- </div>
843
- </div>
844
- </div>
534
+ size="sm"
535
+ pressed={formatting.bold}
536
+ onPressedChange={() => toggleFormat("bold")}
537
+ aria-label="Toggle bold"
538
+ >
539
+ <span className="font-bold">B</span>
540
+ </Toggle>
541
+ <Toggle
542
+ size="sm"
543
+ pressed={formatting.italic}
544
+ onPressedChange={() => toggleFormat("italic")}
545
+ aria-label="Toggle italic"
546
+ >
547
+ <span className="italic">I</span>
548
+ </Toggle>
549
+ <Toggle
550
+ size="sm"
551
+ pressed={formatting.underline}
552
+ onPressedChange={() => toggleFormat("underline")}
553
+ aria-label="Toggle underline"
554
+ >
555
+ <span className="underline">U</span>
556
+ </Toggle>
557
+ <div className="bg-fm-divider-secondary mx-1 h-5 w-px" />
845
558
  <Toggle
846
- pressed={preferences.autoSave}
847
- onPressedChange={() => updatePreference("autoSave")}
848
- aria-label="Toggle auto save"
849
- />
559
+ size="sm"
560
+ pressed={formatting.code}
561
+ onPressedChange={() => toggleFormat("code")}
562
+ aria-label="Toggle code"
563
+ >
564
+ <span className="text-fm-xs font-(--font-fm-mono)">{`</>`}</span>
565
+ </Toggle>
566
+ <div className="bg-fm-divider-secondary mx-1 h-5 w-px" />
567
+ <Toggle size="sm" aria-label="Search">
568
+ <SearchIcon />
569
+ </Toggle>
570
+ <Toggle size="sm" aria-label="Edit">
571
+ <EditBigIcon />
572
+ </Toggle>
850
573
  </div>
851
574
  </div>
852
575
 
576
+ {/* Playback controls */}
853
577
  <div className="space-y-3">
854
- <div className="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-3">
855
- <div className="flex items-center gap-3">
856
- <EyeOpenIcon className="h-4 w-4 text-purple-400" />
857
- <div>
858
- <div className="text-sm text-white">Preview Mode</div>
859
- <div className="text-xs text-white/60">
860
- Show live preview
861
- </div>
862
- </div>
863
- </div>
578
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
579
+ Playback controls
580
+ </h4>
581
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary flex items-center justify-center gap-2 rounded-xl border p-4">
864
582
  <Toggle
865
- pressed={preferences.showPreview}
866
- onPressedChange={() => updatePreference("showPreview")}
867
- aria-label="Toggle preview mode"
868
- />
869
- </div>
870
-
871
- <div className="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-3">
872
- <div className="flex items-center gap-3">
873
- <span className="text-lg">🌙</span>
874
- <div>
875
- <div className="text-sm text-white">Dark Mode</div>
876
- <div className="text-xs text-white/60">
877
- Use dark theme
878
- </div>
879
- </div>
880
- </div>
583
+ variant="outline"
584
+ size="sm"
585
+ pressed={playback.shuffle}
586
+ onPressedChange={() => togglePlayback("shuffle")}
587
+ aria-label="Toggle shuffle"
588
+ >
589
+ <FileChartIcon />
590
+ Shuffle
591
+ </Toggle>
592
+ <Toggle size="default" aria-label="Skip backward">
593
+ <SkipBackwardIcon />
594
+ </Toggle>
595
+ <Toggle size="lg" defaultPressed aria-label="Pause">
596
+ <PauseIcon />
597
+ </Toggle>
598
+ <Toggle size="default" aria-label="Skip forward">
599
+ <SkipForwardIcon />
600
+ </Toggle>
881
601
  <Toggle
882
- pressed={preferences.darkMode}
883
- onPressedChange={() => updatePreference("darkMode")}
884
- aria-label="Toggle dark mode"
885
- />
602
+ variant="outline"
603
+ size="sm"
604
+ pressed={playback.repeat}
605
+ onPressedChange={() => togglePlayback("repeat")}
606
+ aria-label="Toggle repeat"
607
+ >
608
+ <TickCircleIcon />
609
+ Repeat
610
+ </Toggle>
886
611
  </div>
887
612
  </div>
888
- </div>
889
- </div>
890
-
891
- {/* Filter Toolbar */}
892
- <div className="space-y-4">
893
- <h4 className="text-sm font-medium text-white/70">
894
- Filter Toolbar
895
- </h4>
896
- <div className="rounded-lg border border-white/10 bg-white/5 p-4">
897
- <div className="flex flex-wrap gap-2">
898
- <Toggle
899
- variant="outline"
900
- size="sm"
901
- aria-label="Show completed items"
902
- >
903
- <TickCircleIcon />
904
- Completed
905
- </Toggle>
906
- <Toggle
907
- variant="outline"
908
- size="sm"
909
- aria-label="Show pending items"
910
- >
911
- <AlertIcon />
912
- Pending
913
- </Toggle>
914
- <Toggle
915
- variant="outline"
916
- size="sm"
917
- aria-label="Show archived items"
918
- >
919
- <FileChartIcon />
920
- Archived
921
- </Toggle>
922
- <Toggle
923
- variant="outline"
924
- size="sm"
925
- defaultPressed
926
- aria-label="Show active items"
927
- >
928
- <EyeOpenIcon />
929
- Active
930
- </Toggle>
931
- </div>
932
- </div>
933
- </div>
934
613
 
935
- {/* View Options */}
936
- <div className="space-y-4">
937
- <h4 className="text-sm font-medium text-white/70">View Options</h4>
938
- <div className="flex justify-center gap-1 rounded-lg border border-white/10 bg-white/5 p-1">
939
- <Toggle size="sm" defaultPressed aria-label="Grid view">
940
- Grid
941
- </Toggle>
942
- <Toggle size="sm" aria-label="List view">
943
- List
944
- </Toggle>
945
- <Toggle size="sm" aria-label="Card view">
946
- Cards
947
- </Toggle>
948
- </div>
949
- </div>
950
- </div>
951
- </div>
952
- )
953
- },
954
- parameters: {
955
- docs: {
956
- description: {
957
- story:
958
- "Real-world examples showing toggles in editor toolbars, user preferences, filters, and view options.",
959
- },
960
- },
961
- },
962
- }
963
-
964
- // 8. Controlled vs Uncontrolled
965
- export const ControlledVsUncontrolled: Story = {
966
- render: () => {
967
- const [controlledState, setControlledState] = React.useState(false)
968
- const [multipleStates, setMultipleStates] = React.useState({
969
- option1: true,
970
- option2: false,
971
- option3: true,
972
- })
973
-
974
- return (
975
- <div className="space-y-8 p-8">
976
- <h3 className="text-center text-lg font-medium text-white">
977
- Controlled vs Uncontrolled
978
- </h3>
979
-
980
- <div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
981
- {/* Uncontrolled */}
982
- <div className="space-y-4">
983
- <h4 className="text-sm font-medium text-white/70">
984
- Uncontrolled (Internal State)
985
- </h4>
986
- <div className="space-y-3">
987
- <Toggle aria-label="Uncontrolled toggle 1">Default State</Toggle>
988
- <Toggle defaultPressed aria-label="Uncontrolled toggle 2">
989
- Default Pressed
990
- </Toggle>
991
- <Toggle variant="outline" aria-label="Uncontrolled toggle 3">
992
- <AlertIcon />
993
- With Icon
994
- </Toggle>
995
- </div>
996
- <div className="rounded border border-white/10 bg-white/5 p-3 font-mono text-xs text-white/80">
997
- <div>{"<Toggle>"}</div>
998
- <div>{" Default State"}</div>
999
- <div>{"</Toggle>"}</div>
1000
- <br />
1001
- <div>{"<Toggle defaultPressed>"}</div>
1002
- <div>{" Default Pressed"}</div>
1003
- <div>{"</Toggle>"}</div>
1004
- </div>
1005
- </div>
1006
-
1007
- {/* Controlled */}
1008
- <div className="space-y-4">
1009
- <h4 className="text-sm font-medium text-white/70">
1010
- Controlled (External State)
1011
- </h4>
1012
- <div className="space-y-3">
1013
- <Toggle
1014
- pressed={controlledState}
1015
- onPressedChange={setControlledState}
1016
- aria-label="Controlled toggle"
1017
- >
1018
- Controlled: {controlledState ? "ON" : "OFF"}
1019
- </Toggle>
1020
-
1021
- <div className="space-y-2">
1022
- {Object.entries(multipleStates).map(([key, value]) => (
614
+ {/* Stateful icon swap */}
615
+ <div className="space-y-3">
616
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
617
+ Stateful icon swap
618
+ </h4>
619
+ <div className="flex flex-wrap gap-3">
620
+ <Toggle
621
+ pressed={visibility}
622
+ onPressedChange={setVisibility}
623
+ aria-label="Toggle visibility"
624
+ >
625
+ {visibility ? <EyeOpenIcon /> : <EyeCloseIcon />}
626
+ {visibility ? "Visible" : "Hidden"}
627
+ </Toggle>
1023
628
  <Toggle
1024
- key={key}
1025
629
  variant="outline"
1026
- size="sm"
1027
- pressed={value}
1028
- onPressedChange={(pressed) =>
1029
- setMultipleStates((prev) => ({ ...prev, [key]: pressed }))
1030
- }
1031
- aria-label={`Toggle ${key}`}
630
+ pressed={done}
631
+ onPressedChange={setDone}
632
+ aria-label="Toggle complete"
1032
633
  >
1033
634
  <TickCircleIcon />
1034
- {key}: {value ? "ON" : "OFF"}
635
+ {done ? "Done" : "Mark done"}
636
+ </Toggle>
637
+ <Toggle
638
+ variant="filled"
639
+ pressed={playback.mute}
640
+ onPressedChange={() => togglePlayback("mute")}
641
+ aria-label="Toggle mute"
642
+ >
643
+ {playback.mute ? <VolumeFullIcon /> : <VolumeFullIcon />}
644
+ {playback.mute ? "Unmute" : "Mute"}
645
+ </Toggle>
646
+ <Toggle disabled aria-label="Sleep — unavailable">
647
+ <MoonIcon />
648
+ Sleep
1035
649
  </Toggle>
1036
- ))}
650
+ </div>
1037
651
  </div>
1038
- </div>
1039
-
1040
- <div className="rounded border border-white/10 bg-white/5 p-3 font-mono text-xs text-white/80">
1041
- <div>{"const [state, setState] = useState(false)"}</div>
1042
- <br />
1043
- <div>{"<Toggle"}</div>
1044
- <div>{" pressed={state}"}</div>
1045
- <div>{" onPressedChange={setState}"}</div>
1046
- <div>{">"}</div>
1047
- <div>{" Controlled"}</div>
1048
- <div>{"</Toggle>"}</div>
1049
- </div>
1050
- </div>
1051
- </div>
1052
652
 
1053
- <div className="rounded-lg border border-blue-500/30 bg-blue-900/10 p-4">
1054
- <h4 className="mb-2 text-sm font-medium text-blue-300">
1055
- When to Use Each
1056
- </h4>
1057
- <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
1058
- <div>
1059
- <h5 className="mb-1 text-xs font-medium text-blue-200">
1060
- Uncontrolled
1061
- </h5>
1062
- <ul className="space-y-1 text-xs text-blue-200/70">
1063
- <li>• Simple on/off toggles</li>
1064
- <li>• No external state dependency</li>
1065
- <li>• Form elements</li>
1066
- <li>• Less code complexity</li>
1067
- </ul>
1068
- </div>
1069
- <div>
1070
- <h5 className="mb-1 text-xs font-medium text-blue-200">
1071
- Controlled
1072
- </h5>
1073
- <ul className="space-y-1 text-xs text-blue-200/70">
1074
- <li>• Complex state management</li>
1075
- <li>• Multiple dependent toggles</li>
1076
- <li>• Form validation</li>
1077
- <li>• External state updates</li>
1078
- </ul>
653
+ <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
654
+ <code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">
655
+ {`<Toggle pressed={bold} onPressedChange={setBold}>B</Toggle>`}
656
+ </code>
657
+ </div>
1079
658
  </div>
1080
659
  </div>
1081
660
  </div>
@@ -1086,7 +665,7 @@ export const ControlledVsUncontrolled: Story = {
1086
665
  docs: {
1087
666
  description: {
1088
667
  story:
1089
- "Comparison between controlled and uncontrolled toggle usage patterns with practical examples.",
668
+ "Live stateful toggles showing two real-world patterns: a text-formatting toolbar (multi-active) and playback controls. Click any button to toggle its pressed state.",
1090
669
  },
1091
670
  },
1092
671
  },