aural-ui 3.0.7 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/aspect-ratio/AspectRatio.stories.tsx +290 -1199
- package/dist/components/avatar/Avatar.stories.tsx +235 -237
- package/dist/components/badge/Badge.stories.tsx +379 -116
- package/dist/components/banner/Banner.stories.tsx +445 -391
- package/dist/components/breadcrumb/Breadcrumb.stories.tsx +453 -199
- package/dist/components/button/Button.stories.tsx +585 -230
- package/dist/components/button/index.tsx +7 -7
- package/dist/components/card/Card.stories.tsx +619 -301
- package/dist/components/char-count/CharCount.stories.tsx +350 -248
- package/dist/components/checkbox/Checkbox.stories.tsx +309 -167
- package/dist/components/chip/Chip.stories.tsx +362 -168
- package/dist/components/circular-loader/CircularLoader.stories.tsx +221 -620
- package/dist/components/clamp-lines/ClampLines.stories.tsx +246 -117
- package/dist/components/collapsible/Collapsible.stories.tsx +391 -252
- package/dist/components/command/Command.stories.tsx +533 -856
- package/dist/components/dialog/Dialog.stories.tsx +505 -949
- package/dist/components/divider/Divider.stories.tsx +265 -502
- package/dist/components/dot-loader/DotLoader.stories.tsx +256 -257
- package/dist/components/drawer/Drawer.stories.tsx +659 -993
- package/dist/components/drawer/index.tsx +3 -3
- package/dist/components/dropdown/Dropdown.stories.tsx +643 -1018
- package/dist/components/form/Form.stories.tsx +560 -274
- package/dist/components/helper-text/HelperText.stories.tsx +199 -200
- package/dist/components/hover-card/HoverCard.stories.tsx +318 -1221
- package/dist/components/icon-button/IconButton.stories.tsx +837 -194
- package/dist/components/if-else/if-else.stories.tsx +370 -83
- package/dist/components/input/Input.stories.tsx +436 -368
- package/dist/components/label/Label.stories.tsx +156 -154
- package/dist/components/list/List.stories.tsx +485 -822
- package/dist/components/marquee/Marquee.stories.tsx +356 -694
- package/dist/components/otp-inputs/OtpInputs.stories.tsx +352 -410
- package/dist/components/overlay/Overlay.stories.tsx +452 -818
- package/dist/components/overlay/index.tsx +4 -4
- package/dist/components/pagination/Pagination.stories.tsx +721 -210
- package/dist/components/popover/Popover.stories.tsx +484 -873
- package/dist/components/radio/Radio.stories.tsx +432 -124
- package/dist/components/resizable/Resizable.stories.tsx +496 -752
- package/dist/components/scroll-area/ScrollArea.stories.tsx +384 -1006
- package/dist/components/search/Search.stories.tsx +314 -575
- package/dist/components/select/Select.stories.tsx +684 -787
- package/dist/components/sheet/Sheet.stories.tsx +671 -936
- package/dist/components/skelton/Skelton.stories.tsx +230 -764
- package/dist/components/slider/Slider.stories.tsx +384 -737
- package/dist/components/stepper/Stepper.stories.tsx +371 -514
- package/dist/components/switch/Switch.stories.tsx +461 -208
- package/dist/components/switch-case/SwitchCase.stories.tsx +367 -188
- package/dist/components/table/Table.stories.tsx +770 -914
- package/dist/components/tabs/Tabs.stories.tsx +459 -1400
- package/dist/components/tag/Tag.stories.tsx +714 -542
- package/dist/components/textarea/TextArea.stories.tsx +621 -562
- package/dist/components/thumbnail-tags/ThumbnailTags.stories.tsx +228 -148
- package/dist/components/toast/Toast.stories.tsx +452 -1333
- package/dist/components/toggle/Toggle.stories.tsx +488 -909
- package/dist/components/tooltip/Tooltip.stories.tsx +344 -1372
- package/dist/components/typography/Typography.stories.tsx +406 -89
- package/dist/hooks/use-change-state/UseChangeState.stories.tsx +309 -606
- package/dist/hooks/use-previous/UsePrevious.stories.tsx +367 -917
- package/dist/hooks/use-standalone-pagination/UseStandalonePagination.stories.tsx +639 -867
- package/dist/icons/Icons.stories.tsx +0 -12
- package/dist/icons/ai-avatar-icon/AiAvatarIcon.stories.tsx +226 -1013
- package/dist/icons/alert-icon/AlertIcon.stories.tsx +109 -929
- package/dist/icons/all-icons.tsx +124 -87
- package/dist/icons/angle-down-icon/AngleDownIcon.stories.tsx +140 -971
- package/dist/icons/apple-logo-icon/AppleLogoIcon.stories.tsx +148 -888
- package/dist/icons/arrow-box-left-icon/ArrowBoxLeftIcon.stories.tsx +135 -1019
- package/dist/icons/arrow-corner-up-left-icon/ArrowCornerUpLeftIcon.stories.tsx +137 -953
- package/dist/icons/arrow-corner-up-right-icon/ArrowCornerUpRightIcon.stories.tsx +138 -997
- package/dist/icons/arrow-left-icon/ArrowLeftIcon.stories.tsx +136 -942
- package/dist/icons/arrow-right-icon/ArrowRightIcon.stories.tsx +148 -1092
- package/dist/icons/arrow-right-up-icon/ArrowRightUpIcon.stories.tsx +146 -1211
- package/dist/icons/art-board-icon/ArtBoardIcon.stories.tsx +126 -615
- package/dist/icons/audio-bar-icon/AudioBarIcon.stories.tsx +144 -1164
- package/dist/icons/backward-ten-seconds-icon/BackwardTenSecondsIcon.stories.tsx +167 -985
- package/dist/icons/bubble-check-icon/BubbleCheckIcon.stories.tsx +122 -1179
- package/dist/icons/bubble-crossed-icon/BubbleCrossedIcon.stories.tsx +124 -1168
- package/dist/icons/bubble-sparkle-icon/BubbleSparkleIcon.stories.tsx +119 -850
- package/dist/icons/camera-icon/CameraIcon.stories.tsx +112 -1213
- package/dist/icons/capital-a-letter-icon/CapitalALetterIcon.stories.tsx +117 -934
- package/dist/icons/chevron-double-left-icon/ChevronDoubleLeftIcon.stories.tsx +160 -961
- package/dist/icons/chevron-double-right-icon/ChevronDoubleRightIcon.stories.tsx +163 -961
- package/dist/icons/chevron-down-icon/ChevronDownIcon.stories.tsx +144 -942
- package/dist/icons/chevron-left-icon/ChevronLeftIcon.stories.tsx +129 -966
- package/dist/icons/chevron-right-icon/ChevronRightIcon.stories.tsx +147 -964
- package/dist/icons/chevron-up-icon/ChevronUpIcon.stories.tsx +145 -975
- package/dist/icons/circle-tick-icon/CircleTickIcon.stories.tsx +150 -1142
- package/dist/icons/circular-play-icon/CircularPlayIcon.stories.tsx +114 -461
- package/dist/icons/coin-icon/CoinIcon.stories.tsx +124 -1322
- package/dist/icons/coin-toons-icon/CoinToonsIcon.stories.tsx +117 -1318
- package/dist/icons/column-wide-add-icon/ColumnWideAddIcon.stories.tsx +114 -903
- package/dist/icons/command-icon/CommandIcon.stories.tsx +127 -1042
- package/dist/icons/copy-icon/CopyIcon.stories.tsx +123 -962
- package/dist/icons/cross-circle-icon/CrossCircleIcon.stories.tsx +147 -999
- package/dist/icons/cross-icon/CrossIcon.stories.tsx +139 -960
- package/dist/icons/download-icon/DownloadIcon.stories.tsx +126 -820
- package/dist/icons/edit-big-icon/EditBigIcon.stories.tsx +124 -1031
- package/dist/icons/email-icon/EmailIcon.stories.tsx +115 -936
- package/dist/icons/expand-icon/ExpandIcon.stories.tsx +112 -1111
- package/dist/icons/eye-close-icon/EyeCloseIcon.stories.tsx +144 -1025
- package/dist/icons/eye-open-icon/EyeOpenIcon.stories.tsx +143 -1036
- package/dist/icons/feature-shine-icon/FeatureShineIcon.stories.tsx +127 -1011
- package/dist/icons/file-chart-icon/FileChartIcon.stories.tsx +126 -1056
- package/dist/icons/file-text-icon/FileTextIcon.stories.tsx +125 -614
- package/dist/icons/filter-bar-row-icon/FilterBarRowIcon.stories.tsx +119 -1050
- package/dist/icons/forward-ten-seconds-icon/ForwardTenSecondsIcon.stories.tsx +169 -989
- package/dist/icons/git-branch-icon/GitBranchIcon.stories.tsx +115 -1145
- package/dist/icons/git-fork-icon/GitForkIcon.stories.tsx +115 -1122
- package/dist/icons/globe-icon/GlobeIcon.stories.tsx +130 -313
- package/dist/icons/google-logo-icon/GoogleLogoIcon.stories.tsx +145 -940
- package/dist/icons/grip-vertical-icon/GripVerticalIcon.stories.tsx +119 -1174
- package/dist/icons/head-icon/HeadIcon.stories.tsx +111 -916
- package/dist/icons/heart-icon/HeartIcon.stories.tsx +120 -1019
- package/dist/icons/image-avatar-sparkle-icon/ImageAvatarSparkleIcon.stories.tsx +119 -683
- package/dist/icons/image-icon/ImageIcon.stories.tsx +105 -1121
- package/dist/icons/import-folder-icon/ImportFolderIcon.stories.tsx +111 -1192
- package/dist/icons/import-left-arrow-folder-icon/ImportLeftArrowFolderIcon.stories.tsx +136 -1256
- package/dist/icons/indian-flag-icon/IndianFlagIcon.stories.tsx +159 -962
- package/dist/icons/instagram-icon/InstagramIcon.stories.tsx +161 -1385
- package/dist/icons/layout-column-icon/LayoutColumnIcon.stories.tsx +124 -972
- package/dist/icons/layout-left-icon/LayoutLeftIcon.stories.tsx +119 -948
- package/dist/icons/layout-right-icon/LayoutRightIcon.stories.tsx +119 -942
- package/dist/icons/light-bulb-simple-icon/LightBulbSimpleIcon.stories.tsx +108 -1215
- package/dist/icons/linked-in-icon/LinkedInIcon.stories.tsx +154 -1517
- package/dist/icons/magic-book-icon/MagicBookIcon.stories.tsx +110 -1188
- package/dist/icons/magic-edit-icon/MagicEditIcon.stories.tsx +119 -678
- package/dist/icons/maintenance-icon/MaintenanceIcon.stories.tsx +123 -1184
- package/dist/icons/message-icon/MessageIcon.stories.tsx +114 -538
- package/dist/icons/minimize-icon/MinimizeIcon.stories.tsx +116 -1158
- package/dist/icons/moon-icon/MoonIcon.stories.tsx +120 -536
- package/dist/icons/move-horizontal-icon/MoveHorizontalIcon.stories.tsx +109 -1184
- package/dist/icons/move-vertical-icon/MoveVerticalIcon.stories.tsx +115 -1134
- package/dist/icons/musical-note-icon/MusicalNoteIcon.stories.tsx +119 -971
- package/dist/icons/notepad-icon/NotepadIcon.stories.tsx +111 -1100
- package/dist/icons/notes-icon/NotesIcon.stories.tsx +119 -1101
- package/dist/icons/page-search-icon/PageSearchIcon.stories.tsx +109 -1111
- package/dist/icons/page-text-icon/PageTextIcon.stories.tsx +122 -684
- package/dist/icons/paint-roll-icon/PaintRollIcon.stories.tsx +113 -954
- package/dist/icons/paper-plane-icon/PaperPlaneIcon.stories.tsx +112 -877
- package/dist/icons/pause-icon/PauseIcon.stories.tsx +113 -1000
- package/dist/icons/pencil-icon/PencilIcon.stories.tsx +115 -1070
- package/dist/icons/phone-icon/PhoneIcon.stories.tsx +115 -978
- package/dist/icons/plus-icon/PlusIcon.stories.tsx +106 -1093
- package/dist/icons/pocket-studio-icon/PocketStudioIcon.stories.tsx +107 -829
- package/dist/icons/scroll-down-icon/ScrollDownIcon.stories.tsx +102 -469
- package/dist/icons/search-icon/SearchIcon.stories.tsx +111 -1124
- package/dist/icons/setting-icon/SettingIcon.stories.tsx +107 -970
- package/dist/icons/share-icon/ShareIcon.stories.tsx +120 -1025
- package/dist/icons/shield-icon/ShieldIcon.stories.tsx +117 -931
- package/dist/icons/site-logo-icon/SiteLogoIcon.stories.tsx +137 -1104
- package/dist/icons/skip-backward-icon/SkipBackwardIcon.stories.tsx +172 -982
- package/dist/icons/skip-forward-icon/SkipForwardIcon.stories.tsx +164 -983
- package/dist/icons/sparkles-soft-icon/SparklesSoftIcon.stories.tsx +105 -958
- package/dist/icons/spinner-gradient-icon/SpinnerGradientIcon.stories.tsx +158 -580
- package/dist/icons/spinner-gradient-icon/index.tsx +6 -1
- package/dist/icons/spinner-solid-icon/SpinnerSolidIcon.stories.tsx +158 -587
- package/dist/icons/spinner-solid-icon/index.tsx +6 -1
- package/dist/icons/spinner-solid-neutral-icon/SpinnerSolidINeutralcon.stories.tsx +146 -682
- package/dist/icons/spinner-solid-neutral-icon/index.tsx +1 -1
- package/dist/icons/star-icon/StarIcon.stories.tsx +124 -904
- package/dist/icons/store-coin-icon/StoreCoinIcon.stories.tsx +112 -964
- package/dist/icons/suggestion-icon/SuggestionIcon.stories.tsx +116 -852
- package/dist/icons/sun-icon/SunIcon.stories.tsx +120 -831
- package/dist/icons/text-color-icon/TextColorIcon.stories.tsx +116 -950
- package/dist/icons/text-indicator-icon/TextIndicatorIcon.stories.tsx +123 -980
- package/dist/icons/threads-icon/ThreadsIcon.stories.tsx +156 -1427
- package/dist/icons/tick-circle-icon/TickCircleIcon.stories.tsx +146 -1142
- package/dist/icons/tick-icon/TickIcon.stories.tsx +145 -1276
- package/dist/icons/trash-icon/TrashIcon.stories.tsx +108 -933
- package/dist/icons/twitter-x-icon/TwitterXIcon.stories.tsx +157 -1402
- package/dist/icons/upload-icon/UploadIcon.stories.tsx +115 -889
- package/dist/icons/vertical-menu-icon/VerticalMenuIcon.stories.tsx +118 -984
- package/dist/icons/video-play-list-icon/VideoPlaylistIcon.stories.tsx +125 -1049
- package/dist/icons/voice-playing-icon/VoicePlayingIcon.stories.tsx +123 -1356
- package/dist/icons/volume-full-icon/VolumeFullIcon.stories.tsx +110 -1171
- package/dist/icons/volume-half-icon/VolumeHalfIcon.stories.tsx +112 -1093
- package/dist/icons/volume-off-icon/VolumeOffIcon.stories.tsx +115 -1087
- package/dist/icons/warning-icon/WarningIcon.stories.tsx +122 -1046
- package/dist/icons/youtube-icon/YoutubeIcon.stories.tsx +161 -936
- package/dist/index.cjs +84 -84
- package/dist/index.js +84 -84
- package/dist/styles/aural-all-theme.css +1222 -0
- package/dist/styles/{aural-theme.css → aural-dark-theme.css} +15 -3
- package/dist/styles/aural-light-theme.css +1047 -0
- package/package.json +1 -1
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import React from "react"
|
|
2
2
|
import { Badge } from "@components/badge"
|
|
3
3
|
import {
|
|
4
|
-
BubbleCheckIcon,
|
|
5
|
-
BubbleSparkleIcon,
|
|
6
|
-
EditBigIcon,
|
|
7
|
-
EyeOpenIcon,
|
|
8
4
|
FeatureShineIcon,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
LightBulbSimpleIcon,
|
|
13
|
-
MagicBookIcon,
|
|
14
|
-
MaintenanceIcon,
|
|
5
|
+
HeartIcon,
|
|
6
|
+
MusicalNoteIcon,
|
|
7
|
+
PauseIcon,
|
|
15
8
|
SearchIcon,
|
|
16
|
-
|
|
9
|
+
SettingIcon,
|
|
10
|
+
SkipForwardIcon,
|
|
11
|
+
StarIcon,
|
|
17
12
|
TrashIcon,
|
|
18
13
|
UploadIcon,
|
|
14
|
+
VolumeFullIcon,
|
|
19
15
|
} from "@icons/index"
|
|
20
16
|
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
21
17
|
|
|
18
|
+
import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
|
|
19
|
+
|
|
22
20
|
import {
|
|
23
21
|
List,
|
|
24
22
|
ListCheckboxItem,
|
|
@@ -35,114 +33,30 @@ const meta: Meta<typeof List> = {
|
|
|
35
33
|
title: "Components/UI/List",
|
|
36
34
|
component: List,
|
|
37
35
|
parameters: {
|
|
38
|
-
layout: "
|
|
39
|
-
backgrounds: {
|
|
40
|
-
default: "dark",
|
|
41
|
-
values: [
|
|
42
|
-
{ name: "dark", value: "#0a0a0a" },
|
|
43
|
-
{ name: "light", value: "#ffffff" },
|
|
44
|
-
],
|
|
45
|
-
},
|
|
36
|
+
layout: "centered",
|
|
46
37
|
docs: {
|
|
47
38
|
description: {
|
|
48
|
-
component:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
A comprehensive atomic list component system that provides building blocks for creating rich interactive lists, menus, and selection interfaces. Built following atomic design principles.
|
|
52
|
-
|
|
53
|
-
## Atomic Components
|
|
54
|
-
|
|
55
|
-
### Container Level
|
|
56
|
-
- **List**: Main container with styling variants and border options
|
|
57
|
-
- **ListGroup**: Semantic grouping wrapper for related list items
|
|
58
|
-
|
|
59
|
-
### Content Level
|
|
60
|
-
- **ListItem**: Basic interactive list item with states and variants
|
|
61
|
-
- **ListCheckboxItem**: Checkbox-enabled list item for multi-selection
|
|
62
|
-
- **ListRadioItem**: Radio button list item for single selection within groups
|
|
63
|
-
- **ListLabel**: Semantic label component for list sections
|
|
64
|
-
- **ListSeparator**: Visual separator using design system divider
|
|
65
|
-
- **ListSubTrigger**: List item with chevron for nested navigation
|
|
66
|
-
|
|
67
|
-
## Features
|
|
68
|
-
|
|
69
|
-
- **Atomic Design**: Composable components following atomic design principles
|
|
70
|
-
- **Flexible Styling**: CVA variants for size, state, and visual styling
|
|
71
|
-
- **Interactive States**: Hover, focus, selected, and disabled states
|
|
72
|
-
- **Selection Patterns**: Support for single, multi, and radio group selection
|
|
73
|
-
- **Keyboard Navigation**: Full keyboard accessibility support
|
|
74
|
-
- **Icon Integration**: Seamless icon support with proper sizing and coloring
|
|
75
|
-
- **Shortcuts Display**: Built-in keyboard shortcut display
|
|
76
|
-
- **Custom Styling**: Extensive customization through classes prop
|
|
77
|
-
- **Semantic HTML**: Proper ARIA roles and attributes for accessibility
|
|
78
|
-
|
|
79
|
-
## Usage Examples
|
|
80
|
-
|
|
81
|
-
### Basic List
|
|
82
|
-
\`\`\`tsx
|
|
83
|
-
<List>
|
|
84
|
-
<ListItem>
|
|
85
|
-
<FileChartIcon />
|
|
86
|
-
Basic Item
|
|
87
|
-
</ListItem>
|
|
88
|
-
<ListSeparator />
|
|
89
|
-
<ListItem selected>
|
|
90
|
-
<ImageIcon />
|
|
91
|
-
Selected Item
|
|
92
|
-
</ListItem>
|
|
93
|
-
</List>
|
|
94
|
-
\`\`\`
|
|
95
|
-
|
|
96
|
-
### Grouped List with Labels
|
|
97
|
-
\`\`\`tsx
|
|
98
|
-
<List>
|
|
99
|
-
<ListGroup>
|
|
100
|
-
<ListLabel>Actions</ListLabel>
|
|
101
|
-
<ListItem>
|
|
102
|
-
<EditBigIcon />
|
|
103
|
-
Edit File
|
|
104
|
-
<CommandShortcut>⌘E</CommandShortcut>
|
|
105
|
-
</ListItem>
|
|
106
|
-
<ListItem variant="destructive">
|
|
107
|
-
<TrashIcon />
|
|
108
|
-
Delete
|
|
109
|
-
</ListItem>
|
|
110
|
-
</ListGroup>
|
|
111
|
-
</List>
|
|
112
|
-
\`\`\`
|
|
113
|
-
|
|
114
|
-
### Selection Lists
|
|
115
|
-
\`\`\`tsx
|
|
116
|
-
<List>
|
|
117
|
-
<ListCheckboxItem checked onCheckedChange={setChecked}>
|
|
118
|
-
Multi-select Item
|
|
119
|
-
</ListCheckboxItem>
|
|
120
|
-
|
|
121
|
-
<ListRadioGroup value={value} onValueChange={setValue}>
|
|
122
|
-
<ListRadioItem value="option1">Option 1</ListRadioItem>
|
|
123
|
-
<ListRadioItem value="option2">Option 2</ListRadioItem>
|
|
124
|
-
</ListRadioGroup>
|
|
125
|
-
</List>
|
|
126
|
-
\`\`\`
|
|
127
|
-
|
|
128
|
-
### Custom Styling
|
|
129
|
-
\`\`\`tsx
|
|
130
|
-
<List
|
|
131
|
-
variant="elevated"
|
|
132
|
-
size="lg"
|
|
133
|
-
borderVariant="success"
|
|
134
|
-
classes={{ root: "custom-list" }}
|
|
135
|
-
>
|
|
136
|
-
<ListItem
|
|
137
|
-
size="lg"
|
|
138
|
-
classes={{ root: "custom-item" }}
|
|
139
|
-
>
|
|
140
|
-
Custom Styled Item
|
|
141
|
-
</ListItem>
|
|
142
|
-
</List>
|
|
143
|
-
\`\`\`
|
|
144
|
-
`,
|
|
39
|
+
component:
|
|
40
|
+
"A compound list system built for composable menus, selection panels, and navigation drawers. Composed of List (container), ListGroup, ListLabel, ListItem, ListCheckboxItem, ListRadioGroup, ListRadioItem, ListSeparator, and ListSubTrigger. Supports three visual variants (default, elevated, flat), four container sizes (sm, default, lg, xl), and semantic top-border accents.",
|
|
145
41
|
},
|
|
42
|
+
page: () => (
|
|
43
|
+
<AuralComponentDocsPage
|
|
44
|
+
features={[
|
|
45
|
+
{
|
|
46
|
+
title: "Rich Item Types",
|
|
47
|
+
description: "Checkbox, radio, sub-trigger",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
title: "3 Variants",
|
|
51
|
+
description: "Default, elevated, flat",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
title: "4 Container Sizes",
|
|
55
|
+
description: "sm to xl width",
|
|
56
|
+
},
|
|
57
|
+
]}
|
|
58
|
+
/>
|
|
59
|
+
),
|
|
146
60
|
},
|
|
147
61
|
},
|
|
148
62
|
tags: ["autodocs"],
|
|
@@ -150,26 +64,26 @@ A comprehensive atomic list component system that provides building blocks for c
|
|
|
150
64
|
variant: {
|
|
151
65
|
control: "select",
|
|
152
66
|
options: ["default", "elevated", "flat"],
|
|
153
|
-
description: "Visual
|
|
67
|
+
description: "Visual shadow depth of the list container",
|
|
154
68
|
},
|
|
155
69
|
size: {
|
|
156
70
|
control: "select",
|
|
157
71
|
options: ["sm", "default", "lg", "xl"],
|
|
158
|
-
description: "
|
|
72
|
+
description: "Minimum width of the list container",
|
|
159
73
|
},
|
|
160
74
|
rounded: {
|
|
161
75
|
control: "select",
|
|
162
76
|
options: ["none", "sm", "default", "lg"],
|
|
163
|
-
description: "Border radius
|
|
77
|
+
description: "Border radius of the list container",
|
|
164
78
|
},
|
|
165
79
|
borderVariant: {
|
|
166
80
|
control: "select",
|
|
167
81
|
options: ["default", "error", "warning", "success", "info"],
|
|
168
|
-
description: "Color
|
|
82
|
+
description: "Color of the top accent border stripe",
|
|
169
83
|
},
|
|
170
84
|
showBorder: {
|
|
171
85
|
control: "boolean",
|
|
172
|
-
description: "
|
|
86
|
+
description: "Toggle the top accent border stripe",
|
|
173
87
|
},
|
|
174
88
|
},
|
|
175
89
|
}
|
|
@@ -177,775 +91,523 @@ A comprehensive atomic list component system that provides building blocks for c
|
|
|
177
91
|
export default meta
|
|
178
92
|
type Story = StoryObj<typeof List>
|
|
179
93
|
|
|
180
|
-
// 1.
|
|
181
|
-
export const BasicList: Story = {
|
|
182
|
-
args: {
|
|
183
|
-
variant: "default",
|
|
184
|
-
size: "default",
|
|
185
|
-
rounded: "default",
|
|
186
|
-
borderVariant: "default",
|
|
187
|
-
showBorder: true,
|
|
188
|
-
},
|
|
189
|
-
render: (args) => (
|
|
190
|
-
<div className="mx-auto max-w-md p-8">
|
|
191
|
-
<h3 className="mb-4 text-lg font-medium text-white">Basic List</h3>
|
|
192
|
-
<List {...args} className="backdrop-blur-none">
|
|
193
|
-
<ListItem>
|
|
194
|
-
<FileChartIcon />
|
|
195
|
-
Documents
|
|
196
|
-
</ListItem>
|
|
197
|
-
<ListItem>
|
|
198
|
-
<ImageIcon />
|
|
199
|
-
Images
|
|
200
|
-
</ListItem>
|
|
201
|
-
<ListItem selected>
|
|
202
|
-
<MagicBookIcon />
|
|
203
|
-
Magic Book (Selected)
|
|
204
|
-
</ListItem>
|
|
205
|
-
<ListItem disabled>
|
|
206
|
-
<TrashIcon />
|
|
207
|
-
Disabled Item
|
|
208
|
-
</ListItem>
|
|
209
|
-
</List>
|
|
210
|
-
</div>
|
|
211
|
-
),
|
|
212
|
-
parameters: {
|
|
213
|
-
docs: {
|
|
214
|
-
description: {
|
|
215
|
-
story:
|
|
216
|
-
"Basic list with icons and different states including selected and disabled items.",
|
|
217
|
-
},
|
|
218
|
-
},
|
|
219
|
-
},
|
|
220
|
-
}
|
|
94
|
+
// ─── 1. Parts ─────────────────────────────────────────────────────────────────
|
|
221
95
|
|
|
222
|
-
|
|
223
|
-
export const GroupedList: Story = {
|
|
96
|
+
export const Parts: Story = {
|
|
224
97
|
render: () => (
|
|
225
|
-
<div className="mx-auto max-w-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
<ListItem>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
98
|
+
<div className="mx-auto w-full max-w-2xl space-y-10">
|
|
99
|
+
{/* List (container) */}
|
|
100
|
+
<div className="space-y-4">
|
|
101
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
102
|
+
List — container
|
|
103
|
+
</h4>
|
|
104
|
+
<List className="w-56">
|
|
105
|
+
<ListItem>Sample item A</ListItem>
|
|
106
|
+
<ListItem>Sample item B</ListItem>
|
|
107
|
+
</List>
|
|
108
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
109
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
110
|
+
<strong className="text-fm-primary">List</strong> is the root
|
|
111
|
+
container. It applies a frosted-glass backdrop, shadow, and optional
|
|
112
|
+
top-accent border. Sets <code>role="listbox"</code> for
|
|
113
|
+
accessibility.
|
|
114
|
+
</p>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
{/* ListGroup */}
|
|
119
|
+
<div className="space-y-4">
|
|
120
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
121
|
+
ListGroup — semantic grouping
|
|
122
|
+
</h4>
|
|
123
|
+
<List className="w-56">
|
|
124
|
+
<ListGroup>
|
|
125
|
+
<ListItem>Group A · Item 1</ListItem>
|
|
126
|
+
<ListItem>Group A · Item 2</ListItem>
|
|
127
|
+
</ListGroup>
|
|
128
|
+
<ListSeparator />
|
|
129
|
+
<ListGroup>
|
|
130
|
+
<ListItem>Group B · Item 1</ListItem>
|
|
131
|
+
</ListGroup>
|
|
132
|
+
</List>
|
|
133
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
134
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
135
|
+
<strong className="text-fm-primary">ListGroup</strong> wraps related
|
|
136
|
+
items with <code>role="group"</code>. Use it alongside{" "}
|
|
137
|
+
<code>ListSeparator</code> to divide the list into semantic
|
|
138
|
+
sections.
|
|
139
|
+
</p>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
{/* ListLabel */}
|
|
144
|
+
<div className="space-y-4">
|
|
145
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
146
|
+
ListLabel — section heading
|
|
147
|
+
</h4>
|
|
148
|
+
<List className="w-56">
|
|
149
|
+
<ListLabel>Playback</ListLabel>
|
|
237
150
|
<ListItem>
|
|
238
|
-
<
|
|
239
|
-
|
|
240
|
-
<span className="ml-auto text-xs opacity-60">⌘O</span>
|
|
151
|
+
<PauseIcon className="size-4" />
|
|
152
|
+
Pause
|
|
241
153
|
</ListItem>
|
|
242
154
|
<ListItem>
|
|
243
|
-
<
|
|
244
|
-
|
|
245
|
-
<span className="ml-auto text-xs opacity-60">⌘E</span>
|
|
155
|
+
<SkipForwardIcon className="size-4" />
|
|
156
|
+
Skip
|
|
246
157
|
</ListItem>
|
|
247
|
-
</
|
|
248
|
-
|
|
249
|
-
|
|
158
|
+
</List>
|
|
159
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
160
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
161
|
+
<strong className="text-fm-primary">ListLabel</strong> renders a
|
|
162
|
+
small, muted uppercase heading above a group of items. It uses{" "}
|
|
163
|
+
<code>text-fm-label-secondary</code> — not interactive.
|
|
164
|
+
</p>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
250
167
|
|
|
251
|
-
|
|
252
|
-
|
|
168
|
+
{/* ListItem */}
|
|
169
|
+
<div className="space-y-4">
|
|
170
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
171
|
+
ListItem — basic row
|
|
172
|
+
</h4>
|
|
173
|
+
<List className="w-56">
|
|
253
174
|
<ListItem>
|
|
254
|
-
<
|
|
255
|
-
|
|
256
|
-
<Badge color="info" className="ml-auto">
|
|
257
|
-
New
|
|
258
|
-
</Badge>
|
|
175
|
+
<MusicalNoteIcon className="size-4" />
|
|
176
|
+
Default
|
|
259
177
|
</ListItem>
|
|
260
|
-
<ListItem>
|
|
261
|
-
<
|
|
262
|
-
|
|
178
|
+
<ListItem selected>
|
|
179
|
+
<StarIcon className="size-4" />
|
|
180
|
+
Selected
|
|
181
|
+
</ListItem>
|
|
182
|
+
<ListItem disabled>
|
|
183
|
+
<TrashIcon className="size-4" />
|
|
184
|
+
Disabled
|
|
263
185
|
</ListItem>
|
|
264
|
-
<ListSubTrigger>
|
|
265
|
-
<MaintenanceIcon />
|
|
266
|
-
More Options
|
|
267
|
-
</ListSubTrigger>
|
|
268
|
-
</ListGroup>
|
|
269
|
-
|
|
270
|
-
<ListSeparator />
|
|
271
|
-
|
|
272
|
-
<ListGroup>
|
|
273
|
-
<ListLabel>Dangerous Actions</ListLabel>
|
|
274
186
|
<ListItem variant="destructive">
|
|
275
|
-
<TrashIcon />
|
|
276
|
-
|
|
277
|
-
<span className="ml-auto text-xs opacity-60">⌘⌫</span>
|
|
187
|
+
<TrashIcon className="size-4" />
|
|
188
|
+
Destructive
|
|
278
189
|
</ListItem>
|
|
279
|
-
</
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
},
|
|
289
|
-
},
|
|
290
|
-
},
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// 3. Selection Lists
|
|
294
|
-
export const SelectionLists: Story = {
|
|
295
|
-
render: () => {
|
|
296
|
-
const [checkedItems, setCheckedItems] = React.useState<string[]>([
|
|
297
|
-
"item1",
|
|
298
|
-
"item3",
|
|
299
|
-
])
|
|
300
|
-
const [radioValue, setRadioValue] = React.useState("option2")
|
|
301
|
-
|
|
302
|
-
const handleCheckboxChange = (itemId: string, checked: boolean) => {
|
|
303
|
-
setCheckedItems((prev) =>
|
|
304
|
-
checked ? [...prev, itemId] : prev.filter((id) => id !== itemId)
|
|
305
|
-
)
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
return (
|
|
309
|
-
<div className="space-y-8 p-8">
|
|
310
|
-
<h3 className="text-center text-lg font-medium text-white">
|
|
311
|
-
Selection Lists
|
|
312
|
-
</h3>
|
|
313
|
-
|
|
314
|
-
<div className="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
|
315
|
-
{/* Checkbox List */}
|
|
316
|
-
<div className="space-y-4">
|
|
317
|
-
<h4 className="text-sm font-medium text-white/70">
|
|
318
|
-
Multi-Select (Checkbox)
|
|
319
|
-
</h4>
|
|
320
|
-
<List size="default">
|
|
321
|
-
<ListLabel>Choose Features</ListLabel>
|
|
322
|
-
<ListCheckboxItem
|
|
323
|
-
checked={checkedItems.includes("item1")}
|
|
324
|
-
onCheckedChange={(checked) =>
|
|
325
|
-
handleCheckboxChange("item1", checked)
|
|
326
|
-
}
|
|
327
|
-
>
|
|
328
|
-
<FeatureShineIcon />
|
|
329
|
-
Advanced Analytics
|
|
330
|
-
</ListCheckboxItem>
|
|
331
|
-
<ListCheckboxItem
|
|
332
|
-
checked={checkedItems.includes("item2")}
|
|
333
|
-
onCheckedChange={(checked) =>
|
|
334
|
-
handleCheckboxChange("item2", checked)
|
|
335
|
-
}
|
|
336
|
-
>
|
|
337
|
-
<BubbleSparkleIcon />
|
|
338
|
-
Real-time Sync
|
|
339
|
-
</ListCheckboxItem>
|
|
340
|
-
<ListCheckboxItem
|
|
341
|
-
checked={checkedItems.includes("item3")}
|
|
342
|
-
onCheckedChange={(checked) =>
|
|
343
|
-
handleCheckboxChange("item3", checked)
|
|
344
|
-
}
|
|
345
|
-
>
|
|
346
|
-
<LightBulbSimpleIcon />
|
|
347
|
-
AI Suggestions
|
|
348
|
-
</ListCheckboxItem>
|
|
349
|
-
<ListCheckboxItem
|
|
350
|
-
disabled
|
|
351
|
-
checked={checkedItems.includes("item4")}
|
|
352
|
-
onCheckedChange={(checked) =>
|
|
353
|
-
handleCheckboxChange("item4", checked)
|
|
354
|
-
}
|
|
355
|
-
>
|
|
356
|
-
<MaintenanceIcon />
|
|
357
|
-
Premium Feature (Disabled)
|
|
358
|
-
</ListCheckboxItem>
|
|
359
|
-
</List>
|
|
360
|
-
|
|
361
|
-
{checkedItems.length > 0 && (
|
|
362
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-3">
|
|
363
|
-
<p className="text-xs text-white/60">
|
|
364
|
-
Selected: {checkedItems.length} feature
|
|
365
|
-
{checkedItems.length !== 1 ? "s" : ""}
|
|
366
|
-
</p>
|
|
367
|
-
</div>
|
|
368
|
-
)}
|
|
369
|
-
</div>
|
|
370
|
-
|
|
371
|
-
{/* Radio List */}
|
|
372
|
-
<div className="space-y-4">
|
|
373
|
-
<h4 className="text-sm font-medium text-white/70">
|
|
374
|
-
Single Select (Radio)
|
|
375
|
-
</h4>
|
|
376
|
-
<List size="default">
|
|
377
|
-
<ListLabel>Choose Theme</ListLabel>
|
|
378
|
-
<ListRadioGroup value={radioValue} onValueChange={setRadioValue}>
|
|
379
|
-
<ListRadioItem value="option1">
|
|
380
|
-
<EyeOpenIcon />
|
|
381
|
-
Light Theme
|
|
382
|
-
</ListRadioItem>
|
|
383
|
-
<ListRadioItem value="option2">
|
|
384
|
-
<MaintenanceIcon />
|
|
385
|
-
Dark Theme
|
|
386
|
-
</ListRadioItem>
|
|
387
|
-
<ListRadioItem value="option3">
|
|
388
|
-
<FeatureShineIcon />
|
|
389
|
-
Auto Theme
|
|
390
|
-
</ListRadioItem>
|
|
391
|
-
<ListRadioItem value="option4" disabled>
|
|
392
|
-
<BubbleSparkleIcon />
|
|
393
|
-
Custom Theme (Pro)
|
|
394
|
-
</ListRadioItem>
|
|
395
|
-
</ListRadioGroup>
|
|
396
|
-
</List>
|
|
397
|
-
|
|
398
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-3">
|
|
399
|
-
<p className="text-xs text-white/60">
|
|
400
|
-
Selected:{" "}
|
|
401
|
-
{radioValue === "option1"
|
|
402
|
-
? "Light Theme"
|
|
403
|
-
: radioValue === "option2"
|
|
404
|
-
? "Dark Theme"
|
|
405
|
-
: radioValue === "option3"
|
|
406
|
-
? "Auto Theme"
|
|
407
|
-
: "Custom Theme"}
|
|
408
|
-
</p>
|
|
409
|
-
</div>
|
|
410
|
-
</div>
|
|
190
|
+
</List>
|
|
191
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
192
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
193
|
+
<strong className="text-fm-primary">ListItem</strong> is the primary
|
|
194
|
+
interactive row. Supports <code>selected</code>,{" "}
|
|
195
|
+
<code>disabled</code>, and <code>variant="destructive"</code>{" "}
|
|
196
|
+
states, plus an optional right-aligned keyboard shortcut via the{" "}
|
|
197
|
+
<code>shortcut</code> prop.
|
|
198
|
+
</p>
|
|
411
199
|
</div>
|
|
412
200
|
</div>
|
|
413
|
-
)
|
|
414
|
-
},
|
|
415
|
-
parameters: {
|
|
416
|
-
docs: {
|
|
417
|
-
description: {
|
|
418
|
-
story:
|
|
419
|
-
"Interactive selection lists showing checkbox multi-select and radio single-select patterns with state management.",
|
|
420
|
-
},
|
|
421
|
-
},
|
|
422
|
-
},
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// 4. List Variants
|
|
426
|
-
export const ListVariants: Story = {
|
|
427
|
-
render: () => (
|
|
428
|
-
<div className="space-y-8 p-8">
|
|
429
|
-
<h3 className="text-center text-lg font-medium text-white">
|
|
430
|
-
List Variants
|
|
431
|
-
</h3>
|
|
432
|
-
|
|
433
|
-
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
|
434
|
-
{/* Default Variant */}
|
|
435
|
-
<div className="space-y-4">
|
|
436
|
-
<h4 className="text-sm font-medium text-white/70">Default</h4>
|
|
437
|
-
<List variant="default" size="default">
|
|
438
|
-
<ListItem>
|
|
439
|
-
<FileChartIcon />
|
|
440
|
-
Default Style
|
|
441
|
-
</ListItem>
|
|
442
|
-
<ListItem selected>
|
|
443
|
-
<ImageIcon />
|
|
444
|
-
Selected Item
|
|
445
|
-
</ListItem>
|
|
446
|
-
<ListItem>
|
|
447
|
-
<MagicBookIcon />
|
|
448
|
-
Regular Item
|
|
449
|
-
</ListItem>
|
|
450
|
-
</List>
|
|
451
|
-
</div>
|
|
452
|
-
|
|
453
|
-
{/* Elevated Variant */}
|
|
454
|
-
<div className="space-y-4">
|
|
455
|
-
<h4 className="text-sm font-medium text-white/70">Elevated</h4>
|
|
456
|
-
<List variant="elevated" size="default">
|
|
457
|
-
<ListItem>
|
|
458
|
-
<FeatureShineIcon />
|
|
459
|
-
Elevated Style
|
|
460
|
-
</ListItem>
|
|
461
|
-
<ListItem selected>
|
|
462
|
-
<BubbleSparkleIcon />
|
|
463
|
-
More Shadow
|
|
464
|
-
</ListItem>
|
|
465
|
-
<ListItem>
|
|
466
|
-
<LightBulbSimpleIcon />
|
|
467
|
-
Premium Feel
|
|
468
|
-
</ListItem>
|
|
469
|
-
</List>
|
|
470
|
-
</div>
|
|
471
201
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
202
|
+
{/* ListCheckboxItem */}
|
|
203
|
+
<div className="space-y-4">
|
|
204
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
205
|
+
ListCheckboxItem — multi-select row
|
|
206
|
+
</h4>
|
|
207
|
+
<List className="w-56">
|
|
208
|
+
<ListCheckboxItem checked>
|
|
209
|
+
<FeatureShineIcon className="size-4" />
|
|
210
|
+
Spatial Audio
|
|
211
|
+
</ListCheckboxItem>
|
|
212
|
+
<ListCheckboxItem>
|
|
213
|
+
<VolumeFullIcon className="size-4" />
|
|
214
|
+
Crossfade
|
|
215
|
+
</ListCheckboxItem>
|
|
216
|
+
<ListCheckboxItem disabled>
|
|
217
|
+
<SettingIcon className="size-4" />
|
|
218
|
+
Equalizer (Pro)
|
|
219
|
+
</ListCheckboxItem>
|
|
220
|
+
</List>
|
|
221
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
222
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
223
|
+
<strong className="text-fm-primary">ListCheckboxItem</strong>{" "}
|
|
224
|
+
extends ListItem with a tick indicator on the right. Use{" "}
|
|
225
|
+
<code>checked</code> and <code>onCheckedChange</code> for controlled
|
|
226
|
+
state.
|
|
227
|
+
</p>
|
|
489
228
|
</div>
|
|
490
229
|
</div>
|
|
491
|
-
</div>
|
|
492
|
-
),
|
|
493
|
-
parameters: {
|
|
494
|
-
docs: {
|
|
495
|
-
description: {
|
|
496
|
-
story:
|
|
497
|
-
"Different visual variants of the list component: default, elevated (more shadow), and flat (minimal shadow).",
|
|
498
|
-
},
|
|
499
|
-
},
|
|
500
|
-
},
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
// 5. List Sizes
|
|
504
|
-
export const ListSizes: Story = {
|
|
505
|
-
render: () => (
|
|
506
|
-
<div className="space-y-8 p-8">
|
|
507
|
-
<h3 className="text-center text-lg font-medium text-white">List Sizes</h3>
|
|
508
|
-
|
|
509
|
-
<div className="grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-4">
|
|
510
|
-
{/* Small */}
|
|
511
|
-
<div className="space-y-4">
|
|
512
|
-
<h4 className="text-sm font-medium text-white/70">Small</h4>
|
|
513
|
-
<List size="sm">
|
|
514
|
-
<ListItem size="sm">
|
|
515
|
-
<FileChartIcon />
|
|
516
|
-
Small Item
|
|
517
|
-
</ListItem>
|
|
518
|
-
<ListItem size="sm" selected>
|
|
519
|
-
<ImageIcon />
|
|
520
|
-
Selected
|
|
521
|
-
</ListItem>
|
|
522
|
-
</List>
|
|
523
|
-
</div>
|
|
524
230
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
</
|
|
533
|
-
<
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
<ListItem size="lg">
|
|
545
|
-
<BubbleSparkleIcon />
|
|
546
|
-
Large Item
|
|
547
|
-
</ListItem>
|
|
548
|
-
<ListItem size="lg" selected>
|
|
549
|
-
<LightBulbSimpleIcon />
|
|
550
|
-
Selected
|
|
551
|
-
</ListItem>
|
|
552
|
-
</List>
|
|
553
|
-
</div>
|
|
554
|
-
|
|
555
|
-
{/* Extra Large */}
|
|
556
|
-
<div className="space-y-4">
|
|
557
|
-
<h4 className="text-sm font-medium text-white/70">Extra Large</h4>
|
|
558
|
-
<List size="xl">
|
|
559
|
-
<ListItem size="lg">
|
|
560
|
-
<MaintenanceIcon />
|
|
561
|
-
XL Container
|
|
562
|
-
</ListItem>
|
|
563
|
-
<ListItem size="lg" selected>
|
|
564
|
-
<EyeOpenIcon />
|
|
565
|
-
Large Items
|
|
566
|
-
</ListItem>
|
|
567
|
-
</List>
|
|
231
|
+
{/* ListRadioItem */}
|
|
232
|
+
<div className="space-y-4">
|
|
233
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
234
|
+
ListRadioItem — single-select row
|
|
235
|
+
</h4>
|
|
236
|
+
<List className="w-56">
|
|
237
|
+
<ListRadioGroup value="high">
|
|
238
|
+
<ListRadioItem value="low">Low Quality</ListRadioItem>
|
|
239
|
+
<ListRadioItem value="normal">Normal Quality</ListRadioItem>
|
|
240
|
+
<ListRadioItem value="high">High Quality</ListRadioItem>
|
|
241
|
+
</ListRadioGroup>
|
|
242
|
+
</List>
|
|
243
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
244
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
245
|
+
<strong className="text-fm-primary">ListRadioItem</strong> must be
|
|
246
|
+
nested inside a <code>ListRadioGroup</code>. The group manages the{" "}
|
|
247
|
+
<code>value</code>/<code>onValueChange</code> context so only one
|
|
248
|
+
item is selected at a time. Sets <code>role="radio"</code>.
|
|
249
|
+
</p>
|
|
568
250
|
</div>
|
|
569
251
|
</div>
|
|
570
|
-
</div>
|
|
571
|
-
),
|
|
572
|
-
parameters: {
|
|
573
|
-
docs: {
|
|
574
|
-
description: {
|
|
575
|
-
story:
|
|
576
|
-
"Different size variants affecting the minimum width of list containers and padding of list items.",
|
|
577
|
-
},
|
|
578
|
-
},
|
|
579
|
-
},
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
// 6. Border Variants
|
|
583
|
-
export const BorderVariants: Story = {
|
|
584
|
-
render: () => (
|
|
585
|
-
<div className="space-y-8 p-8">
|
|
586
|
-
<h3 className="text-center text-lg font-medium text-white">
|
|
587
|
-
Border Variants
|
|
588
|
-
</h3>
|
|
589
|
-
|
|
590
|
-
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3 xl:grid-cols-5">
|
|
591
|
-
{/* Default */}
|
|
592
|
-
<div className="space-y-4">
|
|
593
|
-
<h4 className="text-sm font-medium text-white/70">Default</h4>
|
|
594
|
-
<List borderVariant="default">
|
|
595
|
-
<ListItem>
|
|
596
|
-
<FileChartIcon />
|
|
597
|
-
Neutral
|
|
598
|
-
</ListItem>
|
|
599
|
-
<ListItem>
|
|
600
|
-
<ImageIcon />
|
|
601
|
-
Border
|
|
602
|
-
</ListItem>
|
|
603
|
-
</List>
|
|
604
|
-
</div>
|
|
605
|
-
|
|
606
|
-
{/* Success */}
|
|
607
|
-
<div className="space-y-4">
|
|
608
|
-
<h4 className="text-sm font-medium text-white/70">Success</h4>
|
|
609
|
-
<List borderVariant="success">
|
|
610
|
-
<ListItem>
|
|
611
|
-
<BubbleCheckIcon />
|
|
612
|
-
Success
|
|
613
|
-
</ListItem>
|
|
614
|
-
<ListItem>
|
|
615
|
-
<TickIcon />
|
|
616
|
-
Complete
|
|
617
|
-
</ListItem>
|
|
618
|
-
</List>
|
|
619
|
-
</div>
|
|
620
|
-
|
|
621
|
-
{/* Error */}
|
|
622
|
-
<div className="space-y-4">
|
|
623
|
-
<h4 className="text-sm font-medium text-white/70">Error</h4>
|
|
624
|
-
<List borderVariant="error">
|
|
625
|
-
<ListItem>
|
|
626
|
-
<TrashIcon />
|
|
627
|
-
Error
|
|
628
|
-
</ListItem>
|
|
629
|
-
<ListItem>
|
|
630
|
-
<MaintenanceIcon />
|
|
631
|
-
Issues
|
|
632
|
-
</ListItem>
|
|
633
|
-
</List>
|
|
634
|
-
</div>
|
|
635
|
-
|
|
636
|
-
{/* Warning */}
|
|
637
|
-
<div className="space-y-4">
|
|
638
|
-
<h4 className="text-sm font-medium text-white/70">Warning</h4>
|
|
639
|
-
<List borderVariant="warning">
|
|
640
|
-
<ListItem>
|
|
641
|
-
<LightBulbSimpleIcon />
|
|
642
|
-
Warning
|
|
643
|
-
</ListItem>
|
|
644
|
-
<ListItem>
|
|
645
|
-
<MaintenanceIcon />
|
|
646
|
-
Caution
|
|
647
|
-
</ListItem>
|
|
648
|
-
</List>
|
|
649
|
-
</div>
|
|
650
252
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
253
|
+
{/* ListSeparator */}
|
|
254
|
+
<div className="space-y-4">
|
|
255
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
256
|
+
ListSeparator — visual divider
|
|
257
|
+
</h4>
|
|
258
|
+
<List className="w-56">
|
|
259
|
+
<ListItem>Above separator</ListItem>
|
|
260
|
+
<ListSeparator />
|
|
261
|
+
<ListItem>Below separator</ListItem>
|
|
262
|
+
</List>
|
|
263
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
264
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
265
|
+
<strong className="text-fm-primary">ListSeparator</strong> renders a
|
|
266
|
+
dashed divider using the design system <code>Divider</code>{" "}
|
|
267
|
+
component with <code>role="separator"</code>.
|
|
268
|
+
</p>
|
|
664
269
|
</div>
|
|
665
270
|
</div>
|
|
666
271
|
|
|
667
|
-
{/*
|
|
668
|
-
<div className="
|
|
669
|
-
<h4 className="
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
No top border
|
|
674
|
-
</ListItem>
|
|
272
|
+
{/* ListSubTrigger */}
|
|
273
|
+
<div className="space-y-4">
|
|
274
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
275
|
+
ListSubTrigger — nested navigation
|
|
276
|
+
</h4>
|
|
277
|
+
<List className="w-56">
|
|
675
278
|
<ListItem>
|
|
676
|
-
<
|
|
677
|
-
|
|
279
|
+
<SearchIcon className="size-4" />
|
|
280
|
+
Search
|
|
678
281
|
</ListItem>
|
|
282
|
+
<ListSubTrigger>
|
|
283
|
+
<SettingIcon className="size-4" />
|
|
284
|
+
More Options
|
|
285
|
+
</ListSubTrigger>
|
|
679
286
|
</List>
|
|
287
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
288
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
289
|
+
<strong className="text-fm-primary">ListSubTrigger</strong> is a
|
|
290
|
+
ListItem with a right-aligned chevron icon indicating a nested
|
|
291
|
+
sub-menu or flyout panel.
|
|
292
|
+
</p>
|
|
293
|
+
</div>
|
|
680
294
|
</div>
|
|
681
295
|
</div>
|
|
682
296
|
),
|
|
683
297
|
parameters: {
|
|
298
|
+
layout: "padded",
|
|
684
299
|
docs: {
|
|
685
300
|
description: {
|
|
686
301
|
story:
|
|
687
|
-
"
|
|
302
|
+
"Each sub-component of the List compound shown individually with a role explanation. Use this as a reference when composing list-based menus and selection panels.",
|
|
688
303
|
},
|
|
689
304
|
},
|
|
690
305
|
},
|
|
691
306
|
}
|
|
692
307
|
|
|
693
|
-
//
|
|
694
|
-
|
|
308
|
+
// ─── 2. AllVariants ───────────────────────────────────────────────────────────
|
|
309
|
+
|
|
310
|
+
export const AllVariants: Story = {
|
|
695
311
|
render: () => (
|
|
696
|
-
<div className="space-y-8
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
312
|
+
<div className="space-y-8">
|
|
313
|
+
{/* Variant axis */}
|
|
314
|
+
<div className="space-y-4">
|
|
315
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
316
|
+
Variant
|
|
317
|
+
</h4>
|
|
318
|
+
<div className="flex flex-wrap items-start justify-center gap-6">
|
|
319
|
+
{(["default", "elevated", "flat"] as const).map((variant) => (
|
|
320
|
+
<div key={variant} className="space-y-2 text-center">
|
|
321
|
+
<List variant={variant} className="w-44">
|
|
322
|
+
<ListItem>
|
|
323
|
+
<MusicalNoteIcon className="size-4" />
|
|
324
|
+
Track item
|
|
325
|
+
</ListItem>
|
|
326
|
+
<ListItem selected>
|
|
327
|
+
<StarIcon className="size-4" />
|
|
328
|
+
Selected
|
|
329
|
+
</ListItem>
|
|
330
|
+
<ListItem>
|
|
331
|
+
<HeartIcon className="size-4" />
|
|
332
|
+
Liked
|
|
333
|
+
</ListItem>
|
|
334
|
+
</List>
|
|
335
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm capitalize">
|
|
336
|
+
{variant}
|
|
337
|
+
</p>
|
|
338
|
+
</div>
|
|
339
|
+
))}
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
700
342
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
<
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
root: "bg-purple-500/30 text-white",
|
|
725
|
-
}}
|
|
726
|
-
>
|
|
727
|
-
<BubbleSparkleIcon />
|
|
728
|
-
Custom Selected
|
|
729
|
-
</ListItem>
|
|
730
|
-
<ListItem
|
|
731
|
-
classes={{
|
|
732
|
-
root: "hover:bg-purple-500/20 text-purple-100",
|
|
733
|
-
}}
|
|
734
|
-
>
|
|
735
|
-
<MagicBookIcon />
|
|
736
|
-
Magic Item
|
|
737
|
-
</ListItem>
|
|
738
|
-
</List>
|
|
343
|
+
{/* Size axis */}
|
|
344
|
+
<div className="space-y-4">
|
|
345
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
346
|
+
Size
|
|
347
|
+
</h4>
|
|
348
|
+
<div className="flex flex-wrap items-start justify-center gap-6">
|
|
349
|
+
{(["sm", "default", "lg", "xl"] as const).map((size) => (
|
|
350
|
+
<div key={size} className="space-y-2 text-center">
|
|
351
|
+
<List size={size}>
|
|
352
|
+
<ListItem size={size === "xl" ? "lg" : size}>
|
|
353
|
+
<MusicalNoteIcon className="size-4" />
|
|
354
|
+
Item
|
|
355
|
+
</ListItem>
|
|
356
|
+
<ListItem size={size === "xl" ? "lg" : size} selected>
|
|
357
|
+
<StarIcon className="size-4" />
|
|
358
|
+
Selected
|
|
359
|
+
</ListItem>
|
|
360
|
+
</List>
|
|
361
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
362
|
+
{size}
|
|
363
|
+
</p>
|
|
364
|
+
</div>
|
|
365
|
+
))}
|
|
739
366
|
</div>
|
|
367
|
+
</div>
|
|
740
368
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
<
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
</div>
|
|
758
|
-
</div>
|
|
759
|
-
<Badge color="positive">Active</Badge>
|
|
760
|
-
</div>
|
|
761
|
-
</ListItem>
|
|
762
|
-
<ListItem size="lg">
|
|
763
|
-
<div className="flex items-center gap-3">
|
|
764
|
-
<div className="rounded-full bg-blue-500/20 p-2">
|
|
765
|
-
<FeatureShineIcon className="size-4 text-blue-400" />
|
|
766
|
-
</div>
|
|
767
|
-
<div className="flex-1">
|
|
768
|
-
<div className="font-medium text-white">AI Assistant</div>
|
|
769
|
-
<div className="text-xs text-white/60">
|
|
770
|
-
Intelligent automation
|
|
771
|
-
</div>
|
|
772
|
-
</div>
|
|
773
|
-
<Badge color="info">Beta</Badge>
|
|
369
|
+
{/* Border variant axis */}
|
|
370
|
+
<div className="space-y-4">
|
|
371
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
372
|
+
Border Variant
|
|
373
|
+
</h4>
|
|
374
|
+
<div className="flex flex-wrap items-start justify-center gap-6">
|
|
375
|
+
{(["default", "success", "error", "warning", "info"] as const).map(
|
|
376
|
+
(bv) => (
|
|
377
|
+
<div key={bv} className="space-y-2 text-center">
|
|
378
|
+
<List borderVariant={bv} className="w-36">
|
|
379
|
+
<ListItem>Item A</ListItem>
|
|
380
|
+
<ListItem>Item B</ListItem>
|
|
381
|
+
</List>
|
|
382
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm capitalize">
|
|
383
|
+
{bv}
|
|
384
|
+
</p>
|
|
774
385
|
</div>
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
386
|
+
)
|
|
387
|
+
)}
|
|
388
|
+
<div className="space-y-2 text-center">
|
|
389
|
+
<List showBorder={false} className="w-36">
|
|
390
|
+
<ListItem>Item A</ListItem>
|
|
391
|
+
<ListItem>Item B</ListItem>
|
|
392
|
+
</List>
|
|
393
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
394
|
+
No border
|
|
395
|
+
</p>
|
|
396
|
+
</div>
|
|
397
|
+
</div>
|
|
398
|
+
</div>
|
|
399
|
+
|
|
400
|
+
{/* Variant × size matrix */}
|
|
401
|
+
<div className="space-y-4">
|
|
402
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
403
|
+
Variant × Size matrix
|
|
404
|
+
</h4>
|
|
405
|
+
<div className="mx-auto grid max-w-4xl grid-cols-2 gap-6 sm:grid-cols-3 lg:grid-cols-4">
|
|
406
|
+
{(["default", "elevated", "flat"] as const).flatMap((variant) =>
|
|
407
|
+
(["sm", "default", "lg"] as const).map((size) => (
|
|
408
|
+
<div key={`${variant}-${size}`} className="space-y-2 text-center">
|
|
409
|
+
<List variant={variant} size={size}>
|
|
410
|
+
<ListItem size={size}>
|
|
411
|
+
<MusicalNoteIcon className="size-4" />
|
|
412
|
+
Track
|
|
413
|
+
</ListItem>
|
|
414
|
+
<ListItem size={size} selected>
|
|
415
|
+
<StarIcon className="size-4" />
|
|
416
|
+
Active
|
|
417
|
+
</ListItem>
|
|
418
|
+
</List>
|
|
419
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
420
|
+
{variant} · {size}
|
|
421
|
+
</p>
|
|
786
422
|
</div>
|
|
787
|
-
|
|
788
|
-
|
|
423
|
+
))
|
|
424
|
+
)}
|
|
789
425
|
</div>
|
|
790
426
|
</div>
|
|
791
427
|
</div>
|
|
792
428
|
),
|
|
793
429
|
parameters: {
|
|
430
|
+
layout: "padded",
|
|
794
431
|
docs: {
|
|
795
432
|
description: {
|
|
796
433
|
story:
|
|
797
|
-
"
|
|
434
|
+
"Full visual matrix across variants (default, elevated, flat), sizes (sm, default, lg, xl), border variants, and a variant × size cross-axis comparison.",
|
|
798
435
|
},
|
|
799
436
|
},
|
|
800
437
|
},
|
|
801
438
|
}
|
|
802
439
|
|
|
803
|
-
//
|
|
804
|
-
|
|
440
|
+
// ─── 3. Interactive ───────────────────────────────────────────────────────────
|
|
441
|
+
|
|
442
|
+
export const Interactive: Story = {
|
|
805
443
|
render: () => {
|
|
806
|
-
const [
|
|
807
|
-
"
|
|
808
|
-
|
|
809
|
-
const [checkedFeatures, setCheckedFeatures] = React.useState<string[]>([
|
|
810
|
-
"analytics",
|
|
444
|
+
const [enabledFeatures, setEnabledFeatures] = React.useState<string[]>([
|
|
445
|
+
"spatial",
|
|
446
|
+
"crossfade",
|
|
811
447
|
])
|
|
812
|
-
const [
|
|
448
|
+
const [audioQuality, setAudioQuality] = React.useState("high")
|
|
449
|
+
const [activeTab, setActiveTab] = React.useState("tracks")
|
|
813
450
|
|
|
814
|
-
const
|
|
815
|
-
|
|
451
|
+
const toggleFeature = (id: string, checked: boolean) => {
|
|
452
|
+
setEnabledFeatures((prev) =>
|
|
453
|
+
checked ? [...prev, id] : prev.filter((f) => f !== id)
|
|
454
|
+
)
|
|
816
455
|
}
|
|
817
456
|
|
|
818
|
-
const
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
)
|
|
457
|
+
const qualityLabel: Record<string, string> = {
|
|
458
|
+
low: "Low (96 kbps)",
|
|
459
|
+
normal: "Normal (160 kbps)",
|
|
460
|
+
high: "High (320 kbps)",
|
|
461
|
+
lossless: "Lossless (FLAC)",
|
|
822
462
|
}
|
|
823
463
|
|
|
824
464
|
return (
|
|
825
|
-
<div className="
|
|
826
|
-
<
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
<
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
465
|
+
<div className="w-full p-8">
|
|
466
|
+
<div className="mx-auto w-full max-w-4xl space-y-6">
|
|
467
|
+
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
|
468
|
+
{/* Controls panel */}
|
|
469
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-5 rounded-xl border p-5">
|
|
470
|
+
<p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
|
|
471
|
+
Navigation
|
|
472
|
+
</p>
|
|
473
|
+
<List showBorder={false} className="w-full">
|
|
474
|
+
<ListItem
|
|
475
|
+
selected={activeTab === "tracks"}
|
|
476
|
+
className="cursor-pointer"
|
|
477
|
+
onClick={() => setActiveTab("tracks")}
|
|
478
|
+
>
|
|
479
|
+
<MusicalNoteIcon className="size-4" />
|
|
480
|
+
Tracks
|
|
481
|
+
</ListItem>
|
|
482
|
+
<ListItem
|
|
483
|
+
selected={activeTab === "artists"}
|
|
484
|
+
className="cursor-pointer"
|
|
485
|
+
onClick={() => setActiveTab("artists")}
|
|
486
|
+
>
|
|
487
|
+
<StarIcon className="size-4" />
|
|
488
|
+
Artists
|
|
489
|
+
<Badge
|
|
490
|
+
color="info"
|
|
491
|
+
size="xs"
|
|
492
|
+
className="bg-fm-surface-info-sec text-fm-info-sec ml-auto"
|
|
493
|
+
>
|
|
494
|
+
NEW
|
|
495
|
+
</Badge>
|
|
496
|
+
</ListItem>
|
|
497
|
+
<ListItem
|
|
498
|
+
selected={activeTab === "liked"}
|
|
499
|
+
className="cursor-pointer"
|
|
500
|
+
onClick={() => setActiveTab("liked")}
|
|
501
|
+
>
|
|
502
|
+
<HeartIcon className="size-4" />
|
|
503
|
+
Liked Songs
|
|
504
|
+
</ListItem>
|
|
505
|
+
<ListItem
|
|
506
|
+
selected={activeTab === "uploads"}
|
|
507
|
+
className="cursor-pointer"
|
|
508
|
+
onClick={() => setActiveTab("uploads")}
|
|
509
|
+
>
|
|
510
|
+
<UploadIcon className="size-4" />
|
|
511
|
+
Uploads
|
|
512
|
+
</ListItem>
|
|
513
|
+
<ListSeparator />
|
|
514
|
+
<ListSubTrigger>
|
|
515
|
+
<SettingIcon className="size-4" />
|
|
516
|
+
Settings
|
|
517
|
+
</ListSubTrigger>
|
|
518
|
+
</List>
|
|
519
|
+
</div>
|
|
870
520
|
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
521
|
+
{/* Preview stage */}
|
|
522
|
+
<div className="flex flex-col gap-6 lg:col-span-2">
|
|
523
|
+
{/* Feature toggles */}
|
|
524
|
+
<div className="space-y-3">
|
|
525
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm font-medium">
|
|
526
|
+
Playback Features (multi-select)
|
|
527
|
+
</p>
|
|
528
|
+
<List borderVariant="success" className="w-full">
|
|
529
|
+
<ListLabel>Audio Enhancements</ListLabel>
|
|
530
|
+
<ListCheckboxItem
|
|
531
|
+
checked={enabledFeatures.includes("spatial")}
|
|
532
|
+
onCheckedChange={(c) => toggleFeature("spatial", c)}
|
|
533
|
+
>
|
|
534
|
+
<VolumeFullIcon className="size-4" />
|
|
535
|
+
Spatial Audio
|
|
536
|
+
</ListCheckboxItem>
|
|
537
|
+
<ListCheckboxItem
|
|
538
|
+
checked={enabledFeatures.includes("crossfade")}
|
|
539
|
+
onCheckedChange={(c) => toggleFeature("crossfade", c)}
|
|
540
|
+
>
|
|
541
|
+
<FeatureShineIcon className="size-4" />
|
|
542
|
+
Crossfade
|
|
543
|
+
</ListCheckboxItem>
|
|
544
|
+
<ListCheckboxItem
|
|
545
|
+
checked={enabledFeatures.includes("normalize")}
|
|
546
|
+
onCheckedChange={(c) => toggleFeature("normalize", c)}
|
|
547
|
+
>
|
|
548
|
+
<SettingIcon className="size-4" />
|
|
549
|
+
Volume Normalize
|
|
550
|
+
</ListCheckboxItem>
|
|
551
|
+
<ListCheckboxItem disabled>
|
|
552
|
+
<StarIcon className="size-4" />
|
|
553
|
+
Dolby Atmos (Pro)
|
|
554
|
+
</ListCheckboxItem>
|
|
555
|
+
</List>
|
|
556
|
+
</div>
|
|
905
557
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
<
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
558
|
+
{/* Quality selector */}
|
|
559
|
+
<div className="space-y-3">
|
|
560
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm font-medium">
|
|
561
|
+
Streaming Quality (single-select)
|
|
562
|
+
</p>
|
|
563
|
+
<List borderVariant="info" className="w-full">
|
|
564
|
+
<ListLabel>Audio Quality</ListLabel>
|
|
565
|
+
<ListRadioGroup
|
|
566
|
+
value={audioQuality}
|
|
567
|
+
onValueChange={setAudioQuality}
|
|
568
|
+
>
|
|
569
|
+
<ListRadioItem value="low">Low (96 kbps)</ListRadioItem>
|
|
570
|
+
<ListRadioItem value="normal">
|
|
571
|
+
Normal (160 kbps)
|
|
572
|
+
</ListRadioItem>
|
|
573
|
+
<ListRadioItem value="high">High (320 kbps)</ListRadioItem>
|
|
574
|
+
<ListRadioItem value="lossless">
|
|
575
|
+
Lossless (FLAC)
|
|
576
|
+
</ListRadioItem>
|
|
577
|
+
</ListRadioGroup>
|
|
578
|
+
</List>
|
|
579
|
+
</div>
|
|
928
580
|
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
581
|
+
{/* State readout */}
|
|
582
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
583
|
+
<p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm mb-3 font-semibold">
|
|
584
|
+
Current State
|
|
585
|
+
</p>
|
|
586
|
+
<div className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm grid grid-cols-1 gap-2 sm:grid-cols-3">
|
|
587
|
+
<div>
|
|
588
|
+
<span className="text-fm-primary font-medium">
|
|
589
|
+
Section:{" "}
|
|
590
|
+
</span>
|
|
591
|
+
<span className="capitalize">{activeTab}</span>
|
|
592
|
+
</div>
|
|
593
|
+
<div>
|
|
594
|
+
<span className="text-fm-primary font-medium">
|
|
595
|
+
Features:{" "}
|
|
596
|
+
</span>
|
|
597
|
+
<span>
|
|
598
|
+
{enabledFeatures.length > 0
|
|
599
|
+
? enabledFeatures.join(", ")
|
|
600
|
+
: "none"}
|
|
601
|
+
</span>
|
|
602
|
+
</div>
|
|
603
|
+
<div>
|
|
604
|
+
<span className="text-fm-primary font-medium">
|
|
605
|
+
Quality:{" "}
|
|
606
|
+
</span>
|
|
607
|
+
<span>{qualityLabel[audioQuality]}</span>
|
|
608
|
+
</div>
|
|
609
|
+
</div>
|
|
610
|
+
</div>
|
|
949
611
|
</div>
|
|
950
612
|
</div>
|
|
951
613
|
</div>
|
|
@@ -953,10 +615,11 @@ export const InteractiveShowcase: Story = {
|
|
|
953
615
|
)
|
|
954
616
|
},
|
|
955
617
|
parameters: {
|
|
618
|
+
layout: "fullscreen",
|
|
956
619
|
docs: {
|
|
957
620
|
description: {
|
|
958
621
|
story:
|
|
959
|
-
"Fully interactive
|
|
622
|
+
"Fully interactive story demonstrating navigation selection (single active tab), multi-select feature toggles via ListCheckboxItem, and streaming quality selection via ListRadioItem — all with live state readout.",
|
|
960
623
|
},
|
|
961
624
|
},
|
|
962
625
|
},
|