aural-ui 3.0.7 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1199
  2. package/dist/components/avatar/Avatar.stories.tsx +235 -237
  3. package/dist/components/badge/Badge.stories.tsx +379 -116
  4. package/dist/components/banner/Banner.stories.tsx +445 -391
  5. package/dist/components/breadcrumb/Breadcrumb.stories.tsx +453 -199
  6. package/dist/components/button/Button.stories.tsx +585 -230
  7. package/dist/components/button/index.tsx +7 -7
  8. package/dist/components/card/Card.stories.tsx +619 -301
  9. package/dist/components/char-count/CharCount.stories.tsx +350 -248
  10. package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
  11. package/dist/components/chip/Chip.stories.tsx +362 -168
  12. package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -620
  13. package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
  14. package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
  15. package/dist/components/command/Command.stories.tsx +533 -856
  16. package/dist/components/dialog/Dialog.stories.tsx +505 -949
  17. package/dist/components/divider/Divider.stories.tsx +265 -502
  18. package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
  19. package/dist/components/drawer/Drawer.stories.tsx +659 -993
  20. package/dist/components/drawer/index.tsx +3 -3
  21. package/dist/components/dropdown/Dropdown.stories.tsx +643 -1018
  22. package/dist/components/form/Form.stories.tsx +560 -274
  23. package/dist/components/helper-text/HelperText.stories.tsx +199 -200
  24. package/dist/components/hover-card/HoverCard.stories.tsx +318 -1221
  25. package/dist/components/icon-button/IconButton.stories.tsx +837 -194
  26. package/dist/components/if-else/if-else.stories.tsx +370 -83
  27. package/dist/components/input/Input.stories.tsx +436 -368
  28. package/dist/components/label/Label.stories.tsx +156 -154
  29. package/dist/components/list/List.stories.tsx +485 -822
  30. package/dist/components/marquee/Marquee.stories.tsx +356 -694
  31. package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -410
  32. package/dist/components/overlay/Overlay.stories.tsx +452 -818
  33. package/dist/components/overlay/index.tsx +4 -4
  34. package/dist/components/pagination/Pagination.stories.tsx +721 -210
  35. package/dist/components/popover/Popover.stories.tsx +484 -873
  36. package/dist/components/radio/Radio.stories.tsx +432 -124
  37. package/dist/components/resizable/Resizable.stories.tsx +496 -752
  38. package/dist/components/scroll-area/ScrollArea.stories.tsx +384 -1006
  39. package/dist/components/search/Search.stories.tsx +314 -575
  40. package/dist/components/select/Select.stories.tsx +684 -787
  41. package/dist/components/sheet/Sheet.stories.tsx +671 -936
  42. package/dist/components/skelton/Skelton.stories.tsx +230 -764
  43. package/dist/components/slider/Slider.stories.tsx +384 -737
  44. package/dist/components/stepper/Stepper.stories.tsx +371 -514
  45. package/dist/components/switch/Switch.stories.tsx +461 -208
  46. package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
  47. package/dist/components/table/Table.stories.tsx +770 -914
  48. package/dist/components/tabs/Tabs.stories.tsx +459 -1400
  49. package/dist/components/tag/Tag.stories.tsx +714 -542
  50. package/dist/components/textarea/TextArea.stories.tsx +621 -562
  51. package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -148
  52. package/dist/components/toast/Toast.stories.tsx +452 -1333
  53. package/dist/components/toggle/Toggle.stories.tsx +488 -909
  54. package/dist/components/tooltip/Tooltip.stories.tsx +344 -1372
  55. package/dist/components/typography/Typography.stories.tsx +406 -89
  56. package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
  57. package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
  58. package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
  59. package/dist/icons/Icons.stories.tsx +0 -12
  60. package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +226 -1013
  61. package/dist/icons/alert-icon/AlertIcon.stories.tsx +109 -929
  62. package/dist/icons/all-icons.tsx +124 -87
  63. package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +140 -971
  64. package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +148 -888
  65. package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +135 -1019
  66. package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +137 -953
  67. package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +138 -997
  68. package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +136 -942
  69. package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +148 -1092
  70. package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +146 -1211
  71. package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +126 -615
  72. package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +144 -1164
  73. package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +167 -985
  74. package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +122 -1179
  75. package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +124 -1168
  76. package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +119 -850
  77. package/dist/icons/camera-icon/CameraIcon.stories.tsx +112 -1213
  78. package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +117 -934
  79. package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +160 -961
  80. package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +163 -961
  81. package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +144 -942
  82. package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +129 -966
  83. package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +147 -964
  84. package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +145 -975
  85. package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +150 -1142
  86. package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +114 -461
  87. package/dist/icons/coin-icon/CoinIcon.stories.tsx +124 -1322
  88. package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +117 -1318
  89. package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +114 -903
  90. package/dist/icons/command-icon/CommandIcon.stories.tsx +127 -1042
  91. package/dist/icons/copy-icon/CopyIcon.stories.tsx +123 -962
  92. package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +147 -999
  93. package/dist/icons/cross-icon/CrossIcon.stories.tsx +139 -960
  94. package/dist/icons/download-icon/DownloadIcon.stories.tsx +126 -820
  95. package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +124 -1031
  96. package/dist/icons/email-icon/EmailIcon.stories.tsx +115 -936
  97. package/dist/icons/expand-icon/ExpandIcon.stories.tsx +112 -1111
  98. package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +144 -1025
  99. package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +143 -1036
  100. package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +127 -1011
  101. package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +126 -1056
  102. package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +125 -614
  103. package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +119 -1050
  104. package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +169 -989
  105. package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +115 -1145
  106. package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +115 -1122
  107. package/dist/icons/globe-icon/GlobeIcon.stories.tsx +130 -313
  108. package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +145 -940
  109. package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +119 -1174
  110. package/dist/icons/head-icon/HeadIcon.stories.tsx +111 -916
  111. package/dist/icons/heart-icon/HeartIcon.stories.tsx +120 -1019
  112. package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +119 -683
  113. package/dist/icons/image-icon/ImageIcon.stories.tsx +105 -1121
  114. package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +111 -1192
  115. package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +136 -1256
  116. package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +159 -962
  117. package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +161 -1385
  118. package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +124 -972
  119. package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +119 -948
  120. package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +119 -942
  121. package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +108 -1215
  122. package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +154 -1517
  123. package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +110 -1188
  124. package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +119 -678
  125. package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +123 -1184
  126. package/dist/icons/message-icon/MessageIcon.stories.tsx +114 -538
  127. package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +116 -1158
  128. package/dist/icons/moon-icon/MoonIcon.stories.tsx +120 -536
  129. package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +109 -1184
  130. package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +115 -1134
  131. package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +119 -971
  132. package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +111 -1100
  133. package/dist/icons/notes-icon/NotesIcon.stories.tsx +119 -1101
  134. package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +109 -1111
  135. package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +122 -684
  136. package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +113 -954
  137. package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +112 -877
  138. package/dist/icons/pause-icon/PauseIcon.stories.tsx +113 -1000
  139. package/dist/icons/pencil-icon/PencilIcon.stories.tsx +115 -1070
  140. package/dist/icons/phone-icon/PhoneIcon.stories.tsx +115 -978
  141. package/dist/icons/plus-icon/PlusIcon.stories.tsx +106 -1093
  142. package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +107 -829
  143. package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +102 -469
  144. package/dist/icons/search-icon/SearchIcon.stories.tsx +111 -1124
  145. package/dist/icons/setting-icon/SettingIcon.stories.tsx +107 -970
  146. package/dist/icons/share-icon/ShareIcon.stories.tsx +120 -1025
  147. package/dist/icons/shield-icon/ShieldIcon.stories.tsx +117 -931
  148. package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +137 -1104
  149. package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +172 -982
  150. package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +164 -983
  151. package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +105 -958
  152. package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +158 -580
  153. package/dist/icons/spinner-gradient-icon/index.tsx +6 -1
  154. package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +158 -587
  155. package/dist/icons/spinner-solid-icon/index.tsx +6 -1
  156. package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +146 -682
  157. package/dist/icons/spinner-solid-neutral-icon/index.tsx +1 -1
  158. package/dist/icons/star-icon/StarIcon.stories.tsx +124 -904
  159. package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +112 -964
  160. package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +116 -852
  161. package/dist/icons/sun-icon/SunIcon.stories.tsx +120 -831
  162. package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +116 -950
  163. package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +123 -980
  164. package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +156 -1427
  165. package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +146 -1142
  166. package/dist/icons/tick-icon/TickIcon.stories.tsx +145 -1276
  167. package/dist/icons/trash-icon/TrashIcon.stories.tsx +108 -933
  168. package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +157 -1402
  169. package/dist/icons/upload-icon/UploadIcon.stories.tsx +115 -889
  170. package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +118 -984
  171. package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +125 -1049
  172. package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +123 -1356
  173. package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +110 -1171
  174. package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +112 -1093
  175. package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +115 -1087
  176. package/dist/icons/warning-icon/WarningIcon.stories.tsx +122 -1046
  177. package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +161 -936
  178. package/dist/index.cjs +84 -84
  179. package/dist/index.js +84 -84
  180. package/dist/styles/aural-all-theme.css +1222 -0
  181. package/dist/styles/{aural-theme.css → aural-dark-theme.css} +15 -3
  182. package/dist/styles/aural-light-theme.css +1047 -0
  183. package/package.json +1 -1
@@ -1,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
- # ScrollArea Component
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. Basic Vertical Scroll
83
- export const BasicVerticalScroll: Story = {
44
+ // ─── 1. Configurations ────────────────────────────────────────────────────────
45
+
46
+ export const Configurations: Story = {
84
47
  render: () => (
85
48
  <div className="space-y-8">
86
- <div className="text-center">
87
- <h3 className="mb-2 font-medium text-white">Basic Vertical Scroll</h3>
88
- <p className="text-sm text-white/60">
89
- Standard vertical scrolling with custom styled scrollbar
90
- </p>
91
- </div>
92
-
93
- <div className="flex flex-wrap justify-center gap-8">
94
- {/* Text Content */}
95
- <div className="space-y-2">
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={index}
186
- className="rounded-lg border border-white/10 bg-white/5 p-3"
60
+ key={i}
61
+ className="border-fm-divider-secondary bg-fm-surface-primary rounded-md border px-3 py-2"
187
62
  >
188
- <div className="font-medium text-white">{lang.name}</div>
189
- <div className="text-xs text-white/60">{lang.desc}</div>
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
- </div>
194
- </ScrollArea>
195
- </div>
196
- </div>
197
- </div>
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
- <div className="space-y-6">
221
- {/* Image Gallery */}
222
- <div className="space-y-2">
223
- <h4 className="text-sm font-medium text-white/80">Image Gallery</h4>
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
- className={`h-32 w-48 rounded-lg bg-gradient-to-br ${item.color} flex items-center justify-center font-medium text-white`}
80
+ key={i}
81
+ className="border-fm-divider-secondary bg-fm-surface-primary rounded-md border px-3 py-2"
271
82
  >
272
- {item.name}
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
- <p className="text-center text-xs text-white/60">
275
- {item.name}
276
- </p>
277
- </div>
278
- ))}
279
- </div>
280
- <ScrollBar orientation="horizontal" />
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
- {/* Tag List */}
285
- <div className="space-y-2">
286
- <h4 className="text-sm font-medium text-white/80">Technology Tags</h4>
287
- <ScrollArea className="w-full max-w-2xl rounded-lg border border-white/10 bg-white/5 whitespace-nowrap">
288
- <div className="flex w-max gap-2 p-4">
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
- "React",
291
- "Vue.js",
292
- "Angular",
293
- "Svelte",
294
- "Next.js",
295
- "Nuxt.js",
296
- "Gatsby",
297
- "TypeScript",
298
- "JavaScript",
299
- "Node.js",
300
- "Express",
301
- "Fastify",
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={index}
318
- className="flex-none rounded-full border border-blue-500/30 bg-blue-500/20 px-3 py-1 text-xs text-blue-300"
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
- {tag}
321
- </div>
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
- {/* Large Canvas */}
471
- <div className="space-y-2">
472
- <h4 className="text-sm font-medium text-white/80">Design Canvas</h4>
473
- <ScrollArea className="h-96 w-full max-w-2xl rounded-lg border border-white/10 bg-white/5">
474
- <div className="h-[1200px] w-[1500px] bg-gradient-to-br from-blue-900/20 to-purple-900/20 p-4">
475
- <div className="relative h-full w-full">
476
- {/* Grid Pattern */}
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
- className="absolute inset-0 opacity-20"
479
- style={{
480
- backgroundImage: `
481
- linear-gradient(rgba(255,255,255,0.1) 1px, transparent 1px),
482
- linear-gradient(90deg, rgba(255,255,255,0.1) 1px, transparent 1px)
483
- `,
484
- backgroundSize: "50px 50px",
485
- }}
486
- />
487
-
488
- {/* Design Elements */}
489
- <div className="absolute top-20 left-20 flex h-32 w-48 items-center justify-center rounded-lg border border-blue-400/50 bg-blue-500/30 text-white">
490
- Header Component
491
- </div>
492
- <div className="absolute top-60 left-20 flex h-40 w-64 items-center justify-center rounded-lg border border-green-400/50 bg-green-500/30 text-white">
493
- Navigation Menu
494
- </div>
495
- <div className="absolute top-20 left-80 flex h-96 w-80 items-center justify-center rounded-lg border border-purple-400/50 bg-purple-500/30 text-white">
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
- </div>
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
- "Two-dimensional scrolling examples including data tables and design canvases that require both horizontal and vertical scrolling.",
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
- // 4. Different Sizes
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
- <div className="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
534
- {/* Small */}
535
- <div className="space-y-2">
536
- <h4 className="text-sm font-medium text-white/80">Small (h-40)</h4>
537
- <ScrollArea className="h-40 w-full rounded-lg border border-white/10 bg-white/5">
538
- <div className="p-3">
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
- // 5. Real World Examples
625
- export const RealWorldExamples: Story = {
356
+ export const UseCases: Story = {
626
357
  render: () => (
627
- <div className="space-y-8">
628
- <div className="text-center">
629
- <h3 className="mb-2 font-medium text-white">Real World Examples</h3>
630
- <p className="text-sm text-white/60">
631
- Common use cases for scrollable areas in applications
632
- </p>
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
- <div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
636
- {/* Chat Messages */}
637
- <div className="space-y-2">
638
- <h4 className="text-sm font-medium text-white/80">Chat Messages</h4>
639
- <ScrollArea className="h-80 w-full rounded-lg border border-white/10 bg-white/5">
640
- <div className="space-y-4 p-4">
641
- {[
642
- {
643
- user: "Alice",
644
- message: "Hey everyone! How's the project going?",
645
- time: "10:30",
646
- self: false,
647
- },
648
- {
649
- user: "You",
650
- message:
651
- "Going well! Just finished the new component library.",
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
- key={i}
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={`max-w-xs rounded-lg p-3 ${
420
+ className={`rounded-2xl px-3 py-2 ${
726
421
  msg.self
727
- ? "bg-blue-500 text-white"
728
- : "bg-white/10 text-white"
422
+ ? "bg-fm-surface-info-sec"
423
+ : "bg-fm-surface-primary border-fm-divider-secondary border"
729
424
  }`}
730
425
  >
731
- {!msg.self && (
732
- <div className="mb-1 text-xs font-medium text-white/80">
733
- {msg.user}
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
- </div>
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
- </div>
437
+ </ScrollArea>
438
+ </div>
1050
439
 
1051
- <ScrollArea className="mx-auto h-96 w-full max-w-2xl rounded-lg border border-white/10 bg-white/5">
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
- <h4 className="mb-4 text-sm leading-none font-medium text-white">
1054
- Large Item List (1000 items)
1055
- </h4>
1056
- <div className="space-y-1">
1057
- {Array.from({ length: 1000 }, (_, i) => (
1058
- <div
1059
- key={i}
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
- className={`flex h-8 w-8 items-center justify-center rounded-full text-xs font-medium text-white ${
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
- {i + 1}
1074
- </div>
1075
- <div>
1076
- <div className="text-sm font-medium text-white">
1077
- Item {i + 1}
1078
- </div>
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
- </div>
1085
- <div className="text-xs text-white/60">
1086
- {new Date(Date.now() - i * 60000).toLocaleTimeString()}
1087
- </div>
465
+ ))}
1088
466
  </div>
1089
- ))}
1090
- </div>
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
- "Performance demonstration with 1000+ items showing how ScrollArea maintains smooth scrolling with large datasets.",
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
  },