aural-ui 4.0.1 → 4.2.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.
- package/README.md +8 -1
- package/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1228
- package/dist/components/avatar/Avatar.stories.tsx +219 -235
- package/dist/components/badge/Badge.stories.tsx +379 -116
- package/dist/components/banner/Banner.stories.tsx +445 -391
- package/dist/components/breadcrumb/Breadcrumb.stories.tsx +453 -199
- package/dist/components/button/Button.stories.tsx +585 -230
- package/dist/components/card/Card.stories.tsx +619 -301
- package/dist/components/char-count/CharCount.stories.tsx +350 -248
- package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
- package/dist/components/chip/Chip.stories.tsx +362 -168
- package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -636
- package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
- package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
- package/dist/components/command/Command.stories.tsx +530 -867
- package/dist/components/dialog/Dialog.stories.tsx +501 -950
- package/dist/components/divider/Divider.stories.tsx +264 -527
- package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
- package/dist/components/drawer/Drawer.stories.tsx +659 -1023
- package/dist/components/dropdown/Dropdown.stories.tsx +643 -1028
- package/dist/components/form/Form.stories.tsx +560 -274
- package/dist/components/helper-text/HelperText.stories.tsx +199 -200
- package/dist/components/hover-card/HoverCard.stories.tsx +318 -1254
- package/dist/components/icon-button/IconButton.stories.tsx +837 -194
- package/dist/components/if-else/if-else.stories.tsx +370 -83
- package/dist/components/input/Input.stories.tsx +436 -368
- package/dist/components/label/Label.stories.tsx +156 -154
- package/dist/components/list/List.stories.tsx +484 -835
- package/dist/components/marquee/Marquee.stories.tsx +356 -712
- package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -422
- package/dist/components/overlay/Overlay.stories.tsx +452 -824
- package/dist/components/pagination/Pagination.stories.tsx +721 -210
- package/dist/components/popover/Popover.stories.tsx +481 -896
- package/dist/components/radio/Radio.stories.tsx +432 -124
- package/dist/components/resizable/Resizable.stories.tsx +495 -799
- package/dist/components/scroll-area/ScrollArea.stories.tsx +383 -1059
- package/dist/components/search/Search.stories.tsx +312 -595
- package/dist/components/select/Select.stories.tsx +684 -789
- package/dist/components/sheet/Sheet.stories.tsx +671 -950
- package/dist/components/skelton/Skelton.stories.tsx +230 -764
- package/dist/components/slider/Slider.stories.tsx +383 -760
- package/dist/components/stepper/Stepper.stories.tsx +371 -514
- package/dist/components/switch/Switch.stories.tsx +461 -208
- package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
- package/dist/components/table/Table.stories.tsx +770 -916
- package/dist/components/tabs/Tabs.stories.tsx +458 -1455
- package/dist/components/tag/Tag.stories.tsx +714 -542
- package/dist/components/textarea/TextArea.stories.tsx +621 -562
- package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -154
- package/dist/components/toast/Toast.stories.tsx +452 -1339
- package/dist/components/toggle/Toggle.stories.tsx +488 -931
- package/dist/components/tooltip/Tooltip.stories.tsx +344 -1388
- package/dist/components/typography/Typography.stories.tsx +406 -89
- package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
- package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
- package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
- package/dist/icons/Icons.stories.tsx +0 -12
- package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +223 -1060
- package/dist/icons/alert-icon/AlertIcon.stories.tsx +106 -968
- package/dist/icons/all-icons.tsx +37 -16
- package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +137 -1010
- package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +145 -935
- package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +132 -1046
- package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +134 -986
- package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +135 -1028
- package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +133 -971
- package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +145 -1123
- package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +143 -1252
- package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +123 -632
- package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +141 -1223
- package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +164 -1018
- package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +121 -1236
- package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +121 -1213
- package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +116 -893
- package/dist/icons/camera-icon/CameraIcon.stories.tsx +109 -1254
- package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +114 -975
- package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +157 -994
- package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +160 -992
- package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +140 -970
- package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +126 -993
- package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +144 -987
- package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +141 -1007
- package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +147 -1187
- package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +110 -476
- package/dist/icons/coin-icon/CoinIcon.stories.tsx +120 -1364
- package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +113 -1360
- package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +111 -942
- package/dist/icons/command-icon/CommandIcon.stories.tsx +124 -1087
- package/dist/icons/copy-icon/CopyIcon.stories.tsx +119 -996
- package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +144 -1046
- package/dist/icons/cross-icon/CrossIcon.stories.tsx +136 -999
- package/dist/icons/download-icon/DownloadIcon.stories.tsx +123 -857
- package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +121 -1080
- package/dist/icons/email-icon/EmailIcon.stories.tsx +112 -979
- package/dist/icons/expand-icon/ExpandIcon.stories.tsx +109 -1146
- package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +141 -1068
- package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +140 -1081
- package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +124 -1050
- package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +123 -1091
- package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +122 -633
- package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +116 -1087
- package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +166 -1020
- package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +112 -1182
- package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +112 -1155
- package/dist/icons/globe-icon/GlobeIcon.stories.tsx +127 -325
- package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +142 -985
- package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +116 -1217
- package/dist/icons/head-icon/HeadIcon.stories.tsx +108 -953
- package/dist/icons/heart-icon/HeartIcon.stories.tsx +117 -1060
- package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +116 -716
- package/dist/icons/image-icon/ImageIcon.stories.tsx +102 -1164
- package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +108 -1233
- package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +133 -1289
- package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +155 -1012
- package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +158 -1438
- package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +121 -1011
- package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +116 -981
- package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +116 -979
- package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +105 -1252
- package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +151 -1554
- package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +107 -1227
- package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +116 -707
- package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +119 -1226
- package/dist/icons/message-icon/MessageIcon.stories.tsx +111 -557
- package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +112 -1198
- package/dist/icons/moon-icon/MoonIcon.stories.tsx +117 -557
- package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +106 -1235
- package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +112 -1185
- package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +116 -1012
- package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +108 -1137
- package/dist/icons/notes-icon/NotesIcon.stories.tsx +116 -1138
- package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +106 -1146
- package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +119 -719
- package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +110 -999
- package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +109 -912
- package/dist/icons/pause-icon/PauseIcon.stories.tsx +110 -1041
- package/dist/icons/pencil-icon/PencilIcon.stories.tsx +112 -1109
- package/dist/icons/phone-icon/PhoneIcon.stories.tsx +112 -1023
- package/dist/icons/plus-icon/PlusIcon.stories.tsx +103 -1132
- package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +104 -870
- package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +99 -476
- package/dist/icons/search-icon/SearchIcon.stories.tsx +108 -1161
- package/dist/icons/setting-icon/SettingIcon.stories.tsx +104 -1009
- package/dist/icons/share-icon/ShareIcon.stories.tsx +117 -1064
- package/dist/icons/shield-icon/ShieldIcon.stories.tsx +114 -974
- package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +134 -1160
- package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +169 -1017
- package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +161 -1016
- package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +102 -1001
- package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +155 -593
- package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +155 -608
- package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +142 -712
- package/dist/icons/star-icon/StarIcon.stories.tsx +120 -946
- package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +109 -1013
- package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +113 -891
- package/dist/icons/sun-icon/SunIcon.stories.tsx +117 -864
- package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +113 -989
- package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +120 -1027
- package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +153 -1476
- package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +143 -1187
- package/dist/icons/tick-icon/TickIcon.stories.tsx +142 -1322
- package/dist/icons/trash-icon/TrashIcon.stories.tsx +105 -970
- package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +154 -1457
- package/dist/icons/upload-icon/UploadIcon.stories.tsx +112 -930
- package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +115 -1019
- package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +122 -1092
- package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +120 -1401
- package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +107 -1212
- package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +109 -1122
- package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +112 -1124
- package/dist/icons/warning-icon/WarningIcon.stories.tsx +119 -1083
- package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +158 -983
- package/dist/index.cjs +90 -90
- package/dist/index.js +90 -90
- package/package.json +8 -3
|
@@ -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
|
-
|
|
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: "
|
|
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
|
-
//
|
|
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
|
-
|
|
292
|
-
export const NestedLayouts: Story = {
|
|
71
|
+
export const Configurations: Story = {
|
|
293
72
|
render: () => (
|
|
294
|
-
<div className="
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
className="border-fm-divider-secondary overflow-hidden rounded-lg border"
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
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={
|
|
331
|
-
<div className="flex h-full items-center justify-center
|
|
332
|
-
<div className="text-center">
|
|
333
|
-
<
|
|
334
|
-
|
|
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-
|
|
340
|
-
|
|
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
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
className="
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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
|
-
</
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
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
|
-
</
|
|
419
|
-
</
|
|
420
|
-
</
|
|
140
|
+
</div>
|
|
141
|
+
</ResizablePanel>
|
|
142
|
+
</ResizablePanelGroup>
|
|
421
143
|
</div>
|
|
144
|
+
</div>
|
|
422
145
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
className="
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
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
|
-
</
|
|
449
|
-
</
|
|
450
|
-
|
|
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
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
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
|
-
</
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
<
|
|
510
|
-
<
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
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
|
-
<<span className="text-fm-icon-negative">div</span>
|
|
546
|
-
>Hello World</
|
|
547
|
-
<span className="text-fm-icon-negative">div</span>
|
|
548
|
-
>
|
|
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
|
-
</
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
<
|
|
559
|
-
<div className="
|
|
560
|
-
<
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
</
|
|
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
|
-
</
|
|
599
|
-
</
|
|
600
|
-
</
|
|
601
|
-
</
|
|
240
|
+
</ResizablePanel>
|
|
241
|
+
</ResizablePanelGroup>
|
|
242
|
+
</ResizablePanel>
|
|
243
|
+
</ResizablePanelGroup>
|
|
602
244
|
</div>
|
|
245
|
+
</div>
|
|
603
246
|
|
|
604
|
-
|
|
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
|
-
<
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
<
|
|
611
|
-
direction="horizontal"
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
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
|
-
</
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
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
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
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
|
-
"
|
|
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
|
-
//
|
|
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
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
<p className="text-fm-
|
|
757
|
-
|
|
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
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
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
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
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
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
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={
|
|
880
|
-
<div className="flex h-full
|
|
881
|
-
<div className="
|
|
882
|
-
<
|
|
883
|
-
|
|
884
|
-
</
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
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
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
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 & 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
|
-
"
|
|
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
|
},
|