aural-ui 4.0.1 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -1
- package/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1228
- package/dist/components/avatar/Avatar.stories.tsx +219 -235
- package/dist/components/badge/Badge.stories.tsx +379 -116
- package/dist/components/banner/Banner.stories.tsx +445 -391
- package/dist/components/breadcrumb/Breadcrumb.stories.tsx +453 -199
- package/dist/components/button/Button.stories.tsx +585 -230
- package/dist/components/card/Card.stories.tsx +619 -301
- package/dist/components/char-count/CharCount.stories.tsx +350 -248
- package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
- package/dist/components/chip/Chip.stories.tsx +362 -168
- package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -636
- package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
- package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
- package/dist/components/command/Command.stories.tsx +530 -867
- package/dist/components/dialog/Dialog.stories.tsx +501 -950
- package/dist/components/divider/Divider.stories.tsx +264 -527
- package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
- package/dist/components/drawer/Drawer.stories.tsx +659 -1023
- package/dist/components/dropdown/Dropdown.stories.tsx +643 -1028
- package/dist/components/form/Form.stories.tsx +560 -274
- package/dist/components/helper-text/HelperText.stories.tsx +199 -200
- package/dist/components/hover-card/HoverCard.stories.tsx +318 -1254
- package/dist/components/icon-button/IconButton.stories.tsx +837 -194
- package/dist/components/if-else/if-else.stories.tsx +370 -83
- package/dist/components/input/Input.stories.tsx +436 -368
- package/dist/components/label/Label.stories.tsx +156 -154
- package/dist/components/list/List.stories.tsx +484 -835
- package/dist/components/marquee/Marquee.stories.tsx +356 -712
- package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -422
- package/dist/components/overlay/Overlay.stories.tsx +452 -824
- package/dist/components/pagination/Pagination.stories.tsx +721 -210
- package/dist/components/popover/Popover.stories.tsx +481 -896
- package/dist/components/radio/Radio.stories.tsx +432 -124
- package/dist/components/resizable/Resizable.stories.tsx +495 -799
- package/dist/components/scroll-area/ScrollArea.stories.tsx +383 -1059
- package/dist/components/search/Search.stories.tsx +312 -595
- package/dist/components/select/Select.stories.tsx +684 -789
- package/dist/components/sheet/Sheet.stories.tsx +671 -950
- package/dist/components/skelton/Skelton.stories.tsx +230 -764
- package/dist/components/slider/Slider.stories.tsx +383 -760
- package/dist/components/stepper/Stepper.stories.tsx +371 -514
- package/dist/components/switch/Switch.stories.tsx +461 -208
- package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
- package/dist/components/table/Table.stories.tsx +770 -916
- package/dist/components/tabs/Tabs.stories.tsx +458 -1455
- package/dist/components/tag/Tag.stories.tsx +714 -542
- package/dist/components/textarea/TextArea.stories.tsx +621 -562
- package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -154
- package/dist/components/toast/Toast.stories.tsx +452 -1339
- package/dist/components/toggle/Toggle.stories.tsx +488 -931
- package/dist/components/tooltip/Tooltip.stories.tsx +344 -1388
- package/dist/components/typography/Typography.stories.tsx +406 -89
- package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
- package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
- package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
- package/dist/icons/Icons.stories.tsx +0 -12
- package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +223 -1060
- package/dist/icons/alert-icon/AlertIcon.stories.tsx +106 -968
- package/dist/icons/all-icons.tsx +37 -16
- package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +137 -1010
- package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +145 -935
- package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +132 -1046
- package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +134 -986
- package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +135 -1028
- package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +133 -971
- package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +145 -1123
- package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +143 -1252
- package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +123 -632
- package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +141 -1223
- package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +164 -1018
- package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +121 -1236
- package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +121 -1213
- package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +116 -893
- package/dist/icons/camera-icon/CameraIcon.stories.tsx +109 -1254
- package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +114 -975
- package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +157 -994
- package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +160 -992
- package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +140 -970
- package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +126 -993
- package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +144 -987
- package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +141 -1007
- package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +147 -1187
- package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +110 -476
- package/dist/icons/coin-icon/CoinIcon.stories.tsx +120 -1364
- package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +113 -1360
- package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +111 -942
- package/dist/icons/command-icon/CommandIcon.stories.tsx +124 -1087
- package/dist/icons/copy-icon/CopyIcon.stories.tsx +119 -996
- package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +144 -1046
- package/dist/icons/cross-icon/CrossIcon.stories.tsx +136 -999
- package/dist/icons/download-icon/DownloadIcon.stories.tsx +123 -857
- package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +121 -1080
- package/dist/icons/email-icon/EmailIcon.stories.tsx +112 -979
- package/dist/icons/expand-icon/ExpandIcon.stories.tsx +109 -1146
- package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +141 -1068
- package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +140 -1081
- package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +124 -1050
- package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +123 -1091
- package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +122 -633
- package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +116 -1087
- package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +166 -1020
- package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +112 -1182
- package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +112 -1155
- package/dist/icons/globe-icon/GlobeIcon.stories.tsx +127 -325
- package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +142 -985
- package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +116 -1217
- package/dist/icons/head-icon/HeadIcon.stories.tsx +108 -953
- package/dist/icons/heart-icon/HeartIcon.stories.tsx +117 -1060
- package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +116 -716
- package/dist/icons/image-icon/ImageIcon.stories.tsx +102 -1164
- package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +108 -1233
- package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +133 -1289
- package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +155 -1012
- package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +158 -1438
- package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +121 -1011
- package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +116 -981
- package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +116 -979
- package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +105 -1252
- package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +151 -1554
- package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +107 -1227
- package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +116 -707
- package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +119 -1226
- package/dist/icons/message-icon/MessageIcon.stories.tsx +111 -557
- package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +112 -1198
- package/dist/icons/moon-icon/MoonIcon.stories.tsx +117 -557
- package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +106 -1235
- package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +112 -1185
- package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +116 -1012
- package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +108 -1137
- package/dist/icons/notes-icon/NotesIcon.stories.tsx +116 -1138
- package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +106 -1146
- package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +119 -719
- package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +110 -999
- package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +109 -912
- package/dist/icons/pause-icon/PauseIcon.stories.tsx +110 -1041
- package/dist/icons/pencil-icon/PencilIcon.stories.tsx +112 -1109
- package/dist/icons/phone-icon/PhoneIcon.stories.tsx +112 -1023
- package/dist/icons/plus-icon/PlusIcon.stories.tsx +103 -1132
- package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +104 -870
- package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +99 -476
- package/dist/icons/search-icon/SearchIcon.stories.tsx +108 -1161
- package/dist/icons/setting-icon/SettingIcon.stories.tsx +104 -1009
- package/dist/icons/share-icon/ShareIcon.stories.tsx +117 -1064
- package/dist/icons/shield-icon/ShieldIcon.stories.tsx +114 -974
- package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +134 -1160
- package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +169 -1017
- package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +161 -1016
- package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +102 -1001
- package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +155 -593
- package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +155 -608
- package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +142 -712
- package/dist/icons/star-icon/StarIcon.stories.tsx +120 -946
- package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +109 -1013
- package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +113 -891
- package/dist/icons/sun-icon/SunIcon.stories.tsx +117 -864
- package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +113 -989
- package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +120 -1027
- package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +153 -1476
- package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +143 -1187
- package/dist/icons/tick-icon/TickIcon.stories.tsx +142 -1322
- package/dist/icons/trash-icon/TrashIcon.stories.tsx +105 -970
- package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +154 -1457
- package/dist/icons/upload-icon/UploadIcon.stories.tsx +112 -930
- package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +115 -1019
- package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +122 -1092
- package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +120 -1401
- package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +107 -1212
- package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +109 -1122
- package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +112 -1124
- package/dist/icons/warning-icon/WarningIcon.stories.tsx +119 -1083
- package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +158 -983
- package/dist/index.cjs +90 -90
- package/dist/index.js +90 -90
- package/package.json +8 -3
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import React from "react"
|
|
2
2
|
import { Badge } from "@components/badge"
|
|
3
3
|
import { Button } from "@components/button"
|
|
4
|
+
import {
|
|
5
|
+
HeartIcon,
|
|
6
|
+
MusicalNoteIcon,
|
|
7
|
+
PauseIcon,
|
|
8
|
+
SkipForwardIcon,
|
|
9
|
+
StarIcon,
|
|
10
|
+
VolumeFullIcon,
|
|
11
|
+
} from "@icons/index"
|
|
4
12
|
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
5
13
|
|
|
14
|
+
import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
|
|
15
|
+
|
|
6
16
|
import {
|
|
7
17
|
Card,
|
|
8
18
|
CardAction,
|
|
@@ -18,107 +28,36 @@ const meta: Meta<typeof Card> = {
|
|
|
18
28
|
component: Card,
|
|
19
29
|
parameters: {
|
|
20
30
|
layout: "centered",
|
|
21
|
-
backgrounds: {
|
|
22
|
-
default: "dark",
|
|
23
|
-
values: [
|
|
24
|
-
{ name: "light", value: "#ffffff" },
|
|
25
|
-
{ name: "dark", value: "#0a0a0a" },
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
31
|
docs: {
|
|
29
32
|
description: {
|
|
30
|
-
component:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
A flexible and interactive card component that serves as a container for related content. Features hover effects and clean styling perfect for displaying information in an organized, visually appealing way.
|
|
34
|
-
|
|
35
|
-
## Features
|
|
36
|
-
|
|
37
|
-
- **Interactive Design**: Hover gradient effects for better user engagement
|
|
38
|
-
- **Flexible Layout**: Column-based flex layout with customizable gap spacing
|
|
39
|
-
- **Clean Styling**: Neutral color scheme with subtle shadows
|
|
40
|
-
- **Responsive**: Works well across different screen sizes
|
|
41
|
-
- **Accessible**: Proper cursor states and semantic structure
|
|
42
|
-
- **Customizable**: Easy to extend with additional CSS classes
|
|
43
|
-
- **Bordered Design**: Clean borders with rounded corners
|
|
44
|
-
|
|
45
|
-
## Usage Examples
|
|
46
|
-
|
|
47
|
-
### Basic Card
|
|
48
|
-
\`\`\`tsx
|
|
49
|
-
<Card>
|
|
50
|
-
<p>Simple card content</p>
|
|
51
|
-
</Card>
|
|
52
|
-
\`\`\`
|
|
53
|
-
|
|
54
|
-
### Card with Header and Content
|
|
55
|
-
\`\`\`tsx
|
|
56
|
-
<Card className="w-96">
|
|
57
|
-
<CardHeader>
|
|
58
|
-
<CardTitle>Card Title</CardTitle>
|
|
59
|
-
<CardDescription>Card description</CardDescription>
|
|
60
|
-
</CardHeader>
|
|
61
|
-
<CardContent>Content goes here</CardContent>
|
|
62
|
-
</Card>
|
|
63
|
-
\`\`\`
|
|
64
|
-
|
|
65
|
-
### Card with Custom Width
|
|
66
|
-
\`\`\`tsx
|
|
67
|
-
<Card className="w-80 max-w-sm">
|
|
68
|
-
<div className="space-y-2">
|
|
69
|
-
<h3 className="font-semibold">Custom Card</h3>
|
|
70
|
-
<p className="text-sm text-gray-600">
|
|
71
|
-
This card has custom width styling
|
|
72
|
-
</p>
|
|
73
|
-
</div>
|
|
74
|
-
</Card>
|
|
75
|
-
\`\`\`
|
|
76
|
-
|
|
77
|
-
### Clickable Card
|
|
78
|
-
\`\`\`tsx
|
|
79
|
-
<Card
|
|
80
|
-
className="w-72 transition-transform hover:scale-105"
|
|
81
|
-
onClick={() => console.log('Card clicked')}
|
|
82
|
-
>
|
|
83
|
-
<div className="p-2">
|
|
84
|
-
<h4 className="font-medium">Clickable Card</h4>
|
|
85
|
-
<p className="text-sm mt-1">Click me for interaction</p>
|
|
86
|
-
</div>
|
|
87
|
-
</Card>
|
|
88
|
-
\`\`\`
|
|
89
|
-
|
|
90
|
-
### Card Grid Layout
|
|
91
|
-
\`\`\`tsx
|
|
92
|
-
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
93
|
-
<Card>
|
|
94
|
-
<CardHeader>
|
|
95
|
-
<CardTitle>Feature 1</CardTitle>
|
|
96
|
-
</CardHeader>
|
|
97
|
-
<CardContent>Description of feature 1</CardContent>
|
|
98
|
-
</Card>
|
|
99
|
-
<Card>
|
|
100
|
-
<CardHeader>
|
|
101
|
-
<CardTitle>Feature 2</CardTitle>
|
|
102
|
-
</CardHeader>
|
|
103
|
-
<CardContent>Description of feature 2</CardContent>
|
|
104
|
-
</Card>
|
|
105
|
-
<Card>
|
|
106
|
-
<CardHeader>
|
|
107
|
-
<CardTitle>Feature 3</CardTitle>
|
|
108
|
-
</CardHeader>
|
|
109
|
-
<CardContent>Description of feature 3</CardContent>
|
|
110
|
-
</Card>
|
|
111
|
-
</div>
|
|
112
|
-
\`\`\`
|
|
113
|
-
`,
|
|
33
|
+
component:
|
|
34
|
+
"A flexible compound-component card for grouping related content. Composed of CardHeader, CardTitle, CardDescription, CardAction, CardContent, and CardFooter — each a distinct slot that can be used independently or combined. Designed for audio app contexts: track listings, artist profiles, playlist previews, and more.",
|
|
114
35
|
},
|
|
36
|
+
page: () => (
|
|
37
|
+
<AuralComponentDocsPage
|
|
38
|
+
features={[
|
|
39
|
+
{
|
|
40
|
+
title: "6 Composable Parts",
|
|
41
|
+
description: "Mix and match slots",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
title: "Action Slot",
|
|
45
|
+
description: "Badge or button in header",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
title: "Flexible Layout",
|
|
49
|
+
description: "Header, content, footer",
|
|
50
|
+
},
|
|
51
|
+
]}
|
|
52
|
+
/>
|
|
53
|
+
),
|
|
115
54
|
},
|
|
116
55
|
},
|
|
117
56
|
tags: ["autodocs"],
|
|
118
57
|
argTypes: {
|
|
119
58
|
className: {
|
|
120
59
|
control: "text",
|
|
121
|
-
description: "Additional CSS classes
|
|
60
|
+
description: "Additional CSS classes applied to the card root",
|
|
122
61
|
},
|
|
123
62
|
},
|
|
124
63
|
}
|
|
@@ -126,252 +65,631 @@ const meta: Meta<typeof Card> = {
|
|
|
126
65
|
export default meta
|
|
127
66
|
type Story = StoryObj<typeof meta>
|
|
128
67
|
|
|
129
|
-
//
|
|
130
|
-
export const Simple: Story = {
|
|
131
|
-
render: () => (
|
|
132
|
-
<Card>
|
|
133
|
-
<CardHeader>
|
|
134
|
-
<CardTitle>Simple Card</CardTitle>
|
|
135
|
-
<CardDescription>
|
|
136
|
-
This is a basic card with header and content.
|
|
137
|
-
</CardDescription>
|
|
138
|
-
</CardHeader>
|
|
139
|
-
<CardContent>
|
|
140
|
-
<p>
|
|
141
|
-
This is the main content area of the card. You can put any content
|
|
142
|
-
here.
|
|
143
|
-
</p>
|
|
144
|
-
</CardContent>
|
|
145
|
-
</Card>
|
|
146
|
-
),
|
|
147
|
-
}
|
|
68
|
+
// ─── 1. Parts ─────────────────────────────────────────────────────────────────
|
|
148
69
|
|
|
149
|
-
export const
|
|
70
|
+
export const Parts: Story = {
|
|
150
71
|
render: () => (
|
|
151
|
-
<
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
<
|
|
155
|
-
|
|
156
|
-
</
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
72
|
+
<div className="mx-auto w-full max-w-2xl space-y-10">
|
|
73
|
+
{/* CardHeader */}
|
|
74
|
+
<div className="space-y-4">
|
|
75
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
76
|
+
CardHeader
|
|
77
|
+
</h4>
|
|
78
|
+
<Card className="w-80">
|
|
79
|
+
<CardHeader>
|
|
80
|
+
<CardTitle>Track Title</CardTitle>
|
|
81
|
+
<CardDescription>Artist · Album · 2024</CardDescription>
|
|
82
|
+
</CardHeader>
|
|
83
|
+
</Card>
|
|
84
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
85
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
86
|
+
<strong className="text-fm-primary">CardHeader</strong> is the top
|
|
87
|
+
zone of the card. It uses a CSS grid that reserves a right column
|
|
88
|
+
when a <code>CardAction</code> is present. Contains{" "}
|
|
89
|
+
<code>CardTitle</code> and <code>CardDescription</code> by
|
|
90
|
+
convention.
|
|
91
|
+
</p>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
168
94
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
<
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
95
|
+
{/* CardTitle */}
|
|
96
|
+
<div className="space-y-4">
|
|
97
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
98
|
+
CardTitle
|
|
99
|
+
</h4>
|
|
100
|
+
<Card className="w-80">
|
|
101
|
+
<CardHeader>
|
|
102
|
+
<CardTitle>Midnight Dreams</CardTitle>
|
|
103
|
+
</CardHeader>
|
|
104
|
+
</Card>
|
|
105
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
106
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
107
|
+
<strong className="text-fm-primary">CardTitle</strong> renders a
|
|
108
|
+
semibold heading with <code>leading-none</code>. It spans the full
|
|
109
|
+
first column of the header grid.
|
|
110
|
+
</p>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
188
113
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
<
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
<div className="
|
|
203
|
-
<
|
|
204
|
-
<
|
|
205
|
-
<
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
<span>Theme</span>
|
|
209
|
-
<span className="text-muted-foreground">Dark</span>
|
|
210
|
-
</div>
|
|
114
|
+
{/* CardDescription */}
|
|
115
|
+
<div className="space-y-4">
|
|
116
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
117
|
+
CardDescription
|
|
118
|
+
</h4>
|
|
119
|
+
<Card className="w-80">
|
|
120
|
+
<CardHeader>
|
|
121
|
+
<CardTitle>Electric Sunrise</CardTitle>
|
|
122
|
+
<CardDescription>
|
|
123
|
+
Neon Collective · Wavelength · 2024
|
|
124
|
+
</CardDescription>
|
|
125
|
+
</CardHeader>
|
|
126
|
+
</Card>
|
|
127
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
128
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
129
|
+
<strong className="text-fm-primary">CardDescription</strong> sits
|
|
130
|
+
beneath the title in the header grid. Uses <code>text-sm</code> —
|
|
131
|
+
inherits the card's primary text color at reduced contrast.
|
|
132
|
+
</p>
|
|
211
133
|
</div>
|
|
212
|
-
</
|
|
213
|
-
</Card>
|
|
214
|
-
),
|
|
215
|
-
}
|
|
134
|
+
</div>
|
|
216
135
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
<
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
136
|
+
{/* CardAction */}
|
|
137
|
+
<div className="space-y-4">
|
|
138
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
139
|
+
CardAction
|
|
140
|
+
</h4>
|
|
141
|
+
<Card className="w-80">
|
|
142
|
+
<CardHeader>
|
|
143
|
+
<CardTitle>Echoes in Rain</CardTitle>
|
|
144
|
+
<CardDescription>Ambient · 3:42</CardDescription>
|
|
145
|
+
<CardAction>
|
|
146
|
+
<Badge
|
|
147
|
+
color="positive"
|
|
148
|
+
className="bg-fm-surface-positive-sec text-fm-positive-sec"
|
|
149
|
+
>
|
|
150
|
+
LIVE
|
|
151
|
+
</Badge>
|
|
152
|
+
</CardAction>
|
|
153
|
+
</CardHeader>
|
|
154
|
+
</Card>
|
|
155
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
156
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
157
|
+
<strong className="text-fm-primary">CardAction</strong> occupies the
|
|
158
|
+
right column of the header grid, spanning both title and description
|
|
159
|
+
rows. Use it for badges, icon buttons, or status indicators.
|
|
160
|
+
</p>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
229
163
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
</
|
|
235
|
-
<
|
|
236
|
-
<
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
164
|
+
{/* CardContent */}
|
|
165
|
+
<div className="space-y-4">
|
|
166
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
167
|
+
CardContent
|
|
168
|
+
</h4>
|
|
169
|
+
<Card className="w-80">
|
|
170
|
+
<CardContent>
|
|
171
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
172
|
+
CardContent is a free-form slot. Place any child content here —
|
|
173
|
+
metadata rows, waveform visualisers, track lists, or stat
|
|
174
|
+
summaries.
|
|
175
|
+
</p>
|
|
176
|
+
</CardContent>
|
|
177
|
+
</Card>
|
|
178
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
179
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
180
|
+
<strong className="text-fm-primary">CardContent</strong> is an
|
|
181
|
+
unstyled passthrough slot. It adds no padding of its own — the
|
|
182
|
+
parent <code>Card</code> gap handles spacing between parts.
|
|
183
|
+
</p>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
{/* CardFooter */}
|
|
188
|
+
<div className="space-y-4">
|
|
189
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
190
|
+
CardFooter
|
|
191
|
+
</h4>
|
|
192
|
+
<Card className="w-80">
|
|
193
|
+
<CardHeader>
|
|
194
|
+
<CardTitle>Neon Horizon</CardTitle>
|
|
195
|
+
<CardDescription>Synthwave · 4:15</CardDescription>
|
|
196
|
+
</CardHeader>
|
|
197
|
+
<CardFooter className="gap-2">
|
|
198
|
+
<Button variant="outline" size="sm" className="flex-1">
|
|
199
|
+
Add to Queue
|
|
200
|
+
</Button>
|
|
201
|
+
<Button size="sm" className="flex-1">
|
|
202
|
+
Play Now
|
|
203
|
+
</Button>
|
|
204
|
+
</CardFooter>
|
|
205
|
+
</Card>
|
|
206
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
207
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
208
|
+
<strong className="text-fm-primary">CardFooter</strong> is a flex
|
|
209
|
+
row at the bottom of the card. Use it for action buttons, metadata,
|
|
210
|
+
or secondary controls. Supports optional <code>border-t</code>{" "}
|
|
211
|
+
separator via class.
|
|
212
|
+
</p>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
242
215
|
</div>
|
|
243
216
|
),
|
|
244
217
|
parameters: {
|
|
245
218
|
layout: "padded",
|
|
219
|
+
docs: {
|
|
220
|
+
description: {
|
|
221
|
+
story:
|
|
222
|
+
"Each sub-component of the Card compound displayed individually with a role explanation. Use this as a reference when composing card layouts.",
|
|
223
|
+
},
|
|
224
|
+
},
|
|
246
225
|
},
|
|
247
226
|
}
|
|
248
227
|
|
|
249
|
-
|
|
228
|
+
// ─── 2. Configurations ────────────────────────────────────────────────────────
|
|
229
|
+
|
|
230
|
+
export const Configurations: Story = {
|
|
250
231
|
render: () => (
|
|
251
|
-
<
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
<
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
232
|
+
<div className="mx-auto w-full max-w-4xl space-y-8">
|
|
233
|
+
{/* Minimal */}
|
|
234
|
+
<div className="space-y-4">
|
|
235
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
236
|
+
Minimal — content only
|
|
237
|
+
</h4>
|
|
238
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
239
|
+
<div className="space-y-2 text-center">
|
|
240
|
+
<Card className="w-72">
|
|
241
|
+
<CardContent>
|
|
242
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
243
|
+
A minimal card with no header or footer — just freeform
|
|
244
|
+
content inside.
|
|
245
|
+
</p>
|
|
246
|
+
</CardContent>
|
|
247
|
+
</Card>
|
|
248
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
249
|
+
Content only
|
|
250
|
+
</p>
|
|
261
251
|
</div>
|
|
262
|
-
</
|
|
263
|
-
</
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
|
|
255
|
+
{/* Header only */}
|
|
256
|
+
<div className="space-y-4">
|
|
257
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
258
|
+
Header only
|
|
259
|
+
</h4>
|
|
260
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
261
|
+
<div className="space-y-2 text-center">
|
|
262
|
+
<Card className="w-72">
|
|
263
|
+
<CardHeader>
|
|
264
|
+
<CardTitle>Track Title</CardTitle>
|
|
265
|
+
<CardDescription>Artist · 3:24</CardDescription>
|
|
266
|
+
</CardHeader>
|
|
267
|
+
</Card>
|
|
268
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
269
|
+
Title + description
|
|
270
|
+
</p>
|
|
268
271
|
</div>
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
|
|
275
|
+
{/* With footer */}
|
|
276
|
+
<div className="space-y-4">
|
|
277
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
278
|
+
With footer
|
|
279
|
+
</h4>
|
|
280
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
281
|
+
<div className="space-y-2 text-center">
|
|
282
|
+
<Card className="w-72">
|
|
283
|
+
<CardHeader>
|
|
284
|
+
<CardTitle>Wavelength EP</CardTitle>
|
|
285
|
+
<CardDescription>Neon Collective · 6 tracks</CardDescription>
|
|
286
|
+
</CardHeader>
|
|
287
|
+
<CardContent>
|
|
288
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-xl">
|
|
289
|
+
An ambient electronic project exploring texture and space.
|
|
290
|
+
</p>
|
|
291
|
+
</CardContent>
|
|
292
|
+
<CardFooter className="gap-2 border-t">
|
|
293
|
+
<Button variant="outline" size="sm" className="flex-1">
|
|
294
|
+
Save
|
|
295
|
+
</Button>
|
|
296
|
+
<Button size="sm" className="flex-1">
|
|
297
|
+
Play
|
|
298
|
+
</Button>
|
|
299
|
+
</CardFooter>
|
|
300
|
+
</Card>
|
|
301
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
302
|
+
Header + content + footer
|
|
273
303
|
</p>
|
|
274
304
|
</div>
|
|
275
305
|
</div>
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
{/* With action */}
|
|
309
|
+
<div className="space-y-4">
|
|
310
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
311
|
+
With action slot
|
|
312
|
+
</h4>
|
|
313
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
314
|
+
<div className="space-y-2 text-center">
|
|
315
|
+
<Card className="w-72">
|
|
316
|
+
<CardHeader>
|
|
317
|
+
<CardTitle>Electric Sunrise</CardTitle>
|
|
318
|
+
<CardDescription>Synthwave · 5:01</CardDescription>
|
|
319
|
+
<CardAction>
|
|
320
|
+
<Badge color="negative">EXPLICIT</Badge>
|
|
321
|
+
</CardAction>
|
|
322
|
+
</CardHeader>
|
|
323
|
+
<CardContent>
|
|
324
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-xl">
|
|
325
|
+
High-energy track from the Horizon album.
|
|
326
|
+
</p>
|
|
327
|
+
</CardContent>
|
|
328
|
+
</Card>
|
|
329
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
330
|
+
Header with action badge
|
|
331
|
+
</p>
|
|
332
|
+
</div>
|
|
333
|
+
<div className="space-y-2 text-center">
|
|
334
|
+
<Card className="w-72">
|
|
335
|
+
<CardHeader>
|
|
336
|
+
<CardTitle>Playlist Settings</CardTitle>
|
|
337
|
+
<CardDescription>Manage your queue</CardDescription>
|
|
338
|
+
<CardAction>
|
|
339
|
+
<Button variant="outline" size="sm">
|
|
340
|
+
Edit
|
|
341
|
+
</Button>
|
|
342
|
+
</CardAction>
|
|
343
|
+
</CardHeader>
|
|
344
|
+
<CardContent>
|
|
345
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-xl">
|
|
346
|
+
24 tracks · 1h 32m total duration
|
|
347
|
+
</p>
|
|
348
|
+
</CardContent>
|
|
349
|
+
</Card>
|
|
350
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
351
|
+
Header with action button
|
|
352
|
+
</p>
|
|
280
353
|
</div>
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
|
|
357
|
+
{/* Full card */}
|
|
358
|
+
<div className="space-y-4">
|
|
359
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
360
|
+
Full card — all parts combined
|
|
361
|
+
</h4>
|
|
362
|
+
<div className="flex flex-wrap justify-center gap-4">
|
|
363
|
+
<div className="space-y-2 text-center">
|
|
364
|
+
<Card className="w-72">
|
|
365
|
+
<CardHeader className="border-b">
|
|
366
|
+
<CardTitle>Midnight Dreams</CardTitle>
|
|
367
|
+
<CardDescription>
|
|
368
|
+
Aura Band · Dark Frequencies · 2024
|
|
369
|
+
</CardDescription>
|
|
370
|
+
<CardAction>
|
|
371
|
+
<Badge
|
|
372
|
+
color="info"
|
|
373
|
+
className="bg-fm-surface-info-sec text-fm-info-sec"
|
|
374
|
+
>
|
|
375
|
+
NEW
|
|
376
|
+
</Badge>
|
|
377
|
+
</CardAction>
|
|
378
|
+
</CardHeader>
|
|
379
|
+
<CardContent className="space-y-2">
|
|
380
|
+
<div className="flex items-center justify-between">
|
|
381
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
382
|
+
Duration
|
|
383
|
+
</span>
|
|
384
|
+
<span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
|
|
385
|
+
4:17
|
|
386
|
+
</span>
|
|
387
|
+
</div>
|
|
388
|
+
<div className="flex items-center justify-between">
|
|
389
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
390
|
+
Plays
|
|
391
|
+
</span>
|
|
392
|
+
<span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
|
|
393
|
+
1.2M
|
|
394
|
+
</span>
|
|
395
|
+
</div>
|
|
396
|
+
<div className="flex items-center justify-between">
|
|
397
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
398
|
+
Genre
|
|
399
|
+
</span>
|
|
400
|
+
<span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
|
|
401
|
+
Electronic
|
|
402
|
+
</span>
|
|
403
|
+
</div>
|
|
404
|
+
</CardContent>
|
|
405
|
+
<CardFooter className="gap-2 border-t">
|
|
406
|
+
<Button variant="outline" size="sm" className="flex-1">
|
|
407
|
+
Add to Queue
|
|
408
|
+
</Button>
|
|
409
|
+
<Button size="sm" className="flex-1">
|
|
410
|
+
Play
|
|
411
|
+
</Button>
|
|
412
|
+
</CardFooter>
|
|
413
|
+
</Card>
|
|
414
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
415
|
+
All parts · border separators
|
|
416
|
+
</p>
|
|
284
417
|
</div>
|
|
285
418
|
</div>
|
|
286
|
-
</
|
|
287
|
-
|
|
288
|
-
<Button variant="outline" className="flex-1">
|
|
289
|
-
Edit Profile
|
|
290
|
-
</Button>
|
|
291
|
-
<Button className="flex-1">View Details</Button>
|
|
292
|
-
</CardFooter>
|
|
293
|
-
</Card>
|
|
419
|
+
</div>
|
|
420
|
+
</div>
|
|
294
421
|
),
|
|
422
|
+
parameters: {
|
|
423
|
+
layout: "padded",
|
|
424
|
+
docs: {
|
|
425
|
+
description: {
|
|
426
|
+
story:
|
|
427
|
+
"Five card layout configurations: minimal content-only, header-only, with footer, with action slot, and the full compound using all parts together.",
|
|
428
|
+
},
|
|
429
|
+
},
|
|
430
|
+
},
|
|
295
431
|
}
|
|
296
432
|
|
|
297
|
-
|
|
298
|
-
render: () => (
|
|
299
|
-
<div className="grid w-full max-w-4xl grid-cols-1 gap-4 md:grid-cols-2">
|
|
300
|
-
<Card>
|
|
301
|
-
<CardHeader>
|
|
302
|
-
<CardTitle>Minimal Card</CardTitle>
|
|
303
|
-
</CardHeader>
|
|
304
|
-
<CardContent>
|
|
305
|
-
<p>Just a title and content.</p>
|
|
306
|
-
</CardContent>
|
|
307
|
-
</Card>
|
|
433
|
+
// ─── 3. Use Cases ─────────────────────────────────────────────────────────────
|
|
308
434
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
435
|
+
export const UseCases: Story = {
|
|
436
|
+
render: () => (
|
|
437
|
+
<div className="mx-auto max-w-3xl space-y-8 p-8">
|
|
438
|
+
{/* Track Card */}
|
|
439
|
+
<div className="space-y-4">
|
|
440
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
441
|
+
Track Card
|
|
442
|
+
</h4>
|
|
443
|
+
<div className="mx-auto max-w-md">
|
|
444
|
+
<Card>
|
|
445
|
+
<CardHeader>
|
|
446
|
+
<CardTitle className="text-fm-primary font-fm-text text-fm-lg leading-fm-lg flex items-center gap-2 font-semibold">
|
|
447
|
+
<MusicalNoteIcon className="text-fm-secondary size-4 shrink-0" />
|
|
448
|
+
Midnight Dreams
|
|
449
|
+
</CardTitle>
|
|
450
|
+
<CardDescription className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
451
|
+
Aura Band · Dark Frequencies · 4:17
|
|
452
|
+
</CardDescription>
|
|
453
|
+
<CardAction>
|
|
454
|
+
<Badge
|
|
455
|
+
color="positive"
|
|
456
|
+
className="bg-fm-surface-positive-sec text-fm-positive-sec"
|
|
457
|
+
>
|
|
458
|
+
LIVE
|
|
459
|
+
</Badge>
|
|
460
|
+
</CardAction>
|
|
461
|
+
</CardHeader>
|
|
462
|
+
<CardContent>
|
|
463
|
+
{/* Waveform placeholder */}
|
|
464
|
+
<div className="bg-fm-surface-secondary rounded-fm-s flex h-10 items-center justify-between gap-1 px-2">
|
|
465
|
+
{Array.from({ length: 32 }).map((_, i) => (
|
|
466
|
+
<div
|
|
467
|
+
key={i}
|
|
468
|
+
className="bg-fm-surface-frosted/40 w-1 rounded-full"
|
|
469
|
+
style={{ height: `${20 + Math.sin(i * 0.8) * 14}px` }}
|
|
470
|
+
/>
|
|
471
|
+
))}
|
|
472
|
+
</div>
|
|
473
|
+
</CardContent>
|
|
474
|
+
<CardFooter className="gap-2 border-t">
|
|
475
|
+
<Button variant="text" size="sm">
|
|
476
|
+
<HeartIcon className="size-4" />
|
|
477
|
+
</Button>
|
|
478
|
+
<div className="flex flex-1 items-center justify-center gap-3">
|
|
479
|
+
<Button variant="text" size="sm">
|
|
480
|
+
<SkipForwardIcon className="size-4 rotate-180" />
|
|
481
|
+
</Button>
|
|
482
|
+
<Button size="sm">
|
|
483
|
+
<PauseIcon className="size-4" />
|
|
484
|
+
</Button>
|
|
485
|
+
<Button variant="text" size="sm">
|
|
486
|
+
<SkipForwardIcon className="size-4" />
|
|
487
|
+
</Button>
|
|
488
|
+
</div>
|
|
489
|
+
<Button variant="text" size="sm">
|
|
490
|
+
<VolumeFullIcon className="size-4" />
|
|
491
|
+
</Button>
|
|
492
|
+
</CardFooter>
|
|
493
|
+
</Card>
|
|
494
|
+
</div>
|
|
495
|
+
</div>
|
|
314
496
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
</
|
|
320
|
-
|
|
497
|
+
{/* Artist Profile Card */}
|
|
498
|
+
<div className="space-y-4">
|
|
499
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
500
|
+
Artist Profile Card
|
|
501
|
+
</h4>
|
|
502
|
+
<div className="mx-auto max-w-md">
|
|
503
|
+
<Card>
|
|
504
|
+
<CardHeader className="border-b">
|
|
505
|
+
<CardTitle className="text-fm-primary font-fm-brand text-fm-xl leading-fm-xl flex items-center gap-3 font-semibold">
|
|
506
|
+
<div className="bg-fm-surface-secondary text-fm-primary flex size-10 shrink-0 items-center justify-center rounded-full font-semibold">
|
|
507
|
+
NC
|
|
508
|
+
</div>
|
|
509
|
+
Neon Collective
|
|
510
|
+
</CardTitle>
|
|
511
|
+
<CardDescription className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
512
|
+
Ambient Electronic · Berlin, DE
|
|
513
|
+
</CardDescription>
|
|
514
|
+
<CardAction>
|
|
515
|
+
<div className="flex items-center gap-1">
|
|
516
|
+
<StarIcon className="text-fm-label-primary size-4" />
|
|
517
|
+
<span className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
|
|
518
|
+
4.9
|
|
519
|
+
</span>
|
|
520
|
+
</div>
|
|
521
|
+
</CardAction>
|
|
522
|
+
</CardHeader>
|
|
523
|
+
<CardContent className="grid grid-cols-3 gap-4 text-center">
|
|
524
|
+
<div className="space-y-1">
|
|
525
|
+
<p className="text-fm-primary font-fm-brand text-fm-lg leading-fm-lg font-semibold">
|
|
526
|
+
2.4M
|
|
527
|
+
</p>
|
|
528
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
529
|
+
Monthly Listeners
|
|
530
|
+
</p>
|
|
531
|
+
</div>
|
|
532
|
+
<div className="space-y-1">
|
|
533
|
+
<p className="text-fm-primary font-fm-brand text-fm-lg leading-fm-lg font-semibold">
|
|
534
|
+
18
|
|
535
|
+
</p>
|
|
536
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
537
|
+
Albums
|
|
538
|
+
</p>
|
|
539
|
+
</div>
|
|
540
|
+
<div className="space-y-1">
|
|
541
|
+
<p className="text-fm-primary font-fm-brand text-fm-lg leading-fm-lg font-semibold">
|
|
542
|
+
142
|
|
543
|
+
</p>
|
|
544
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
545
|
+
Tracks
|
|
546
|
+
</p>
|
|
547
|
+
</div>
|
|
548
|
+
</CardContent>
|
|
549
|
+
<CardFooter className="gap-2 border-t">
|
|
550
|
+
<Button variant="outline" size="sm" className="flex-1">
|
|
551
|
+
Follow
|
|
552
|
+
</Button>
|
|
553
|
+
<Button size="sm" className="flex-1">
|
|
554
|
+
Play Artist Radio
|
|
555
|
+
</Button>
|
|
556
|
+
</CardFooter>
|
|
557
|
+
</Card>
|
|
558
|
+
</div>
|
|
559
|
+
</div>
|
|
321
560
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
<
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
<
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
</
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
561
|
+
{/* Playlist Card */}
|
|
562
|
+
<div className="space-y-4">
|
|
563
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
564
|
+
Playlist Card
|
|
565
|
+
</h4>
|
|
566
|
+
<div className="mx-auto max-w-md">
|
|
567
|
+
<Card>
|
|
568
|
+
<CardHeader>
|
|
569
|
+
<CardTitle className="text-fm-primary font-fm-brand text-fm-lg leading-fm-lg font-semibold">
|
|
570
|
+
Late Night Sessions
|
|
571
|
+
</CardTitle>
|
|
572
|
+
<CardDescription className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
573
|
+
Curated by you · 24 tracks · 1h 32m
|
|
574
|
+
</CardDescription>
|
|
575
|
+
<CardAction>
|
|
576
|
+
<Badge color="neutral">PRIVATE</Badge>
|
|
577
|
+
</CardAction>
|
|
578
|
+
</CardHeader>
|
|
579
|
+
<CardContent className="space-y-2">
|
|
580
|
+
{[
|
|
581
|
+
{
|
|
582
|
+
title: "Midnight Dreams",
|
|
583
|
+
artist: "Aura Band",
|
|
584
|
+
duration: "4:17",
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
title: "Electric Sunrise",
|
|
588
|
+
artist: "Neon Collective",
|
|
589
|
+
duration: "5:01",
|
|
590
|
+
},
|
|
591
|
+
{
|
|
592
|
+
title: "Echoes in Rain",
|
|
593
|
+
artist: "The Drifters",
|
|
594
|
+
duration: "3:42",
|
|
595
|
+
},
|
|
596
|
+
].map((track) => (
|
|
597
|
+
<div
|
|
598
|
+
key={track.title}
|
|
599
|
+
className="border-fm-divider-secondary flex items-center justify-between rounded border px-3 py-2"
|
|
600
|
+
>
|
|
601
|
+
<div className="flex items-center gap-2">
|
|
602
|
+
<MusicalNoteIcon className="text-fm-tertiary size-3.5 shrink-0" />
|
|
603
|
+
<div>
|
|
604
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm font-medium">
|
|
605
|
+
{track.title}
|
|
606
|
+
</p>
|
|
607
|
+
<p className="text-fm-secondary font-fm-text text-fm-xs leading-fm-xs">
|
|
608
|
+
{track.artist}
|
|
609
|
+
</p>
|
|
610
|
+
</div>
|
|
611
|
+
</div>
|
|
612
|
+
<span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
|
|
613
|
+
{track.duration}
|
|
614
|
+
</span>
|
|
615
|
+
</div>
|
|
616
|
+
))}
|
|
617
|
+
</CardContent>
|
|
618
|
+
<CardFooter className="gap-2 border-t">
|
|
619
|
+
<Button variant="outline" size="sm" className="flex-1">
|
|
620
|
+
Shuffle
|
|
621
|
+
</Button>
|
|
622
|
+
<Button size="sm" className="flex-1">
|
|
623
|
+
Play All
|
|
624
|
+
</Button>
|
|
625
|
+
</CardFooter>
|
|
626
|
+
</Card>
|
|
627
|
+
</div>
|
|
628
|
+
</div>
|
|
343
629
|
</div>
|
|
344
630
|
),
|
|
345
631
|
parameters: {
|
|
346
|
-
layout: "
|
|
632
|
+
layout: "fullscreen",
|
|
633
|
+
docs: {
|
|
634
|
+
description: {
|
|
635
|
+
story:
|
|
636
|
+
"Realistic audio app card compositions: a playback-ready track card with waveform, an artist profile card with stats, and a playlist card with an inline track listing.",
|
|
637
|
+
},
|
|
638
|
+
},
|
|
347
639
|
},
|
|
348
640
|
}
|
|
349
641
|
|
|
350
|
-
//
|
|
642
|
+
// ─── 4. Playground ────────────────────────────────────────────────────────────
|
|
643
|
+
|
|
351
644
|
export const Playground: Story = {
|
|
352
645
|
args: {
|
|
353
|
-
className: "w-
|
|
646
|
+
className: "w-80",
|
|
354
647
|
},
|
|
355
|
-
render: (args
|
|
356
|
-
<
|
|
357
|
-
<
|
|
358
|
-
<
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
<
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
648
|
+
render: (args) => (
|
|
649
|
+
<div className="mx-auto w-full max-w-sm space-y-4">
|
|
650
|
+
<Card {...args}>
|
|
651
|
+
<CardHeader>
|
|
652
|
+
<CardTitle>Playground Card</CardTitle>
|
|
653
|
+
<CardDescription>
|
|
654
|
+
Adjust this card using the controls panel
|
|
655
|
+
</CardDescription>
|
|
656
|
+
<CardAction>
|
|
657
|
+
<Badge
|
|
658
|
+
color="info"
|
|
659
|
+
className="bg-fm-surface-info-sec text-fm-info-sec"
|
|
660
|
+
>
|
|
661
|
+
NEW
|
|
662
|
+
</Badge>
|
|
663
|
+
</CardAction>
|
|
664
|
+
</CardHeader>
|
|
665
|
+
<CardContent>
|
|
666
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-xl">
|
|
667
|
+
Use the Storybook controls panel to modify the card's className and
|
|
668
|
+
observe layout changes.
|
|
669
|
+
</p>
|
|
670
|
+
</CardContent>
|
|
671
|
+
<CardFooter className="gap-2">
|
|
672
|
+
<Button variant="outline" size="sm" className="flex-1">
|
|
673
|
+
Cancel
|
|
674
|
+
</Button>
|
|
675
|
+
<Button size="sm" className="flex-1">
|
|
676
|
+
Confirm
|
|
677
|
+
</Button>
|
|
678
|
+
</CardFooter>
|
|
679
|
+
</Card>
|
|
680
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border px-4 py-3">
|
|
681
|
+
<code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">
|
|
682
|
+
{`<Card className="${(args as { className?: string }).className ?? ""}">`}
|
|
683
|
+
</code>
|
|
684
|
+
</div>
|
|
685
|
+
</div>
|
|
376
686
|
),
|
|
687
|
+
parameters: {
|
|
688
|
+
docs: {
|
|
689
|
+
description: {
|
|
690
|
+
story:
|
|
691
|
+
"Controls-driven story. Use the Storybook sidebar to adjust the className prop and experiment with card widths and overrides.",
|
|
692
|
+
},
|
|
693
|
+
},
|
|
694
|
+
},
|
|
377
695
|
}
|