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,19 @@
1
1
  import React from "react"
2
+ import {
3
+ AlertIcon,
4
+ HeartIcon,
5
+ MusicalNoteIcon,
6
+ PauseIcon,
7
+ SearchIcon,
8
+ SettingIcon,
9
+ SkipBackwardIcon,
10
+ SkipForwardIcon,
11
+ VolumeFullIcon,
12
+ } from "@icons/index"
2
13
  import type { Meta, StoryObj } from "@storybook/react-vite"
3
14
 
15
+ import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
16
+
4
17
  import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "."
5
18
 
6
19
  const meta: Meta<typeof ResizablePanelGroup> = {
@@ -17,111 +30,27 @@ const meta: Meta<typeof ResizablePanelGroup> = {
17
30
  },
18
31
  docs: {
19
32
  description: {
20
- component: `
21
- # Resizable Component
22
-
23
- A flexible resizable panel system built on top of react-resizable-panels, providing smooth panel resizing with customizable handles and layouts.
24
-
25
- ## Components
26
-
27
- ### Core Components
28
- - **ResizablePanelGroup**: Container that manages the resizable layout and direction
29
- - **ResizablePanel**: Individual panel that can be resized
30
- - **ResizableHandle**: The draggable handle between panels with optional visual indicator
31
-
32
- ## Features
33
-
34
- - **Bi-directional**: Supports both horizontal and vertical panel layouts
35
- - **Smooth Resizing**: Fluid drag-to-resize interactions
36
- - **Visual Handles**: Optional drag handles with move icons
37
- - **Keyboard Accessible**: Full keyboard navigation support
38
- - **Flexible Sizing**: Supports percentage-based and minimum size constraints
39
- - **Auto-rotation**: Icons automatically rotate for vertical layouts
40
- - **Design System**: Integrated with design tokens for consistent styling
41
- - **Focus Management**: Proper focus indicators and keyboard navigation
42
-
43
- ## Usage Examples
44
-
45
- ### Basic Horizontal Layout
46
- \`\`\`tsx
47
- <ResizablePanelGroup direction="horizontal">
48
- <ResizablePanel defaultSize={50}>
49
- Left Panel Content
50
- </ResizablePanel>
51
- <ResizableHandle />
52
- <ResizablePanel defaultSize={50}>
53
- Right Panel Content
54
- </ResizablePanel>
55
- </ResizablePanelGroup>
56
- \`\`\`
57
-
58
- ### Vertical Layout with Handles
59
- \`\`\`tsx
60
- <ResizablePanelGroup direction="vertical" className="h-96">
61
- <ResizablePanel defaultSize={30}>
62
- Top Panel
63
- </ResizablePanel>
64
- <ResizableHandle withHandle />
65
- <ResizablePanel defaultSize={70}>
66
- Bottom Panel
67
- </ResizablePanel>
68
- </ResizablePanelGroup>
69
- \`\`\`
70
-
71
- ### Three Panel Layout
72
- \`\`\`tsx
73
- <ResizablePanelGroup direction="horizontal">
74
- <ResizablePanel defaultSize={25} minSize={20}>
75
- Sidebar
76
- </ResizablePanel>
77
- <ResizableHandle withHandle />
78
- <ResizablePanel defaultSize={50}>
79
- Main Content
80
- </ResizablePanel>
81
- <ResizableHandle withHandle />
82
- <ResizablePanel defaultSize={25} minSize={15}>
83
- Right Panel
84
- </ResizablePanel>
85
- </ResizablePanelGroup>
86
- \`\`\`
87
-
88
- ### Nested Resizable Layouts
89
- \`\`\`tsx
90
- <ResizablePanelGroup direction="horizontal">
91
- <ResizablePanel defaultSize={30}>
92
- Sidebar Content
93
- </ResizablePanel>
94
- <ResizableHandle withHandle />
95
- <ResizablePanel defaultSize={70}>
96
- <ResizablePanelGroup direction="vertical">
97
- <ResizablePanel defaultSize={60}>
98
- Main Content
99
- </ResizablePanel>
100
- <ResizableHandle withHandle />
101
- <ResizablePanel defaultSize={40}>
102
- Bottom Panel
103
- </ResizablePanel>
104
- </ResizablePanelGroup>
105
- </ResizablePanel>
106
- </ResizablePanelGroup>
107
- \`\`\`
108
-
109
- ## Accessibility
110
-
111
- - **Keyboard Navigation**: Handles can be focused and adjusted with arrow keys
112
- - **ARIA Support**: Proper ARIA roles and attributes for screen readers
113
- - **Focus Indicators**: Clear focus rings following design system patterns
114
- - **Semantic Structure**: Proper DOM structure for assistive technologies
115
-
116
- ## Design Tokens
117
-
118
- The component uses design system tokens:
119
- - \`--color-fm-button-fill-secondary\`: Handle background color
120
- - \`--color-fm-primary\`: Focus ring color
121
- - \`--color-fm-contrast\`: Focus ring offset color
122
- - \`--radius-fm-xs\`: Handle border radius
123
- `,
33
+ component:
34
+ "A layout primitive built on react-resizable-panels providing fluid drag-to-resize behaviour. Composed of three parts: ResizablePanelGroup (sets direction and manages layout), ResizablePanel (individual resizable area with optional min/default sizes), and ResizableHandle (the draggable divider with an optional visual grip). Supports horizontal and vertical directions and arbitrary nesting.",
124
35
  },
36
+ page: () => (
37
+ <AuralComponentDocsPage
38
+ features={[
39
+ {
40
+ title: "Drag to Resize",
41
+ description: "Fluid panel splitting",
42
+ },
43
+ {
44
+ title: "H & V Directions",
45
+ description: "Horizontal or vertical",
46
+ },
47
+ {
48
+ title: "Nestable",
49
+ description: "Groups within groups",
50
+ },
51
+ ]}
52
+ />
53
+ ),
125
54
  },
126
55
  },
127
56
  tags: ["autodocs"],
@@ -129,11 +58,7 @@ The component uses design system tokens:
129
58
  direction: {
130
59
  control: "select",
131
60
  options: ["horizontal", "vertical"],
132
- description: "Direction of the panel group layout",
133
- },
134
- className: {
135
- control: "text",
136
- description: "Additional CSS classes",
61
+ description: "Layout direction for the panel group",
137
62
  },
138
63
  },
139
64
  }
@@ -141,548 +66,238 @@ The component uses design system tokens:
141
66
  export default meta
142
67
  type Story = StoryObj<typeof ResizablePanelGroup>
143
68
 
144
- // 1. Basic Horizontal Layout
145
- export const BasicHorizontal: Story = {
146
- args: {
147
- direction: "horizontal",
148
- },
149
- render: (args) => (
150
- <div className="h-96 w-full p-8">
151
- <h3 className="text-fm-primary mb-4 text-lg font-medium">
152
- Basic Horizontal Layout
153
- </h3>
154
- <ResizablePanelGroup
155
- {...args}
156
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
157
- >
158
- <ResizablePanel defaultSize={50}>
159
- <div className="flex h-full items-center justify-center bg-blue-500/10 p-4">
160
- <div className="text-center">
161
- <h4 className="text-fm-primary text-lg font-medium">
162
- Left Panel
163
- </h4>
164
- <p className="text-fm-secondary text-sm">Resize me!</p>
165
- </div>
166
- </div>
167
- </ResizablePanel>
168
- <ResizableHandle />
169
- <ResizablePanel defaultSize={50}>
170
- <div className="flex h-full items-center justify-center bg-purple-500/10 p-4">
171
- <div className="text-center">
172
- <h4 className="text-fm-primary text-lg font-medium">
173
- Right Panel
174
- </h4>
175
- <p className="text-fm-secondary text-sm">I resize too!</p>
176
- </div>
177
- </div>
178
- </ResizablePanel>
179
- </ResizablePanelGroup>
180
- </div>
181
- ),
182
- parameters: {
183
- docs: {
184
- description: {
185
- story:
186
- "Basic two-panel horizontal layout with a simple resize handle between panels.",
187
- },
188
- },
189
- },
190
- }
191
-
192
- // 2. Vertical Layout with Handles
193
- export const VerticalWithHandles: Story = {
194
- render: () => (
195
- <div className="h-96 w-full p-8">
196
- <h3 className="text-fm-primary mb-4 text-lg font-medium">
197
- Vertical Layout with Visual Handles
198
- </h3>
199
- <ResizablePanelGroup
200
- direction="vertical"
201
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
202
- >
203
- <ResizablePanel defaultSize={40}>
204
- <div className="flex h-full items-center justify-center bg-green-500/10 p-4">
205
- <div className="text-center">
206
- <h4 className="text-fm-primary text-lg font-medium">Top Panel</h4>
207
- <p className="text-fm-secondary text-sm">40% default size</p>
208
- </div>
209
- </div>
210
- </ResizablePanel>
211
- <ResizableHandle withHandle />
212
- <ResizablePanel defaultSize={60}>
213
- <div className="flex h-full items-center justify-center bg-orange-500/10 p-4">
214
- <div className="text-center">
215
- <h4 className="text-fm-primary text-lg font-medium">
216
- Bottom Panel
217
- </h4>
218
- <p className="text-fm-secondary text-sm">60% default size</p>
219
- <p className="text-fm-tertiary mt-2 text-xs">
220
- Notice the rotated handle icon
221
- </p>
222
- </div>
223
- </div>
224
- </ResizablePanel>
225
- </ResizablePanelGroup>
226
- </div>
227
- ),
228
- parameters: {
229
- docs: {
230
- description: {
231
- story:
232
- "Vertical panel layout with visual drag handles. Notice how the move icon automatically rotates for vertical orientation.",
233
- },
234
- },
235
- },
236
- }
237
-
238
- // 3. Three Panel Layout
239
- export const ThreePanel: Story = {
240
- render: () => (
241
- <div className="h-96 w-full p-8">
242
- <h3 className="text-fm-primary mb-4 text-lg font-medium">
243
- Three Panel Layout
244
- </h3>
245
- <ResizablePanelGroup
246
- direction="horizontal"
247
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
248
- >
249
- <ResizablePanel defaultSize={25} minSize={15}>
250
- <div className="flex h-full flex-col justify-center bg-red-500/10 p-4">
251
- <h4 className="text-fm-primary text-sm font-medium">Sidebar</h4>
252
- <p className="text-fm-secondary mt-1 text-xs">25% default</p>
253
- <p className="text-fm-tertiary mt-1 text-xs">15% minimum</p>
254
- </div>
255
- </ResizablePanel>
256
- <ResizableHandle withHandle />
257
- <ResizablePanel defaultSize={50}>
258
- <div className="flex h-full items-center justify-center bg-blue-500/10 p-4">
259
- <div className="text-center">
260
- <h4 className="text-fm-primary text-lg font-medium">
261
- Main Content
262
- </h4>
263
- <p className="text-fm-secondary text-sm">50% default size</p>
264
- <p className="text-fm-tertiary mt-2 text-xs">
265
- Primary content area
266
- </p>
267
- </div>
268
- </div>
269
- </ResizablePanel>
270
- <ResizableHandle withHandle />
271
- <ResizablePanel defaultSize={25} minSize={20}>
272
- <div className="flex h-full flex-col justify-center bg-purple-500/10 p-4">
273
- <h4 className="text-fm-primary text-sm font-medium">Right Panel</h4>
274
- <p className="text-fm-secondary mt-1 text-xs">25% default</p>
275
- <p className="text-fm-tertiary mt-1 text-xs">20% minimum</p>
276
- </div>
277
- </ResizablePanel>
278
- </ResizablePanelGroup>
279
- </div>
280
- ),
281
- parameters: {
282
- docs: {
283
- description: {
284
- story:
285
- "Three-panel layout with minimum size constraints and visual drag handles between each panel.",
286
- },
287
- },
288
- },
289
- }
69
+ // ─── Configurations ───────────────────────────────────────────────────────────
290
70
 
291
- // 4. Nested Layouts
292
- export const NestedLayouts: Story = {
71
+ export const Configurations: Story = {
293
72
  render: () => (
294
- <div className="h-96 w-full p-8">
295
- <h3 className="text-fm-primary mb-4 text-lg font-medium">
296
- Nested Resizable Layouts
297
- </h3>
298
- <ResizablePanelGroup
299
- direction="horizontal"
300
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
301
- >
302
- <ResizablePanel defaultSize={30} minSize={25}>
303
- <div className="flex h-full flex-col justify-center bg-indigo-500/10 p-4">
304
- <h4 className="text-fm-primary text-sm font-medium">Sidebar</h4>
305
- <p className="text-fm-secondary mt-1 text-xs">Navigation & Tools</p>
306
- <div className="mt-4 space-y-2">
307
- <div className="bg-fm-surface-secondary h-2 rounded"></div>
308
- <div className="bg-fm-surface-secondary h-2 rounded"></div>
309
- <div className="bg-fm-surface-secondary h-2 rounded"></div>
310
- </div>
311
- </div>
312
- </ResizablePanel>
313
- <ResizableHandle withHandle />
314
- <ResizablePanel defaultSize={70}>
315
- <ResizablePanelGroup direction="vertical">
316
- <ResizablePanel defaultSize={65}>
317
- <div className="flex h-full items-center justify-center bg-green-500/10 p-4">
318
- <div className="text-center">
319
- <h4 className="text-fm-primary text-lg font-medium">
320
- Main Content Area
321
- </h4>
322
- <p className="text-fm-secondary text-sm">Primary workspace</p>
323
- <p className="text-fm-tertiary mt-2 text-xs">
324
- This panel can be resized vertically
73
+ <div className="space-y-8 p-8">
74
+ {/* Horizontal split */}
75
+ <div className="space-y-3">
76
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
77
+ Horizontal Split
78
+ </h4>
79
+ <div className="border-fm-divider-secondary h-48 overflow-hidden rounded-lg border">
80
+ <ResizablePanelGroup direction="horizontal">
81
+ <ResizablePanel defaultSize={50}>
82
+ <div className="bg-fm-surface-secondary flex h-full items-center justify-center p-4">
83
+ <div className="space-y-1 text-center">
84
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
85
+ Left Panel
86
+ </p>
87
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
88
+ 50% default
325
89
  </p>
326
90
  </div>
327
91
  </div>
328
92
  </ResizablePanel>
329
93
  <ResizableHandle withHandle />
330
- <ResizablePanel defaultSize={35} minSize={25}>
331
- <div className="flex h-full items-center justify-center bg-orange-500/10 p-4">
332
- <div className="text-center">
333
- <h4 className="text-md text-fm-primary font-medium">
334
- Bottom Panel
335
- </h4>
336
- <p className="text-fm-secondary text-sm">
337
- Console / Terminal
94
+ <ResizablePanel defaultSize={50}>
95
+ <div className="bg-fm-surface-primary flex h-full items-center justify-center p-4">
96
+ <div className="space-y-1 text-center">
97
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
98
+ Right Panel
338
99
  </p>
339
- <p className="text-fm-tertiary mt-2 text-xs">
340
- Nested vertical layout
100
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
101
+ 50% default
341
102
  </p>
342
103
  </div>
343
104
  </div>
344
105
  </ResizablePanel>
345
106
  </ResizablePanelGroup>
346
- </ResizablePanel>
347
- </ResizablePanelGroup>
348
- </div>
349
- ),
350
- parameters: {
351
- docs: {
352
- description: {
353
- story:
354
- "Complex nested layout demonstrating horizontal and vertical resizable panels within each other, similar to IDE layouts.",
355
- },
356
- },
357
- },
358
- }
359
-
360
- // 5. Handle Variations
361
- export const HandleVariations: Story = {
362
- render: () => (
363
- <div className="space-y-8 p-8">
364
- <h3 className="text-fm-primary text-center text-lg font-medium">
365
- Handle Variations
366
- </h3>
367
-
368
- <div className="space-y-6">
369
- {/* Without Visual Handle */}
370
- <div className="space-y-2">
371
- <h4 className="text-fm-secondary text-sm font-medium">
372
- Without Visual Handle
373
- </h4>
374
- <div className="h-32">
375
- <ResizablePanelGroup
376
- direction="horizontal"
377
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
378
- >
379
- <ResizablePanel defaultSize={50}>
380
- <div className="flex h-full items-center justify-center bg-blue-500/10 p-4">
381
- <span className="text-fm-primary text-sm">
382
- Minimal Handle
383
- </span>
384
- </div>
385
- </ResizablePanel>
386
- <ResizableHandle />
387
- <ResizablePanel defaultSize={50}>
388
- <div className="flex h-full items-center justify-center bg-purple-500/10 p-4">
389
- <span className="text-fm-primary text-sm">Clean Look</span>
390
- </div>
391
- </ResizablePanel>
392
- </ResizablePanelGroup>
393
- </div>
394
107
  </div>
108
+ </div>
395
109
 
396
- {/* With Visual Handle */}
397
- <div className="space-y-2">
398
- <h4 className="text-fm-secondary text-sm font-medium">
399
- With Visual Handle
400
- </h4>
401
- <div className="h-32">
402
- <ResizablePanelGroup
403
- direction="horizontal"
404
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
405
- >
406
- <ResizablePanel defaultSize={50}>
407
- <div className="flex h-full items-center justify-center bg-green-500/10 p-4">
408
- <span className="text-fm-primary text-sm">
409
- Clear Affordance
410
- </span>
110
+ {/* Vertical split */}
111
+ <div className="space-y-3">
112
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
113
+ Vertical Split
114
+ </h4>
115
+ <div className="border-fm-divider-secondary h-48 overflow-hidden rounded-lg border">
116
+ <ResizablePanelGroup direction="vertical">
117
+ <ResizablePanel defaultSize={40}>
118
+ <div className="bg-fm-surface-secondary flex h-full items-center justify-center p-4">
119
+ <div className="space-y-1 text-center">
120
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
121
+ Top Panel
122
+ </p>
123
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
124
+ 40% default
125
+ </p>
411
126
  </div>
412
- </ResizablePanel>
413
- <ResizableHandle withHandle />
414
- <ResizablePanel defaultSize={50}>
415
- <div className="flex h-full items-center justify-center bg-orange-500/10 p-4">
416
- <span className="text-fm-primary text-sm">Easy to Spot</span>
127
+ </div>
128
+ </ResizablePanel>
129
+ <ResizableHandle withHandle />
130
+ <ResizablePanel defaultSize={60}>
131
+ <div className="bg-fm-surface-primary flex h-full items-center justify-center p-4">
132
+ <div className="space-y-1 text-center">
133
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
134
+ Bottom Panel
135
+ </p>
136
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
137
+ 60% default — handle icon rotates automatically
138
+ </p>
417
139
  </div>
418
- </ResizablePanel>
419
- </ResizablePanelGroup>
420
- </div>
140
+ </div>
141
+ </ResizablePanel>
142
+ </ResizablePanelGroup>
421
143
  </div>
144
+ </div>
422
145
 
423
- {/* Custom Styled Handle */}
424
- <div className="space-y-2">
425
- <h4 className="text-fm-secondary text-sm font-medium">
426
- Custom Styled Handle
427
- </h4>
428
- <div className="h-32">
429
- <ResizablePanelGroup
430
- direction="horizontal"
431
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
432
- >
433
- <ResizablePanel defaultSize={50}>
434
- <div className="flex h-full items-center justify-center bg-red-500/10 p-4">
435
- <span className="text-fm-primary text-sm">
436
- Custom Styling
437
- </span>
438
- </div>
439
- </ResizablePanel>
440
- <ResizableHandle
441
- withHandle
442
- className="bg-blue-500/20 transition-colors hover:bg-blue-500/30"
443
- />
444
- <ResizablePanel defaultSize={50}>
445
- <div className="flex h-full items-center justify-center bg-indigo-500/10 p-4">
446
- <span className="text-fm-primary text-sm">Themed Handle</span>
146
+ {/* Three-panel layout */}
147
+ <div className="space-y-3">
148
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
149
+ Three-Panel Layout
150
+ </h4>
151
+ <div className="border-fm-divider-secondary h-48 overflow-hidden rounded-lg border">
152
+ <ResizablePanelGroup direction="horizontal">
153
+ <ResizablePanel defaultSize={25} minSize={15}>
154
+ <div className="bg-fm-surface-info-sec flex h-full flex-col justify-center space-y-1 p-4">
155
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
156
+ Sidebar
157
+ </p>
158
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
159
+ 25% · min 15%
160
+ </p>
161
+ </div>
162
+ </ResizablePanel>
163
+ <ResizableHandle withHandle />
164
+ <ResizablePanel defaultSize={50}>
165
+ <div className="bg-fm-surface-secondary flex h-full items-center justify-center p-4">
166
+ <div className="space-y-1 text-center">
167
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
168
+ Main Content
169
+ </p>
170
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
171
+ 50% default
172
+ </p>
447
173
  </div>
448
- </ResizablePanel>
449
- </ResizablePanelGroup>
450
- </div>
174
+ </div>
175
+ </ResizablePanel>
176
+ <ResizableHandle withHandle />
177
+ <ResizablePanel defaultSize={25} minSize={15}>
178
+ <div className="bg-fm-surface-positive-sec flex h-full flex-col justify-center space-y-1 p-4">
179
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
180
+ Inspector
181
+ </p>
182
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
183
+ 25% · min 15%
184
+ </p>
185
+ </div>
186
+ </ResizablePanel>
187
+ </ResizablePanelGroup>
451
188
  </div>
452
189
  </div>
453
- </div>
454
- ),
455
- parameters: {
456
- docs: {
457
- description: {
458
- story:
459
- "Different handle variations showing minimal handles, visual handles with icons, and custom styled handles.",
460
- },
461
- },
462
- },
463
- }
464
190
 
465
- // 6. Real-world Examples
466
- export const RealWorldExamples: Story = {
467
- render: () => (
468
- <div className="space-y-8 p-8">
469
- <h3 className="text-fm-primary text-center text-lg font-medium">
470
- Real-world Examples
471
- </h3>
472
-
473
- <div className="space-y-8">
474
- {/* IDE Layout */}
475
- <div className="space-y-4">
476
- <h4 className="text-fm-secondary text-sm font-medium">
477
- IDE / Code Editor Layout
478
- </h4>
479
- <div className="h-80">
480
- <ResizablePanelGroup
481
- direction="horizontal"
482
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
483
- >
484
- {/* File Explorer */}
485
- <ResizablePanel defaultSize={20} minSize={15}>
486
- <div className="bg-fm-surface-primary h-full p-3">
487
- <h5 className="text-fm-primary mb-3 text-xs font-medium">
488
- EXPLORER
489
- </h5>
490
- <div className="text-fm-secondary space-y-1 text-xs">
491
- <div className="flex items-center gap-1">
492
- <span>📁</span> src
493
- </div>
494
- <div className="ml-3 flex items-center gap-1">
495
- <span>📄</span> index.tsx
496
- </div>
497
- <div className="ml-3 flex items-center gap-1">
498
- <span>📄</span> App.tsx
499
- </div>
500
- <div className="flex items-center gap-1">
501
- <span>📁</span> components
502
- </div>
503
- </div>
191
+ {/* Nested layouts */}
192
+ <div className="space-y-3">
193
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
194
+ Nested Layouts (horizontal + vertical)
195
+ </h4>
196
+ <div className="border-fm-divider-secondary h-64 overflow-hidden rounded-lg border">
197
+ <ResizablePanelGroup direction="horizontal">
198
+ <ResizablePanel defaultSize={28} minSize={20}>
199
+ <div className="bg-fm-surface-secondary flex h-full flex-col justify-center space-y-2 p-4">
200
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
201
+ Sidebar
202
+ </p>
203
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
204
+ Navigation & tools
205
+ </p>
206
+ <div className="mt-3 space-y-2">
207
+ <div className="bg-fm-surface-primary h-2 rounded" />
208
+ <div className="bg-fm-surface-primary h-2 rounded" />
209
+ <div className="bg-fm-surface-primary h-2 w-2/3 rounded" />
504
210
  </div>
505
- </ResizablePanel>
506
- <ResizableHandle withHandle />
507
-
508
- {/* Main Content */}
509
- <ResizablePanel defaultSize={60}>
510
- <ResizablePanelGroup direction="vertical">
511
- {/* Editor */}
512
- <ResizablePanel defaultSize={70}>
513
- <div className="bg-fm-surface-primary h-full p-4">
514
- <div className="border-fm-divider-secondary mb-4 flex items-center gap-2 border-b pb-2">
515
- <span className="text-fm-secondary text-xs">
516
- App.tsx
517
- </span>
518
- <span className="text-fm-tertiary text-xs">×</span>
519
- </div>
520
- <div className="text-fm-secondary space-y-2 font-mono text-xs">
521
- <div>
522
- <span className="text-fm-icon-brand-secondary">
523
- import
524
- </span>{" "}
525
- React{" "}
526
- <span className="text-fm-icon-brand-secondary">
527
- from
528
- </span>{" "}
529
- <span className="text-fm-positive">'react'</span>
530
- </div>
531
- <div></div>
532
- <div>
533
- <span className="text-fm-icon-brand-secondary">
534
- function
535
- </span>{" "}
536
- <span className="text-fm-info">App</span>() {"{"}
537
- </div>
538
- <div className="ml-4">
539
- <span className="text-fm-icon-brand-secondary">
540
- return
541
- </span>{" "}
542
- (
543
- </div>
544
- <div className="ml-8">
545
- &lt;<span className="text-fm-icon-negative">div</span>
546
- &gt;Hello World&lt;/
547
- <span className="text-fm-icon-negative">div</span>
548
- &gt;
549
- </div>
550
- <div className="ml-4">)</div>
551
- <div>{"}"}</div>
552
- </div>
211
+ </div>
212
+ </ResizablePanel>
213
+ <ResizableHandle withHandle />
214
+ <ResizablePanel defaultSize={72}>
215
+ <ResizablePanelGroup direction="vertical">
216
+ <ResizablePanel defaultSize={65}>
217
+ <div className="bg-fm-surface-primary flex h-full items-center justify-center p-4">
218
+ <div className="space-y-1 text-center">
219
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
220
+ Main Workspace
221
+ </p>
222
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
223
+ Primary content area — resizes vertically
224
+ </p>
553
225
  </div>
554
- </ResizablePanel>
555
- <ResizableHandle withHandle />
556
-
557
- {/* Terminal */}
558
- <ResizablePanel defaultSize={30} minSize={20}>
559
- <div className="h-full bg-black/50 p-3">
560
- <div className="mb-2 flex items-center gap-2">
561
- <h5 className="text-fm-primary text-xs font-medium">
562
- TERMINAL
563
- </h5>
564
- <span className="text-fm-tertiary text-xs">bash</span>
565
- </div>
566
- <div className="text-fm-positive font-mono text-xs">
567
- <div>$ npm start</div>
568
- <div className="text-fm-secondary">
569
- Starting development server...
570
- </div>
571
- <div className="text-fm-secondary">
572
- Local: http://localhost:3000
573
- </div>
574
- <div className="text-fm-positive">
575
- ✓ Compiled successfully!
576
- </div>
577
- </div>
226
+ </div>
227
+ </ResizablePanel>
228
+ <ResizableHandle withHandle />
229
+ <ResizablePanel defaultSize={35} minSize={20}>
230
+ <div className="bg-fm-surface-secondary flex h-full items-center justify-center p-4">
231
+ <div className="space-y-1 text-center">
232
+ <p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-medium">
233
+ Console / Details
234
+ </p>
235
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
236
+ Nested vertical panel · min 20%
237
+ </p>
578
238
  </div>
579
- </ResizablePanel>
580
- </ResizablePanelGroup>
581
- </ResizablePanel>
582
- <ResizableHandle withHandle />
583
-
584
- {/* Right Sidebar */}
585
- <ResizablePanel defaultSize={20} minSize={15}>
586
- <div className="bg-fm-surface-primary h-full p-3">
587
- <h5 className="text-fm-primary mb-3 text-xs font-medium">
588
- OUTLINE
589
- </h5>
590
- <div className="text-fm-secondary space-y-1 text-xs">
591
- <div>📋 Components</div>
592
- <div className="ml-3">⚛️ App</div>
593
- <div className="ml-3">🎨 Header</div>
594
- <div className="ml-3">📝 Content</div>
595
- <div>🎯 Hooks</div>
596
- <div className="ml-3">🔄 useState</div>
597
239
  </div>
598
- </div>
599
- </ResizablePanel>
600
- </ResizablePanelGroup>
601
- </div>
240
+ </ResizablePanel>
241
+ </ResizablePanelGroup>
242
+ </ResizablePanel>
243
+ </ResizablePanelGroup>
602
244
  </div>
245
+ </div>
603
246
 
604
- {/* Dashboard Layout */}
247
+ {/* Handle variations */}
248
+ <div className="space-y-3">
249
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
250
+ Handle Variations
251
+ </h4>
605
252
  <div className="space-y-4">
606
- <h4 className="text-fm-secondary text-sm font-medium">
607
- Dashboard Layout
608
- </h4>
609
- <div className="h-64">
610
- <ResizablePanelGroup
611
- direction="horizontal"
612
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
613
- >
614
- {/* Sidebar */}
615
- <ResizablePanel defaultSize={25} minSize={20}>
616
- <div className="h-full bg-blue-900/20 p-4">
617
- <h5 className="text-fm-primary mb-4 text-sm font-medium">
618
- Navigation
619
- </h5>
620
- <div className="space-y-3">
621
- <div className="text-fm-primary flex items-center gap-2 text-sm">
622
- <span>📊</span> Dashboard
623
- </div>
624
- <div className="text-fm-secondary flex items-center gap-2 text-sm">
625
- <span>👥</span> Users
626
- </div>
627
- <div className="text-fm-secondary flex items-center gap-2 text-sm">
628
- <span>⚙️</span> Settings
629
- </div>
253
+ <div className="space-y-1">
254
+ <p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
255
+ Without visual handle (minimal)
256
+ </p>
257
+ <div className="border-fm-divider-secondary h-24 overflow-hidden rounded-lg border">
258
+ <ResizablePanelGroup direction="horizontal">
259
+ <ResizablePanel defaultSize={50}>
260
+ <div className="bg-fm-surface-secondary flex h-full items-center justify-center p-4">
261
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
262
+ Minimal handle
263
+ </span>
630
264
  </div>
631
- </div>
632
- </ResizablePanel>
633
- <ResizableHandle withHandle />
634
-
635
- {/* Main Dashboard */}
636
- <ResizablePanel defaultSize={75}>
637
- <ResizablePanelGroup direction="vertical">
638
- {/* Top Metrics */}
639
- <ResizablePanel defaultSize={40}>
640
- <div className="h-full bg-green-900/20 p-4">
641
- <h5 className="text-fm-primary mb-3 text-sm font-medium">
642
- Key Metrics
643
- </h5>
644
- <div className="grid h-20 grid-cols-3 gap-4">
645
- <div className="bg-fm-surface-secondary rounded p-3 text-center">
646
- <div className="text-fm-primary text-lg font-bold">
647
- 1,234
648
- </div>
649
- <div className="text-fm-secondary text-xs">Users</div>
650
- </div>
651
- <div className="bg-fm-surface-secondary rounded p-3 text-center">
652
- <div className="text-fm-primary text-lg font-bold">
653
- $12.3k
654
- </div>
655
- <div className="text-fm-secondary text-xs">
656
- Revenue
657
- </div>
658
- </div>
659
- <div className="bg-fm-surface-secondary rounded p-3 text-center">
660
- <div className="text-fm-primary text-lg font-bold">
661
- 98.5%
662
- </div>
663
- <div className="text-fm-secondary text-xs">
664
- Uptime
665
- </div>
666
- </div>
667
- </div>
668
- </div>
669
- </ResizablePanel>
670
- <ResizableHandle withHandle />
265
+ </ResizablePanel>
266
+ <ResizableHandle />
267
+ <ResizablePanel defaultSize={50}>
268
+ <div className="bg-fm-surface-primary flex h-full items-center justify-center p-4">
269
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
270
+ Clean divider
271
+ </span>
272
+ </div>
273
+ </ResizablePanel>
274
+ </ResizablePanelGroup>
275
+ </div>
276
+ </div>
671
277
 
672
- {/* Bottom Charts */}
673
- <ResizablePanel defaultSize={60}>
674
- <div className="h-full bg-purple-900/20 p-4">
675
- <h5 className="text-fm-primary mb-3 text-sm font-medium">
676
- Analytics
677
- </h5>
678
- <div className="bg-fm-surface-secondary flex h-full items-center justify-center rounded p-4">
679
- <span className="text-fm-secondary">📈 Chart Area</span>
680
- </div>
681
- </div>
682
- </ResizablePanel>
683
- </ResizablePanelGroup>
684
- </ResizablePanel>
685
- </ResizablePanelGroup>
278
+ <div className="space-y-1">
279
+ <p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
280
+ With visual handle (grip icon)
281
+ </p>
282
+ <div className="border-fm-divider-secondary h-24 overflow-hidden rounded-lg border">
283
+ <ResizablePanelGroup direction="horizontal">
284
+ <ResizablePanel defaultSize={50}>
285
+ <div className="bg-fm-surface-secondary flex h-full items-center justify-center p-4">
286
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
287
+ Clear affordance
288
+ </span>
289
+ </div>
290
+ </ResizablePanel>
291
+ <ResizableHandle withHandle />
292
+ <ResizablePanel defaultSize={50}>
293
+ <div className="bg-fm-surface-primary flex h-full items-center justify-center p-4">
294
+ <span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
295
+ Grip visible
296
+ </span>
297
+ </div>
298
+ </ResizablePanel>
299
+ </ResizablePanelGroup>
300
+ </div>
686
301
  </div>
687
302
  </div>
688
303
  </div>
@@ -692,222 +307,303 @@ export const RealWorldExamples: Story = {
692
307
  docs: {
693
308
  description: {
694
309
  story:
695
- "Real-world application layouts including IDE/code editor interface and dashboard layout with multiple nested panels.",
310
+ "All layout configurations: horizontal split, vertical split, three-panel with minimum sizes, nested horizontal+vertical layouts, and both handle variants (minimal vs. grip icon).",
696
311
  },
697
312
  },
698
313
  },
699
314
  }
700
315
 
701
- // 7. Accessibility Demo
702
- export const AccessibilityDemo: Story = {
703
- render: () => (
704
- <div className="space-y-6 p-8">
705
- <h3 className="text-fm-primary text-center text-lg font-medium">
706
- Accessibility Features
707
- </h3>
708
-
709
- <div className="space-y-4">
710
- <div className="rounded-lg border border-blue-500/30 bg-blue-900/10 p-4">
711
- <h4 className="text-fm-info mb-2 text-sm font-medium">
712
- Keyboard Navigation
713
- </h4>
714
- <p className="text-fm-info-sec mb-2 text-xs">
715
- Try these keyboard interactions:
716
- </p>
717
- <ul className="text-fm-info-sec space-y-1 text-xs">
718
- <li>
719
- • <kbd className="bg-fm-surface-secondary rounded px-1">Tab</kbd>{" "}
720
- to focus resize handles
721
- </li>
722
- <li>
723
- •{" "}
724
- <kbd className="bg-fm-surface-secondary rounded px-1">
725
- Arrow Keys
726
- </kbd>{" "}
727
- to resize panels
728
- </li>
729
- <li>
730
- •{" "}
731
- <kbd className="bg-fm-surface-secondary rounded px-1">Enter</kbd>{" "}
732
- to activate resize mode
733
- </li>
734
- <li>
735
- •{" "}
736
- <kbd className="bg-fm-surface-secondary rounded px-1">Escape</kbd>{" "}
737
- to exit resize mode
738
- </li>
739
- </ul>
740
- </div>
316
+ // ─── UseCases ─────────────────────────────────────────────────────────────────
741
317
 
742
- <div className="h-48">
743
- <h4 className="text-fm-secondary mb-2 text-sm font-medium">
744
- Keyboard Accessible Resizing
745
- </h4>
746
- <ResizablePanelGroup
747
- direction="horizontal"
748
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
749
- >
750
- <ResizablePanel defaultSize={40}>
751
- <div className="flex h-full items-center justify-center bg-blue-500/10 p-4">
752
- <div className="text-center">
753
- <h5 className="text-md text-fm-primary font-medium">
754
- Left Panel
755
- </h5>
756
- <p className="text-fm-secondary mt-1 text-xs">
757
- Tab to the handle and use arrow keys
318
+ export const UseCases: Story = {
319
+ render: () => (
320
+ <div className="mx-auto max-w-3xl space-y-8 p-8">
321
+ {/* Sidebar + Main — library browser */}
322
+ <div className="space-y-3">
323
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
324
+ Sidebar + Main Content
325
+ </h4>
326
+ <div className="border-fm-divider-secondary h-72 overflow-hidden rounded-xl border">
327
+ <ResizablePanelGroup direction="horizontal">
328
+ {/* Sidebar */}
329
+ <ResizablePanel defaultSize={28} minSize={18}>
330
+ <div className="bg-fm-surface-secondary flex h-full flex-col">
331
+ <div className="border-fm-divider-secondary border-b px-4 py-3">
332
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
333
+ Library
758
334
  </p>
759
335
  </div>
336
+ <nav className="flex-1 space-y-1 p-3">
337
+ {[
338
+ { icon: MusicalNoteIcon, label: "Songs" },
339
+ { icon: HeartIcon, label: "Favorites" },
340
+ { icon: SearchIcon, label: "Discover" },
341
+ { icon: SettingIcon, label: "Settings" },
342
+ ].map(({ icon: Icon, label }) => (
343
+ <button
344
+ key={label}
345
+ className="text-fm-secondary hover:text-fm-primary hover:bg-fm-surface-primary font-fm-text text-fm-sm leading-fm-sm flex w-full items-center gap-2 rounded-lg px-3 py-2 transition-colors"
346
+ >
347
+ <Icon className="h-4 w-4 shrink-0" />
348
+ {label}
349
+ </button>
350
+ ))}
351
+ </nav>
760
352
  </div>
761
353
  </ResizablePanel>
762
354
  <ResizableHandle withHandle />
763
- <ResizablePanel defaultSize={60}>
764
- <div className="flex h-full items-center justify-center bg-purple-500/10 p-4">
765
- <div className="text-center">
766
- <h5 className="text-md text-fm-primary font-medium">
767
- Right Panel
768
- </h5>
769
- <p className="text-fm-secondary mt-1 text-xs">
770
- Focus ring visible when handle is focused
355
+ {/* Main content */}
356
+ <ResizablePanel defaultSize={72}>
357
+ <div className="bg-fm-surface-primary flex h-full flex-col">
358
+ <div className="border-fm-divider-secondary border-b px-4 py-3">
359
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
360
+ Songs
771
361
  </p>
772
362
  </div>
363
+ <div className="flex-1 space-y-1 overflow-auto p-3">
364
+ {[
365
+ {
366
+ title: "Midnight Drive",
367
+ artist: "Nova Wave",
368
+ duration: "3:42",
369
+ },
370
+ {
371
+ title: "Electric Haze",
372
+ artist: "The Circuits",
373
+ duration: "4:15",
374
+ },
375
+ {
376
+ title: "Neon Pulse",
377
+ artist: "Synthcore",
378
+ duration: "3:58",
379
+ },
380
+ {
381
+ title: "Deep Current",
382
+ artist: "Ocean Mind",
383
+ duration: "5:02",
384
+ },
385
+ ].map((song) => (
386
+ <div
387
+ key={song.title}
388
+ className="hover:bg-fm-surface-secondary flex items-center justify-between rounded-lg px-3 py-2 transition-colors"
389
+ >
390
+ <div className="flex items-center gap-3">
391
+ <div className="bg-fm-surface-secondary border-fm-divider-secondary flex h-8 w-8 shrink-0 items-center justify-center rounded-md border">
392
+ <MusicalNoteIcon className="text-fm-tertiary h-4 w-4" />
393
+ </div>
394
+ <div>
395
+ <p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
396
+ {song.title}
397
+ </p>
398
+ <p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
399
+ {song.artist}
400
+ </p>
401
+ </div>
402
+ </div>
403
+ <span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
404
+ {song.duration}
405
+ </span>
406
+ </div>
407
+ ))}
408
+ </div>
773
409
  </div>
774
410
  </ResizablePanel>
775
411
  </ResizablePanelGroup>
776
412
  </div>
777
-
778
- <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
779
- <h4 className="text-fm-secondary mb-3 text-sm font-medium">
780
- Screen Reader Support
781
- </h4>
782
- <div className="text-fm-secondary space-y-1 text-xs">
783
- <p>• Resize handles have proper ARIA labels</p>
784
- <p>• Panel relationships are properly communicated</p>
785
- <p>• Size changes are announced to screen readers</p>
786
- <p>• Keyboard instructions are provided contextually</p>
787
- </div>
788
- </div>
789
413
  </div>
790
- </div>
791
- ),
792
- parameters: {
793
- docs: {
794
- description: {
795
- story:
796
- "Demonstration of accessibility features including keyboard navigation, focus management, and screen reader support.",
797
- },
798
- },
799
- },
800
- }
801
-
802
- // 8. Interactive Playground
803
- export const InteractivePlayground: Story = {
804
- render: () => {
805
- const [sizes, setSizes] = React.useState([25, 50, 25])
806
-
807
- return (
808
- <div className="space-y-6 p-8">
809
- <h3 className="text-fm-primary text-center text-lg font-medium">
810
- Interactive Playground
811
- </h3>
812
-
813
- <div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
814
- <h4 className="text-fm-secondary mb-2 text-sm font-medium">
815
- Current Panel Sizes
816
- </h4>
817
- <div className="grid grid-cols-3 gap-4 text-xs">
818
- <div className="text-center">
819
- <div className="text-fm-primary">Left Panel</div>
820
- <div className="text-fm-info font-mono">
821
- {sizes[0].toFixed(1)}%
822
- </div>
823
- </div>
824
- <div className="text-center">
825
- <div className="text-fm-primary">Center Panel</div>
826
- <div className="text-fm-positive font-mono">
827
- {sizes[1].toFixed(1)}%
828
- </div>
829
- </div>
830
- <div className="text-center">
831
- <div className="text-fm-primary">Right Panel</div>
832
- <div className="text-fm-icon-brand-secondary font-mono">
833
- {sizes[2].toFixed(1)}%
834
- </div>
835
- </div>
836
- </div>
837
- </div>
838
414
 
839
- <div className="h-64">
840
- <ResizablePanelGroup
841
- direction="horizontal"
842
- className="border-fm-divider-secondary overflow-hidden rounded-lg border"
843
- onLayout={(newSizes) => setSizes(newSizes)}
844
- >
845
- <ResizablePanel defaultSize={25} minSize={15}>
846
- <div className="flex h-full items-center justify-center bg-blue-500/10 p-4">
847
- <div className="text-center">
848
- <h5 className="text-md text-fm-primary font-medium">
849
- Panel 1
850
- </h5>
851
- <p className="text-fm-secondary mt-1 text-xs">Min: 15%</p>
852
- <div className="mx-auto mt-3 flex h-16 w-16 items-center justify-center rounded-full bg-blue-500/20">
853
- <span className="text-fm-info font-mono text-xs">
854
- {sizes[0]?.toFixed(0)}%
855
- </span>
856
- </div>
415
+ {/* Inspector panel — track detail */}
416
+ <div className="space-y-3">
417
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
418
+ Inspector Panel
419
+ </h4>
420
+ <div className="border-fm-divider-secondary h-64 overflow-hidden rounded-xl border">
421
+ <ResizablePanelGroup direction="horizontal">
422
+ {/* Track list */}
423
+ <ResizablePanel defaultSize={55}>
424
+ <div className="bg-fm-surface-primary flex h-full flex-col">
425
+ <div className="border-fm-divider-secondary border-b px-4 py-3">
426
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
427
+ Track List
428
+ </p>
857
429
  </div>
858
- </div>
859
- </ResizablePanel>
860
- <ResizableHandle withHandle />
861
-
862
- <ResizablePanel defaultSize={50}>
863
- <div className="flex h-full items-center justify-center bg-green-500/10 p-4">
864
- <div className="text-center">
865
- <h5 className="text-md text-fm-primary font-medium">
866
- Panel 2
867
- </h5>
868
- <p className="text-fm-secondary mt-1 text-xs">Flexible</p>
869
- <div className="mx-auto mt-3 flex h-16 w-16 items-center justify-center rounded-full bg-green-500/20">
870
- <span className="text-fm-positive font-mono text-xs">
871
- {sizes[1]?.toFixed(0)}%
872
- </span>
873
- </div>
430
+ <div className="flex-1 space-y-1 p-3">
431
+ {["Midnight Drive", "Electric Haze", "Neon Pulse"].map(
432
+ (title, i) => (
433
+ <div
434
+ key={title}
435
+ className={`flex items-center gap-3 rounded-lg px-3 py-2 transition-colors ${i === 0 ? "bg-fm-surface-secondary" : "hover:bg-fm-surface-secondary"}`}
436
+ >
437
+ <span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm w-4">
438
+ {i + 1}
439
+ </span>
440
+ <p
441
+ className={`font-fm-text text-fm-sm leading-fm-sm ${i === 0 ? "text-fm-primary" : "text-fm-secondary"}`}
442
+ >
443
+ {title}
444
+ </p>
445
+ </div>
446
+ )
447
+ )}
874
448
  </div>
875
449
  </div>
876
450
  </ResizablePanel>
877
451
  <ResizableHandle withHandle />
878
-
879
- <ResizablePanel defaultSize={25} minSize={20}>
880
- <div className="flex h-full items-center justify-center bg-purple-500/10 p-4">
881
- <div className="text-center">
882
- <h5 className="text-md text-fm-primary font-medium">
883
- Panel 3
884
- </h5>
885
- <p className="text-fm-secondary mt-1 text-xs">Min: 20%</p>
886
- <div className="mx-auto mt-3 flex h-16 w-16 items-center justify-center rounded-full bg-purple-500/20">
887
- <span className="text-fm-icon-brand-secondary font-mono text-xs">
888
- {sizes[2]?.toFixed(0)}%
889
- </span>
890
- </div>
452
+ {/* Inspector */}
453
+ <ResizablePanel defaultSize={45} minSize={30}>
454
+ <div className="bg-fm-surface-secondary flex h-full flex-col">
455
+ <div className="border-fm-divider-secondary border-b px-4 py-3">
456
+ <p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
457
+ Inspector
458
+ </p>
459
+ </div>
460
+ <div className="flex-1 space-y-3 p-4">
461
+ {[
462
+ { label: "Title", value: "Midnight Drive" },
463
+ { label: "Artist", value: "Nova Wave" },
464
+ { label: "Duration", value: "3:42" },
465
+ { label: "BPM", value: "128" },
466
+ { label: "Key", value: "A minor" },
467
+ ].map(({ label, value }) => (
468
+ <div
469
+ key={label}
470
+ className="flex items-center justify-between"
471
+ >
472
+ <span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
473
+ {label}
474
+ </span>
475
+ <span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
476
+ {value}
477
+ </span>
478
+ </div>
479
+ ))}
891
480
  </div>
892
481
  </div>
893
482
  </ResizablePanel>
894
483
  </ResizablePanelGroup>
895
484
  </div>
485
+ </div>
896
486
 
897
- <div className="text-fm-secondary text-center text-xs">
898
- <p>
899
- Drag the handles to resize panels and see the live size updates
900
- above!
901
- </p>
487
+ {/* Waveform editor layout */}
488
+ <div className="space-y-3">
489
+ <h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
490
+ Waveform Editor Layout
491
+ </h4>
492
+ <div className="border-fm-divider-secondary h-80 overflow-hidden rounded-xl border">
493
+ <ResizablePanelGroup direction="horizontal">
494
+ {/* Tools sidebar */}
495
+ <ResizablePanel defaultSize={20} minSize={15}>
496
+ <div className="bg-fm-surface-secondary flex h-full flex-col items-center gap-3 px-2 py-4">
497
+ <p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm writing-mode-vertical-lr hidden rotate-180">
498
+ Tools
499
+ </p>
500
+ {[MusicalNoteIcon, HeartIcon, AlertIcon, SettingIcon].map(
501
+ (Icon, i) => (
502
+ <button
503
+ key={i}
504
+ className="text-fm-secondary hover:text-fm-primary hover:bg-fm-surface-primary rounded-lg p-2 transition-colors"
505
+ >
506
+ <Icon className="h-4 w-4" />
507
+ </button>
508
+ )
509
+ )}
510
+ </div>
511
+ </ResizablePanel>
512
+ <ResizableHandle withHandle />
513
+ {/* Main editor area */}
514
+ <ResizablePanel defaultSize={80}>
515
+ <ResizablePanelGroup direction="vertical">
516
+ {/* Waveform */}
517
+ <ResizablePanel defaultSize={60}>
518
+ <div className="bg-fm-surface-primary flex h-full flex-col">
519
+ <div className="border-fm-divider-secondary flex items-center gap-3 border-b px-4 py-2">
520
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
521
+ Waveform — Midnight Drive.flac
522
+ </p>
523
+ </div>
524
+ <div className="flex flex-1 items-center justify-center gap-1 px-6">
525
+ {Array.from({ length: 48 }, (_, i) => {
526
+ const h = 20 + Math.abs(Math.sin(i * 0.4 + 1) * 60)
527
+ return (
528
+ <div
529
+ key={i}
530
+ className="bg-fm-surface-info-sec w-1 shrink-0 rounded-full"
531
+ style={{ height: `${h}%` }}
532
+ />
533
+ )
534
+ })}
535
+ </div>
536
+ {/* Transport bar */}
537
+ <div className="border-fm-divider-secondary flex items-center justify-center gap-4 border-t px-4 py-2">
538
+ <button className="text-fm-secondary hover:text-fm-primary transition-colors outline-none">
539
+ <SkipBackwardIcon className="h-4 w-4" />
540
+ </button>
541
+ <button className="text-fm-primary hover:text-fm-secondary transition-colors outline-none">
542
+ <PauseIcon className="h-4 w-4" />
543
+ </button>
544
+ <button className="text-fm-secondary hover:text-fm-primary transition-colors outline-none">
545
+ <SkipForwardIcon className="h-4 w-4" />
546
+ </button>
547
+ <button className="text-fm-secondary hover:text-fm-primary transition-colors outline-none">
548
+ <VolumeFullIcon className="h-4 w-4" />
549
+ </button>
550
+ </div>
551
+ </div>
552
+ </ResizablePanel>
553
+ <ResizableHandle withHandle />
554
+ {/* Timeline / markers */}
555
+ <ResizablePanel defaultSize={40} minSize={20}>
556
+ <div className="bg-fm-surface-secondary flex h-full flex-col">
557
+ <div className="border-fm-divider-secondary border-b px-4 py-2">
558
+ <p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
559
+ Markers &amp; Regions
560
+ </p>
561
+ </div>
562
+ <div className="flex-1 space-y-2 p-4">
563
+ {[
564
+ {
565
+ label: "Intro",
566
+ time: "0:00",
567
+ color: "bg-fm-surface-info-sec",
568
+ },
569
+ {
570
+ label: "Verse",
571
+ time: "0:32",
572
+ color: "bg-fm-surface-positive-sec",
573
+ },
574
+ {
575
+ label: "Chorus",
576
+ time: "1:12",
577
+ color: "bg-fm-surface-warning-sec",
578
+ },
579
+ ].map(({ label, time, color }) => (
580
+ <div key={label} className="flex items-center gap-3">
581
+ <div
582
+ className={`h-3 w-3 rounded-sm ${color} shrink-0`}
583
+ />
584
+ <span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
585
+ {label}
586
+ </span>
587
+ <span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm ml-auto">
588
+ {time}
589
+ </span>
590
+ </div>
591
+ ))}
592
+ </div>
593
+ </div>
594
+ </ResizablePanel>
595
+ </ResizablePanelGroup>
596
+ </ResizablePanel>
597
+ </ResizablePanelGroup>
902
598
  </div>
903
599
  </div>
904
- )
905
- },
600
+ </div>
601
+ ),
906
602
  parameters: {
907
603
  docs: {
908
604
  description: {
909
605
  story:
910
- "Interactive playground showing real-time panel size updates and demonstrating the onLayout callback functionality.",
606
+ "Real audio app split views: a collapsible sidebar + main library browser, a track list + inspector panel pair, and a waveform editor with tool sidebar, waveform canvas, transport controls, and a resizable marker region below.",
911
607
  },
912
608
  },
913
609
  },