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,8 @@
|
|
|
1
1
|
import React from "react"
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
3
3
|
|
|
4
|
+
import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
|
|
5
|
+
|
|
4
6
|
import { ScrollArea, ScrollBar } from "."
|
|
5
7
|
|
|
6
8
|
const meta: Meta<typeof ScrollArea> = {
|
|
@@ -8,69 +10,29 @@ const meta: Meta<typeof ScrollArea> = {
|
|
|
8
10
|
component: ScrollArea,
|
|
9
11
|
parameters: {
|
|
10
12
|
layout: "centered",
|
|
11
|
-
backgrounds: {
|
|
12
|
-
default: "dark",
|
|
13
|
-
values: [
|
|
14
|
-
{ name: "dark", value: "#0a0a0a" },
|
|
15
|
-
{ name: "light", value: "#ffffff" },
|
|
16
|
-
],
|
|
17
|
-
},
|
|
18
13
|
docs: {
|
|
19
14
|
description: {
|
|
20
|
-
component:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
A custom scrollable area component built on Radix UI primitives with styled scrollbars and smooth scrolling behavior.
|
|
24
|
-
|
|
25
|
-
## Features
|
|
26
|
-
|
|
27
|
-
- **Custom Scrollbars**: Styled scrollbars that match your design system
|
|
28
|
-
- **Smooth Scrolling**: Optimized scrolling performance with native feel
|
|
29
|
-
- **Keyboard Navigation**: Full keyboard support for accessibility
|
|
30
|
-
- **Focus Management**: Proper focus ring and outline handling
|
|
31
|
-
- **Cross-browser**: Consistent appearance across different browsers
|
|
32
|
-
- **Touch Support**: Touch-friendly scrolling on mobile devices
|
|
33
|
-
- **Orientation Support**: Both vertical and horizontal scrolling
|
|
34
|
-
|
|
35
|
-
## Component Structure
|
|
36
|
-
|
|
37
|
-
- **ScrollArea**: Root container that manages the scrollable region
|
|
38
|
-
- **ScrollBar**: Custom scrollbar component with thumb indicator
|
|
39
|
-
- **Viewport**: The actual scrollable content area
|
|
40
|
-
- **Corner**: Corner element for when both scrollbars are present
|
|
41
|
-
|
|
42
|
-
## Usage Examples
|
|
43
|
-
|
|
44
|
-
### Basic Vertical Scroll
|
|
45
|
-
\`\`\`tsx
|
|
46
|
-
<ScrollArea className="h-72 w-48">
|
|
47
|
-
<div className="p-4">
|
|
48
|
-
{/* Long content that needs scrolling */}
|
|
49
|
-
</div>
|
|
50
|
-
</ScrollArea>
|
|
51
|
-
\`\`\`
|
|
52
|
-
|
|
53
|
-
### Horizontal Scroll
|
|
54
|
-
\`\`\`tsx
|
|
55
|
-
<ScrollArea className="w-72 whitespace-nowrap">
|
|
56
|
-
<div className="flex w-max gap-4 p-4">
|
|
57
|
-
{/* Wide content that needs horizontal scrolling */}
|
|
58
|
-
</div>
|
|
59
|
-
<ScrollBar orientation="horizontal" />
|
|
60
|
-
</ScrollArea>
|
|
61
|
-
\`\`\`
|
|
62
|
-
|
|
63
|
-
### Both Directions
|
|
64
|
-
\`\`\`tsx
|
|
65
|
-
<ScrollArea className="h-72 w-72">
|
|
66
|
-
<div className="w-[800px] h-[600px] p-4">
|
|
67
|
-
{/* Content that overflows both directions */}
|
|
68
|
-
</div>
|
|
69
|
-
<ScrollBar orientation="horizontal" />
|
|
70
|
-
</ScrollArea>
|
|
71
|
-
\`\`\`
|
|
72
|
-
`,
|
|
15
|
+
component:
|
|
16
|
+
"A custom scrollable container built on Radix UI primitives. Provides styled scrollbars and smooth scrolling in vertical, horizontal, or both directions. Ideal for constraining long lists, message threads, track queues, and other overflow content within a fixed viewport.",
|
|
73
17
|
},
|
|
18
|
+
page: () => (
|
|
19
|
+
<AuralComponentDocsPage
|
|
20
|
+
features={[
|
|
21
|
+
{
|
|
22
|
+
title: "Styled Scrollbars",
|
|
23
|
+
description: "Custom Radix scrollbar",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
title: "Both Directions",
|
|
27
|
+
description: "Vertical and horizontal",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
title: "Fixed Viewport",
|
|
31
|
+
description: "Overflow content area",
|
|
32
|
+
},
|
|
33
|
+
]}
|
|
34
|
+
/>
|
|
35
|
+
),
|
|
74
36
|
},
|
|
75
37
|
},
|
|
76
38
|
tags: ["autodocs"],
|
|
@@ -79,459 +41,146 @@ A custom scrollable area component built on Radix UI primitives with styled scro
|
|
|
79
41
|
export default meta
|
|
80
42
|
type Story = StoryObj<typeof ScrollArea>
|
|
81
43
|
|
|
82
|
-
// 1.
|
|
83
|
-
|
|
44
|
+
// ─── 1. Configurations ────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
export const Configurations: Story = {
|
|
84
47
|
render: () => (
|
|
85
48
|
<div className="space-y-8">
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
{/* Text Content */}
|
|
97
|
-
<div className="space-y-2">
|
|
98
|
-
<h4 className="text-fm-secondary text-sm font-medium">
|
|
99
|
-
Text Content
|
|
100
|
-
</h4>
|
|
101
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-72 w-80 rounded-lg border">
|
|
102
|
-
<div className="p-4">
|
|
103
|
-
<h4 className="text-fm-primary mb-4 text-sm leading-none font-medium">
|
|
104
|
-
The Art of Web Development
|
|
105
|
-
</h4>
|
|
106
|
-
<div className="text-fm-secondary space-y-4 text-sm">
|
|
107
|
-
<p>
|
|
108
|
-
Web development is an ever-evolving field that combines
|
|
109
|
-
creativity with technical expertise. Modern developers must
|
|
110
|
-
master a wide array of technologies, from frontend frameworks
|
|
111
|
-
like React and Vue to backend systems built with Node.js,
|
|
112
|
-
Python, or Go.
|
|
113
|
-
</p>
|
|
114
|
-
<p>
|
|
115
|
-
The importance of user experience cannot be overstated. Every
|
|
116
|
-
line of code we write should be with the end user in mind.
|
|
117
|
-
Performance, accessibility, and intuitive design are not just
|
|
118
|
-
buzzwords—they are fundamental requirements for successful web
|
|
119
|
-
applications.
|
|
120
|
-
</p>
|
|
121
|
-
<p>
|
|
122
|
-
Component-driven development has revolutionized how we build
|
|
123
|
-
user interfaces. By creating reusable, modular components, we
|
|
124
|
-
can maintain consistency across large applications while
|
|
125
|
-
reducing development time and improving code quality.
|
|
126
|
-
</p>
|
|
127
|
-
<p>
|
|
128
|
-
CSS has grown tremendously powerful with features like Grid,
|
|
129
|
-
Flexbox, and custom properties. Combined with modern tools
|
|
130
|
-
like Tailwind CSS, we can create beautiful, responsive designs
|
|
131
|
-
with unprecedented efficiency.
|
|
132
|
-
</p>
|
|
133
|
-
<p>
|
|
134
|
-
The future of web development looks bright with emerging
|
|
135
|
-
technologies like WebAssembly, Web Components, and progressive
|
|
136
|
-
enhancement techniques that make the web more capable and
|
|
137
|
-
accessible to everyone.
|
|
138
|
-
</p>
|
|
139
|
-
<p>
|
|
140
|
-
Testing and quality assurance remain critical aspects of
|
|
141
|
-
professional development. Unit tests, integration tests, and
|
|
142
|
-
end-to-end testing help ensure our applications work reliably
|
|
143
|
-
across different environments and use cases.
|
|
144
|
-
</p>
|
|
145
|
-
</div>
|
|
146
|
-
</div>
|
|
147
|
-
</ScrollArea>
|
|
148
|
-
</div>
|
|
149
|
-
|
|
150
|
-
{/* List Content */}
|
|
151
|
-
<div className="space-y-2">
|
|
152
|
-
<h4 className="text-fm-secondary text-sm font-medium">
|
|
153
|
-
List Content
|
|
154
|
-
</h4>
|
|
155
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-72 w-80 rounded-lg border">
|
|
156
|
-
<div className="p-4">
|
|
157
|
-
<h4 className="text-fm-primary mb-4 text-sm leading-none font-medium">
|
|
158
|
-
Popular Programming Languages
|
|
159
|
-
</h4>
|
|
160
|
-
<div className="space-y-2">
|
|
161
|
-
{[
|
|
162
|
-
{
|
|
163
|
-
name: "JavaScript",
|
|
164
|
-
desc: "Dynamic web programming language",
|
|
165
|
-
},
|
|
166
|
-
{ name: "TypeScript", desc: "Typed superset of JavaScript" },
|
|
167
|
-
{ name: "Python", desc: "Versatile and beginner-friendly" },
|
|
168
|
-
{ name: "Java", desc: "Object-oriented enterprise language" },
|
|
169
|
-
{
|
|
170
|
-
name: "C#",
|
|
171
|
-
desc: "Microsoft's modern programming language",
|
|
172
|
-
},
|
|
173
|
-
{ name: "Go", desc: "Fast and efficient systems language" },
|
|
174
|
-
{ name: "Rust", desc: "Memory-safe systems programming" },
|
|
175
|
-
{
|
|
176
|
-
name: "Swift",
|
|
177
|
-
desc: "Apple's modern programming language",
|
|
178
|
-
},
|
|
179
|
-
{ name: "Kotlin", desc: "Modern alternative to Java" },
|
|
180
|
-
{ name: "PHP", desc: "Server-side web development" },
|
|
181
|
-
{ name: "Ruby", desc: "Elegant and expressive language" },
|
|
182
|
-
{
|
|
183
|
-
name: "C++",
|
|
184
|
-
desc: "Powerful systems programming language",
|
|
185
|
-
},
|
|
186
|
-
{ name: "Dart", desc: "Language for Flutter development" },
|
|
187
|
-
{ name: "Scala", desc: "Functional programming on JVM" },
|
|
188
|
-
{ name: "Elixir", desc: "Concurrent and fault-tolerant" },
|
|
189
|
-
].map((lang, index) => (
|
|
49
|
+
{/* Vertical scroll */}
|
|
50
|
+
<div>
|
|
51
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md mb-4 font-medium">
|
|
52
|
+
Vertical Scroll
|
|
53
|
+
</h4>
|
|
54
|
+
<div className="flex flex-wrap gap-6">
|
|
55
|
+
<div className="space-y-2 text-center">
|
|
56
|
+
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-56 w-64 rounded-lg border">
|
|
57
|
+
<div className="space-y-2 p-4">
|
|
58
|
+
{Array.from({ length: 12 }, (_, i) => (
|
|
190
59
|
<div
|
|
191
|
-
key={
|
|
192
|
-
className="border-fm-divider-secondary bg-fm-surface-
|
|
60
|
+
key={i}
|
|
61
|
+
className="border-fm-divider-secondary bg-fm-surface-primary rounded-md border px-3 py-2"
|
|
193
62
|
>
|
|
194
|
-
<
|
|
195
|
-
{
|
|
196
|
-
</
|
|
197
|
-
<div className="text-fm-secondary text-xs">{lang.desc}</div>
|
|
63
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
64
|
+
Track {i + 1}
|
|
65
|
+
</p>
|
|
198
66
|
</div>
|
|
199
67
|
))}
|
|
200
68
|
</div>
|
|
201
|
-
</
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
),
|
|
207
|
-
parameters: {
|
|
208
|
-
docs: {
|
|
209
|
-
description: {
|
|
210
|
-
story:
|
|
211
|
-
"Basic vertical scrolling examples with text content and list items showing custom scrollbar styling.",
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// 2. Horizontal Scroll
|
|
218
|
-
export const HorizontalScroll: Story = {
|
|
219
|
-
render: () => (
|
|
220
|
-
<div className="space-y-8">
|
|
221
|
-
<div className="text-center">
|
|
222
|
-
<h3 className="text-fm-primary mb-2 font-medium">Horizontal Scroll</h3>
|
|
223
|
-
<p className="text-fm-secondary text-sm">
|
|
224
|
-
Horizontal scrolling with custom scrollbar orientation
|
|
225
|
-
</p>
|
|
226
|
-
</div>
|
|
69
|
+
</ScrollArea>
|
|
70
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
71
|
+
Fixed height (224px)
|
|
72
|
+
</p>
|
|
73
|
+
</div>
|
|
227
74
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
Image Gallery
|
|
233
|
-
</h4>
|
|
234
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary w-full max-w-4xl rounded-lg border whitespace-nowrap">
|
|
235
|
-
<div className="flex w-max gap-4 p-4">
|
|
236
|
-
{[
|
|
237
|
-
{
|
|
238
|
-
id: 1,
|
|
239
|
-
color: "from-blue-500 to-purple-600",
|
|
240
|
-
name: "Mountain Vista",
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
id: 2,
|
|
244
|
-
color: "from-green-500 to-teal-600",
|
|
245
|
-
name: "Forest Path",
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
id: 3,
|
|
249
|
-
color: "from-orange-500 to-red-600",
|
|
250
|
-
name: "Desert Sunset",
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
id: 4,
|
|
254
|
-
color: "from-purple-500 to-pink-600",
|
|
255
|
-
name: "Ocean Waves",
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
id: 5,
|
|
259
|
-
color: "from-teal-500 to-cyan-600",
|
|
260
|
-
name: "City Lights",
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
id: 6,
|
|
264
|
-
color: "from-yellow-500 to-orange-600",
|
|
265
|
-
name: "Golden Hour",
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
id: 7,
|
|
269
|
-
color: "from-indigo-500 to-blue-600",
|
|
270
|
-
name: "Starry Night",
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
id: 8,
|
|
274
|
-
color: "from-pink-500 to-rose-600",
|
|
275
|
-
name: "Cherry Blossoms",
|
|
276
|
-
},
|
|
277
|
-
].map((item) => (
|
|
278
|
-
<div key={item.id} className="flex-none space-y-2">
|
|
75
|
+
<div className="space-y-2 text-center">
|
|
76
|
+
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-40 w-64 rounded-lg border">
|
|
77
|
+
<div className="space-y-2 p-4">
|
|
78
|
+
{Array.from({ length: 10 }, (_, i) => (
|
|
279
79
|
<div
|
|
280
|
-
|
|
80
|
+
key={i}
|
|
81
|
+
className="border-fm-divider-secondary bg-fm-surface-primary rounded-md border px-3 py-2"
|
|
281
82
|
>
|
|
282
|
-
|
|
83
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
84
|
+
Playlist item {i + 1}
|
|
85
|
+
</p>
|
|
283
86
|
</div>
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
)
|
|
289
|
-
</
|
|
290
|
-
|
|
291
|
-
</ScrollArea>
|
|
87
|
+
))}
|
|
88
|
+
</div>
|
|
89
|
+
</ScrollArea>
|
|
90
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
91
|
+
Compact height (160px)
|
|
92
|
+
</p>
|
|
93
|
+
</div>
|
|
292
94
|
</div>
|
|
95
|
+
</div>
|
|
293
96
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
97
|
+
{/* Horizontal scroll */}
|
|
98
|
+
<div>
|
|
99
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md mb-4 font-medium">
|
|
100
|
+
Horizontal Scroll
|
|
101
|
+
</h4>
|
|
102
|
+
<div className="space-y-2 text-center">
|
|
103
|
+
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary w-80 rounded-lg border whitespace-nowrap">
|
|
104
|
+
<div className="flex w-max gap-3 p-4">
|
|
301
105
|
{[
|
|
302
|
-
"
|
|
303
|
-
"
|
|
304
|
-
"
|
|
305
|
-
"
|
|
306
|
-
"
|
|
307
|
-
"
|
|
308
|
-
"
|
|
309
|
-
"
|
|
310
|
-
"
|
|
311
|
-
"
|
|
312
|
-
"
|
|
313
|
-
|
|
314
|
-
"Koa",
|
|
315
|
-
"MongoDB",
|
|
316
|
-
"PostgreSQL",
|
|
317
|
-
"MySQL",
|
|
318
|
-
"Redis",
|
|
319
|
-
"GraphQL",
|
|
320
|
-
"REST API",
|
|
321
|
-
"Docker",
|
|
322
|
-
"Kubernetes",
|
|
323
|
-
"AWS",
|
|
324
|
-
"Vercel",
|
|
325
|
-
"Netlify",
|
|
326
|
-
"Firebase",
|
|
327
|
-
].map((tag, index) => (
|
|
106
|
+
"Hip-Hop",
|
|
107
|
+
"R&B",
|
|
108
|
+
"Electronic",
|
|
109
|
+
"Jazz",
|
|
110
|
+
"Classical",
|
|
111
|
+
"Indie",
|
|
112
|
+
"Pop",
|
|
113
|
+
"Metal",
|
|
114
|
+
"Soul",
|
|
115
|
+
"Funk",
|
|
116
|
+
"Reggae",
|
|
117
|
+
].map((genre) => (
|
|
328
118
|
<div
|
|
329
|
-
key={
|
|
330
|
-
className="border-fm-divider-secondary bg-fm-surface-
|
|
119
|
+
key={genre}
|
|
120
|
+
className="border-fm-divider-secondary bg-fm-surface-primary flex-none rounded-full border px-4 py-1.5"
|
|
331
121
|
>
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
</div>
|
|
336
|
-
<ScrollBar orientation="horizontal" />
|
|
337
|
-
</ScrollArea>
|
|
338
|
-
</div>
|
|
339
|
-
|
|
340
|
-
{/* Timeline */}
|
|
341
|
-
<div className="space-y-2">
|
|
342
|
-
<h4 className="text-fm-secondary text-sm font-medium">
|
|
343
|
-
Project Timeline
|
|
344
|
-
</h4>
|
|
345
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary w-full max-w-3xl rounded-lg border whitespace-nowrap">
|
|
346
|
-
<div className="flex w-max gap-6 p-4">
|
|
347
|
-
{[
|
|
348
|
-
{ phase: "Planning", duration: "2 weeks", status: "completed" },
|
|
349
|
-
{ phase: "Design", duration: "3 weeks", status: "completed" },
|
|
350
|
-
{
|
|
351
|
-
phase: "Development",
|
|
352
|
-
duration: "8 weeks",
|
|
353
|
-
status: "in-progress",
|
|
354
|
-
},
|
|
355
|
-
{ phase: "Testing", duration: "2 weeks", status: "pending" },
|
|
356
|
-
{ phase: "Deployment", duration: "1 week", status: "pending" },
|
|
357
|
-
{ phase: "Launch", duration: "1 week", status: "pending" },
|
|
358
|
-
].map((item, index) => (
|
|
359
|
-
<div key={index} className="flex-none space-y-2">
|
|
360
|
-
<div className="border-fm-divider-secondary bg-fm-surface-secondary w-32 rounded-lg border p-3">
|
|
361
|
-
<div
|
|
362
|
-
className={`mb-2 h-2 w-2 rounded-full ${
|
|
363
|
-
item.status === "completed"
|
|
364
|
-
? "bg-fm-surface-positive"
|
|
365
|
-
: item.status === "in-progress"
|
|
366
|
-
? "bg-fm-surface-warning"
|
|
367
|
-
: "bg-fm-surface-tertiary"
|
|
368
|
-
}`}
|
|
369
|
-
></div>
|
|
370
|
-
<div className="text-fm-primary text-sm font-medium">
|
|
371
|
-
{item.phase}
|
|
372
|
-
</div>
|
|
373
|
-
<div className="text-fm-secondary text-xs">
|
|
374
|
-
{item.duration}
|
|
375
|
-
</div>
|
|
376
|
-
</div>
|
|
122
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
123
|
+
{genre}
|
|
124
|
+
</p>
|
|
377
125
|
</div>
|
|
378
126
|
))}
|
|
379
127
|
</div>
|
|
380
128
|
<ScrollBar orientation="horizontal" />
|
|
381
129
|
</ScrollArea>
|
|
130
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
131
|
+
Genre tag strip (fixed width 320px)
|
|
132
|
+
</p>
|
|
382
133
|
</div>
|
|
383
134
|
</div>
|
|
384
|
-
</div>
|
|
385
|
-
),
|
|
386
|
-
parameters: {
|
|
387
|
-
docs: {
|
|
388
|
-
description: {
|
|
389
|
-
story:
|
|
390
|
-
"Horizontal scrolling examples including image galleries, tag lists, and timeline components with horizontal scrollbars.",
|
|
391
|
-
},
|
|
392
|
-
},
|
|
393
|
-
},
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// 3. Both Directions
|
|
397
|
-
export const BothDirectionsScroll: Story = {
|
|
398
|
-
render: () => (
|
|
399
|
-
<div className="space-y-8">
|
|
400
|
-
<div className="text-center">
|
|
401
|
-
<h3 className="text-fm-primary mb-2 font-medium">
|
|
402
|
-
Two-Dimensional Scroll
|
|
403
|
-
</h3>
|
|
404
|
-
<p className="text-fm-secondary text-sm">
|
|
405
|
-
Content that scrolls both horizontally and vertically
|
|
406
|
-
</p>
|
|
407
|
-
</div>
|
|
408
135
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
<
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
<
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
Department
|
|
424
|
-
</th>
|
|
425
|
-
<th className="text-fm-primary p-2 text-left">Location</th>
|
|
426
|
-
<th className="text-fm-primary p-2 text-left">
|
|
427
|
-
Start Date
|
|
428
|
-
</th>
|
|
429
|
-
<th className="text-fm-primary p-2 text-left">Salary</th>
|
|
430
|
-
<th className="text-fm-primary p-2 text-left">Status</th>
|
|
431
|
-
</tr>
|
|
432
|
-
</thead>
|
|
433
|
-
<tbody>
|
|
434
|
-
{Array.from({ length: 50 }, (_, i) => (
|
|
435
|
-
<tr
|
|
436
|
-
key={i}
|
|
437
|
-
className="border-fm-divider-secondary border-b"
|
|
136
|
+
{/* Both directions */}
|
|
137
|
+
<div>
|
|
138
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md mb-4 font-medium">
|
|
139
|
+
Both Directions
|
|
140
|
+
</h4>
|
|
141
|
+
<div className="space-y-2 text-center">
|
|
142
|
+
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-48 w-80 rounded-lg border">
|
|
143
|
+
<div className="w-140 p-4">
|
|
144
|
+
<div className="mb-3 grid grid-cols-5 gap-3">
|
|
145
|
+
{["Title", "Artist", "Album", "Duration", "Plays"].map(
|
|
146
|
+
(col) => (
|
|
147
|
+
<p
|
|
148
|
+
key={col}
|
|
149
|
+
className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm font-medium"
|
|
438
150
|
>
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
</td>
|
|
446
|
-
<td className="text-fm-secondary p-2">
|
|
447
|
-
{["Developer", "Designer", "Manager", "Analyst"][i % 4]}
|
|
448
|
-
</td>
|
|
449
|
-
<td className="text-fm-secondary p-2">
|
|
450
|
-
{["Engineering", "Design", "Marketing", "Sales"][i % 4]}
|
|
451
|
-
</td>
|
|
452
|
-
<td className="text-fm-secondary p-2">
|
|
453
|
-
{
|
|
454
|
-
["San Francisco", "New York", "London", "Tokyo"][
|
|
455
|
-
i % 4
|
|
456
|
-
]
|
|
457
|
-
}
|
|
458
|
-
</td>
|
|
459
|
-
<td className="text-fm-secondary p-2">
|
|
460
|
-
{new Date(
|
|
461
|
-
2020 + (i % 4),
|
|
462
|
-
i % 12,
|
|
463
|
-
(i % 28) + 1
|
|
464
|
-
).toLocaleDateString()}
|
|
465
|
-
</td>
|
|
466
|
-
<td className="text-fm-secondary p-2">
|
|
467
|
-
${(50000 + i * 1000).toLocaleString()}
|
|
468
|
-
</td>
|
|
469
|
-
<td className="p-2">
|
|
470
|
-
<span
|
|
471
|
-
className={`rounded-full px-2 py-1 text-xs ${
|
|
472
|
-
i % 3 === 0
|
|
473
|
-
? "bg-fm-surface-positive-sec text-fm-positive"
|
|
474
|
-
: i % 3 === 1
|
|
475
|
-
? "bg-fm-surface-warning-sec text-fm-warning"
|
|
476
|
-
: "bg-fm-surface-secondary text-fm-icon-negative"
|
|
477
|
-
}`}
|
|
478
|
-
>
|
|
479
|
-
{i % 3 === 0
|
|
480
|
-
? "Active"
|
|
481
|
-
: i % 3 === 1
|
|
482
|
-
? "Away"
|
|
483
|
-
: "Inactive"}
|
|
484
|
-
</span>
|
|
485
|
-
</td>
|
|
486
|
-
</tr>
|
|
487
|
-
))}
|
|
488
|
-
</tbody>
|
|
489
|
-
</table>
|
|
490
|
-
</div>
|
|
491
|
-
<ScrollBar orientation="horizontal" />
|
|
492
|
-
</ScrollArea>
|
|
493
|
-
</div>
|
|
494
|
-
|
|
495
|
-
{/* Large Canvas */}
|
|
496
|
-
<div className="space-y-2">
|
|
497
|
-
<h4 className="text-fm-secondary text-sm font-medium">
|
|
498
|
-
Design Canvas
|
|
499
|
-
</h4>
|
|
500
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-96 w-full max-w-2xl rounded-lg border">
|
|
501
|
-
<div className="h-[1200px] w-[1500px] bg-gradient-to-br from-blue-900/20 to-purple-900/20 p-4">
|
|
502
|
-
<div className="relative h-full w-full">
|
|
503
|
-
{/* Grid Pattern */}
|
|
151
|
+
{col}
|
|
152
|
+
</p>
|
|
153
|
+
)
|
|
154
|
+
)}
|
|
155
|
+
</div>
|
|
156
|
+
{Array.from({ length: 10 }, (_, i) => (
|
|
504
157
|
<div
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
Main Content Area
|
|
524
|
-
</div>
|
|
525
|
-
<div className="text-fm-primary absolute top-20 right-20 flex h-64 w-56 items-center justify-center rounded-lg border border-orange-400/50 bg-orange-500/30">
|
|
526
|
-
Sidebar Widget
|
|
527
|
-
</div>
|
|
528
|
-
<div className="border-fm-divider-secondary bg-fm-surface-secondary text-fm-primary absolute bottom-20 left-20 flex h-24 w-[calc(100%-160px)] items-center justify-center rounded-lg border">
|
|
529
|
-
Footer Component
|
|
158
|
+
key={i}
|
|
159
|
+
className="border-fm-divider-secondary grid grid-cols-5 gap-3 border-t py-2"
|
|
160
|
+
>
|
|
161
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm truncate">
|
|
162
|
+
Song {i + 1}
|
|
163
|
+
</p>
|
|
164
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm truncate">
|
|
165
|
+
Artist
|
|
166
|
+
</p>
|
|
167
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm truncate">
|
|
168
|
+
Album Name
|
|
169
|
+
</p>
|
|
170
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
171
|
+
3:45
|
|
172
|
+
</p>
|
|
173
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
174
|
+
1.2M
|
|
175
|
+
</p>
|
|
530
176
|
</div>
|
|
531
|
-
|
|
177
|
+
))}
|
|
532
178
|
</div>
|
|
533
179
|
<ScrollBar orientation="horizontal" />
|
|
534
180
|
</ScrollArea>
|
|
181
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
182
|
+
Wide table (560px content, 320px viewport)
|
|
183
|
+
</p>
|
|
535
184
|
</div>
|
|
536
185
|
</div>
|
|
537
186
|
</div>
|
|
@@ -540,608 +189,283 @@ export const BothDirectionsScroll: Story = {
|
|
|
540
189
|
docs: {
|
|
541
190
|
description: {
|
|
542
191
|
story:
|
|
543
|
-
"
|
|
192
|
+
"Comparison of all three scroll orientations: vertical with different height constraints, horizontal with a tag strip, and bidirectional with a wide data table.",
|
|
544
193
|
},
|
|
545
194
|
},
|
|
546
195
|
},
|
|
547
196
|
}
|
|
548
197
|
|
|
549
|
-
//
|
|
550
|
-
export const DifferentSizes: Story = {
|
|
551
|
-
render: () => (
|
|
552
|
-
<div className="space-y-8">
|
|
553
|
-
<div className="text-center">
|
|
554
|
-
<h3 className="text-fm-primary mb-2 font-medium">Different Sizes</h3>
|
|
555
|
-
<p className="text-fm-secondary text-sm">
|
|
556
|
-
ScrollArea components in various sizes and configurations
|
|
557
|
-
</p>
|
|
558
|
-
</div>
|
|
559
|
-
|
|
560
|
-
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
|
561
|
-
{/* Small */}
|
|
562
|
-
<div className="space-y-2">
|
|
563
|
-
<h4 className="text-fm-secondary text-sm font-medium">
|
|
564
|
-
Small (h-40)
|
|
565
|
-
</h4>
|
|
566
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-40 w-full rounded-lg border">
|
|
567
|
-
<div className="p-3">
|
|
568
|
-
<h5 className="text-fm-primary mb-2 text-sm font-medium">
|
|
569
|
-
Quick Notes
|
|
570
|
-
</h5>
|
|
571
|
-
<div className="text-fm-secondary space-y-2 text-xs">
|
|
572
|
-
{Array.from({ length: 15 }, (_, i) => (
|
|
573
|
-
<div key={i} className="bg-fm-surface-secondary rounded p-2">
|
|
574
|
-
Note item {i + 1}: This is a quick note or reminder item.
|
|
575
|
-
</div>
|
|
576
|
-
))}
|
|
577
|
-
</div>
|
|
578
|
-
</div>
|
|
579
|
-
</ScrollArea>
|
|
580
|
-
</div>
|
|
198
|
+
// ─── 2. UseCases ──────────────────────────────────────────────────────────────
|
|
581
199
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
<div className="p-4">
|
|
589
|
-
<h5 className="text-fm-primary mb-3 text-sm font-medium">
|
|
590
|
-
Task List
|
|
591
|
-
</h5>
|
|
592
|
-
<div className="space-y-3">
|
|
593
|
-
{Array.from({ length: 12 }, (_, i) => (
|
|
594
|
-
<div
|
|
595
|
-
key={i}
|
|
596
|
-
className="bg-fm-surface-secondary flex items-center gap-3 rounded-lg p-3"
|
|
597
|
-
>
|
|
598
|
-
<div
|
|
599
|
-
className={`h-3 w-3 rounded-full ${
|
|
600
|
-
i % 3 === 0
|
|
601
|
-
? "bg-fm-surface-positive"
|
|
602
|
-
: "bg-fm-surface-tertiary"
|
|
603
|
-
}`}
|
|
604
|
-
></div>
|
|
605
|
-
<div>
|
|
606
|
-
<div className="text-fm-primary text-sm">
|
|
607
|
-
Task {i + 1}
|
|
608
|
-
</div>
|
|
609
|
-
<div className="text-fm-secondary text-xs">
|
|
610
|
-
{i % 3 === 0 ? "Completed" : "Pending"}
|
|
611
|
-
</div>
|
|
612
|
-
</div>
|
|
613
|
-
</div>
|
|
614
|
-
))}
|
|
615
|
-
</div>
|
|
616
|
-
</div>
|
|
617
|
-
</ScrollArea>
|
|
618
|
-
</div>
|
|
619
|
-
|
|
620
|
-
{/* Large */}
|
|
621
|
-
<div className="space-y-2">
|
|
622
|
-
<h4 className="text-fm-secondary text-sm font-medium">
|
|
623
|
-
Large (h-96)
|
|
624
|
-
</h4>
|
|
625
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-96 w-full rounded-lg border">
|
|
626
|
-
<div className="p-4">
|
|
627
|
-
<h5 className="text-fm-primary mb-4 text-sm font-medium">
|
|
628
|
-
Activity Feed
|
|
629
|
-
</h5>
|
|
630
|
-
<div className="space-y-4">
|
|
631
|
-
{Array.from({ length: 20 }, (_, i) => (
|
|
632
|
-
<div
|
|
633
|
-
key={i}
|
|
634
|
-
className="bg-fm-surface-secondary flex gap-3 rounded-lg p-3"
|
|
635
|
-
>
|
|
636
|
-
<div className="text-fm-primary flex h-8 w-8 items-center justify-center rounded-full bg-gradient-to-br from-blue-500 to-purple-600 text-xs font-medium">
|
|
637
|
-
{String.fromCharCode(65 + (i % 26))}
|
|
638
|
-
</div>
|
|
639
|
-
<div className="flex-1">
|
|
640
|
-
<div className="text-fm-primary text-sm">
|
|
641
|
-
User {i + 1} performed an action
|
|
642
|
-
</div>
|
|
643
|
-
<div className="text-fm-secondary text-xs">
|
|
644
|
-
{Math.floor(Math.random() * 60)} minutes ago
|
|
645
|
-
</div>
|
|
646
|
-
</div>
|
|
647
|
-
</div>
|
|
648
|
-
))}
|
|
649
|
-
</div>
|
|
650
|
-
</div>
|
|
651
|
-
</ScrollArea>
|
|
652
|
-
</div>
|
|
653
|
-
</div>
|
|
654
|
-
</div>
|
|
655
|
-
),
|
|
656
|
-
parameters: {
|
|
657
|
-
docs: {
|
|
658
|
-
description: {
|
|
659
|
-
story:
|
|
660
|
-
"ScrollArea components in different sizes from small notification lists to large activity feeds.",
|
|
661
|
-
},
|
|
662
|
-
},
|
|
200
|
+
const tracks = [
|
|
201
|
+
{
|
|
202
|
+
title: "Neon Pulse",
|
|
203
|
+
artist: "Synthwave Collective",
|
|
204
|
+
duration: "3:42",
|
|
205
|
+
plays: "4.1M",
|
|
663
206
|
},
|
|
664
|
-
|
|
207
|
+
{
|
|
208
|
+
title: "Midnight Rain",
|
|
209
|
+
artist: "Luna Beats",
|
|
210
|
+
duration: "4:10",
|
|
211
|
+
plays: "2.8M",
|
|
212
|
+
},
|
|
213
|
+
{ title: "Golden Hour", artist: "Solstice", duration: "3:55", plays: "6.3M" },
|
|
214
|
+
{
|
|
215
|
+
title: "City Echoes",
|
|
216
|
+
artist: "Urban Drift",
|
|
217
|
+
duration: "2:58",
|
|
218
|
+
plays: "1.4M",
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
title: "Deep Waters",
|
|
222
|
+
artist: "Ocean State",
|
|
223
|
+
duration: "5:12",
|
|
224
|
+
plays: "892K",
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
title: "Electric Sky",
|
|
228
|
+
artist: "Volt Lab",
|
|
229
|
+
duration: "3:30",
|
|
230
|
+
plays: "3.7M",
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
title: "Static Dreams",
|
|
234
|
+
artist: "Cassette Ghost",
|
|
235
|
+
duration: "4:05",
|
|
236
|
+
plays: "2.1M",
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
title: "Sunrise Protocol",
|
|
240
|
+
artist: "Dawn Circuit",
|
|
241
|
+
duration: "3:18",
|
|
242
|
+
plays: "5.0M",
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
title: "Phantom Groove",
|
|
246
|
+
artist: "The Frequency",
|
|
247
|
+
duration: "4:48",
|
|
248
|
+
plays: "1.6M",
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
title: "Quiet Storm",
|
|
252
|
+
artist: "Ember Tone",
|
|
253
|
+
duration: "3:22",
|
|
254
|
+
plays: "3.2M",
|
|
255
|
+
},
|
|
256
|
+
]
|
|
257
|
+
|
|
258
|
+
const messages = [
|
|
259
|
+
{
|
|
260
|
+
user: "Mia",
|
|
261
|
+
avatar: "M",
|
|
262
|
+
text: "Just dropped a new EP — check it out!",
|
|
263
|
+
time: "2m ago",
|
|
264
|
+
self: false,
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
user: "You",
|
|
268
|
+
avatar: "Y",
|
|
269
|
+
text: "Sounds amazing, already on repeat.",
|
|
270
|
+
time: "1m ago",
|
|
271
|
+
self: true,
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
user: "Mia",
|
|
275
|
+
avatar: "M",
|
|
276
|
+
text: "Thanks! Recorded it all in one weekend.",
|
|
277
|
+
time: "1m ago",
|
|
278
|
+
self: false,
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
user: "Kai",
|
|
282
|
+
avatar: "K",
|
|
283
|
+
text: "The production on track 3 is incredible.",
|
|
284
|
+
time: "45s ago",
|
|
285
|
+
self: false,
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
user: "You",
|
|
289
|
+
avatar: "Y",
|
|
290
|
+
text: "Agreed. The bass line hits hard.",
|
|
291
|
+
time: "30s ago",
|
|
292
|
+
self: true,
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
user: "Mia",
|
|
296
|
+
avatar: "M",
|
|
297
|
+
text: "I'll share the stems if you want to remix.",
|
|
298
|
+
time: "20s ago",
|
|
299
|
+
self: false,
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
user: "Kai",
|
|
303
|
+
avatar: "K",
|
|
304
|
+
text: "Yes please! Would love to flip it.",
|
|
305
|
+
time: "10s ago",
|
|
306
|
+
self: false,
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
user: "You",
|
|
310
|
+
avatar: "Y",
|
|
311
|
+
text: "Count me in too.",
|
|
312
|
+
time: "just now",
|
|
313
|
+
self: true,
|
|
314
|
+
},
|
|
315
|
+
]
|
|
316
|
+
|
|
317
|
+
const settingsSections = [
|
|
318
|
+
{
|
|
319
|
+
section: "Playback",
|
|
320
|
+
items: [
|
|
321
|
+
"Audio quality",
|
|
322
|
+
"Crossfade duration",
|
|
323
|
+
"Equalizer presets",
|
|
324
|
+
"Volume normalisation",
|
|
325
|
+
],
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
section: "Downloads",
|
|
329
|
+
items: [
|
|
330
|
+
"Download quality",
|
|
331
|
+
"Storage location",
|
|
332
|
+
"Auto-download new releases",
|
|
333
|
+
"Cache size limit",
|
|
334
|
+
],
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
section: "Notifications",
|
|
338
|
+
items: [
|
|
339
|
+
"New release alerts",
|
|
340
|
+
"Friend activity",
|
|
341
|
+
"Podcast updates",
|
|
342
|
+
"Weekly digest",
|
|
343
|
+
],
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
section: "Privacy",
|
|
347
|
+
items: [
|
|
348
|
+
"Listening history",
|
|
349
|
+
"Public profile",
|
|
350
|
+
"Activity status",
|
|
351
|
+
"Data sharing",
|
|
352
|
+
],
|
|
353
|
+
},
|
|
354
|
+
]
|
|
665
355
|
|
|
666
|
-
|
|
667
|
-
export const RealWorldExamples: Story = {
|
|
356
|
+
export const UseCases: Story = {
|
|
668
357
|
render: () => (
|
|
669
|
-
<div className="space-y-8">
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
358
|
+
<div className="mx-auto max-w-3xl space-y-8 p-8">
|
|
359
|
+
{/* Track list */}
|
|
360
|
+
<div>
|
|
361
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md mb-4 font-medium">
|
|
362
|
+
Scrollable Track List
|
|
363
|
+
</h4>
|
|
364
|
+
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-72 rounded-xl border">
|
|
365
|
+
<div className="p-2">
|
|
366
|
+
{tracks.map((track, i) => (
|
|
367
|
+
<div
|
|
368
|
+
key={i}
|
|
369
|
+
className="hover:bg-fm-surface-primary flex items-center gap-4 rounded-lg px-3 py-2.5 transition-colors"
|
|
370
|
+
>
|
|
371
|
+
<span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm w-5 text-right">
|
|
372
|
+
{i + 1}
|
|
373
|
+
</span>
|
|
374
|
+
<div className="bg-fm-surface-tertiary flex h-9 w-9 flex-none items-center justify-center rounded-md">
|
|
375
|
+
<span className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold">
|
|
376
|
+
♪
|
|
377
|
+
</span>
|
|
378
|
+
</div>
|
|
379
|
+
<div className="min-w-0 flex-1">
|
|
380
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm truncate font-medium">
|
|
381
|
+
{track.title}
|
|
382
|
+
</p>
|
|
383
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm truncate">
|
|
384
|
+
{track.artist}
|
|
385
|
+
</p>
|
|
386
|
+
</div>
|
|
387
|
+
<span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm hidden sm:block">
|
|
388
|
+
{track.plays}
|
|
389
|
+
</span>
|
|
390
|
+
<span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
|
|
391
|
+
{track.duration}
|
|
392
|
+
</span>
|
|
393
|
+
</div>
|
|
394
|
+
))}
|
|
395
|
+
</div>
|
|
396
|
+
</ScrollArea>
|
|
677
397
|
</div>
|
|
678
398
|
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
<
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
<
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
{
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
message:
|
|
697
|
-
"Going well! Just finished the new component library.",
|
|
698
|
-
time: "10:32",
|
|
699
|
-
self: true,
|
|
700
|
-
},
|
|
701
|
-
{
|
|
702
|
-
user: "Bob",
|
|
703
|
-
message: "That's awesome! Can't wait to try it out.",
|
|
704
|
-
time: "10:33",
|
|
705
|
-
self: false,
|
|
706
|
-
},
|
|
707
|
-
{
|
|
708
|
-
user: "Alice",
|
|
709
|
-
message: "Same here! Are there any examples we can look at?",
|
|
710
|
-
time: "10:35",
|
|
711
|
-
self: false,
|
|
712
|
-
},
|
|
713
|
-
{
|
|
714
|
-
user: "You",
|
|
715
|
-
message:
|
|
716
|
-
"Yes! I've created a Storybook with all the components and examples.",
|
|
717
|
-
time: "10:36",
|
|
718
|
-
self: true,
|
|
719
|
-
},
|
|
720
|
-
{
|
|
721
|
-
user: "Carol",
|
|
722
|
-
message:
|
|
723
|
-
"Perfect timing! I was just about to ask about documentation.",
|
|
724
|
-
time: "10:38",
|
|
725
|
-
self: false,
|
|
726
|
-
},
|
|
727
|
-
{
|
|
728
|
-
user: "Bob",
|
|
729
|
-
message: "The dark theme looks really good btw 👍",
|
|
730
|
-
time: "10:40",
|
|
731
|
-
self: false,
|
|
732
|
-
},
|
|
733
|
-
{
|
|
734
|
-
user: "You",
|
|
735
|
-
message:
|
|
736
|
-
"Thanks! We spent a lot of time getting the frosted glass effects right.",
|
|
737
|
-
time: "10:41",
|
|
738
|
-
self: true,
|
|
739
|
-
},
|
|
740
|
-
{
|
|
741
|
-
user: "Alice",
|
|
742
|
-
message:
|
|
743
|
-
"It really shows! The attention to detail is impressive.",
|
|
744
|
-
time: "10:43",
|
|
745
|
-
self: false,
|
|
746
|
-
},
|
|
747
|
-
{
|
|
748
|
-
user: "Carol",
|
|
749
|
-
message: "Should we schedule a demo session for the team?",
|
|
750
|
-
time: "10:45",
|
|
751
|
-
self: false,
|
|
752
|
-
},
|
|
753
|
-
{
|
|
754
|
-
user: "You",
|
|
755
|
-
message: "Great idea! How about tomorrow at 2 PM?",
|
|
756
|
-
time: "10:46",
|
|
757
|
-
self: true,
|
|
758
|
-
},
|
|
759
|
-
{
|
|
760
|
-
user: "Bob",
|
|
761
|
-
message: "Works for me! I'll send out calendar invites.",
|
|
762
|
-
time: "10:47",
|
|
763
|
-
self: false,
|
|
764
|
-
},
|
|
765
|
-
].map((msg, i) => (
|
|
399
|
+
{/* Message thread */}
|
|
400
|
+
<div>
|
|
401
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md mb-4 font-medium">
|
|
402
|
+
Message Thread
|
|
403
|
+
</h4>
|
|
404
|
+
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-64 rounded-xl border">
|
|
405
|
+
<div className="flex flex-col gap-3 p-4">
|
|
406
|
+
{messages.map((msg, i) => (
|
|
407
|
+
<div
|
|
408
|
+
key={i}
|
|
409
|
+
className={`flex items-end gap-2 ${msg.self ? "flex-row-reverse" : "flex-row"}`}
|
|
410
|
+
>
|
|
411
|
+
<div className="bg-fm-surface-tertiary flex h-7 w-7 flex-none items-center justify-center rounded-full">
|
|
412
|
+
<span className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold">
|
|
413
|
+
{msg.avatar}
|
|
414
|
+
</span>
|
|
415
|
+
</div>
|
|
766
416
|
<div
|
|
767
|
-
|
|
768
|
-
className={`flex ${msg.self ? "justify-end" : "justify-start"}`}
|
|
417
|
+
className={`max-w-[72%] space-y-1 ${msg.self ? "items-end" : "items-start"} flex flex-col`}
|
|
769
418
|
>
|
|
770
419
|
<div
|
|
771
|
-
className={`
|
|
420
|
+
className={`rounded-2xl px-3 py-2 ${
|
|
772
421
|
msg.self
|
|
773
|
-
? "bg-fm-surface-info
|
|
774
|
-
: "bg-fm-surface-
|
|
422
|
+
? "bg-fm-surface-info-sec"
|
|
423
|
+
: "bg-fm-surface-primary border-fm-divider-secondary border"
|
|
775
424
|
}`}
|
|
776
425
|
>
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
</div>
|
|
781
|
-
)}
|
|
782
|
-
<div className="text-sm">{msg.message}</div>
|
|
783
|
-
<div
|
|
784
|
-
className={`mt-1 text-xs ${
|
|
785
|
-
msg.self ? "text-fm-info-sec" : "text-fm-secondary"
|
|
786
|
-
}`}
|
|
787
|
-
>
|
|
788
|
-
{msg.time}
|
|
789
|
-
</div>
|
|
426
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
427
|
+
{msg.text}
|
|
428
|
+
</p>
|
|
790
429
|
</div>
|
|
430
|
+
<p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm px-1">
|
|
431
|
+
{msg.time}
|
|
432
|
+
</p>
|
|
791
433
|
</div>
|
|
792
|
-
))}
|
|
793
|
-
</div>
|
|
794
|
-
</ScrollArea>
|
|
795
|
-
</div>
|
|
796
|
-
|
|
797
|
-
{/* File Explorer */}
|
|
798
|
-
<div className="space-y-2">
|
|
799
|
-
<h4 className="text-fm-secondary text-sm font-medium">
|
|
800
|
-
File Explorer
|
|
801
|
-
</h4>
|
|
802
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-80 w-full rounded-lg border">
|
|
803
|
-
<div className="text-fm-primary p-2">
|
|
804
|
-
{[
|
|
805
|
-
{
|
|
806
|
-
name: "📁 Documents",
|
|
807
|
-
type: "folder",
|
|
808
|
-
size: "",
|
|
809
|
-
modified: "Today",
|
|
810
|
-
},
|
|
811
|
-
{
|
|
812
|
-
name: "📁 Images",
|
|
813
|
-
type: "folder",
|
|
814
|
-
size: "",
|
|
815
|
-
modified: "Yesterday",
|
|
816
|
-
},
|
|
817
|
-
{
|
|
818
|
-
name: "📁 Projects",
|
|
819
|
-
type: "folder",
|
|
820
|
-
size: "",
|
|
821
|
-
modified: "2 days ago",
|
|
822
|
-
},
|
|
823
|
-
{
|
|
824
|
-
name: "📄 README.md",
|
|
825
|
-
type: "file",
|
|
826
|
-
size: "2.1 KB",
|
|
827
|
-
modified: "Today",
|
|
828
|
-
},
|
|
829
|
-
{
|
|
830
|
-
name: "📄 package.json",
|
|
831
|
-
type: "file",
|
|
832
|
-
size: "1.8 KB",
|
|
833
|
-
modified: "Today",
|
|
834
|
-
},
|
|
835
|
-
{
|
|
836
|
-
name: "🖼️ hero-image.jpg",
|
|
837
|
-
type: "file",
|
|
838
|
-
size: "245 KB",
|
|
839
|
-
modified: "Yesterday",
|
|
840
|
-
},
|
|
841
|
-
{
|
|
842
|
-
name: "📄 index.html",
|
|
843
|
-
type: "file",
|
|
844
|
-
size: "3.2 KB",
|
|
845
|
-
modified: "2 days ago",
|
|
846
|
-
},
|
|
847
|
-
{
|
|
848
|
-
name: "🎨 styles.css",
|
|
849
|
-
type: "file",
|
|
850
|
-
size: "12.5 KB",
|
|
851
|
-
modified: "Today",
|
|
852
|
-
},
|
|
853
|
-
{
|
|
854
|
-
name: "⚡ app.js",
|
|
855
|
-
type: "file",
|
|
856
|
-
size: "8.7 KB",
|
|
857
|
-
modified: "Today",
|
|
858
|
-
},
|
|
859
|
-
{
|
|
860
|
-
name: "📄 config.json",
|
|
861
|
-
type: "file",
|
|
862
|
-
size: "892 B",
|
|
863
|
-
modified: "3 days ago",
|
|
864
|
-
},
|
|
865
|
-
{
|
|
866
|
-
name: "🖼️ logo.svg",
|
|
867
|
-
type: "file",
|
|
868
|
-
size: "3.4 KB",
|
|
869
|
-
modified: "Yesterday",
|
|
870
|
-
},
|
|
871
|
-
{
|
|
872
|
-
name: "📄 .gitignore",
|
|
873
|
-
type: "file",
|
|
874
|
-
size: "156 B",
|
|
875
|
-
modified: "5 days ago",
|
|
876
|
-
},
|
|
877
|
-
{
|
|
878
|
-
name: "📁 node_modules",
|
|
879
|
-
type: "folder",
|
|
880
|
-
size: "",
|
|
881
|
-
modified: "Today",
|
|
882
|
-
},
|
|
883
|
-
{
|
|
884
|
-
name: "📄 tsconfig.json",
|
|
885
|
-
type: "file",
|
|
886
|
-
size: "654 B",
|
|
887
|
-
modified: "Yesterday",
|
|
888
|
-
},
|
|
889
|
-
{
|
|
890
|
-
name: "🔧 webpack.config.js",
|
|
891
|
-
type: "file",
|
|
892
|
-
size: "2.9 KB",
|
|
893
|
-
modified: "3 days ago",
|
|
894
|
-
},
|
|
895
|
-
].map((item, i) => (
|
|
896
|
-
<div
|
|
897
|
-
key={i}
|
|
898
|
-
className="hover:bg-fm-surface-secondary flex cursor-pointer items-center justify-between rounded p-2"
|
|
899
|
-
>
|
|
900
|
-
<div className="flex min-w-0 flex-1 items-center gap-2">
|
|
901
|
-
<span className="text-sm">{item.name}</span>
|
|
902
|
-
</div>
|
|
903
|
-
<div className="text-fm-secondary flex items-center gap-4 text-xs">
|
|
904
|
-
<span className="w-12 text-right">{item.size}</span>
|
|
905
|
-
<span className="w-20 text-right">{item.modified}</span>
|
|
906
|
-
</div>
|
|
907
|
-
</div>
|
|
908
|
-
))}
|
|
909
|
-
</div>
|
|
910
|
-
</ScrollArea>
|
|
911
|
-
</div>
|
|
912
|
-
|
|
913
|
-
{/* Code Editor Sidebar */}
|
|
914
|
-
<div className="space-y-2">
|
|
915
|
-
<h4 className="text-fm-secondary text-sm font-medium">
|
|
916
|
-
Code Editor Sidebar
|
|
917
|
-
</h4>
|
|
918
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-80 w-full rounded-lg border">
|
|
919
|
-
<div className="p-2">
|
|
920
|
-
<div className="space-y-1">
|
|
921
|
-
<div className="text-fm-primary p-2 text-xs font-medium tracking-wide uppercase">
|
|
922
|
-
Explorer
|
|
923
|
-
</div>
|
|
924
|
-
{[
|
|
925
|
-
{ name: "src", level: 0, type: "folder", expanded: true },
|
|
926
|
-
{
|
|
927
|
-
name: "components",
|
|
928
|
-
level: 1,
|
|
929
|
-
type: "folder",
|
|
930
|
-
expanded: true,
|
|
931
|
-
},
|
|
932
|
-
{ name: "Button.tsx", level: 2, type: "file" },
|
|
933
|
-
{ name: "Button.stories.tsx", level: 2, type: "file" },
|
|
934
|
-
{ name: "Avatar.tsx", level: 2, type: "file" },
|
|
935
|
-
{ name: "Avatar.stories.tsx", level: 2, type: "file" },
|
|
936
|
-
{ name: "ScrollArea.tsx", level: 2, type: "file" },
|
|
937
|
-
{ name: "hooks", level: 1, type: "folder", expanded: false },
|
|
938
|
-
{ name: "utils", level: 1, type: "folder", expanded: true },
|
|
939
|
-
{ name: "cn.ts", level: 2, type: "file" },
|
|
940
|
-
{ name: "types.ts", level: 2, type: "file" },
|
|
941
|
-
{ name: "index.ts", level: 1, type: "file" },
|
|
942
|
-
{ name: "App.tsx", level: 1, type: "file" },
|
|
943
|
-
{ name: "public", level: 0, type: "folder", expanded: false },
|
|
944
|
-
{ name: "package.json", level: 0, type: "file" },
|
|
945
|
-
{ name: "tsconfig.json", level: 0, type: "file" },
|
|
946
|
-
{ name: "tailwind.config.js", level: 0, type: "file" },
|
|
947
|
-
{ name: "vite.config.ts", level: 0, type: "file" },
|
|
948
|
-
].map((item, i) => (
|
|
949
|
-
<div
|
|
950
|
-
key={i}
|
|
951
|
-
className="hover:bg-fm-surface-secondary flex cursor-pointer items-center gap-1 rounded p-1 text-sm"
|
|
952
|
-
style={{ paddingLeft: `${8 + item.level * 16}px` }}
|
|
953
|
-
>
|
|
954
|
-
{item.type === "folder" && (
|
|
955
|
-
<span className="text-fm-secondary">
|
|
956
|
-
{item.expanded ? "📂" : "📁"}
|
|
957
|
-
</span>
|
|
958
|
-
)}
|
|
959
|
-
{item.type === "file" && (
|
|
960
|
-
<span className="text-fm-secondary">📄</span>
|
|
961
|
-
)}
|
|
962
|
-
<span className="text-fm-primary">{item.name}</span>
|
|
963
|
-
</div>
|
|
964
|
-
))}
|
|
965
434
|
</div>
|
|
966
|
-
|
|
967
|
-
</ScrollArea>
|
|
968
|
-
</div>
|
|
969
|
-
|
|
970
|
-
{/* Settings Panel */}
|
|
971
|
-
<div className="space-y-2">
|
|
972
|
-
<h4 className="text-fm-secondary text-sm font-medium">
|
|
973
|
-
Settings Panel
|
|
974
|
-
</h4>
|
|
975
|
-
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-80 w-full rounded-lg border">
|
|
976
|
-
<div className="space-y-6 p-4">
|
|
977
|
-
{[
|
|
978
|
-
{
|
|
979
|
-
section: "Appearance",
|
|
980
|
-
settings: [
|
|
981
|
-
{ label: "Theme", value: "Dark", type: "select" },
|
|
982
|
-
{ label: "Font Size", value: "Medium", type: "select" },
|
|
983
|
-
{ label: "Animations", value: true, type: "toggle" },
|
|
984
|
-
],
|
|
985
|
-
},
|
|
986
|
-
{
|
|
987
|
-
section: "Behavior",
|
|
988
|
-
settings: [
|
|
989
|
-
{ label: "Auto Save", value: true, type: "toggle" },
|
|
990
|
-
{
|
|
991
|
-
label: "Smart Suggestions",
|
|
992
|
-
value: false,
|
|
993
|
-
type: "toggle",
|
|
994
|
-
},
|
|
995
|
-
{
|
|
996
|
-
label: "Keyboard Shortcuts",
|
|
997
|
-
value: true,
|
|
998
|
-
type: "toggle",
|
|
999
|
-
},
|
|
1000
|
-
],
|
|
1001
|
-
},
|
|
1002
|
-
{
|
|
1003
|
-
section: "Privacy",
|
|
1004
|
-
settings: [
|
|
1005
|
-
{ label: "Analytics", value: false, type: "toggle" },
|
|
1006
|
-
{ label: "Crash Reports", value: true, type: "toggle" },
|
|
1007
|
-
{ label: "Usage Data", value: false, type: "toggle" },
|
|
1008
|
-
],
|
|
1009
|
-
},
|
|
1010
|
-
{
|
|
1011
|
-
section: "Advanced",
|
|
1012
|
-
settings: [
|
|
1013
|
-
{ label: "Developer Mode", value: false, type: "toggle" },
|
|
1014
|
-
{
|
|
1015
|
-
label: "Experimental Features",
|
|
1016
|
-
value: false,
|
|
1017
|
-
type: "toggle",
|
|
1018
|
-
},
|
|
1019
|
-
{ label: "Debug Logging", value: false, type: "toggle" },
|
|
1020
|
-
],
|
|
1021
|
-
},
|
|
1022
|
-
].map((group, i) => (
|
|
1023
|
-
<div key={i}>
|
|
1024
|
-
<h5 className="text-fm-primary mb-3 text-sm font-medium">
|
|
1025
|
-
{group.section}
|
|
1026
|
-
</h5>
|
|
1027
|
-
<div className="space-y-3">
|
|
1028
|
-
{group.settings.map((setting, j) => (
|
|
1029
|
-
<div
|
|
1030
|
-
key={j}
|
|
1031
|
-
className="flex items-center justify-between"
|
|
1032
|
-
>
|
|
1033
|
-
<span className="text-fm-secondary text-sm">
|
|
1034
|
-
{setting.label}
|
|
1035
|
-
</span>
|
|
1036
|
-
{setting.type === "toggle" ? (
|
|
1037
|
-
<div
|
|
1038
|
-
className={`h-5 w-10 rounded-full p-1 ${
|
|
1039
|
-
setting.value
|
|
1040
|
-
? "bg-fm-surface-info"
|
|
1041
|
-
: "bg-fm-surface-tertiary"
|
|
1042
|
-
}`}
|
|
1043
|
-
>
|
|
1044
|
-
<div
|
|
1045
|
-
className={`bg-fm-surface-primary h-3 w-3 rounded-full transition-transform ${
|
|
1046
|
-
setting.value
|
|
1047
|
-
? "translate-x-5"
|
|
1048
|
-
: "translate-x-0"
|
|
1049
|
-
}`}
|
|
1050
|
-
></div>
|
|
1051
|
-
</div>
|
|
1052
|
-
) : (
|
|
1053
|
-
<span className="text-fm-secondary text-sm">
|
|
1054
|
-
{setting.value}
|
|
1055
|
-
</span>
|
|
1056
|
-
)}
|
|
1057
|
-
</div>
|
|
1058
|
-
))}
|
|
1059
|
-
</div>
|
|
1060
|
-
</div>
|
|
1061
|
-
))}
|
|
1062
|
-
</div>
|
|
1063
|
-
</ScrollArea>
|
|
1064
|
-
</div>
|
|
1065
|
-
</div>
|
|
1066
|
-
</div>
|
|
1067
|
-
),
|
|
1068
|
-
parameters: {
|
|
1069
|
-
docs: {
|
|
1070
|
-
description: {
|
|
1071
|
-
story:
|
|
1072
|
-
"Real-world examples including chat interfaces, file explorers, code editor sidebars, and settings panels demonstrating practical ScrollArea usage.",
|
|
1073
|
-
},
|
|
1074
|
-
},
|
|
1075
|
-
},
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
// 6. Performance Example
|
|
1079
|
-
export const PerformanceExample: Story = {
|
|
1080
|
-
render: () => (
|
|
1081
|
-
<div className="space-y-8">
|
|
1082
|
-
<div className="text-center">
|
|
1083
|
-
<h3 className="text-fm-primary mb-2 font-medium">
|
|
1084
|
-
Performance Example
|
|
1085
|
-
</h3>
|
|
1086
|
-
<p className="text-fm-secondary text-sm">
|
|
1087
|
-
Large datasets handled efficiently with virtual scrolling simulation
|
|
1088
|
-
</p>
|
|
1089
|
-
</div>
|
|
1090
|
-
|
|
1091
|
-
<div className="space-y-4">
|
|
1092
|
-
<div className="text-center">
|
|
1093
|
-
<div className="border-fm-divider-secondary bg-fm-surface-secondary inline-block rounded-lg border p-4">
|
|
1094
|
-
<h4 className="text-fm-primary mb-2 text-sm font-medium">
|
|
1095
|
-
Large Dataset
|
|
1096
|
-
</h4>
|
|
1097
|
-
<p className="text-fm-secondary text-xs leading-relaxed">
|
|
1098
|
-
This example shows 1000+ items in a scrollable area. The
|
|
1099
|
-
ScrollArea component handles smooth scrolling even with large
|
|
1100
|
-
amounts of content.
|
|
1101
|
-
</p>
|
|
435
|
+
))}
|
|
1102
436
|
</div>
|
|
1103
|
-
</
|
|
437
|
+
</ScrollArea>
|
|
438
|
+
</div>
|
|
1104
439
|
|
|
1105
|
-
|
|
440
|
+
{/* Settings panel */}
|
|
441
|
+
<div>
|
|
442
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md mb-4 font-medium">
|
|
443
|
+
Settings Panel
|
|
444
|
+
</h4>
|
|
445
|
+
<ScrollArea className="border-fm-divider-secondary bg-fm-surface-secondary h-64 w-72 rounded-xl border">
|
|
1106
446
|
<div className="p-4">
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
<div
|
|
1113
|
-
|
|
1114
|
-
className="bg-fm-surface-secondary hover:bg-fm-surface-tertiary flex items-center justify-between rounded-lg p-3 transition-colors"
|
|
1115
|
-
>
|
|
1116
|
-
<div className="flex items-center gap-3">
|
|
447
|
+
{settingsSections.map((group) => (
|
|
448
|
+
<div key={group.section} className="mb-5 last:mb-0">
|
|
449
|
+
<p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm mb-2 font-semibold tracking-widest uppercase">
|
|
450
|
+
{group.section}
|
|
451
|
+
</p>
|
|
452
|
+
<div className="space-y-px">
|
|
453
|
+
{group.items.map((item) => (
|
|
1117
454
|
<div
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
"bg-blue-500",
|
|
1121
|
-
"bg-green-500",
|
|
1122
|
-
"bg-purple-500",
|
|
1123
|
-
"bg-orange-500",
|
|
1124
|
-
][i % 4]
|
|
1125
|
-
}`}
|
|
455
|
+
key={item}
|
|
456
|
+
className="hover:bg-fm-surface-primary flex items-center justify-between rounded-md px-3 py-2 transition-colors"
|
|
1126
457
|
>
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
<
|
|
1131
|
-
|
|
1132
|
-
</
|
|
1133
|
-
<div className="text-fm-secondary text-xs">
|
|
1134
|
-
Category:{" "}
|
|
1135
|
-
{["Development", "Design", "Marketing", "Sales"][i % 4]}
|
|
1136
|
-
</div>
|
|
458
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
459
|
+
{item}
|
|
460
|
+
</p>
|
|
461
|
+
<span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
|
|
462
|
+
›
|
|
463
|
+
</span>
|
|
1137
464
|
</div>
|
|
1138
|
-
|
|
1139
|
-
<div className="text-fm-secondary text-xs">
|
|
1140
|
-
{new Date(Date.now() - i * 60000).toLocaleTimeString()}
|
|
1141
|
-
</div>
|
|
465
|
+
))}
|
|
1142
466
|
</div>
|
|
1143
|
-
|
|
1144
|
-
|
|
467
|
+
</div>
|
|
468
|
+
))}
|
|
1145
469
|
</div>
|
|
1146
470
|
</ScrollArea>
|
|
1147
471
|
</div>
|
|
@@ -1151,7 +475,7 @@ export const PerformanceExample: Story = {
|
|
|
1151
475
|
docs: {
|
|
1152
476
|
description: {
|
|
1153
477
|
story:
|
|
1154
|
-
"
|
|
478
|
+
"Real product-shaped scenarios: a numbered track list with play counts, a chat message thread between collaborators, and a settings panel with categorised preferences — all inside fixed-height scroll regions.",
|
|
1155
479
|
},
|
|
1156
480
|
},
|
|
1157
481
|
},
|