aural-ui 3.0.7 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1199
- package/dist/components/avatar/Avatar.stories.tsx +235 -237
- 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/button/index.tsx +7 -7
- 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 -620
- 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 +533 -856
- package/dist/components/dialog/Dialog.stories.tsx +505 -949
- package/dist/components/divider/Divider.stories.tsx +265 -502
- package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
- package/dist/components/drawer/Drawer.stories.tsx +659 -993
- package/dist/components/drawer/index.tsx +3 -3
- package/dist/components/dropdown/Dropdown.stories.tsx +643 -1018
- 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 -1221
- 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 +485 -822
- package/dist/components/marquee/Marquee.stories.tsx +356 -694
- package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -410
- package/dist/components/overlay/Overlay.stories.tsx +452 -818
- package/dist/components/overlay/index.tsx +4 -4
- package/dist/components/pagination/Pagination.stories.tsx +721 -210
- package/dist/components/popover/Popover.stories.tsx +484 -873
- package/dist/components/radio/Radio.stories.tsx +432 -124
- package/dist/components/resizable/Resizable.stories.tsx +496 -752
- package/dist/components/scroll-area/ScrollArea.stories.tsx +384 -1006
- package/dist/components/search/Search.stories.tsx +314 -575
- package/dist/components/select/Select.stories.tsx +684 -787
- package/dist/components/sheet/Sheet.stories.tsx +671 -936
- package/dist/components/skelton/Skelton.stories.tsx +230 -764
- package/dist/components/slider/Slider.stories.tsx +384 -737
- 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 -914
- package/dist/components/tabs/Tabs.stories.tsx +459 -1400
- 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 -148
- package/dist/components/toast/Toast.stories.tsx +452 -1333
- package/dist/components/toggle/Toggle.stories.tsx +488 -909
- package/dist/components/tooltip/Tooltip.stories.tsx +344 -1372
- 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 +226 -1013
- package/dist/icons/alert-icon/AlertIcon.stories.tsx +109 -929
- package/dist/icons/all-icons.tsx +124 -87
- package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +140 -971
- package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +148 -888
- package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +135 -1019
- package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +137 -953
- package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +138 -997
- package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +136 -942
- package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +148 -1092
- package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +146 -1211
- package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +126 -615
- package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +144 -1164
- package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +167 -985
- package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +122 -1179
- package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +124 -1168
- package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +119 -850
- package/dist/icons/camera-icon/CameraIcon.stories.tsx +112 -1213
- package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +117 -934
- package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +160 -961
- package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +163 -961
- package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +144 -942
- package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +129 -966
- package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +147 -964
- package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +145 -975
- package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +150 -1142
- package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +114 -461
- package/dist/icons/coin-icon/CoinIcon.stories.tsx +124 -1322
- package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +117 -1318
- package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +114 -903
- package/dist/icons/command-icon/CommandIcon.stories.tsx +127 -1042
- package/dist/icons/copy-icon/CopyIcon.stories.tsx +123 -962
- package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +147 -999
- package/dist/icons/cross-icon/CrossIcon.stories.tsx +139 -960
- package/dist/icons/download-icon/DownloadIcon.stories.tsx +126 -820
- package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +124 -1031
- package/dist/icons/email-icon/EmailIcon.stories.tsx +115 -936
- package/dist/icons/expand-icon/ExpandIcon.stories.tsx +112 -1111
- package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +144 -1025
- package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +143 -1036
- package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +127 -1011
- package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +126 -1056
- package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +125 -614
- package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +119 -1050
- package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +169 -989
- package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +115 -1145
- package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +115 -1122
- package/dist/icons/globe-icon/GlobeIcon.stories.tsx +130 -313
- package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +145 -940
- package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +119 -1174
- package/dist/icons/head-icon/HeadIcon.stories.tsx +111 -916
- package/dist/icons/heart-icon/HeartIcon.stories.tsx +120 -1019
- package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +119 -683
- package/dist/icons/image-icon/ImageIcon.stories.tsx +105 -1121
- package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +111 -1192
- package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +136 -1256
- package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +159 -962
- package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +161 -1385
- package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +124 -972
- package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +119 -948
- package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +119 -942
- package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +108 -1215
- package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +154 -1517
- package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +110 -1188
- package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +119 -678
- package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +123 -1184
- package/dist/icons/message-icon/MessageIcon.stories.tsx +114 -538
- package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +116 -1158
- package/dist/icons/moon-icon/MoonIcon.stories.tsx +120 -536
- package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +109 -1184
- package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +115 -1134
- package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +119 -971
- package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +111 -1100
- package/dist/icons/notes-icon/NotesIcon.stories.tsx +119 -1101
- package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +109 -1111
- package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +122 -684
- package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +113 -954
- package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +112 -877
- package/dist/icons/pause-icon/PauseIcon.stories.tsx +113 -1000
- package/dist/icons/pencil-icon/PencilIcon.stories.tsx +115 -1070
- package/dist/icons/phone-icon/PhoneIcon.stories.tsx +115 -978
- package/dist/icons/plus-icon/PlusIcon.stories.tsx +106 -1093
- package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +107 -829
- package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +102 -469
- package/dist/icons/search-icon/SearchIcon.stories.tsx +111 -1124
- package/dist/icons/setting-icon/SettingIcon.stories.tsx +107 -970
- package/dist/icons/share-icon/ShareIcon.stories.tsx +120 -1025
- package/dist/icons/shield-icon/ShieldIcon.stories.tsx +117 -931
- package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +137 -1104
- package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +172 -982
- package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +164 -983
- package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +105 -958
- package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +158 -580
- package/dist/icons/spinner-gradient-icon/index.tsx +6 -1
- package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +158 -587
- package/dist/icons/spinner-solid-icon/index.tsx +6 -1
- package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +146 -682
- package/dist/icons/spinner-solid-neutral-icon/index.tsx +1 -1
- package/dist/icons/star-icon/StarIcon.stories.tsx +124 -904
- package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +112 -964
- package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +116 -852
- package/dist/icons/sun-icon/SunIcon.stories.tsx +120 -831
- package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +116 -950
- package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +123 -980
- package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +156 -1427
- package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +146 -1142
- package/dist/icons/tick-icon/TickIcon.stories.tsx +145 -1276
- package/dist/icons/trash-icon/TrashIcon.stories.tsx +108 -933
- package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +157 -1402
- package/dist/icons/upload-icon/UploadIcon.stories.tsx +115 -889
- package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +118 -984
- package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +125 -1049
- package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +123 -1356
- package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +110 -1171
- package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +112 -1093
- package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +115 -1087
- package/dist/icons/warning-icon/WarningIcon.stories.tsx +122 -1046
- package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +161 -936
- package/dist/index.cjs +84 -84
- package/dist/index.js +84 -84
- package/dist/styles/aural-all-theme.css +1222 -0
- package/dist/styles/{aural-theme.css → aural-dark-theme.css} +15 -3
- package/dist/styles/aural-light-theme.css +1047 -0
- package/package.json +1 -1
|
@@ -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,432 +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
|
-
<h4 className="text-sm font-medium text-white/80">Text Content</h4>
|
|
97
|
-
<ScrollArea className="h-72 w-80 rounded-lg border border-white/10 bg-white/5">
|
|
98
|
-
<div className="p-4">
|
|
99
|
-
<h4 className="mb-4 text-sm leading-none font-medium text-white">
|
|
100
|
-
The Art of Web Development
|
|
101
|
-
</h4>
|
|
102
|
-
<div className="space-y-4 text-sm text-white/80">
|
|
103
|
-
<p>
|
|
104
|
-
Web development is an ever-evolving field that combines
|
|
105
|
-
creativity with technical expertise. Modern developers must
|
|
106
|
-
master a wide array of technologies, from frontend frameworks
|
|
107
|
-
like React and Vue to backend systems built with Node.js,
|
|
108
|
-
Python, or Go.
|
|
109
|
-
</p>
|
|
110
|
-
<p>
|
|
111
|
-
The importance of user experience cannot be overstated. Every
|
|
112
|
-
line of code we write should be with the end user in mind.
|
|
113
|
-
Performance, accessibility, and intuitive design are not just
|
|
114
|
-
buzzwords—they are fundamental requirements for successful web
|
|
115
|
-
applications.
|
|
116
|
-
</p>
|
|
117
|
-
<p>
|
|
118
|
-
Component-driven development has revolutionized how we build
|
|
119
|
-
user interfaces. By creating reusable, modular components, we
|
|
120
|
-
can maintain consistency across large applications while
|
|
121
|
-
reducing development time and improving code quality.
|
|
122
|
-
</p>
|
|
123
|
-
<p>
|
|
124
|
-
CSS has grown tremendously powerful with features like Grid,
|
|
125
|
-
Flexbox, and custom properties. Combined with modern tools
|
|
126
|
-
like Tailwind CSS, we can create beautiful, responsive designs
|
|
127
|
-
with unprecedented efficiency.
|
|
128
|
-
</p>
|
|
129
|
-
<p>
|
|
130
|
-
The future of web development looks bright with emerging
|
|
131
|
-
technologies like WebAssembly, Web Components, and progressive
|
|
132
|
-
enhancement techniques that make the web more capable and
|
|
133
|
-
accessible to everyone.
|
|
134
|
-
</p>
|
|
135
|
-
<p>
|
|
136
|
-
Testing and quality assurance remain critical aspects of
|
|
137
|
-
professional development. Unit tests, integration tests, and
|
|
138
|
-
end-to-end testing help ensure our applications work reliably
|
|
139
|
-
across different environments and use cases.
|
|
140
|
-
</p>
|
|
141
|
-
</div>
|
|
142
|
-
</div>
|
|
143
|
-
</ScrollArea>
|
|
144
|
-
</div>
|
|
145
|
-
|
|
146
|
-
{/* List Content */}
|
|
147
|
-
<div className="space-y-2">
|
|
148
|
-
<h4 className="text-sm font-medium text-white/80">List Content</h4>
|
|
149
|
-
<ScrollArea className="h-72 w-80 rounded-lg border border-white/10 bg-white/5">
|
|
150
|
-
<div className="p-4">
|
|
151
|
-
<h4 className="mb-4 text-sm leading-none font-medium text-white">
|
|
152
|
-
Popular Programming Languages
|
|
153
|
-
</h4>
|
|
154
|
-
<div className="space-y-2">
|
|
155
|
-
{[
|
|
156
|
-
{
|
|
157
|
-
name: "JavaScript",
|
|
158
|
-
desc: "Dynamic web programming language",
|
|
159
|
-
},
|
|
160
|
-
{ name: "TypeScript", desc: "Typed superset of JavaScript" },
|
|
161
|
-
{ name: "Python", desc: "Versatile and beginner-friendly" },
|
|
162
|
-
{ name: "Java", desc: "Object-oriented enterprise language" },
|
|
163
|
-
{
|
|
164
|
-
name: "C#",
|
|
165
|
-
desc: "Microsoft's modern programming language",
|
|
166
|
-
},
|
|
167
|
-
{ name: "Go", desc: "Fast and efficient systems language" },
|
|
168
|
-
{ name: "Rust", desc: "Memory-safe systems programming" },
|
|
169
|
-
{
|
|
170
|
-
name: "Swift",
|
|
171
|
-
desc: "Apple's modern programming language",
|
|
172
|
-
},
|
|
173
|
-
{ name: "Kotlin", desc: "Modern alternative to Java" },
|
|
174
|
-
{ name: "PHP", desc: "Server-side web development" },
|
|
175
|
-
{ name: "Ruby", desc: "Elegant and expressive language" },
|
|
176
|
-
{
|
|
177
|
-
name: "C++",
|
|
178
|
-
desc: "Powerful systems programming language",
|
|
179
|
-
},
|
|
180
|
-
{ name: "Dart", desc: "Language for Flutter development" },
|
|
181
|
-
{ name: "Scala", desc: "Functional programming on JVM" },
|
|
182
|
-
{ name: "Elixir", desc: "Concurrent and fault-tolerant" },
|
|
183
|
-
].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) => (
|
|
184
59
|
<div
|
|
185
|
-
key={
|
|
186
|
-
className="rounded-
|
|
60
|
+
key={i}
|
|
61
|
+
className="border-fm-divider-secondary bg-fm-surface-primary rounded-md border px-3 py-2"
|
|
187
62
|
>
|
|
188
|
-
<
|
|
189
|
-
|
|
63
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
64
|
+
Track {i + 1}
|
|
65
|
+
</p>
|
|
190
66
|
</div>
|
|
191
67
|
))}
|
|
192
68
|
</div>
|
|
193
|
-
</
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
),
|
|
199
|
-
parameters: {
|
|
200
|
-
docs: {
|
|
201
|
-
description: {
|
|
202
|
-
story:
|
|
203
|
-
"Basic vertical scrolling examples with text content and list items showing custom scrollbar styling.",
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// 2. Horizontal Scroll
|
|
210
|
-
export const HorizontalScroll: Story = {
|
|
211
|
-
render: () => (
|
|
212
|
-
<div className="space-y-8">
|
|
213
|
-
<div className="text-center">
|
|
214
|
-
<h3 className="mb-2 font-medium text-white">Horizontal Scroll</h3>
|
|
215
|
-
<p className="text-sm text-white/60">
|
|
216
|
-
Horizontal scrolling with custom scrollbar orientation
|
|
217
|
-
</p>
|
|
218
|
-
</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>
|
|
219
74
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
<ScrollArea className="w-full max-w-4xl rounded-lg border border-white/10 bg-white/5 whitespace-nowrap">
|
|
225
|
-
<div className="flex w-max gap-4 p-4">
|
|
226
|
-
{[
|
|
227
|
-
{
|
|
228
|
-
id: 1,
|
|
229
|
-
color: "from-blue-500 to-purple-600",
|
|
230
|
-
name: "Mountain Vista",
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
id: 2,
|
|
234
|
-
color: "from-green-500 to-teal-600",
|
|
235
|
-
name: "Forest Path",
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
id: 3,
|
|
239
|
-
color: "from-orange-500 to-red-600",
|
|
240
|
-
name: "Desert Sunset",
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
id: 4,
|
|
244
|
-
color: "from-purple-500 to-pink-600",
|
|
245
|
-
name: "Ocean Waves",
|
|
246
|
-
},
|
|
247
|
-
{
|
|
248
|
-
id: 5,
|
|
249
|
-
color: "from-teal-500 to-cyan-600",
|
|
250
|
-
name: "City Lights",
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
id: 6,
|
|
254
|
-
color: "from-yellow-500 to-orange-600",
|
|
255
|
-
name: "Golden Hour",
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
id: 7,
|
|
259
|
-
color: "from-indigo-500 to-blue-600",
|
|
260
|
-
name: "Starry Night",
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
id: 8,
|
|
264
|
-
color: "from-pink-500 to-rose-600",
|
|
265
|
-
name: "Cherry Blossoms",
|
|
266
|
-
},
|
|
267
|
-
].map((item) => (
|
|
268
|
-
<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) => (
|
|
269
79
|
<div
|
|
270
|
-
|
|
80
|
+
key={i}
|
|
81
|
+
className="border-fm-divider-secondary bg-fm-surface-primary rounded-md border px-3 py-2"
|
|
271
82
|
>
|
|
272
|
-
|
|
83
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
84
|
+
Playlist item {i + 1}
|
|
85
|
+
</p>
|
|
273
86
|
</div>
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
)
|
|
279
|
-
</
|
|
280
|
-
|
|
281
|
-
</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>
|
|
282
94
|
</div>
|
|
95
|
+
</div>
|
|
283
96
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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">
|
|
289
105
|
{[
|
|
290
|
-
"
|
|
291
|
-
"
|
|
292
|
-
"
|
|
293
|
-
"
|
|
294
|
-
"
|
|
295
|
-
"
|
|
296
|
-
"
|
|
297
|
-
"
|
|
298
|
-
"
|
|
299
|
-
"
|
|
300
|
-
"
|
|
301
|
-
|
|
302
|
-
"Koa",
|
|
303
|
-
"MongoDB",
|
|
304
|
-
"PostgreSQL",
|
|
305
|
-
"MySQL",
|
|
306
|
-
"Redis",
|
|
307
|
-
"GraphQL",
|
|
308
|
-
"REST API",
|
|
309
|
-
"Docker",
|
|
310
|
-
"Kubernetes",
|
|
311
|
-
"AWS",
|
|
312
|
-
"Vercel",
|
|
313
|
-
"Netlify",
|
|
314
|
-
"Firebase",
|
|
315
|
-
].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) => (
|
|
316
118
|
<div
|
|
317
|
-
key={
|
|
318
|
-
className="flex-none rounded-full border
|
|
119
|
+
key={genre}
|
|
120
|
+
className="border-fm-divider-secondary bg-fm-surface-primary flex-none rounded-full border px-4 py-1.5"
|
|
319
121
|
>
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
</div>
|
|
324
|
-
<ScrollBar orientation="horizontal" />
|
|
325
|
-
</ScrollArea>
|
|
326
|
-
</div>
|
|
327
|
-
|
|
328
|
-
{/* Timeline */}
|
|
329
|
-
<div className="space-y-2">
|
|
330
|
-
<h4 className="text-sm font-medium text-white/80">
|
|
331
|
-
Project Timeline
|
|
332
|
-
</h4>
|
|
333
|
-
<ScrollArea className="w-full max-w-3xl rounded-lg border border-white/10 bg-white/5 whitespace-nowrap">
|
|
334
|
-
<div className="flex w-max gap-6 p-4">
|
|
335
|
-
{[
|
|
336
|
-
{ phase: "Planning", duration: "2 weeks", status: "completed" },
|
|
337
|
-
{ phase: "Design", duration: "3 weeks", status: "completed" },
|
|
338
|
-
{
|
|
339
|
-
phase: "Development",
|
|
340
|
-
duration: "8 weeks",
|
|
341
|
-
status: "in-progress",
|
|
342
|
-
},
|
|
343
|
-
{ phase: "Testing", duration: "2 weeks", status: "pending" },
|
|
344
|
-
{ phase: "Deployment", duration: "1 week", status: "pending" },
|
|
345
|
-
{ phase: "Launch", duration: "1 week", status: "pending" },
|
|
346
|
-
].map((item, index) => (
|
|
347
|
-
<div key={index} className="flex-none space-y-2">
|
|
348
|
-
<div className="w-32 rounded-lg border border-white/10 bg-white/5 p-3">
|
|
349
|
-
<div
|
|
350
|
-
className={`mb-2 h-2 w-2 rounded-full ${
|
|
351
|
-
item.status === "completed"
|
|
352
|
-
? "bg-green-500"
|
|
353
|
-
: item.status === "in-progress"
|
|
354
|
-
? "bg-yellow-500"
|
|
355
|
-
: "bg-gray-500"
|
|
356
|
-
}`}
|
|
357
|
-
></div>
|
|
358
|
-
<div className="text-sm font-medium text-white">
|
|
359
|
-
{item.phase}
|
|
360
|
-
</div>
|
|
361
|
-
<div className="text-xs text-white/60">{item.duration}</div>
|
|
362
|
-
</div>
|
|
122
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
123
|
+
{genre}
|
|
124
|
+
</p>
|
|
363
125
|
</div>
|
|
364
126
|
))}
|
|
365
127
|
</div>
|
|
366
128
|
<ScrollBar orientation="horizontal" />
|
|
367
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>
|
|
368
133
|
</div>
|
|
369
134
|
</div>
|
|
370
|
-
</div>
|
|
371
|
-
),
|
|
372
|
-
parameters: {
|
|
373
|
-
docs: {
|
|
374
|
-
description: {
|
|
375
|
-
story:
|
|
376
|
-
"Horizontal scrolling examples including image galleries, tag lists, and timeline components with horizontal scrollbars.",
|
|
377
|
-
},
|
|
378
|
-
},
|
|
379
|
-
},
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// 3. Both Directions
|
|
383
|
-
export const BothDirectionsScroll: Story = {
|
|
384
|
-
render: () => (
|
|
385
|
-
<div className="space-y-8">
|
|
386
|
-
<div className="text-center">
|
|
387
|
-
<h3 className="mb-2 font-medium text-white">Two-Dimensional Scroll</h3>
|
|
388
|
-
<p className="text-sm text-white/60">
|
|
389
|
-
Content that scrolls both horizontally and vertically
|
|
390
|
-
</p>
|
|
391
|
-
</div>
|
|
392
|
-
|
|
393
|
-
<div className="space-y-6">
|
|
394
|
-
{/* Data Table */}
|
|
395
|
-
<div className="space-y-2">
|
|
396
|
-
<h4 className="text-sm font-medium text-white/80">Data Table</h4>
|
|
397
|
-
<ScrollArea className="h-80 w-full max-w-4xl rounded-lg border border-white/10 bg-white/5">
|
|
398
|
-
<div className="w-[1200px] p-4">
|
|
399
|
-
<table className="w-full text-sm">
|
|
400
|
-
<thead>
|
|
401
|
-
<tr className="border-b border-white/10">
|
|
402
|
-
<th className="p-2 text-left text-white">ID</th>
|
|
403
|
-
<th className="p-2 text-left text-white">Name</th>
|
|
404
|
-
<th className="p-2 text-left text-white">Email</th>
|
|
405
|
-
<th className="p-2 text-left text-white">Role</th>
|
|
406
|
-
<th className="p-2 text-left text-white">Department</th>
|
|
407
|
-
<th className="p-2 text-left text-white">Location</th>
|
|
408
|
-
<th className="p-2 text-left text-white">Start Date</th>
|
|
409
|
-
<th className="p-2 text-left text-white">Salary</th>
|
|
410
|
-
<th className="p-2 text-left text-white">Status</th>
|
|
411
|
-
</tr>
|
|
412
|
-
</thead>
|
|
413
|
-
<tbody>
|
|
414
|
-
{Array.from({ length: 50 }, (_, i) => (
|
|
415
|
-
<tr key={i} className="border-b border-white/5">
|
|
416
|
-
<td className="p-2 text-white/80">{1000 + i}</td>
|
|
417
|
-
<td className="p-2 text-white/80">Employee {i + 1}</td>
|
|
418
|
-
<td className="p-2 text-white/60">
|
|
419
|
-
employee{i + 1}@company.com
|
|
420
|
-
</td>
|
|
421
|
-
<td className="p-2 text-white/60">
|
|
422
|
-
{["Developer", "Designer", "Manager", "Analyst"][i % 4]}
|
|
423
|
-
</td>
|
|
424
|
-
<td className="p-2 text-white/60">
|
|
425
|
-
{["Engineering", "Design", "Marketing", "Sales"][i % 4]}
|
|
426
|
-
</td>
|
|
427
|
-
<td className="p-2 text-white/60">
|
|
428
|
-
{
|
|
429
|
-
["San Francisco", "New York", "London", "Tokyo"][
|
|
430
|
-
i % 4
|
|
431
|
-
]
|
|
432
|
-
}
|
|
433
|
-
</td>
|
|
434
|
-
<td className="p-2 text-white/60">
|
|
435
|
-
{new Date(
|
|
436
|
-
2020 + (i % 4),
|
|
437
|
-
i % 12,
|
|
438
|
-
(i % 28) + 1
|
|
439
|
-
).toLocaleDateString()}
|
|
440
|
-
</td>
|
|
441
|
-
<td className="p-2 text-white/60">
|
|
442
|
-
${(50000 + i * 1000).toLocaleString()}
|
|
443
|
-
</td>
|
|
444
|
-
<td className="p-2">
|
|
445
|
-
<span
|
|
446
|
-
className={`rounded-full px-2 py-1 text-xs ${
|
|
447
|
-
i % 3 === 0
|
|
448
|
-
? "bg-green-500/20 text-green-400"
|
|
449
|
-
: i % 3 === 1
|
|
450
|
-
? "bg-yellow-500/20 text-yellow-400"
|
|
451
|
-
: "bg-red-500/20 text-red-400"
|
|
452
|
-
}`}
|
|
453
|
-
>
|
|
454
|
-
{i % 3 === 0
|
|
455
|
-
? "Active"
|
|
456
|
-
: i % 3 === 1
|
|
457
|
-
? "Away"
|
|
458
|
-
: "Inactive"}
|
|
459
|
-
</span>
|
|
460
|
-
</td>
|
|
461
|
-
</tr>
|
|
462
|
-
))}
|
|
463
|
-
</tbody>
|
|
464
|
-
</table>
|
|
465
|
-
</div>
|
|
466
|
-
<ScrollBar orientation="horizontal" />
|
|
467
|
-
</ScrollArea>
|
|
468
|
-
</div>
|
|
469
135
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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"
|
|
150
|
+
>
|
|
151
|
+
{col}
|
|
152
|
+
</p>
|
|
153
|
+
)
|
|
154
|
+
)}
|
|
155
|
+
</div>
|
|
156
|
+
{Array.from({ length: 10 }, (_, i) => (
|
|
477
157
|
<div
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
Main Content Area
|
|
497
|
-
</div>
|
|
498
|
-
<div className="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 text-white">
|
|
499
|
-
Sidebar Widget
|
|
500
|
-
</div>
|
|
501
|
-
<div className="absolute bottom-20 left-20 flex h-24 w-[calc(100%-160px)] items-center justify-center rounded-lg border border-gray-400/50 bg-gray-500/30 text-white">
|
|
502
|
-
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>
|
|
503
176
|
</div>
|
|
504
|
-
|
|
177
|
+
))}
|
|
505
178
|
</div>
|
|
506
179
|
<ScrollBar orientation="horizontal" />
|
|
507
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>
|
|
508
184
|
</div>
|
|
509
185
|
</div>
|
|
510
186
|
</div>
|
|
@@ -513,581 +189,283 @@ export const BothDirectionsScroll: Story = {
|
|
|
513
189
|
docs: {
|
|
514
190
|
description: {
|
|
515
191
|
story:
|
|
516
|
-
"
|
|
192
|
+
"Comparison of all three scroll orientations: vertical with different height constraints, horizontal with a tag strip, and bidirectional with a wide data table.",
|
|
517
193
|
},
|
|
518
194
|
},
|
|
519
195
|
},
|
|
520
196
|
}
|
|
521
197
|
|
|
522
|
-
//
|
|
523
|
-
export const DifferentSizes: Story = {
|
|
524
|
-
render: () => (
|
|
525
|
-
<div className="space-y-8">
|
|
526
|
-
<div className="text-center">
|
|
527
|
-
<h3 className="mb-2 font-medium text-white">Different Sizes</h3>
|
|
528
|
-
<p className="text-sm text-white/60">
|
|
529
|
-
ScrollArea components in various sizes and configurations
|
|
530
|
-
</p>
|
|
531
|
-
</div>
|
|
198
|
+
// ─── 2. UseCases ──────────────────────────────────────────────────────────────
|
|
532
199
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
<h5 className="mb-2 text-sm font-medium text-white">
|
|
540
|
-
Quick Notes
|
|
541
|
-
</h5>
|
|
542
|
-
<div className="space-y-2 text-xs text-white/70">
|
|
543
|
-
{Array.from({ length: 15 }, (_, i) => (
|
|
544
|
-
<div key={i} className="rounded bg-white/5 p-2">
|
|
545
|
-
Note item {i + 1}: This is a quick note or reminder item.
|
|
546
|
-
</div>
|
|
547
|
-
))}
|
|
548
|
-
</div>
|
|
549
|
-
</div>
|
|
550
|
-
</ScrollArea>
|
|
551
|
-
</div>
|
|
552
|
-
|
|
553
|
-
{/* Medium */}
|
|
554
|
-
<div className="space-y-2">
|
|
555
|
-
<h4 className="text-sm font-medium text-white/80">Medium (h-64)</h4>
|
|
556
|
-
<ScrollArea className="h-64 w-full rounded-lg border border-white/10 bg-white/5">
|
|
557
|
-
<div className="p-4">
|
|
558
|
-
<h5 className="mb-3 text-sm font-medium text-white">Task List</h5>
|
|
559
|
-
<div className="space-y-3">
|
|
560
|
-
{Array.from({ length: 12 }, (_, i) => (
|
|
561
|
-
<div
|
|
562
|
-
key={i}
|
|
563
|
-
className="flex items-center gap-3 rounded-lg bg-white/5 p-3"
|
|
564
|
-
>
|
|
565
|
-
<div
|
|
566
|
-
className={`h-3 w-3 rounded-full ${
|
|
567
|
-
i % 3 === 0 ? "bg-green-500" : "bg-gray-500"
|
|
568
|
-
}`}
|
|
569
|
-
></div>
|
|
570
|
-
<div>
|
|
571
|
-
<div className="text-sm text-white">Task {i + 1}</div>
|
|
572
|
-
<div className="text-xs text-white/60">
|
|
573
|
-
{i % 3 === 0 ? "Completed" : "Pending"}
|
|
574
|
-
</div>
|
|
575
|
-
</div>
|
|
576
|
-
</div>
|
|
577
|
-
))}
|
|
578
|
-
</div>
|
|
579
|
-
</div>
|
|
580
|
-
</ScrollArea>
|
|
581
|
-
</div>
|
|
582
|
-
|
|
583
|
-
{/* Large */}
|
|
584
|
-
<div className="space-y-2">
|
|
585
|
-
<h4 className="text-sm font-medium text-white/80">Large (h-96)</h4>
|
|
586
|
-
<ScrollArea className="h-96 w-full rounded-lg border border-white/10 bg-white/5">
|
|
587
|
-
<div className="p-4">
|
|
588
|
-
<h5 className="mb-4 text-sm font-medium text-white">
|
|
589
|
-
Activity Feed
|
|
590
|
-
</h5>
|
|
591
|
-
<div className="space-y-4">
|
|
592
|
-
{Array.from({ length: 20 }, (_, i) => (
|
|
593
|
-
<div key={i} className="flex gap-3 rounded-lg bg-white/5 p-3">
|
|
594
|
-
<div className="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 text-white">
|
|
595
|
-
{String.fromCharCode(65 + (i % 26))}
|
|
596
|
-
</div>
|
|
597
|
-
<div className="flex-1">
|
|
598
|
-
<div className="text-sm text-white">
|
|
599
|
-
User {i + 1} performed an action
|
|
600
|
-
</div>
|
|
601
|
-
<div className="text-xs text-white/60">
|
|
602
|
-
{Math.floor(Math.random() * 60)} minutes ago
|
|
603
|
-
</div>
|
|
604
|
-
</div>
|
|
605
|
-
</div>
|
|
606
|
-
))}
|
|
607
|
-
</div>
|
|
608
|
-
</div>
|
|
609
|
-
</ScrollArea>
|
|
610
|
-
</div>
|
|
611
|
-
</div>
|
|
612
|
-
</div>
|
|
613
|
-
),
|
|
614
|
-
parameters: {
|
|
615
|
-
docs: {
|
|
616
|
-
description: {
|
|
617
|
-
story:
|
|
618
|
-
"ScrollArea components in different sizes from small notification lists to large activity feeds.",
|
|
619
|
-
},
|
|
620
|
-
},
|
|
200
|
+
const tracks = [
|
|
201
|
+
{
|
|
202
|
+
title: "Neon Pulse",
|
|
203
|
+
artist: "Synthwave Collective",
|
|
204
|
+
duration: "3:42",
|
|
205
|
+
plays: "4.1M",
|
|
621
206
|
},
|
|
622
|
-
|
|
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
|
+
]
|
|
623
355
|
|
|
624
|
-
|
|
625
|
-
export const RealWorldExamples: Story = {
|
|
356
|
+
export const UseCases: Story = {
|
|
626
357
|
render: () => (
|
|
627
|
-
<div className="space-y-8">
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
<
|
|
631
|
-
|
|
632
|
-
</
|
|
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>
|
|
633
397
|
</div>
|
|
634
398
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
<
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
time: "10:32",
|
|
653
|
-
self: true,
|
|
654
|
-
},
|
|
655
|
-
{
|
|
656
|
-
user: "Bob",
|
|
657
|
-
message: "That's awesome! Can't wait to try it out.",
|
|
658
|
-
time: "10:33",
|
|
659
|
-
self: false,
|
|
660
|
-
},
|
|
661
|
-
{
|
|
662
|
-
user: "Alice",
|
|
663
|
-
message: "Same here! Are there any examples we can look at?",
|
|
664
|
-
time: "10:35",
|
|
665
|
-
self: false,
|
|
666
|
-
},
|
|
667
|
-
{
|
|
668
|
-
user: "You",
|
|
669
|
-
message:
|
|
670
|
-
"Yes! I've created a Storybook with all the components and examples.",
|
|
671
|
-
time: "10:36",
|
|
672
|
-
self: true,
|
|
673
|
-
},
|
|
674
|
-
{
|
|
675
|
-
user: "Carol",
|
|
676
|
-
message:
|
|
677
|
-
"Perfect timing! I was just about to ask about documentation.",
|
|
678
|
-
time: "10:38",
|
|
679
|
-
self: false,
|
|
680
|
-
},
|
|
681
|
-
{
|
|
682
|
-
user: "Bob",
|
|
683
|
-
message: "The dark theme looks really good btw 👍",
|
|
684
|
-
time: "10:40",
|
|
685
|
-
self: false,
|
|
686
|
-
},
|
|
687
|
-
{
|
|
688
|
-
user: "You",
|
|
689
|
-
message:
|
|
690
|
-
"Thanks! We spent a lot of time getting the frosted glass effects right.",
|
|
691
|
-
time: "10:41",
|
|
692
|
-
self: true,
|
|
693
|
-
},
|
|
694
|
-
{
|
|
695
|
-
user: "Alice",
|
|
696
|
-
message:
|
|
697
|
-
"It really shows! The attention to detail is impressive.",
|
|
698
|
-
time: "10:43",
|
|
699
|
-
self: false,
|
|
700
|
-
},
|
|
701
|
-
{
|
|
702
|
-
user: "Carol",
|
|
703
|
-
message: "Should we schedule a demo session for the team?",
|
|
704
|
-
time: "10:45",
|
|
705
|
-
self: false,
|
|
706
|
-
},
|
|
707
|
-
{
|
|
708
|
-
user: "You",
|
|
709
|
-
message: "Great idea! How about tomorrow at 2 PM?",
|
|
710
|
-
time: "10:46",
|
|
711
|
-
self: true,
|
|
712
|
-
},
|
|
713
|
-
{
|
|
714
|
-
user: "Bob",
|
|
715
|
-
message: "Works for me! I'll send out calendar invites.",
|
|
716
|
-
time: "10:47",
|
|
717
|
-
self: false,
|
|
718
|
-
},
|
|
719
|
-
].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>
|
|
720
416
|
<div
|
|
721
|
-
|
|
722
|
-
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`}
|
|
723
418
|
>
|
|
724
419
|
<div
|
|
725
|
-
className={`
|
|
420
|
+
className={`rounded-2xl px-3 py-2 ${
|
|
726
421
|
msg.self
|
|
727
|
-
? "bg-
|
|
728
|
-
: "bg-
|
|
422
|
+
? "bg-fm-surface-info-sec"
|
|
423
|
+
: "bg-fm-surface-primary border-fm-divider-secondary border"
|
|
729
424
|
}`}
|
|
730
425
|
>
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
</div>
|
|
735
|
-
)}
|
|
736
|
-
<div className="text-sm">{msg.message}</div>
|
|
737
|
-
<div
|
|
738
|
-
className={`mt-1 text-xs ${
|
|
739
|
-
msg.self ? "text-blue-100" : "text-white/60"
|
|
740
|
-
}`}
|
|
741
|
-
>
|
|
742
|
-
{msg.time}
|
|
743
|
-
</div>
|
|
426
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
427
|
+
{msg.text}
|
|
428
|
+
</p>
|
|
744
429
|
</div>
|
|
430
|
+
<p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm px-1">
|
|
431
|
+
{msg.time}
|
|
432
|
+
</p>
|
|
745
433
|
</div>
|
|
746
|
-
))}
|
|
747
|
-
</div>
|
|
748
|
-
</ScrollArea>
|
|
749
|
-
</div>
|
|
750
|
-
|
|
751
|
-
{/* File Explorer */}
|
|
752
|
-
<div className="space-y-2">
|
|
753
|
-
<h4 className="text-sm font-medium text-white/80">File Explorer</h4>
|
|
754
|
-
<ScrollArea className="h-80 w-full rounded-lg border border-white/10 bg-white/5">
|
|
755
|
-
<div className="text-fm-primary p-2">
|
|
756
|
-
{[
|
|
757
|
-
{
|
|
758
|
-
name: "📁 Documents",
|
|
759
|
-
type: "folder",
|
|
760
|
-
size: "",
|
|
761
|
-
modified: "Today",
|
|
762
|
-
},
|
|
763
|
-
{
|
|
764
|
-
name: "📁 Images",
|
|
765
|
-
type: "folder",
|
|
766
|
-
size: "",
|
|
767
|
-
modified: "Yesterday",
|
|
768
|
-
},
|
|
769
|
-
{
|
|
770
|
-
name: "📁 Projects",
|
|
771
|
-
type: "folder",
|
|
772
|
-
size: "",
|
|
773
|
-
modified: "2 days ago",
|
|
774
|
-
},
|
|
775
|
-
{
|
|
776
|
-
name: "📄 README.md",
|
|
777
|
-
type: "file",
|
|
778
|
-
size: "2.1 KB",
|
|
779
|
-
modified: "Today",
|
|
780
|
-
},
|
|
781
|
-
{
|
|
782
|
-
name: "📄 package.json",
|
|
783
|
-
type: "file",
|
|
784
|
-
size: "1.8 KB",
|
|
785
|
-
modified: "Today",
|
|
786
|
-
},
|
|
787
|
-
{
|
|
788
|
-
name: "🖼️ hero-image.jpg",
|
|
789
|
-
type: "file",
|
|
790
|
-
size: "245 KB",
|
|
791
|
-
modified: "Yesterday",
|
|
792
|
-
},
|
|
793
|
-
{
|
|
794
|
-
name: "📄 index.html",
|
|
795
|
-
type: "file",
|
|
796
|
-
size: "3.2 KB",
|
|
797
|
-
modified: "2 days ago",
|
|
798
|
-
},
|
|
799
|
-
{
|
|
800
|
-
name: "🎨 styles.css",
|
|
801
|
-
type: "file",
|
|
802
|
-
size: "12.5 KB",
|
|
803
|
-
modified: "Today",
|
|
804
|
-
},
|
|
805
|
-
{
|
|
806
|
-
name: "⚡ app.js",
|
|
807
|
-
type: "file",
|
|
808
|
-
size: "8.7 KB",
|
|
809
|
-
modified: "Today",
|
|
810
|
-
},
|
|
811
|
-
{
|
|
812
|
-
name: "📄 config.json",
|
|
813
|
-
type: "file",
|
|
814
|
-
size: "892 B",
|
|
815
|
-
modified: "3 days ago",
|
|
816
|
-
},
|
|
817
|
-
{
|
|
818
|
-
name: "🖼️ logo.svg",
|
|
819
|
-
type: "file",
|
|
820
|
-
size: "3.4 KB",
|
|
821
|
-
modified: "Yesterday",
|
|
822
|
-
},
|
|
823
|
-
{
|
|
824
|
-
name: "📄 .gitignore",
|
|
825
|
-
type: "file",
|
|
826
|
-
size: "156 B",
|
|
827
|
-
modified: "5 days ago",
|
|
828
|
-
},
|
|
829
|
-
{
|
|
830
|
-
name: "📁 node_modules",
|
|
831
|
-
type: "folder",
|
|
832
|
-
size: "",
|
|
833
|
-
modified: "Today",
|
|
834
|
-
},
|
|
835
|
-
{
|
|
836
|
-
name: "📄 tsconfig.json",
|
|
837
|
-
type: "file",
|
|
838
|
-
size: "654 B",
|
|
839
|
-
modified: "Yesterday",
|
|
840
|
-
},
|
|
841
|
-
{
|
|
842
|
-
name: "🔧 webpack.config.js",
|
|
843
|
-
type: "file",
|
|
844
|
-
size: "2.9 KB",
|
|
845
|
-
modified: "3 days ago",
|
|
846
|
-
},
|
|
847
|
-
].map((item, i) => (
|
|
848
|
-
<div
|
|
849
|
-
key={i}
|
|
850
|
-
className="flex cursor-pointer items-center justify-between rounded p-2 hover:bg-white/10"
|
|
851
|
-
>
|
|
852
|
-
<div className="flex min-w-0 flex-1 items-center gap-2">
|
|
853
|
-
<span className="text-sm">{item.name}</span>
|
|
854
|
-
</div>
|
|
855
|
-
<div className="flex items-center gap-4 text-xs text-white/60">
|
|
856
|
-
<span className="w-12 text-right">{item.size}</span>
|
|
857
|
-
<span className="w-20 text-right">{item.modified}</span>
|
|
858
|
-
</div>
|
|
859
|
-
</div>
|
|
860
|
-
))}
|
|
861
|
-
</div>
|
|
862
|
-
</ScrollArea>
|
|
863
|
-
</div>
|
|
864
|
-
|
|
865
|
-
{/* Code Editor Sidebar */}
|
|
866
|
-
<div className="space-y-2">
|
|
867
|
-
<h4 className="text-sm font-medium text-white/80">
|
|
868
|
-
Code Editor Sidebar
|
|
869
|
-
</h4>
|
|
870
|
-
<ScrollArea className="h-80 w-full rounded-lg border border-white/10 bg-white/5">
|
|
871
|
-
<div className="p-2">
|
|
872
|
-
<div className="space-y-1">
|
|
873
|
-
<div className="p-2 text-xs font-medium tracking-wide text-white/80 uppercase">
|
|
874
|
-
Explorer
|
|
875
|
-
</div>
|
|
876
|
-
{[
|
|
877
|
-
{ name: "src", level: 0, type: "folder", expanded: true },
|
|
878
|
-
{
|
|
879
|
-
name: "components",
|
|
880
|
-
level: 1,
|
|
881
|
-
type: "folder",
|
|
882
|
-
expanded: true,
|
|
883
|
-
},
|
|
884
|
-
{ name: "Button.tsx", level: 2, type: "file" },
|
|
885
|
-
{ name: "Button.stories.tsx", level: 2, type: "file" },
|
|
886
|
-
{ name: "Avatar.tsx", level: 2, type: "file" },
|
|
887
|
-
{ name: "Avatar.stories.tsx", level: 2, type: "file" },
|
|
888
|
-
{ name: "ScrollArea.tsx", level: 2, type: "file" },
|
|
889
|
-
{ name: "hooks", level: 1, type: "folder", expanded: false },
|
|
890
|
-
{ name: "utils", level: 1, type: "folder", expanded: true },
|
|
891
|
-
{ name: "cn.ts", level: 2, type: "file" },
|
|
892
|
-
{ name: "types.ts", level: 2, type: "file" },
|
|
893
|
-
{ name: "index.ts", level: 1, type: "file" },
|
|
894
|
-
{ name: "App.tsx", level: 1, type: "file" },
|
|
895
|
-
{ name: "public", level: 0, type: "folder", expanded: false },
|
|
896
|
-
{ name: "package.json", level: 0, type: "file" },
|
|
897
|
-
{ name: "tsconfig.json", level: 0, type: "file" },
|
|
898
|
-
{ name: "tailwind.config.js", level: 0, type: "file" },
|
|
899
|
-
{ name: "vite.config.ts", level: 0, type: "file" },
|
|
900
|
-
].map((item, i) => (
|
|
901
|
-
<div
|
|
902
|
-
key={i}
|
|
903
|
-
className="flex cursor-pointer items-center gap-1 rounded p-1 text-sm hover:bg-white/10"
|
|
904
|
-
style={{ paddingLeft: `${8 + item.level * 16}px` }}
|
|
905
|
-
>
|
|
906
|
-
{item.type === "folder" && (
|
|
907
|
-
<span className="text-white/60">
|
|
908
|
-
{item.expanded ? "📂" : "📁"}
|
|
909
|
-
</span>
|
|
910
|
-
)}
|
|
911
|
-
{item.type === "file" && (
|
|
912
|
-
<span className="text-white/60">📄</span>
|
|
913
|
-
)}
|
|
914
|
-
<span className="text-white/90">{item.name}</span>
|
|
915
|
-
</div>
|
|
916
|
-
))}
|
|
917
434
|
</div>
|
|
918
|
-
|
|
919
|
-
</ScrollArea>
|
|
920
|
-
</div>
|
|
921
|
-
|
|
922
|
-
{/* Settings Panel */}
|
|
923
|
-
<div className="space-y-2">
|
|
924
|
-
<h4 className="text-sm font-medium text-white/80">Settings Panel</h4>
|
|
925
|
-
<ScrollArea className="h-80 w-full rounded-lg border border-white/10 bg-white/5">
|
|
926
|
-
<div className="space-y-6 p-4">
|
|
927
|
-
{[
|
|
928
|
-
{
|
|
929
|
-
section: "Appearance",
|
|
930
|
-
settings: [
|
|
931
|
-
{ label: "Theme", value: "Dark", type: "select" },
|
|
932
|
-
{ label: "Font Size", value: "Medium", type: "select" },
|
|
933
|
-
{ label: "Animations", value: true, type: "toggle" },
|
|
934
|
-
],
|
|
935
|
-
},
|
|
936
|
-
{
|
|
937
|
-
section: "Behavior",
|
|
938
|
-
settings: [
|
|
939
|
-
{ label: "Auto Save", value: true, type: "toggle" },
|
|
940
|
-
{
|
|
941
|
-
label: "Smart Suggestions",
|
|
942
|
-
value: false,
|
|
943
|
-
type: "toggle",
|
|
944
|
-
},
|
|
945
|
-
{
|
|
946
|
-
label: "Keyboard Shortcuts",
|
|
947
|
-
value: true,
|
|
948
|
-
type: "toggle",
|
|
949
|
-
},
|
|
950
|
-
],
|
|
951
|
-
},
|
|
952
|
-
{
|
|
953
|
-
section: "Privacy",
|
|
954
|
-
settings: [
|
|
955
|
-
{ label: "Analytics", value: false, type: "toggle" },
|
|
956
|
-
{ label: "Crash Reports", value: true, type: "toggle" },
|
|
957
|
-
{ label: "Usage Data", value: false, type: "toggle" },
|
|
958
|
-
],
|
|
959
|
-
},
|
|
960
|
-
{
|
|
961
|
-
section: "Advanced",
|
|
962
|
-
settings: [
|
|
963
|
-
{ label: "Developer Mode", value: false, type: "toggle" },
|
|
964
|
-
{
|
|
965
|
-
label: "Experimental Features",
|
|
966
|
-
value: false,
|
|
967
|
-
type: "toggle",
|
|
968
|
-
},
|
|
969
|
-
{ label: "Debug Logging", value: false, type: "toggle" },
|
|
970
|
-
],
|
|
971
|
-
},
|
|
972
|
-
].map((group, i) => (
|
|
973
|
-
<div key={i}>
|
|
974
|
-
<h5 className="mb-3 text-sm font-medium text-white">
|
|
975
|
-
{group.section}
|
|
976
|
-
</h5>
|
|
977
|
-
<div className="space-y-3">
|
|
978
|
-
{group.settings.map((setting, j) => (
|
|
979
|
-
<div
|
|
980
|
-
key={j}
|
|
981
|
-
className="flex items-center justify-between"
|
|
982
|
-
>
|
|
983
|
-
<span className="text-sm text-white/80">
|
|
984
|
-
{setting.label}
|
|
985
|
-
</span>
|
|
986
|
-
{setting.type === "toggle" ? (
|
|
987
|
-
<div
|
|
988
|
-
className={`h-5 w-10 rounded-full p-1 ${
|
|
989
|
-
setting.value ? "bg-blue-500" : "bg-gray-600"
|
|
990
|
-
}`}
|
|
991
|
-
>
|
|
992
|
-
<div
|
|
993
|
-
className={`h-3 w-3 rounded-full bg-white transition-transform ${
|
|
994
|
-
setting.value
|
|
995
|
-
? "translate-x-5"
|
|
996
|
-
: "translate-x-0"
|
|
997
|
-
}`}
|
|
998
|
-
></div>
|
|
999
|
-
</div>
|
|
1000
|
-
) : (
|
|
1001
|
-
<span className="text-sm text-white/60">
|
|
1002
|
-
{setting.value}
|
|
1003
|
-
</span>
|
|
1004
|
-
)}
|
|
1005
|
-
</div>
|
|
1006
|
-
))}
|
|
1007
|
-
</div>
|
|
1008
|
-
</div>
|
|
1009
|
-
))}
|
|
1010
|
-
</div>
|
|
1011
|
-
</ScrollArea>
|
|
1012
|
-
</div>
|
|
1013
|
-
</div>
|
|
1014
|
-
</div>
|
|
1015
|
-
),
|
|
1016
|
-
parameters: {
|
|
1017
|
-
docs: {
|
|
1018
|
-
description: {
|
|
1019
|
-
story:
|
|
1020
|
-
"Real-world examples including chat interfaces, file explorers, code editor sidebars, and settings panels demonstrating practical ScrollArea usage.",
|
|
1021
|
-
},
|
|
1022
|
-
},
|
|
1023
|
-
},
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
// 6. Performance Example
|
|
1027
|
-
export const PerformanceExample: Story = {
|
|
1028
|
-
render: () => (
|
|
1029
|
-
<div className="space-y-8">
|
|
1030
|
-
<div className="text-center">
|
|
1031
|
-
<h3 className="mb-2 font-medium text-white">Performance Example</h3>
|
|
1032
|
-
<p className="text-sm text-white/60">
|
|
1033
|
-
Large datasets handled efficiently with virtual scrolling simulation
|
|
1034
|
-
</p>
|
|
1035
|
-
</div>
|
|
1036
|
-
|
|
1037
|
-
<div className="space-y-4">
|
|
1038
|
-
<div className="text-center">
|
|
1039
|
-
<div className="inline-block rounded-lg border border-white/10 bg-white/5 p-4">
|
|
1040
|
-
<h4 className="mb-2 text-sm font-medium text-white">
|
|
1041
|
-
Large Dataset
|
|
1042
|
-
</h4>
|
|
1043
|
-
<p className="text-xs leading-relaxed text-white/60">
|
|
1044
|
-
This example shows 1000+ items in a scrollable area. The
|
|
1045
|
-
ScrollArea component handles smooth scrolling even with large
|
|
1046
|
-
amounts of content.
|
|
1047
|
-
</p>
|
|
435
|
+
))}
|
|
1048
436
|
</div>
|
|
1049
|
-
</
|
|
437
|
+
</ScrollArea>
|
|
438
|
+
</div>
|
|
1050
439
|
|
|
1051
|
-
|
|
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">
|
|
1052
446
|
<div className="p-4">
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
<div
|
|
1059
|
-
|
|
1060
|
-
className="flex items-center justify-between rounded-lg bg-white/5 p-3 transition-colors hover:bg-white/10"
|
|
1061
|
-
>
|
|
1062
|
-
<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) => (
|
|
1063
454
|
<div
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
"bg-blue-500",
|
|
1067
|
-
"bg-green-500",
|
|
1068
|
-
"bg-purple-500",
|
|
1069
|
-
"bg-orange-500",
|
|
1070
|
-
][i % 4]
|
|
1071
|
-
}`}
|
|
455
|
+
key={item}
|
|
456
|
+
className="hover:bg-fm-surface-primary flex items-center justify-between rounded-md px-3 py-2 transition-colors"
|
|
1072
457
|
>
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
<
|
|
1077
|
-
|
|
1078
|
-
</
|
|
1079
|
-
<div className="text-xs text-white/60">
|
|
1080
|
-
Category:{" "}
|
|
1081
|
-
{["Development", "Design", "Marketing", "Sales"][i % 4]}
|
|
1082
|
-
</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>
|
|
1083
464
|
</div>
|
|
1084
|
-
|
|
1085
|
-
<div className="text-xs text-white/60">
|
|
1086
|
-
{new Date(Date.now() - i * 60000).toLocaleTimeString()}
|
|
1087
|
-
</div>
|
|
465
|
+
))}
|
|
1088
466
|
</div>
|
|
1089
|
-
|
|
1090
|
-
|
|
467
|
+
</div>
|
|
468
|
+
))}
|
|
1091
469
|
</div>
|
|
1092
470
|
</ScrollArea>
|
|
1093
471
|
</div>
|
|
@@ -1097,7 +475,7 @@ export const PerformanceExample: Story = {
|
|
|
1097
475
|
docs: {
|
|
1098
476
|
description: {
|
|
1099
477
|
story:
|
|
1100
|
-
"
|
|
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.",
|
|
1101
479
|
},
|
|
1102
480
|
},
|
|
1103
481
|
},
|