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,16 +1,17 @@
|
|
|
1
1
|
import React from "react"
|
|
2
2
|
import {
|
|
3
3
|
AlertIcon,
|
|
4
|
-
CrossIcon,
|
|
5
|
-
EditBigIcon,
|
|
6
|
-
EyeOpenIcon,
|
|
7
4
|
FileChartIcon,
|
|
8
|
-
|
|
5
|
+
HeartIcon,
|
|
6
|
+
MusicalNoteIcon,
|
|
9
7
|
SearchIcon,
|
|
10
|
-
|
|
8
|
+
SettingIcon,
|
|
9
|
+
StarIcon,
|
|
11
10
|
} from "@icons/index"
|
|
12
11
|
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
13
12
|
|
|
13
|
+
import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
|
|
14
|
+
|
|
14
15
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "."
|
|
15
16
|
|
|
16
17
|
const meta: Meta<typeof Tabs> = {
|
|
@@ -27,168 +28,27 @@ const meta: Meta<typeof Tabs> = {
|
|
|
27
28
|
},
|
|
28
29
|
docs: {
|
|
29
30
|
description: {
|
|
30
|
-
component:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
A beautiful and accessible tabs component built on top of Radix UI's Tabs primitive with custom styling and animations. Features smooth tab transitions, hover effects, and a stunning gradient glow for active tabs.
|
|
34
|
-
|
|
35
|
-
## Components
|
|
36
|
-
|
|
37
|
-
### Core Components
|
|
38
|
-
- **Tabs**: Root container for the entire tabs system with size context
|
|
39
|
-
- **TabsList**: Container for all tab triggers
|
|
40
|
-
- **TabsTrigger**: Individual tab buttons with custom glow effects
|
|
41
|
-
- **TabsContent**: Content panels that display when tabs are active
|
|
42
|
-
|
|
43
|
-
## Features
|
|
44
|
-
|
|
45
|
-
- **Gradient Glow Effects**: Beautiful radial gradient with blur effects on active tabs
|
|
46
|
-
- **Smooth Animations**: Fade in/out transitions between active and inactive states
|
|
47
|
-
- **Size Variants**: Small, medium, and large tab sizes via context
|
|
48
|
-
- **Keyboard Accessible**: Full keyboard navigation support
|
|
49
|
-
- **Screen Reader Support**: Proper ARIA attributes and announcements
|
|
50
|
-
- **Custom Styling**: Tailored design system integration
|
|
51
|
-
- **Responsive Design**: Adapts to different screen sizes
|
|
52
|
-
- **Icon Support**: Built-in support for icons in tab labels
|
|
53
|
-
|
|
54
|
-
## Size Variants
|
|
55
|
-
|
|
56
|
-
### Small (sm)
|
|
57
|
-
- Font size: var(--text-fm-md)
|
|
58
|
-
- Padding: 8px (p-2)
|
|
59
|
-
- Ideal for: Compact interfaces, sidebars
|
|
60
|
-
|
|
61
|
-
### Medium (md) - Default
|
|
62
|
-
- Font size: var(--text-fm-xl)
|
|
63
|
-
- Padding: 12px horizontal, 16px top, 12px bottom
|
|
64
|
-
- Ideal for: Main navigation, content sections
|
|
65
|
-
|
|
66
|
-
### Large (lg)
|
|
67
|
-
- Font size: var(--text-fm-2xl)
|
|
68
|
-
- Padding: 12px horizontal, 16px top, 12px bottom
|
|
69
|
-
- Ideal for: Primary navigation, hero sections
|
|
70
|
-
|
|
71
|
-
## Visual Effects
|
|
72
|
-
|
|
73
|
-
### Active Tab Glow
|
|
74
|
-
The active tab features a stunning dual-layer gradient effect with configurable direction:
|
|
75
|
-
- **Glow Direction**: Choose between "bottom" (default) or "top" glow positioning
|
|
76
|
-
- **Bottom Layer**: Curved gradient line at the tab base
|
|
77
|
-
- **Top Layer**: Blurred elliptical glow with screen blend mode
|
|
78
|
-
- **Colors**: Red to purple to black gradient (#FF3E4C → #5200A3 → #0A0A0A)
|
|
79
|
-
|
|
80
|
-
### Animations
|
|
81
|
-
- **Fade In**: Active tabs fade in with animate-fm-fadeIn
|
|
82
|
-
- **Fade Out**: Inactive tabs fade out with animate-fm-fadeOut
|
|
83
|
-
- **Smooth Transitions**: Color and glow transitions
|
|
84
|
-
|
|
85
|
-
## Usage Examples
|
|
86
|
-
|
|
87
|
-
### Basic Tabs with Size
|
|
88
|
-
\`\`\`tsx
|
|
89
|
-
<Tabs defaultValue="tab1" size="lg">
|
|
90
|
-
<TabsList>
|
|
91
|
-
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
|
|
92
|
-
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
|
|
93
|
-
</TabsList>
|
|
94
|
-
<TabsContent value="tab1">Content 1</TabsContent>
|
|
95
|
-
<TabsContent value="tab2">Content 2</TabsContent>
|
|
96
|
-
</Tabs>
|
|
97
|
-
\`\`\`
|
|
98
|
-
|
|
99
|
-
### With Icons
|
|
100
|
-
\`\`\`tsx
|
|
101
|
-
<Tabs defaultValue="dashboard" size="md">
|
|
102
|
-
<TabsList>
|
|
103
|
-
<TabsTrigger value="dashboard">
|
|
104
|
-
<BarChart className="w-4 h-4" />
|
|
105
|
-
Dashboard
|
|
106
|
-
</TabsTrigger>
|
|
107
|
-
<TabsTrigger value="settings">
|
|
108
|
-
<Settings className="w-4 h-4" />
|
|
109
|
-
Settings
|
|
110
|
-
</TabsTrigger>
|
|
111
|
-
</TabsList>
|
|
112
|
-
<TabsContent value="dashboard">Dashboard content</TabsContent>
|
|
113
|
-
<TabsContent value="settings">Settings content</TabsContent>
|
|
114
|
-
</Tabs>
|
|
115
|
-
\`\`\`
|
|
116
|
-
|
|
117
|
-
### With Glow Direction
|
|
118
|
-
\`\`\`tsx
|
|
119
|
-
<Tabs defaultValue="overview" size="md">
|
|
120
|
-
<TabsList>
|
|
121
|
-
<TabsTrigger value="overview" glowDirection="bottom">Overview</TabsTrigger>
|
|
122
|
-
<TabsTrigger value="analytics" glowDirection="top">Analytics</TabsTrigger>
|
|
123
|
-
<TabsTrigger value="settings" glowDirection="bottom">Settings</TabsTrigger>
|
|
124
|
-
</TabsList>
|
|
125
|
-
<TabsContent value="overview">Overview content</TabsContent>
|
|
126
|
-
<TabsContent value="analytics">Analytics content</TabsContent>
|
|
127
|
-
<TabsContent value="settings">Settings content</TabsContent>
|
|
128
|
-
</Tabs>
|
|
129
|
-
\`\`\`
|
|
130
|
-
|
|
131
|
-
### Individual Size Override
|
|
132
|
-
\`\`\`tsx
|
|
133
|
-
<Tabs defaultValue="home" size="md">
|
|
134
|
-
<TabsList>
|
|
135
|
-
<TabsTrigger value="home">Home</TabsTrigger>
|
|
136
|
-
<TabsTrigger value="about" size="lg">About (Large)</TabsTrigger>
|
|
137
|
-
</TabsList>
|
|
138
|
-
<TabsContent value="home">Home content</TabsContent>
|
|
139
|
-
<TabsContent value="about">About content</TabsContent>
|
|
140
|
-
</Tabs>
|
|
141
|
-
\`\`\`
|
|
142
|
-
|
|
143
|
-
## Props
|
|
144
|
-
|
|
145
|
-
### Tabs Props
|
|
146
|
-
- **size**: "sm" | "md" | "lg" - Sets the size for all child TabsTrigger components
|
|
147
|
-
- **defaultValue**: string - The default active tab
|
|
148
|
-
- **value**: string - Controlled active tab value
|
|
149
|
-
- **onValueChange**: (value: string) => void - Callback when tab changes
|
|
150
|
-
|
|
151
|
-
### TabsTrigger Props
|
|
152
|
-
- **size**: "sm" | "md" | "lg" - Optional override for individual triggers
|
|
153
|
-
- **glowDirection**: "bottom" | "top" - Direction of the glow effect (default: "bottom")
|
|
154
|
-
- **value**: string - Unique identifier for the tab
|
|
155
|
-
- **disabled**: boolean - Disable the tab trigger
|
|
156
|
-
|
|
157
|
-
## Accessibility
|
|
158
|
-
|
|
159
|
-
- **Keyboard Navigation**: Arrow keys to move between tabs, Space/Enter to activate
|
|
160
|
-
- **Screen Reader Support**: Proper ARIA labels and announcements
|
|
161
|
-
- **Focus Management**: Clear focus indicators and logical tab order
|
|
162
|
-
- **Role Attributes**: Correct tab, tablist, and tabpanel roles
|
|
163
|
-
- **State Announcements**: Active/inactive states announced to screen readers
|
|
164
|
-
|
|
165
|
-
## Design System Integration
|
|
166
|
-
|
|
167
|
-
- **Color Tokens**: Uses design system color tokens (fm-primary, fm-tertiary, etc.)
|
|
168
|
-
- **Typography**: Integrated with font size and leading variables
|
|
169
|
-
- **Focus States**: Consistent focus ring styling
|
|
170
|
-
- **Transitions**: Smooth color and effect transitions
|
|
171
|
-
- **Border Styles**: Consistent with design system borders
|
|
172
|
-
|
|
173
|
-
## Best Practices
|
|
174
|
-
|
|
175
|
-
- Keep tab labels concise and descriptive
|
|
176
|
-
- Use icons to improve visual hierarchy
|
|
177
|
-
- Don't use more than 7-8 tabs in a single group
|
|
178
|
-
- Ensure tab content is substantial enough to warrant separation
|
|
179
|
-
- Test keyboard navigation thoroughly
|
|
180
|
-
- Consider mobile responsive behavior
|
|
181
|
-
- Use consistent sizing throughout your application
|
|
182
|
-
- Set size on Tabs component instead of individual triggers
|
|
183
|
-
|
|
184
|
-
## Performance
|
|
185
|
-
|
|
186
|
-
- **Lazy Loading**: Content panels only render when active
|
|
187
|
-
- **Efficient Re-renders**: Optimized state management with context
|
|
188
|
-
- **CSS Animations**: Hardware-accelerated animations
|
|
189
|
-
- **Minimal DOM**: Clean, semantic HTML structure
|
|
190
|
-
`,
|
|
31
|
+
component:
|
|
32
|
+
"A compound tabs component built on Radix UI Tabs with gradient glow effects on active triggers, smooth fade animations, and three size variants. Supports bottom and top glow directions and per-trigger size overrides via a shared size context.",
|
|
191
33
|
},
|
|
34
|
+
page: () => (
|
|
35
|
+
<AuralComponentDocsPage
|
|
36
|
+
features={[
|
|
37
|
+
{
|
|
38
|
+
title: "Gradient Glow",
|
|
39
|
+
description: "Active trigger effect",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
title: "3 Sizes",
|
|
43
|
+
description: "sm, md, lg via context",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
title: "Fade Animation",
|
|
47
|
+
description: "Smooth content switch",
|
|
48
|
+
},
|
|
49
|
+
]}
|
|
50
|
+
/>
|
|
51
|
+
),
|
|
192
52
|
},
|
|
193
53
|
},
|
|
194
54
|
tags: ["autodocs"],
|
|
@@ -196,626 +56,123 @@ The active tab features a stunning dual-layer gradient effect with configurable
|
|
|
196
56
|
size: {
|
|
197
57
|
control: "select",
|
|
198
58
|
options: ["sm", "md", "lg"],
|
|
199
|
-
description: "Size variant applied to all tab triggers",
|
|
59
|
+
description: "Size variant applied to all tab triggers via context",
|
|
200
60
|
},
|
|
201
61
|
defaultValue: {
|
|
202
62
|
control: "text",
|
|
203
63
|
description: "The default active tab value",
|
|
204
64
|
},
|
|
205
|
-
value: {
|
|
206
|
-
control: "text",
|
|
207
|
-
description: "The controlled active tab value",
|
|
208
|
-
},
|
|
209
|
-
onValueChange: {
|
|
210
|
-
action: "valueChanged",
|
|
211
|
-
description: "Callback when tab changes",
|
|
212
|
-
},
|
|
213
65
|
},
|
|
214
66
|
}
|
|
215
67
|
|
|
216
68
|
export default meta
|
|
217
69
|
type Story = StoryObj<typeof Tabs>
|
|
218
70
|
|
|
219
|
-
//
|
|
220
|
-
export const Basic: Story = {
|
|
221
|
-
render: () => (
|
|
222
|
-
<div className="w-full max-w-2xl">
|
|
223
|
-
<Tabs defaultValue="overview" className="w-full">
|
|
224
|
-
<TabsList className="grid w-full grid-cols-3">
|
|
225
|
-
<TabsTrigger value="overview">Overview</TabsTrigger>
|
|
226
|
-
<TabsTrigger value="analytics">Analytics</TabsTrigger>
|
|
227
|
-
<TabsTrigger value="reports">Reports</TabsTrigger>
|
|
228
|
-
</TabsList>
|
|
229
|
-
<TabsContent value="overview" className="mt-6">
|
|
230
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
231
|
-
<h3 className="mb-4 text-lg font-semibold text-white">Overview</h3>
|
|
232
|
-
<p className="mb-4 text-white/70">
|
|
233
|
-
Get a comprehensive view of your project's key metrics and
|
|
234
|
-
performance indicators.
|
|
235
|
-
</p>
|
|
236
|
-
<div className="grid grid-cols-2 gap-4">
|
|
237
|
-
<div className="rounded-lg border border-blue-500/20 bg-blue-500/10 p-4">
|
|
238
|
-
<div className="text-2xl font-bold text-blue-400">1,234</div>
|
|
239
|
-
<div className="text-sm text-white/60">Total Users</div>
|
|
240
|
-
</div>
|
|
241
|
-
<div className="rounded-lg border border-green-500/20 bg-green-500/10 p-4">
|
|
242
|
-
<div className="text-2xl font-bold text-green-400">98.5%</div>
|
|
243
|
-
<div className="text-sm text-white/60">Uptime</div>
|
|
244
|
-
</div>
|
|
245
|
-
</div>
|
|
246
|
-
</div>
|
|
247
|
-
</TabsContent>
|
|
248
|
-
<TabsContent value="analytics" className="mt-6">
|
|
249
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
250
|
-
<h3 className="mb-4 text-lg font-semibold text-white">Analytics</h3>
|
|
251
|
-
<p className="mb-4 text-white/70">
|
|
252
|
-
Deep dive into user behavior and engagement patterns across your
|
|
253
|
-
platform.
|
|
254
|
-
</p>
|
|
255
|
-
<div className="space-y-4">
|
|
256
|
-
<div className="flex items-center justify-between rounded-lg bg-white/5 p-3">
|
|
257
|
-
<span className="text-white">Page Views</span>
|
|
258
|
-
<span className="font-semibold text-green-400">+12.5%</span>
|
|
259
|
-
</div>
|
|
260
|
-
<div className="flex items-center justify-between rounded-lg bg-white/5 p-3">
|
|
261
|
-
<span className="text-white">Session Duration</span>
|
|
262
|
-
<span className="font-semibold text-blue-400">4:32 avg</span>
|
|
263
|
-
</div>
|
|
264
|
-
<div className="flex items-center justify-between rounded-lg bg-white/5 p-3">
|
|
265
|
-
<span className="text-white">Bounce Rate</span>
|
|
266
|
-
<span className="font-semibold text-orange-400">32.1%</span>
|
|
267
|
-
</div>
|
|
268
|
-
</div>
|
|
269
|
-
</div>
|
|
270
|
-
</TabsContent>
|
|
271
|
-
<TabsContent value="reports" className="mt-6">
|
|
272
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
273
|
-
<h3 className="mb-4 text-lg font-semibold text-white">Reports</h3>
|
|
274
|
-
<p className="mb-4 text-white/70">
|
|
275
|
-
Generate and download detailed reports for stakeholders and
|
|
276
|
-
analysis.
|
|
277
|
-
</p>
|
|
278
|
-
<div className="space-y-3">
|
|
279
|
-
<button className="w-full rounded-lg bg-white/5 p-3 text-left transition-colors hover:bg-white/10">
|
|
280
|
-
<div className="font-medium text-white">
|
|
281
|
-
Monthly Performance Report
|
|
282
|
-
</div>
|
|
283
|
-
<div className="text-sm text-white/60">
|
|
284
|
-
Last generated: 2 days ago
|
|
285
|
-
</div>
|
|
286
|
-
</button>
|
|
287
|
-
<button className="w-full rounded-lg bg-white/5 p-3 text-left transition-colors hover:bg-white/10">
|
|
288
|
-
<div className="font-medium text-white">
|
|
289
|
-
User Engagement Analysis
|
|
290
|
-
</div>
|
|
291
|
-
<div className="text-sm text-white/60">
|
|
292
|
-
Last generated: 1 week ago
|
|
293
|
-
</div>
|
|
294
|
-
</button>
|
|
295
|
-
<button className="w-full rounded-lg bg-white/5 p-3 text-left transition-colors hover:bg-white/10">
|
|
296
|
-
<div className="font-medium text-white">Revenue Breakdown</div>
|
|
297
|
-
<div className="text-sm text-white/60">
|
|
298
|
-
Last generated: 3 days ago
|
|
299
|
-
</div>
|
|
300
|
-
</button>
|
|
301
|
-
</div>
|
|
302
|
-
</div>
|
|
303
|
-
</TabsContent>
|
|
304
|
-
</Tabs>
|
|
305
|
-
</div>
|
|
306
|
-
),
|
|
307
|
-
parameters: {
|
|
308
|
-
docs: {
|
|
309
|
-
description: {
|
|
310
|
-
story:
|
|
311
|
-
"Basic tabs implementation with three panels showing different types of content using default medium size.",
|
|
312
|
-
},
|
|
313
|
-
},
|
|
314
|
-
},
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// 2. With Icons
|
|
318
|
-
export const WithIcons: Story = {
|
|
319
|
-
render: () => (
|
|
320
|
-
<div className="w-full max-w-3xl">
|
|
321
|
-
<Tabs defaultValue="dashboard" className="w-full">
|
|
322
|
-
<TabsList className="grid w-full grid-cols-4">
|
|
323
|
-
<TabsTrigger value="dashboard" className="gap-2">
|
|
324
|
-
<FileChartIcon className="h-4 w-4" />
|
|
325
|
-
Dashboard
|
|
326
|
-
</TabsTrigger>
|
|
327
|
-
<TabsTrigger value="users" className="gap-2">
|
|
328
|
-
<EyeOpenIcon className="h-4 w-4" />
|
|
329
|
-
Users
|
|
330
|
-
</TabsTrigger>
|
|
331
|
-
<TabsTrigger value="settings" className="gap-2">
|
|
332
|
-
<EditBigIcon className="h-4 w-4" />
|
|
333
|
-
Settings
|
|
334
|
-
</TabsTrigger>
|
|
335
|
-
<TabsTrigger value="alerts" className="gap-2">
|
|
336
|
-
<AlertIcon className="h-4 w-4" />
|
|
337
|
-
Alerts
|
|
338
|
-
</TabsTrigger>
|
|
339
|
-
</TabsList>
|
|
340
|
-
|
|
341
|
-
<TabsContent value="dashboard" className="mt-6">
|
|
342
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
343
|
-
<div className="mb-4 flex items-center gap-3">
|
|
344
|
-
<FileChartIcon className="h-6 w-6 text-blue-400" />
|
|
345
|
-
<h3 className="text-lg font-semibold text-white">Dashboard</h3>
|
|
346
|
-
</div>
|
|
347
|
-
<div className="grid grid-cols-1 gap-4 md:grid-cols-3">
|
|
348
|
-
<div className="rounded-lg border border-blue-500/30 bg-gradient-to-br from-blue-500/20 to-purple-500/20 p-4">
|
|
349
|
-
<div className="text-2xl font-bold text-white">847</div>
|
|
350
|
-
<div className="text-sm text-white/70">Active Sessions</div>
|
|
351
|
-
<div className="mt-1 text-xs text-green-400">
|
|
352
|
-
↗ +15% from yesterday
|
|
353
|
-
</div>
|
|
354
|
-
</div>
|
|
355
|
-
<div className="rounded-lg border border-green-500/30 bg-gradient-to-br from-green-500/20 to-teal-500/20 p-4">
|
|
356
|
-
<div className="text-2xl font-bold text-white">$12,847</div>
|
|
357
|
-
<div className="text-sm text-white/70">Revenue Today</div>
|
|
358
|
-
<div className="mt-1 text-xs text-green-400">
|
|
359
|
-
↗ +8% from yesterday
|
|
360
|
-
</div>
|
|
361
|
-
</div>
|
|
362
|
-
<div className="rounded-lg border border-orange-500/30 bg-gradient-to-br from-orange-500/20 to-red-500/20 p-4">
|
|
363
|
-
<div className="text-2xl font-bold text-white">23</div>
|
|
364
|
-
<div className="text-sm text-white/70">Critical Issues</div>
|
|
365
|
-
<div className="mt-1 text-xs text-red-400">↗ +3 new issues</div>
|
|
366
|
-
</div>
|
|
367
|
-
</div>
|
|
368
|
-
</div>
|
|
369
|
-
</TabsContent>
|
|
370
|
-
|
|
371
|
-
<TabsContent value="users" className="mt-6">
|
|
372
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
373
|
-
<div className="mb-4 flex items-center gap-3">
|
|
374
|
-
<EyeOpenIcon className="h-6 w-6 text-green-400" />
|
|
375
|
-
<h3 className="text-lg font-semibold text-white">
|
|
376
|
-
User Management
|
|
377
|
-
</h3>
|
|
378
|
-
</div>
|
|
379
|
-
<div className="space-y-3">
|
|
380
|
-
{[
|
|
381
|
-
{
|
|
382
|
-
name: "Alice Johnson",
|
|
383
|
-
role: "Admin",
|
|
384
|
-
status: "online",
|
|
385
|
-
avatar: "AJ",
|
|
386
|
-
},
|
|
387
|
-
{
|
|
388
|
-
name: "Bob Smith",
|
|
389
|
-
role: "Editor",
|
|
390
|
-
status: "away",
|
|
391
|
-
avatar: "BS",
|
|
392
|
-
},
|
|
393
|
-
{
|
|
394
|
-
name: "Carol Davis",
|
|
395
|
-
role: "Viewer",
|
|
396
|
-
status: "offline",
|
|
397
|
-
avatar: "CD",
|
|
398
|
-
},
|
|
399
|
-
{
|
|
400
|
-
name: "David Wilson",
|
|
401
|
-
role: "Admin",
|
|
402
|
-
status: "online",
|
|
403
|
-
avatar: "DW",
|
|
404
|
-
},
|
|
405
|
-
].map((user, index) => (
|
|
406
|
-
<div
|
|
407
|
-
key={index}
|
|
408
|
-
className="flex items-center justify-between rounded-lg bg-white/5 p-3 transition-colors hover:bg-white/10"
|
|
409
|
-
>
|
|
410
|
-
<div className="flex items-center gap-3">
|
|
411
|
-
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-gradient-to-br from-purple-500 to-pink-500">
|
|
412
|
-
<span className="text-sm font-semibold text-white">
|
|
413
|
-
{user.avatar}
|
|
414
|
-
</span>
|
|
415
|
-
</div>
|
|
416
|
-
<div>
|
|
417
|
-
<div className="font-medium text-white">{user.name}</div>
|
|
418
|
-
<div className="text-sm text-white/60">{user.role}</div>
|
|
419
|
-
</div>
|
|
420
|
-
</div>
|
|
421
|
-
<div className="flex items-center gap-2">
|
|
422
|
-
<div
|
|
423
|
-
className={`h-2 w-2 rounded-full ${
|
|
424
|
-
user.status === "online"
|
|
425
|
-
? "bg-green-500"
|
|
426
|
-
: user.status === "away"
|
|
427
|
-
? "bg-yellow-500"
|
|
428
|
-
: "bg-gray-500"
|
|
429
|
-
}`}
|
|
430
|
-
/>
|
|
431
|
-
<span className="text-xs text-white/60 capitalize">
|
|
432
|
-
{user.status}
|
|
433
|
-
</span>
|
|
434
|
-
</div>
|
|
435
|
-
</div>
|
|
436
|
-
))}
|
|
437
|
-
</div>
|
|
438
|
-
</div>
|
|
439
|
-
</TabsContent>
|
|
440
|
-
|
|
441
|
-
<TabsContent value="settings" className="mt-6">
|
|
442
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
443
|
-
<div className="mb-4 flex items-center gap-3">
|
|
444
|
-
<EditBigIcon className="h-6 w-6 text-purple-400" />
|
|
445
|
-
<h3 className="text-lg font-semibold text-white">Settings</h3>
|
|
446
|
-
</div>
|
|
447
|
-
<div className="space-y-4">
|
|
448
|
-
<div className="flex items-center justify-between rounded-lg bg-white/5 p-3">
|
|
449
|
-
<div>
|
|
450
|
-
<div className="font-medium text-white">
|
|
451
|
-
Email Notifications
|
|
452
|
-
</div>
|
|
453
|
-
<div className="text-sm text-white/60">
|
|
454
|
-
Receive updates via email
|
|
455
|
-
</div>
|
|
456
|
-
</div>
|
|
457
|
-
<button className="relative h-6 w-12 rounded-full bg-blue-500">
|
|
458
|
-
<div className="absolute top-0.5 right-0.5 h-5 w-5 rounded-full bg-white transition-transform"></div>
|
|
459
|
-
</button>
|
|
460
|
-
</div>
|
|
461
|
-
<div className="flex items-center justify-between rounded-lg bg-white/5 p-3">
|
|
462
|
-
<div>
|
|
463
|
-
<div className="font-medium text-white">Dark Mode</div>
|
|
464
|
-
<div className="text-sm text-white/60">Use dark theme</div>
|
|
465
|
-
</div>
|
|
466
|
-
<button className="relative h-6 w-12 rounded-full bg-blue-500">
|
|
467
|
-
<div className="absolute top-0.5 right-0.5 h-5 w-5 rounded-full bg-white transition-transform"></div>
|
|
468
|
-
</button>
|
|
469
|
-
</div>
|
|
470
|
-
<div className="flex items-center justify-between rounded-lg bg-white/5 p-3">
|
|
471
|
-
<div>
|
|
472
|
-
<div className="font-medium text-white">Auto-save</div>
|
|
473
|
-
<div className="text-sm text-white/60">
|
|
474
|
-
Automatically save changes
|
|
475
|
-
</div>
|
|
476
|
-
</div>
|
|
477
|
-
<button className="relative h-6 w-12 rounded-full bg-gray-600">
|
|
478
|
-
<div className="absolute top-0.5 left-0.5 h-5 w-5 rounded-full bg-white transition-transform"></div>
|
|
479
|
-
</button>
|
|
480
|
-
</div>
|
|
481
|
-
</div>
|
|
482
|
-
</div>
|
|
483
|
-
</TabsContent>
|
|
484
|
-
|
|
485
|
-
<TabsContent value="alerts" className="mt-6">
|
|
486
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
487
|
-
<div className="mb-4 flex items-center gap-3">
|
|
488
|
-
<AlertIcon className="h-6 w-6 text-red-400" />
|
|
489
|
-
<h3 className="text-lg font-semibold text-white">
|
|
490
|
-
System Alerts
|
|
491
|
-
</h3>
|
|
492
|
-
</div>
|
|
493
|
-
<div className="space-y-3">
|
|
494
|
-
<div className="flex items-start gap-3 rounded-lg border border-red-500/20 bg-red-500/10 p-3">
|
|
495
|
-
<AlertIcon className="mt-0.5 h-5 w-5 flex-shrink-0 text-red-400" />
|
|
496
|
-
<div>
|
|
497
|
-
<div className="font-medium text-white">High CPU Usage</div>
|
|
498
|
-
<div className="text-sm text-white/70">
|
|
499
|
-
Server load is above 90% threshold
|
|
500
|
-
</div>
|
|
501
|
-
<div className="mt-1 text-xs text-white/50">
|
|
502
|
-
2 minutes ago
|
|
503
|
-
</div>
|
|
504
|
-
</div>
|
|
505
|
-
</div>
|
|
506
|
-
<div className="flex items-start gap-3 rounded-lg border border-yellow-500/20 bg-yellow-500/10 p-3">
|
|
507
|
-
<AlertIcon className="mt-0.5 h-5 w-5 flex-shrink-0 text-yellow-400" />
|
|
508
|
-
<div>
|
|
509
|
-
<div className="font-medium text-white">
|
|
510
|
-
Database Connection
|
|
511
|
-
</div>
|
|
512
|
-
<div className="text-sm text-white/70">
|
|
513
|
-
Intermittent connectivity issues detected
|
|
514
|
-
</div>
|
|
515
|
-
<div className="mt-1 text-xs text-white/50">
|
|
516
|
-
15 minutes ago
|
|
517
|
-
</div>
|
|
518
|
-
</div>
|
|
519
|
-
</div>
|
|
520
|
-
<div className="flex items-start gap-3 rounded-lg border border-green-500/20 bg-green-500/10 p-3">
|
|
521
|
-
<TickCircleIcon className="mt-0.5 h-5 w-5 flex-shrink-0 text-green-400" />
|
|
522
|
-
<div>
|
|
523
|
-
<div className="font-medium text-white">Backup Completed</div>
|
|
524
|
-
<div className="text-sm text-white/70">
|
|
525
|
-
Daily backup finished successfully
|
|
526
|
-
</div>
|
|
527
|
-
<div className="mt-1 text-xs text-white/50">1 hour ago</div>
|
|
528
|
-
</div>
|
|
529
|
-
</div>
|
|
530
|
-
</div>
|
|
531
|
-
</div>
|
|
532
|
-
</TabsContent>
|
|
533
|
-
</Tabs>
|
|
534
|
-
</div>
|
|
535
|
-
),
|
|
536
|
-
parameters: {
|
|
537
|
-
docs: {
|
|
538
|
-
description: {
|
|
539
|
-
story:
|
|
540
|
-
"Tabs with icons showing a complete admin dashboard interface with different functional areas using default medium size.",
|
|
541
|
-
},
|
|
542
|
-
},
|
|
543
|
-
},
|
|
544
|
-
}
|
|
71
|
+
// ─── AllVariants ──────────────────────────────────────────────────────────────
|
|
545
72
|
|
|
546
|
-
|
|
547
|
-
export const SizeVariations: Story = {
|
|
73
|
+
export const AllVariants: Story = {
|
|
548
74
|
render: () => (
|
|
549
|
-
<div className="
|
|
75
|
+
<div className="space-y-8">
|
|
76
|
+
{/* Size variants */}
|
|
550
77
|
<div className="space-y-4">
|
|
551
|
-
<
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
<
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
<p className="text-white/70">
|
|
569
|
-
Ideal for sidebars, modal dialogs, and tight spaces.
|
|
570
|
-
</p>
|
|
571
|
-
</div>
|
|
572
|
-
</TabsContent>
|
|
573
|
-
<TabsContent value="tab3" className="mt-4">
|
|
574
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-4">
|
|
575
|
-
<p className="text-white/70">
|
|
576
|
-
Minimal design with efficient use of space.
|
|
577
|
-
</p>
|
|
578
|
-
</div>
|
|
579
|
-
</TabsContent>
|
|
580
|
-
</Tabs>
|
|
581
|
-
</div>
|
|
582
|
-
|
|
583
|
-
<div className="space-y-4">
|
|
584
|
-
<h3 className="text-lg font-medium text-white">
|
|
585
|
-
Medium Size (Default)
|
|
586
|
-
</h3>
|
|
587
|
-
<Tabs defaultValue="tab1" size="md" className="w-full">
|
|
588
|
-
<TabsList className="grid w-full grid-cols-3">
|
|
589
|
-
<TabsTrigger value="tab1">Standard</TabsTrigger>
|
|
590
|
-
<TabsTrigger value="tab2">Medium</TabsTrigger>
|
|
591
|
-
<TabsTrigger value="tab3">Default</TabsTrigger>
|
|
592
|
-
</TabsList>
|
|
593
|
-
<TabsContent value="tab1" className="mt-4">
|
|
594
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
595
|
-
<p className="text-white/70">
|
|
596
|
-
Medium tabs provide the perfect balance between visibility and
|
|
597
|
-
space efficiency.
|
|
598
|
-
</p>
|
|
599
|
-
</div>
|
|
600
|
-
</TabsContent>
|
|
601
|
-
<TabsContent value="tab2" className="mt-4">
|
|
602
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
603
|
-
<p className="text-white/70">
|
|
604
|
-
Great for main content areas and primary navigation.
|
|
605
|
-
</p>
|
|
606
|
-
</div>
|
|
607
|
-
</TabsContent>
|
|
608
|
-
<TabsContent value="tab3" className="mt-4">
|
|
609
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
610
|
-
<p className="text-white/70">
|
|
611
|
-
The default choice for most tab implementations.
|
|
612
|
-
</p>
|
|
613
|
-
</div>
|
|
614
|
-
</TabsContent>
|
|
615
|
-
</Tabs>
|
|
616
|
-
</div>
|
|
617
|
-
|
|
618
|
-
<div className="space-y-4">
|
|
619
|
-
<h3 className="text-lg font-medium text-white">Large Size</h3>
|
|
620
|
-
<Tabs defaultValue="tab1" size="lg" className="w-full">
|
|
621
|
-
<TabsList className="grid w-full grid-cols-3">
|
|
622
|
-
<TabsTrigger value="tab1">Prominent</TabsTrigger>
|
|
623
|
-
<TabsTrigger value="tab2">Large</TabsTrigger>
|
|
624
|
-
<TabsTrigger value="tab3">Bold</TabsTrigger>
|
|
625
|
-
</TabsList>
|
|
626
|
-
<TabsContent value="tab1" className="mt-4">
|
|
627
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-8">
|
|
628
|
-
<p className="text-white/70">
|
|
629
|
-
Large tabs make a statement and are perfect for hero sections
|
|
630
|
-
and primary interfaces.
|
|
631
|
-
</p>
|
|
632
|
-
</div>
|
|
633
|
-
</TabsContent>
|
|
634
|
-
<TabsContent value="tab2" className="mt-4">
|
|
635
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-8">
|
|
636
|
-
<p className="text-white/70">
|
|
637
|
-
Enhanced visibility and improved touch targets for mobile
|
|
638
|
-
interfaces.
|
|
639
|
-
</p>
|
|
640
|
-
</div>
|
|
641
|
-
</TabsContent>
|
|
642
|
-
<TabsContent value="tab3" className="mt-4">
|
|
643
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-8">
|
|
644
|
-
<p className="text-white/70">
|
|
645
|
-
Bold design that commands attention and improves user
|
|
646
|
-
experience.
|
|
647
|
-
</p>
|
|
648
|
-
</div>
|
|
649
|
-
</TabsContent>
|
|
650
|
-
</Tabs>
|
|
651
|
-
</div>
|
|
652
|
-
</div>
|
|
653
|
-
),
|
|
654
|
-
parameters: {
|
|
655
|
-
docs: {
|
|
656
|
-
description: {
|
|
657
|
-
story:
|
|
658
|
-
"All three size variants (small, medium, large) showing different use cases and visual hierarchy. Notice how the size is set once on the Tabs component instead of each individual trigger.",
|
|
659
|
-
},
|
|
660
|
-
},
|
|
661
|
-
},
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
// 4. Individual Size Override
|
|
665
|
-
export const IndividualSizeOverride: Story = {
|
|
666
|
-
render: () => (
|
|
667
|
-
<div className="w-full max-w-3xl space-y-6">
|
|
668
|
-
<div className="text-center">
|
|
669
|
-
<h3 className="mb-2 text-lg font-medium text-white">
|
|
670
|
-
Individual Size Override
|
|
671
|
-
</h3>
|
|
672
|
-
<p className="text-sm text-white/70">
|
|
673
|
-
Tabs component has size="md" set, but individual triggers can override
|
|
674
|
-
with their own size prop
|
|
675
|
-
</p>
|
|
676
|
-
</div>
|
|
677
|
-
|
|
678
|
-
<Tabs defaultValue="normal" size="md" className="w-full">
|
|
679
|
-
<TabsList className="grid w-full grid-cols-4">
|
|
680
|
-
<TabsTrigger value="small" size="sm">
|
|
681
|
-
Small Override
|
|
682
|
-
</TabsTrigger>
|
|
683
|
-
<TabsTrigger value="normal">Normal (md)</TabsTrigger>
|
|
684
|
-
<TabsTrigger value="normal2">Normal (md)</TabsTrigger>
|
|
685
|
-
<TabsTrigger value="large" size="lg">
|
|
686
|
-
Large Override
|
|
687
|
-
</TabsTrigger>
|
|
688
|
-
</TabsList>
|
|
689
|
-
|
|
690
|
-
<TabsContent value="small" className="mt-6">
|
|
691
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
692
|
-
<h3 className="mb-4 text-lg font-semibold text-white">
|
|
693
|
-
Small Override
|
|
694
|
-
</h3>
|
|
695
|
-
<p className="text-white/70">
|
|
696
|
-
This tab trigger has{" "}
|
|
697
|
-
<code className="rounded bg-white/10 px-2 py-1 text-sm">
|
|
698
|
-
size="sm"
|
|
699
|
-
</code>{" "}
|
|
700
|
-
which overrides the parent Tabs component's{" "}
|
|
701
|
-
<code className="rounded bg-white/10 px-2 py-1 text-sm">
|
|
702
|
-
size="md"
|
|
703
|
-
</code>{" "}
|
|
704
|
-
setting.
|
|
78
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
79
|
+
Size Variants
|
|
80
|
+
</h4>
|
|
81
|
+
<div className="space-y-6">
|
|
82
|
+
<div className="space-y-2 text-center">
|
|
83
|
+
<Tabs defaultValue="a" size="sm">
|
|
84
|
+
<TabsList>
|
|
85
|
+
<TabsTrigger value="a">Songs</TabsTrigger>
|
|
86
|
+
<TabsTrigger value="b">Albums</TabsTrigger>
|
|
87
|
+
<TabsTrigger value="c">Artists</TabsTrigger>
|
|
88
|
+
</TabsList>
|
|
89
|
+
<TabsContent value="a" />
|
|
90
|
+
<TabsContent value="b" />
|
|
91
|
+
<TabsContent value="c" />
|
|
92
|
+
</Tabs>
|
|
93
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
94
|
+
Small (sm)
|
|
705
95
|
</p>
|
|
706
|
-
<div className="mt-4 rounded-lg border border-blue-500/20 bg-blue-500/10 p-3">
|
|
707
|
-
<div className="text-sm text-blue-200">
|
|
708
|
-
<strong>Use case:</strong> When you need most tabs to be medium
|
|
709
|
-
size but want to emphasize or de-emphasize specific tabs.
|
|
710
|
-
</div>
|
|
711
|
-
</div>
|
|
712
96
|
</div>
|
|
713
|
-
</TabsContent>
|
|
714
97
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
<
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
98
|
+
<div className="space-y-2 text-center">
|
|
99
|
+
<Tabs defaultValue="a" size="md">
|
|
100
|
+
<TabsList>
|
|
101
|
+
<TabsTrigger value="a">Songs</TabsTrigger>
|
|
102
|
+
<TabsTrigger value="b">Albums</TabsTrigger>
|
|
103
|
+
<TabsTrigger value="c">Artists</TabsTrigger>
|
|
104
|
+
</TabsList>
|
|
105
|
+
<TabsContent value="a" />
|
|
106
|
+
<TabsContent value="b" />
|
|
107
|
+
<TabsContent value="c" />
|
|
108
|
+
</Tabs>
|
|
109
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
110
|
+
Medium (md) — default
|
|
727
111
|
</p>
|
|
728
|
-
<div className="mt-4 grid grid-cols-2 gap-4">
|
|
729
|
-
<div className="rounded-lg border border-green-500/20 bg-green-500/10 p-3">
|
|
730
|
-
<div className="text-sm text-green-200">
|
|
731
|
-
Consistent sizing across most tabs
|
|
732
|
-
</div>
|
|
733
|
-
</div>
|
|
734
|
-
<div className="rounded-lg border border-purple-500/20 bg-purple-500/10 p-3">
|
|
735
|
-
<div className="text-sm text-purple-200">
|
|
736
|
-
Clean, unified appearance
|
|
737
|
-
</div>
|
|
738
|
-
</div>
|
|
739
|
-
</div>
|
|
740
112
|
</div>
|
|
741
|
-
</TabsContent>
|
|
742
113
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
114
|
+
<div className="space-y-2 text-center">
|
|
115
|
+
<Tabs defaultValue="a" size="lg">
|
|
116
|
+
<TabsList>
|
|
117
|
+
<TabsTrigger value="a">Songs</TabsTrigger>
|
|
118
|
+
<TabsTrigger value="b">Albums</TabsTrigger>
|
|
119
|
+
<TabsTrigger value="c">Artists</TabsTrigger>
|
|
120
|
+
</TabsList>
|
|
121
|
+
<TabsContent value="a" />
|
|
122
|
+
<TabsContent value="b" />
|
|
123
|
+
<TabsContent value="c" />
|
|
124
|
+
</Tabs>
|
|
125
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
126
|
+
Large (lg)
|
|
751
127
|
</p>
|
|
752
|
-
<div className="mt-4 space-y-3">
|
|
753
|
-
<div className="flex items-center gap-3 rounded-lg bg-white/5 p-3">
|
|
754
|
-
<TickCircleIcon className="h-5 w-5 text-green-400" />
|
|
755
|
-
<span className="text-white/70">
|
|
756
|
-
Inherits parent size automatically
|
|
757
|
-
</span>
|
|
758
|
-
</div>
|
|
759
|
-
<div className="flex items-center gap-3 rounded-lg bg-white/5 p-3">
|
|
760
|
-
<TickCircleIcon className="h-5 w-5 text-green-400" />
|
|
761
|
-
<span className="text-white/70">
|
|
762
|
-
No need to specify size prop
|
|
763
|
-
</span>
|
|
764
|
-
</div>
|
|
765
|
-
<div className="flex items-center gap-3 rounded-lg bg-white/5 p-3">
|
|
766
|
-
<TickCircleIcon className="h-5 w-5 text-green-400" />
|
|
767
|
-
<span className="text-white/70">
|
|
768
|
-
Maintains consistent appearance
|
|
769
|
-
</span>
|
|
770
|
-
</div>
|
|
771
|
-
</div>
|
|
772
128
|
</div>
|
|
773
|
-
</
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
774
131
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
132
|
+
{/* Glow direction variants */}
|
|
133
|
+
<div className="space-y-4">
|
|
134
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
135
|
+
Glow Direction Variants
|
|
136
|
+
</h4>
|
|
137
|
+
<div className="flex flex-wrap gap-8">
|
|
138
|
+
<div className="space-y-2 text-center">
|
|
139
|
+
<Tabs defaultValue="active" size="md">
|
|
140
|
+
<TabsList>
|
|
141
|
+
<TabsTrigger value="active" glowDirection="bottom">
|
|
142
|
+
Active
|
|
143
|
+
</TabsTrigger>
|
|
144
|
+
<TabsTrigger value="other" glowDirection="bottom">
|
|
145
|
+
Inactive
|
|
146
|
+
</TabsTrigger>
|
|
147
|
+
</TabsList>
|
|
148
|
+
<TabsContent value="active" />
|
|
149
|
+
<TabsContent value="other" />
|
|
150
|
+
</Tabs>
|
|
151
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
152
|
+
Glow Bottom (default)
|
|
787
153
|
</p>
|
|
788
|
-
<div className="mt-4 rounded-lg border border-orange-500/20 bg-orange-500/10 p-3">
|
|
789
|
-
<div className="text-sm text-orange-200">
|
|
790
|
-
<strong>Use case:</strong> Call-to-action tabs, primary
|
|
791
|
-
navigation items, or tabs that need extra visual emphasis in
|
|
792
|
-
your interface.
|
|
793
|
-
</div>
|
|
794
|
-
</div>
|
|
795
|
-
<div className="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
796
|
-
<div className="rounded-lg border border-blue-500/30 bg-gradient-to-br from-blue-500/20 to-purple-500/20 p-4">
|
|
797
|
-
<div className="text-lg font-semibold text-white">Enhanced</div>
|
|
798
|
-
<div className="text-sm text-white/70">Better visibility</div>
|
|
799
|
-
</div>
|
|
800
|
-
<div className="rounded-lg border border-green-500/30 bg-gradient-to-br from-green-500/20 to-teal-500/20 p-4">
|
|
801
|
-
<div className="text-lg font-semibold text-white">
|
|
802
|
-
Prominent
|
|
803
|
-
</div>
|
|
804
|
-
<div className="text-sm text-white/70">Draws attention</div>
|
|
805
|
-
</div>
|
|
806
|
-
</div>
|
|
807
154
|
</div>
|
|
808
|
-
</TabsContent>
|
|
809
|
-
</Tabs>
|
|
810
155
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
156
|
+
<div className="space-y-2 text-center">
|
|
157
|
+
<div className="pt-8">
|
|
158
|
+
<Tabs defaultValue="active" size="md">
|
|
159
|
+
<TabsList>
|
|
160
|
+
<TabsTrigger value="active" glowDirection="top">
|
|
161
|
+
Active
|
|
162
|
+
</TabsTrigger>
|
|
163
|
+
<TabsTrigger value="other" glowDirection="top">
|
|
164
|
+
Inactive
|
|
165
|
+
</TabsTrigger>
|
|
166
|
+
</TabsList>
|
|
167
|
+
<TabsContent value="active" />
|
|
168
|
+
<TabsContent value="other" />
|
|
169
|
+
</Tabs>
|
|
170
|
+
</div>
|
|
171
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
172
|
+
Glow Top
|
|
173
|
+
</p>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
819
176
|
</div>
|
|
820
177
|
</div>
|
|
821
178
|
),
|
|
@@ -823,722 +180,424 @@ export const IndividualSizeOverride: Story = {
|
|
|
823
180
|
docs: {
|
|
824
181
|
description: {
|
|
825
182
|
story:
|
|
826
|
-
"
|
|
183
|
+
"All three size variants (sm, md, lg) and both glow direction options (bottom, top) shown as labeled item cards.",
|
|
827
184
|
},
|
|
828
185
|
},
|
|
829
186
|
},
|
|
830
187
|
}
|
|
831
188
|
|
|
832
|
-
//
|
|
833
|
-
export const ComplexContent: Story = {
|
|
834
|
-
render: () => (
|
|
835
|
-
<div className="w-full max-w-4xl">
|
|
836
|
-
<Tabs defaultValue="products" size="md" className="w-full">
|
|
837
|
-
<TabsList className="grid w-full grid-cols-4">
|
|
838
|
-
<TabsTrigger value="products" className="gap-2">
|
|
839
|
-
<SearchIcon className="h-4 w-4" />
|
|
840
|
-
Products
|
|
841
|
-
</TabsTrigger>
|
|
842
|
-
<TabsTrigger value="customers" className="gap-2">
|
|
843
|
-
<EyeOpenIcon className="h-4 w-4" />
|
|
844
|
-
Customers
|
|
845
|
-
</TabsTrigger>
|
|
846
|
-
<TabsTrigger value="orders" className="gap-2">
|
|
847
|
-
<FileChartIcon className="h-4 w-4" />
|
|
848
|
-
Orders
|
|
849
|
-
</TabsTrigger>
|
|
850
|
-
<TabsTrigger value="analytics" className="gap-2" size="lg">
|
|
851
|
-
<TickCircleIcon className="h-4 w-4" />
|
|
852
|
-
Analytics
|
|
853
|
-
</TabsTrigger>
|
|
854
|
-
</TabsList>
|
|
855
|
-
|
|
856
|
-
<TabsContent value="products" className="mt-6">
|
|
857
|
-
<div className="space-y-4">
|
|
858
|
-
<div className="flex items-center justify-between">
|
|
859
|
-
<h3 className="text-lg font-semibold text-white">
|
|
860
|
-
Product Catalog
|
|
861
|
-
</h3>
|
|
862
|
-
<button className="flex items-center gap-2 rounded-lg bg-blue-500 px-4 py-2 text-white transition-colors hover:bg-blue-600">
|
|
863
|
-
<PlusIcon className="h-4 w-4" />
|
|
864
|
-
Add Product
|
|
865
|
-
</button>
|
|
866
|
-
</div>
|
|
867
|
-
|
|
868
|
-
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
869
|
-
{[
|
|
870
|
-
{
|
|
871
|
-
name: "Wireless Headphones",
|
|
872
|
-
price: "$199",
|
|
873
|
-
category: "Electronics",
|
|
874
|
-
stock: 45,
|
|
875
|
-
},
|
|
876
|
-
{
|
|
877
|
-
name: "Smart Watch",
|
|
878
|
-
price: "$299",
|
|
879
|
-
category: "Wearables",
|
|
880
|
-
stock: 23,
|
|
881
|
-
},
|
|
882
|
-
{
|
|
883
|
-
name: "Laptop Stand",
|
|
884
|
-
price: "$49",
|
|
885
|
-
category: "Accessories",
|
|
886
|
-
stock: 67,
|
|
887
|
-
},
|
|
888
|
-
{
|
|
889
|
-
name: "USB-C Cable",
|
|
890
|
-
price: "$29",
|
|
891
|
-
category: "Cables",
|
|
892
|
-
stock: 156,
|
|
893
|
-
},
|
|
894
|
-
{
|
|
895
|
-
name: "Wireless Mouse",
|
|
896
|
-
price: "$79",
|
|
897
|
-
category: "Electronics",
|
|
898
|
-
stock: 34,
|
|
899
|
-
},
|
|
900
|
-
{
|
|
901
|
-
name: "Keyboard",
|
|
902
|
-
price: "$149",
|
|
903
|
-
category: "Electronics",
|
|
904
|
-
stock: 28,
|
|
905
|
-
},
|
|
906
|
-
].map((product, index) => (
|
|
907
|
-
<div
|
|
908
|
-
key={index}
|
|
909
|
-
className="rounded-lg border border-white/10 bg-white/5 p-4 transition-colors hover:bg-white/10"
|
|
910
|
-
>
|
|
911
|
-
<div className="mb-3 flex aspect-square items-center justify-center rounded-lg bg-gradient-to-br from-purple-500/20 to-pink-500/20">
|
|
912
|
-
<SearchIcon className="h-8 w-8 text-white/50" />
|
|
913
|
-
</div>
|
|
914
|
-
<h4 className="mb-1 font-medium text-white">
|
|
915
|
-
{product.name}
|
|
916
|
-
</h4>
|
|
917
|
-
<p className="mb-2 text-sm text-white/60">
|
|
918
|
-
{product.category}
|
|
919
|
-
</p>
|
|
920
|
-
<div className="flex items-center justify-between">
|
|
921
|
-
<span className="font-semibold text-white">
|
|
922
|
-
{product.price}
|
|
923
|
-
</span>
|
|
924
|
-
<span className="text-xs text-white/60">
|
|
925
|
-
{product.stock} in stock
|
|
926
|
-
</span>
|
|
927
|
-
</div>
|
|
928
|
-
</div>
|
|
929
|
-
))}
|
|
930
|
-
</div>
|
|
931
|
-
</div>
|
|
932
|
-
</TabsContent>
|
|
933
|
-
|
|
934
|
-
<TabsContent value="customers" className="mt-6">
|
|
935
|
-
<div className="space-y-4">
|
|
936
|
-
<div className="flex items-center justify-between">
|
|
937
|
-
<h3 className="text-lg font-semibold text-white">
|
|
938
|
-
Customer Directory
|
|
939
|
-
</h3>
|
|
940
|
-
<div className="flex gap-2">
|
|
941
|
-
<button className="rounded bg-white/10 px-3 py-1 text-sm text-white transition-colors hover:bg-white/20">
|
|
942
|
-
Export
|
|
943
|
-
</button>
|
|
944
|
-
<button className="rounded bg-blue-500 px-3 py-1 text-sm text-white transition-colors hover:bg-blue-600">
|
|
945
|
-
Add Customer
|
|
946
|
-
</button>
|
|
947
|
-
</div>
|
|
948
|
-
</div>
|
|
949
|
-
|
|
950
|
-
<div className="space-y-2">
|
|
951
|
-
{[
|
|
952
|
-
{
|
|
953
|
-
name: "Alice Cooper",
|
|
954
|
-
email: "alice@example.com",
|
|
955
|
-
orders: 12,
|
|
956
|
-
value: "$2,847",
|
|
957
|
-
},
|
|
958
|
-
{
|
|
959
|
-
name: "Bob Martinez",
|
|
960
|
-
email: "bob@example.com",
|
|
961
|
-
orders: 8,
|
|
962
|
-
value: "$1,923",
|
|
963
|
-
},
|
|
964
|
-
{
|
|
965
|
-
name: "Carol Johnson",
|
|
966
|
-
email: "carol@example.com",
|
|
967
|
-
orders: 15,
|
|
968
|
-
value: "$3,456",
|
|
969
|
-
},
|
|
970
|
-
{
|
|
971
|
-
name: "David Kim",
|
|
972
|
-
email: "david@example.com",
|
|
973
|
-
orders: 6,
|
|
974
|
-
value: "$1,234",
|
|
975
|
-
},
|
|
976
|
-
{
|
|
977
|
-
name: "Eva Rodriguez",
|
|
978
|
-
email: "eva@example.com",
|
|
979
|
-
orders: 22,
|
|
980
|
-
value: "$4,567",
|
|
981
|
-
},
|
|
982
|
-
].map((customer, index) => (
|
|
983
|
-
<div
|
|
984
|
-
key={index}
|
|
985
|
-
className="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-4 transition-colors hover:bg-white/10"
|
|
986
|
-
>
|
|
987
|
-
<div className="flex items-center gap-3">
|
|
988
|
-
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-gradient-to-br from-blue-500 to-purple-500">
|
|
989
|
-
<span className="text-sm font-semibold text-white">
|
|
990
|
-
{customer.name
|
|
991
|
-
.split(" ")
|
|
992
|
-
.map((n) => n[0])
|
|
993
|
-
.join("")}
|
|
994
|
-
</span>
|
|
995
|
-
</div>
|
|
996
|
-
<div>
|
|
997
|
-
<div className="font-medium text-white">
|
|
998
|
-
{customer.name}
|
|
999
|
-
</div>
|
|
1000
|
-
<div className="text-sm text-white/60">
|
|
1001
|
-
{customer.email}
|
|
1002
|
-
</div>
|
|
1003
|
-
</div>
|
|
1004
|
-
</div>
|
|
1005
|
-
<div className="text-right">
|
|
1006
|
-
<div className="font-medium text-white">
|
|
1007
|
-
{customer.value}
|
|
1008
|
-
</div>
|
|
1009
|
-
<div className="text-sm text-white/60">
|
|
1010
|
-
{customer.orders} orders
|
|
1011
|
-
</div>
|
|
1012
|
-
</div>
|
|
1013
|
-
</div>
|
|
1014
|
-
))}
|
|
1015
|
-
</div>
|
|
1016
|
-
</div>
|
|
1017
|
-
</TabsContent>
|
|
1018
|
-
|
|
1019
|
-
<TabsContent value="orders" className="mt-6">
|
|
1020
|
-
<div className="space-y-4">
|
|
1021
|
-
<div className="flex items-center justify-between">
|
|
1022
|
-
<h3 className="text-lg font-semibold text-white">
|
|
1023
|
-
Recent Orders
|
|
1024
|
-
</h3>
|
|
1025
|
-
<div className="flex gap-2">
|
|
1026
|
-
<select className="rounded border border-white/20 bg-white/10 px-3 py-1 text-sm text-white">
|
|
1027
|
-
<option>All Status</option>
|
|
1028
|
-
<option>Pending</option>
|
|
1029
|
-
<option>Processing</option>
|
|
1030
|
-
<option>Shipped</option>
|
|
1031
|
-
<option>Delivered</option>
|
|
1032
|
-
</select>
|
|
1033
|
-
</div>
|
|
1034
|
-
</div>
|
|
1035
|
-
|
|
1036
|
-
<div className="space-y-3">
|
|
1037
|
-
{[
|
|
1038
|
-
{
|
|
1039
|
-
id: "#ORD-001",
|
|
1040
|
-
customer: "Alice Cooper",
|
|
1041
|
-
total: "$247.99",
|
|
1042
|
-
status: "delivered",
|
|
1043
|
-
date: "2 hours ago",
|
|
1044
|
-
},
|
|
1045
|
-
{
|
|
1046
|
-
id: "#ORD-002",
|
|
1047
|
-
customer: "Bob Martinez",
|
|
1048
|
-
total: "$89.50",
|
|
1049
|
-
status: "shipped",
|
|
1050
|
-
date: "4 hours ago",
|
|
1051
|
-
},
|
|
1052
|
-
{
|
|
1053
|
-
id: "#ORD-003",
|
|
1054
|
-
customer: "Carol Johnson",
|
|
1055
|
-
total: "$156.75",
|
|
1056
|
-
status: "processing",
|
|
1057
|
-
date: "6 hours ago",
|
|
1058
|
-
},
|
|
1059
|
-
{
|
|
1060
|
-
id: "#ORD-004",
|
|
1061
|
-
customer: "David Kim",
|
|
1062
|
-
total: "$324.00",
|
|
1063
|
-
status: "pending",
|
|
1064
|
-
date: "8 hours ago",
|
|
1065
|
-
},
|
|
1066
|
-
{
|
|
1067
|
-
id: "#ORD-005",
|
|
1068
|
-
customer: "Eva Rodriguez",
|
|
1069
|
-
total: "$78.25",
|
|
1070
|
-
status: "delivered",
|
|
1071
|
-
date: "1 day ago",
|
|
1072
|
-
},
|
|
1073
|
-
].map((order, index) => (
|
|
1074
|
-
<div
|
|
1075
|
-
key={index}
|
|
1076
|
-
className="flex items-center justify-between rounded-lg border border-white/10 bg-white/5 p-4 transition-colors hover:bg-white/10"
|
|
1077
|
-
>
|
|
1078
|
-
<div className="flex items-center gap-4">
|
|
1079
|
-
<div>
|
|
1080
|
-
<div className="font-medium text-white">{order.id}</div>
|
|
1081
|
-
<div className="text-sm text-white/60">
|
|
1082
|
-
{order.customer}
|
|
1083
|
-
</div>
|
|
1084
|
-
</div>
|
|
1085
|
-
</div>
|
|
1086
|
-
<div className="flex items-center gap-4">
|
|
1087
|
-
<div className="text-right">
|
|
1088
|
-
<div className="font-medium text-white">
|
|
1089
|
-
{order.total}
|
|
1090
|
-
</div>
|
|
1091
|
-
<div className="text-sm text-white/60">{order.date}</div>
|
|
1092
|
-
</div>
|
|
1093
|
-
<span
|
|
1094
|
-
className={`rounded-full px-2 py-1 text-xs ${
|
|
1095
|
-
order.status === "delivered"
|
|
1096
|
-
? "bg-green-500/20 text-green-400"
|
|
1097
|
-
: order.status === "shipped"
|
|
1098
|
-
? "bg-blue-500/20 text-blue-400"
|
|
1099
|
-
: order.status === "processing"
|
|
1100
|
-
? "bg-yellow-500/20 text-yellow-400"
|
|
1101
|
-
: "bg-gray-500/20 text-gray-400"
|
|
1102
|
-
}`}
|
|
1103
|
-
>
|
|
1104
|
-
{order.status}
|
|
1105
|
-
</span>
|
|
1106
|
-
</div>
|
|
1107
|
-
</div>
|
|
1108
|
-
))}
|
|
1109
|
-
</div>
|
|
1110
|
-
</div>
|
|
1111
|
-
</TabsContent>
|
|
1112
|
-
|
|
1113
|
-
<TabsContent value="analytics" className="mt-6">
|
|
1114
|
-
<div className="space-y-6">
|
|
1115
|
-
<div className="flex items-center gap-3">
|
|
1116
|
-
<TickCircleIcon className="h-6 w-6 text-green-400" />
|
|
1117
|
-
<h3 className="text-lg font-semibold text-white">
|
|
1118
|
-
Sales Analytics
|
|
1119
|
-
</h3>
|
|
1120
|
-
<span className="rounded-full bg-green-500/20 px-3 py-1 text-xs text-green-400">
|
|
1121
|
-
Large Tab
|
|
1122
|
-
</span>
|
|
1123
|
-
</div>
|
|
1124
|
-
|
|
1125
|
-
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
|
|
1126
|
-
<div className="rounded-lg border border-blue-500/30 bg-gradient-to-br from-blue-500/20 to-cyan-500/20 p-4">
|
|
1127
|
-
<div className="text-2xl font-bold text-white">$45,231</div>
|
|
1128
|
-
<div className="text-sm text-white/70">Revenue This Month</div>
|
|
1129
|
-
<div className="mt-1 text-xs text-green-400">
|
|
1130
|
-
↗ +12% vs last month
|
|
1131
|
-
</div>
|
|
1132
|
-
</div>
|
|
1133
|
-
<div className="rounded-lg border border-green-500/30 bg-gradient-to-br from-green-500/20 to-emerald-500/20 p-4">
|
|
1134
|
-
<div className="text-2xl font-bold text-white">1,847</div>
|
|
1135
|
-
<div className="text-sm text-white/70">Orders This Month</div>
|
|
1136
|
-
<div className="mt-1 text-xs text-green-400">
|
|
1137
|
-
↗ +8% vs last month
|
|
1138
|
-
</div>
|
|
1139
|
-
</div>
|
|
1140
|
-
<div className="rounded-lg border border-purple-500/30 bg-gradient-to-br from-purple-500/20 to-pink-500/20 p-4">
|
|
1141
|
-
<div className="text-2xl font-bold text-white">324</div>
|
|
1142
|
-
<div className="text-sm text-white/70">New Customers</div>
|
|
1143
|
-
<div className="mt-1 text-xs text-green-400">
|
|
1144
|
-
↗ +15% vs last month
|
|
1145
|
-
</div>
|
|
1146
|
-
</div>
|
|
1147
|
-
<div className="rounded-lg border border-orange-500/30 bg-gradient-to-br from-orange-500/20 to-red-500/20 p-4">
|
|
1148
|
-
<div className="text-2xl font-bold text-white">$24.50</div>
|
|
1149
|
-
<div className="text-sm text-white/70">Avg Order Value</div>
|
|
1150
|
-
<div className="mt-1 text-xs text-red-400">
|
|
1151
|
-
↘ -3% vs last month
|
|
1152
|
-
</div>
|
|
1153
|
-
</div>
|
|
1154
|
-
</div>
|
|
1155
|
-
|
|
1156
|
-
<div className="rounded-lg border border-amber-500/20 bg-amber-500/10 p-4">
|
|
1157
|
-
<div className="text-sm text-amber-200">
|
|
1158
|
-
<strong>Note:</strong> The Analytics tab uses{" "}
|
|
1159
|
-
<code className="rounded bg-white/10 px-2 py-1">size="lg"</code>
|
|
1160
|
-
to emphasize its importance as the primary data view, while
|
|
1161
|
-
other tabs inherit the default medium size.
|
|
1162
|
-
</div>
|
|
1163
|
-
</div>
|
|
1164
|
-
</div>
|
|
1165
|
-
</TabsContent>
|
|
1166
|
-
</Tabs>
|
|
1167
|
-
</div>
|
|
1168
|
-
),
|
|
1169
|
-
parameters: {
|
|
1170
|
-
docs: {
|
|
1171
|
-
description: {
|
|
1172
|
-
story:
|
|
1173
|
-
"Complex e-commerce admin interface demonstrating the new size prop functionality. The parent Tabs has size='md' but the Analytics tab uses size='lg' to emphasize its importance.",
|
|
1174
|
-
},
|
|
1175
|
-
},
|
|
1176
|
-
},
|
|
1177
|
-
}
|
|
189
|
+
// ─── Configurations ───────────────────────────────────────────────────────────
|
|
1178
190
|
|
|
1179
|
-
|
|
1180
|
-
export const GlowDirectionVariations: Story = {
|
|
191
|
+
export const Configurations: Story = {
|
|
1181
192
|
render: () => (
|
|
1182
|
-
<div className="
|
|
193
|
+
<div className="space-y-8">
|
|
194
|
+
{/* With icons */}
|
|
1183
195
|
<div className="space-y-4">
|
|
1184
|
-
<
|
|
1185
|
-
|
|
1186
|
-
</
|
|
1187
|
-
<Tabs defaultValue="
|
|
1188
|
-
<TabsList
|
|
1189
|
-
<TabsTrigger value="
|
|
1190
|
-
|
|
196
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
197
|
+
With Icons
|
|
198
|
+
</h4>
|
|
199
|
+
<Tabs defaultValue="songs" size="md" className="w-full max-w-lg">
|
|
200
|
+
<TabsList>
|
|
201
|
+
<TabsTrigger value="songs" className="gap-2">
|
|
202
|
+
<MusicalNoteIcon className="h-4 w-4" />
|
|
203
|
+
Songs
|
|
1191
204
|
</TabsTrigger>
|
|
1192
|
-
<TabsTrigger value="
|
|
1193
|
-
|
|
205
|
+
<TabsTrigger value="favorites" className="gap-2">
|
|
206
|
+
<HeartIcon className="h-4 w-4" />
|
|
207
|
+
Favorites
|
|
1194
208
|
</TabsTrigger>
|
|
1195
|
-
<TabsTrigger value="
|
|
1196
|
-
|
|
209
|
+
<TabsTrigger value="discover" className="gap-2">
|
|
210
|
+
<SearchIcon className="h-4 w-4" />
|
|
211
|
+
Discover
|
|
1197
212
|
</TabsTrigger>
|
|
1198
213
|
</TabsList>
|
|
1199
|
-
<TabsContent value="
|
|
1200
|
-
<div className="rounded-lg border
|
|
1201
|
-
<p className="text-
|
|
1202
|
-
|
|
1203
|
-
|
|
214
|
+
<TabsContent value="songs" className="mt-4">
|
|
215
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
216
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
217
|
+
Your full song library lives here — browse by title, artist, or
|
|
218
|
+
recently played.
|
|
1204
219
|
</p>
|
|
1205
220
|
</div>
|
|
1206
221
|
</TabsContent>
|
|
1207
|
-
<TabsContent value="
|
|
1208
|
-
<div className="rounded-lg border
|
|
1209
|
-
<p className="text-
|
|
1210
|
-
|
|
1211
|
-
content area.
|
|
222
|
+
<TabsContent value="favorites" className="mt-4">
|
|
223
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
224
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
225
|
+
Songs you've hearted appear here for quick access.
|
|
1212
226
|
</p>
|
|
1213
227
|
</div>
|
|
1214
228
|
</TabsContent>
|
|
1215
|
-
<TabsContent value="
|
|
1216
|
-
<div className="rounded-lg border
|
|
1217
|
-
<p className="text-
|
|
1218
|
-
|
|
1219
|
-
associated content.
|
|
229
|
+
<TabsContent value="discover" className="mt-4">
|
|
230
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
231
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
232
|
+
Personalized recommendations based on your listening habits.
|
|
1220
233
|
</p>
|
|
1221
234
|
</div>
|
|
1222
235
|
</TabsContent>
|
|
1223
236
|
</Tabs>
|
|
1224
237
|
</div>
|
|
1225
238
|
|
|
239
|
+
{/* Individual size override */}
|
|
1226
240
|
<div className="space-y-4">
|
|
1227
|
-
<
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
</TabsTrigger>
|
|
1233
|
-
<TabsTrigger value="
|
|
1234
|
-
|
|
241
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
242
|
+
Individual Size Override
|
|
243
|
+
</h4>
|
|
244
|
+
<Tabs defaultValue="featured" size="sm" className="w-full max-w-lg">
|
|
245
|
+
<TabsList>
|
|
246
|
+
<TabsTrigger value="featured">Featured</TabsTrigger>
|
|
247
|
+
<TabsTrigger value="trending" size="md">
|
|
248
|
+
Trending (md)
|
|
1235
249
|
</TabsTrigger>
|
|
1236
|
-
<TabsTrigger value="
|
|
1237
|
-
|
|
250
|
+
<TabsTrigger value="new" size="lg">
|
|
251
|
+
New (lg)
|
|
1238
252
|
</TabsTrigger>
|
|
1239
253
|
</TabsList>
|
|
1240
|
-
<TabsContent value="
|
|
1241
|
-
<div className="rounded-lg border
|
|
1242
|
-
<p className="text-
|
|
1243
|
-
|
|
1244
|
-
|
|
254
|
+
<TabsContent value="featured" className="mt-4">
|
|
255
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
256
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
257
|
+
The first trigger inherits the parent{" "}
|
|
258
|
+
<code className="text-fm-primary font-(--font-fm-mono)">
|
|
259
|
+
size="sm"
|
|
260
|
+
</code>
|
|
261
|
+
. The other two override to md and lg respectively.
|
|
1245
262
|
</p>
|
|
1246
263
|
</div>
|
|
1247
264
|
</TabsContent>
|
|
1248
|
-
<TabsContent value="
|
|
1249
|
-
<div className="rounded-lg border
|
|
1250
|
-
<p className="text-
|
|
1251
|
-
|
|
265
|
+
<TabsContent value="trending" className="mt-4">
|
|
266
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
267
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
268
|
+
This trigger uses{" "}
|
|
269
|
+
<code className="text-fm-primary font-(--font-fm-mono)">
|
|
270
|
+
size="md"
|
|
271
|
+
</code>{" "}
|
|
272
|
+
directly on the trigger, overriding the parent context.
|
|
1252
273
|
</p>
|
|
1253
274
|
</div>
|
|
1254
275
|
</TabsContent>
|
|
1255
|
-
<TabsContent value="
|
|
1256
|
-
<div className="rounded-lg border
|
|
1257
|
-
<p className="text-
|
|
1258
|
-
|
|
276
|
+
<TabsContent value="new" className="mt-4">
|
|
277
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
278
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
279
|
+
This trigger uses{" "}
|
|
280
|
+
<code className="text-fm-primary font-(--font-fm-mono)">
|
|
281
|
+
size="lg"
|
|
282
|
+
</code>{" "}
|
|
283
|
+
for a prominent call-to-action feel.
|
|
1259
284
|
</p>
|
|
1260
285
|
</div>
|
|
1261
286
|
</TabsContent>
|
|
1262
287
|
</Tabs>
|
|
1263
288
|
</div>
|
|
1264
289
|
|
|
290
|
+
{/* Different content panels */}
|
|
1265
291
|
<div className="space-y-4">
|
|
1266
|
-
<
|
|
1267
|
-
|
|
1268
|
-
</
|
|
1269
|
-
<Tabs defaultValue="
|
|
1270
|
-
<TabsList
|
|
1271
|
-
<TabsTrigger value="
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
<TabsTrigger value="tab2" glowDirection="top">
|
|
1275
|
-
Top Glow
|
|
292
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
293
|
+
Rich Content Panels
|
|
294
|
+
</h4>
|
|
295
|
+
<Tabs defaultValue="stats" size="md" className="w-full max-w-lg">
|
|
296
|
+
<TabsList>
|
|
297
|
+
<TabsTrigger value="stats" className="gap-2">
|
|
298
|
+
<FileChartIcon className="h-4 w-4" />
|
|
299
|
+
Stats
|
|
1276
300
|
</TabsTrigger>
|
|
1277
|
-
<TabsTrigger value="
|
|
1278
|
-
|
|
301
|
+
<TabsTrigger value="top" className="gap-2">
|
|
302
|
+
<StarIcon className="h-4 w-4" />
|
|
303
|
+
Top Tracks
|
|
1279
304
|
</TabsTrigger>
|
|
1280
|
-
<TabsTrigger value="
|
|
1281
|
-
|
|
305
|
+
<TabsTrigger value="settings" className="gap-2">
|
|
306
|
+
<SettingIcon className="h-4 w-4" />
|
|
307
|
+
Settings
|
|
1282
308
|
</TabsTrigger>
|
|
1283
309
|
</TabsList>
|
|
1284
|
-
<TabsContent value="
|
|
1285
|
-
<div className="
|
|
1286
|
-
<
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
<
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
310
|
+
<TabsContent value="stats" className="mt-4">
|
|
311
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-3 rounded-lg border p-4">
|
|
312
|
+
<div className="flex items-center justify-between">
|
|
313
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
314
|
+
Listening time this week
|
|
315
|
+
</span>
|
|
316
|
+
<span className="text-fm-primary font-fm-brand text-fm-md leading-fm-md font-semibold">
|
|
317
|
+
14h 32m
|
|
318
|
+
</span>
|
|
319
|
+
</div>
|
|
320
|
+
<div className="flex items-center justify-between">
|
|
321
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
322
|
+
Songs played
|
|
323
|
+
</span>
|
|
324
|
+
<span className="text-fm-primary font-fm-brand text-fm-md leading-fm-md font-semibold">
|
|
325
|
+
312
|
|
326
|
+
</span>
|
|
327
|
+
</div>
|
|
328
|
+
<div className="flex items-center justify-between">
|
|
329
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
330
|
+
Artists explored
|
|
331
|
+
</span>
|
|
332
|
+
<span className="text-fm-primary font-fm-brand text-fm-md leading-fm-md font-semibold">
|
|
333
|
+
47
|
|
334
|
+
</span>
|
|
335
|
+
</div>
|
|
1298
336
|
</div>
|
|
1299
337
|
</TabsContent>
|
|
1300
|
-
<TabsContent value="
|
|
1301
|
-
<div className="
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
338
|
+
<TabsContent value="top" className="mt-4">
|
|
339
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-2 rounded-lg border p-4">
|
|
340
|
+
{["Midnight Drive", "Electric Haze", "Neon Pulse"].map(
|
|
341
|
+
(track, i) => (
|
|
342
|
+
<div
|
|
343
|
+
key={track}
|
|
344
|
+
className="flex items-center gap-3 rounded-md px-2 py-2"
|
|
345
|
+
>
|
|
346
|
+
<span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm w-4">
|
|
347
|
+
{i + 1}
|
|
348
|
+
</span>
|
|
349
|
+
<div className="bg-fm-surface-secondary border-fm-divider-secondary flex h-8 w-8 items-center justify-center rounded-md border">
|
|
350
|
+
<MusicalNoteIcon className="text-fm-secondary h-4 w-4" />
|
|
351
|
+
</div>
|
|
352
|
+
<span className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
|
|
353
|
+
{track}
|
|
354
|
+
</span>
|
|
355
|
+
</div>
|
|
356
|
+
)
|
|
357
|
+
)}
|
|
1306
358
|
</div>
|
|
1307
359
|
</TabsContent>
|
|
1308
|
-
<TabsContent value="
|
|
1309
|
-
<div className="
|
|
1310
|
-
<
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
360
|
+
<TabsContent value="settings" className="mt-4">
|
|
361
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-3 rounded-lg border p-4">
|
|
362
|
+
<div className="flex items-center justify-between">
|
|
363
|
+
<span className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
|
|
364
|
+
Crossfade
|
|
365
|
+
</span>
|
|
366
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
367
|
+
3s
|
|
368
|
+
</span>
|
|
369
|
+
</div>
|
|
370
|
+
<div className="flex items-center justify-between">
|
|
371
|
+
<span className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
|
|
372
|
+
Normalize volume
|
|
373
|
+
</span>
|
|
374
|
+
<span className="text-fm-positive font-fm-text text-fm-sm leading-fm-sm">
|
|
375
|
+
On
|
|
376
|
+
</span>
|
|
377
|
+
</div>
|
|
378
|
+
<div className="flex items-center justify-between">
|
|
379
|
+
<span className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
|
|
380
|
+
Download quality
|
|
381
|
+
</span>
|
|
382
|
+
<span className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
383
|
+
High
|
|
384
|
+
</span>
|
|
385
|
+
</div>
|
|
1314
386
|
</div>
|
|
1315
387
|
</TabsContent>
|
|
1316
388
|
</Tabs>
|
|
1317
389
|
</div>
|
|
1318
|
-
|
|
1319
|
-
<div className="rounded-lg border border-blue-500/20 bg-blue-500/10 p-4">
|
|
1320
|
-
<div className="text-sm text-blue-200">
|
|
1321
|
-
<strong>Note:</strong> The glowDirection prop allows you to customize
|
|
1322
|
-
the visual effect of active tabs. Use "bottom" (default) for an
|
|
1323
|
-
underline-style glow or "top" for a subtle highlight effect. You can
|
|
1324
|
-
mix different directions within the same tab group for creative
|
|
1325
|
-
designs.
|
|
1326
|
-
</div>
|
|
1327
|
-
</div>
|
|
1328
390
|
</div>
|
|
1329
391
|
),
|
|
1330
392
|
parameters: {
|
|
1331
393
|
docs: {
|
|
1332
394
|
description: {
|
|
1333
395
|
story:
|
|
1334
|
-
"
|
|
396
|
+
"Configuration axes: tabs with icons, individual per-trigger size overrides against a parent size context, and tabs with rich differentiated content panels.",
|
|
1335
397
|
},
|
|
1336
398
|
},
|
|
1337
399
|
},
|
|
1338
400
|
}
|
|
1339
401
|
|
|
1340
|
-
//
|
|
1341
|
-
export const InteractiveStates: Story = {
|
|
1342
|
-
render: () => {
|
|
1343
|
-
const [activeTab, setActiveTab] = React.useState("normal")
|
|
1344
|
-
const [isLoading, setIsLoading] = React.useState(false)
|
|
402
|
+
// ─── Interactive ──────────────────────────────────────────────────────────────
|
|
1345
403
|
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
},
|
|
1354
|
-
|
|
404
|
+
export const Interactive: Story = {
|
|
405
|
+
render: () => {
|
|
406
|
+
const [activeTab, setActiveTab] = React.useState("songs")
|
|
407
|
+
|
|
408
|
+
const tabs = [
|
|
409
|
+
{ value: "songs", label: "Songs", icon: MusicalNoteIcon },
|
|
410
|
+
{ value: "albums", label: "Albums", icon: StarIcon },
|
|
411
|
+
{ value: "artists", label: "Artists", icon: HeartIcon },
|
|
412
|
+
{ value: "about", label: "About", icon: AlertIcon },
|
|
413
|
+
]
|
|
414
|
+
|
|
415
|
+
const songs = [
|
|
416
|
+
{ title: "Midnight Drive", artist: "Nova Wave", duration: "3:42" },
|
|
417
|
+
{ title: "Electric Haze", artist: "The Circuits", duration: "4:15" },
|
|
418
|
+
{ title: "Neon Pulse", artist: "Synthcore", duration: "3:58" },
|
|
419
|
+
{ title: "Deep Current", artist: "Ocean Mind", duration: "5:02" },
|
|
420
|
+
]
|
|
421
|
+
|
|
422
|
+
const albums = [
|
|
423
|
+
{ title: "Chromatic", artist: "Nova Wave", tracks: 12, year: 2024 },
|
|
424
|
+
{ title: "Static Dreams", artist: "The Circuits", tracks: 9, year: 2023 },
|
|
425
|
+
{ title: "Parallax", artist: "Synthcore", tracks: 14, year: 2024 },
|
|
426
|
+
]
|
|
427
|
+
|
|
428
|
+
const artists = [
|
|
429
|
+
{ name: "Nova Wave", genre: "Synthpop", listeners: "1.2M" },
|
|
430
|
+
{ name: "The Circuits", genre: "Electronic", listeners: "840K" },
|
|
431
|
+
{ name: "Synthcore", genre: "Ambient", listeners: "620K" },
|
|
432
|
+
{ name: "Ocean Mind", genre: "Chill", listeners: "390K" },
|
|
433
|
+
]
|
|
1355
434
|
|
|
1356
435
|
return (
|
|
1357
|
-
<div className="w-full
|
|
1358
|
-
<div className="
|
|
1359
|
-
<
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
</p>
|
|
1365
|
-
</div>
|
|
1366
|
-
|
|
1367
|
-
<Tabs
|
|
1368
|
-
value={activeTab}
|
|
1369
|
-
onValueChange={handleTabChange}
|
|
1370
|
-
size="md"
|
|
1371
|
-
className="w-full"
|
|
1372
|
-
>
|
|
1373
|
-
<TabsList className="grid w-full grid-cols-4">
|
|
1374
|
-
<TabsTrigger value="normal" className="gap-2">
|
|
1375
|
-
<TickCircleIcon className="h-4 w-4" />
|
|
1376
|
-
Normal
|
|
1377
|
-
</TabsTrigger>
|
|
1378
|
-
<TabsTrigger value="loading" className="gap-2" disabled={isLoading}>
|
|
1379
|
-
{isLoading && activeTab === "loading" ? (
|
|
1380
|
-
<div className="h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white" />
|
|
1381
|
-
) : (
|
|
1382
|
-
<AlertIcon className="h-4 w-4" />
|
|
1383
|
-
)}
|
|
1384
|
-
Loading
|
|
1385
|
-
</TabsTrigger>
|
|
1386
|
-
<TabsTrigger value="error" className="gap-2">
|
|
1387
|
-
<CrossIcon className="h-4 w-4" />
|
|
1388
|
-
Error
|
|
1389
|
-
</TabsTrigger>
|
|
1390
|
-
<TabsTrigger value="success" className="gap-2">
|
|
1391
|
-
<TickCircleIcon className="h-4 w-4" />
|
|
1392
|
-
Success
|
|
1393
|
-
</TabsTrigger>
|
|
1394
|
-
</TabsList>
|
|
1395
|
-
|
|
1396
|
-
<TabsContent value="normal" className="mt-6">
|
|
1397
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-6">
|
|
1398
|
-
<h3 className="mb-4 text-lg font-semibold text-white">
|
|
1399
|
-
Normal State
|
|
1400
|
-
</h3>
|
|
1401
|
-
<p className="mb-4 text-white/70">
|
|
1402
|
-
This is the default state of the component with all
|
|
1403
|
-
functionality working normally.
|
|
436
|
+
<div className="w-full p-8">
|
|
437
|
+
<div className="mx-auto max-w-3xl space-y-6">
|
|
438
|
+
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
|
439
|
+
{/* Controls panel */}
|
|
440
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-5 rounded-xl border p-5">
|
|
441
|
+
<p className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold tracking-widest uppercase">
|
|
442
|
+
Active Tab
|
|
1404
443
|
</p>
|
|
1405
|
-
<div className="
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
<h3 className="mb-2 text-lg font-semibold text-white">
|
|
1424
|
-
Loading Content...
|
|
1425
|
-
</h3>
|
|
1426
|
-
<p className="text-white/70">
|
|
1427
|
-
Please wait while we fetch the latest data.
|
|
1428
|
-
</p>
|
|
1429
|
-
</div>
|
|
1430
|
-
) : (
|
|
1431
|
-
<>
|
|
1432
|
-
<h3 className="mb-4 text-lg font-semibold text-white">
|
|
1433
|
-
Loading State Demo
|
|
1434
|
-
</h3>
|
|
1435
|
-
<p className="mb-4 text-white/70">
|
|
1436
|
-
This tab demonstrates loading states and async content
|
|
1437
|
-
fetching.
|
|
1438
|
-
</p>
|
|
1439
|
-
<div className="space-y-3">
|
|
1440
|
-
<div className="flex items-center gap-3 rounded-lg bg-white/5 p-3">
|
|
1441
|
-
<div className="flex h-5 w-5 items-center justify-center rounded-full bg-green-500">
|
|
1442
|
-
<TickCircleIcon className="h-3 w-3 text-white" />
|
|
1443
|
-
</div>
|
|
1444
|
-
<span className="text-white/70">
|
|
1445
|
-
Content loaded successfully
|
|
1446
|
-
</span>
|
|
1447
|
-
</div>
|
|
1448
|
-
<div className="flex items-center gap-3 rounded-lg bg-white/5 p-3">
|
|
1449
|
-
<div className="flex h-5 w-5 items-center justify-center rounded-full bg-blue-500">
|
|
1450
|
-
<AlertIcon className="h-3 w-3 text-white" />
|
|
1451
|
-
</div>
|
|
1452
|
-
<span className="text-white/70">
|
|
1453
|
-
Data synchronized with server
|
|
1454
|
-
</span>
|
|
1455
|
-
</div>
|
|
1456
|
-
</div>
|
|
1457
|
-
</>
|
|
1458
|
-
)}
|
|
1459
|
-
</div>
|
|
1460
|
-
</TabsContent>
|
|
1461
|
-
|
|
1462
|
-
<TabsContent value="error" className="mt-6">
|
|
1463
|
-
<div className="rounded-lg border border-red-500/20 bg-red-500/5 p-6">
|
|
1464
|
-
<div className="mb-4 flex items-start gap-3">
|
|
1465
|
-
<CrossIcon className="mt-0.5 h-6 w-6 flex-shrink-0 text-red-400" />
|
|
1466
|
-
<div>
|
|
1467
|
-
<h3 className="text-lg font-semibold text-white">
|
|
1468
|
-
Error State
|
|
1469
|
-
</h3>
|
|
1470
|
-
<p className="text-white/70">
|
|
1471
|
-
Something went wrong while loading the content.
|
|
1472
|
-
</p>
|
|
1473
|
-
</div>
|
|
1474
|
-
</div>
|
|
1475
|
-
|
|
1476
|
-
<div className="mb-4 rounded-lg border border-red-500/20 bg-red-500/10 p-4">
|
|
1477
|
-
<div className="text-sm text-red-200">
|
|
1478
|
-
<strong>Error:</strong> Failed to fetch data from the server.
|
|
1479
|
-
Please check your connection and try again.
|
|
1480
|
-
</div>
|
|
444
|
+
<div className="space-y-2">
|
|
445
|
+
{tabs.map((tab) => {
|
|
446
|
+
const Icon = tab.icon
|
|
447
|
+
return (
|
|
448
|
+
<button
|
|
449
|
+
key={tab.value}
|
|
450
|
+
onClick={() => setActiveTab(tab.value)}
|
|
451
|
+
className={`font-fm-text text-fm-sm leading-fm-sm flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left transition-colors ${
|
|
452
|
+
activeTab === tab.value
|
|
453
|
+
? "bg-fm-surface-primary text-fm-primary"
|
|
454
|
+
: "text-fm-secondary hover:text-fm-primary"
|
|
455
|
+
}`}
|
|
456
|
+
>
|
|
457
|
+
<Icon className="h-4 w-4 shrink-0" />
|
|
458
|
+
{tab.label}
|
|
459
|
+
</button>
|
|
460
|
+
)
|
|
461
|
+
})}
|
|
1481
462
|
</div>
|
|
1482
|
-
|
|
1483
|
-
<div className="
|
|
1484
|
-
<
|
|
1485
|
-
|
|
1486
|
-
</
|
|
1487
|
-
<button className="rounded-lg bg-white/10 px-4 py-2 text-white transition-colors hover:bg-white/20">
|
|
1488
|
-
Report Issue
|
|
1489
|
-
</button>
|
|
463
|
+
<div className="border-fm-divider-secondary border-t pt-4" />
|
|
464
|
+
<div className="border-fm-divider-secondary bg-fm-surface-primary rounded-lg border px-4 py-3">
|
|
465
|
+
<code className="text-fm-secondary text-fm-md leading-fm-md font-(--font-fm-mono)">
|
|
466
|
+
value="{activeTab}"
|
|
467
|
+
</code>
|
|
1490
468
|
</div>
|
|
1491
469
|
</div>
|
|
1492
|
-
</TabsContent>
|
|
1493
470
|
|
|
1494
|
-
|
|
1495
|
-
<div className="
|
|
1496
|
-
<
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
471
|
+
{/* Preview stage */}
|
|
472
|
+
<div className="flex flex-col gap-3 lg:col-span-2">
|
|
473
|
+
<Tabs
|
|
474
|
+
value={activeTab}
|
|
475
|
+
onValueChange={setActiveTab}
|
|
476
|
+
size="md"
|
|
477
|
+
className="w-full"
|
|
478
|
+
>
|
|
479
|
+
<TabsList>
|
|
480
|
+
{tabs.map((tab) => {
|
|
481
|
+
const Icon = tab.icon
|
|
482
|
+
return (
|
|
483
|
+
<TabsTrigger
|
|
484
|
+
key={tab.value}
|
|
485
|
+
value={tab.value}
|
|
486
|
+
className="gap-2"
|
|
487
|
+
>
|
|
488
|
+
<Icon className="h-4 w-4" />
|
|
489
|
+
{tab.label}
|
|
490
|
+
</TabsTrigger>
|
|
491
|
+
)
|
|
492
|
+
})}
|
|
493
|
+
</TabsList>
|
|
494
|
+
|
|
495
|
+
<TabsContent value="songs" className="mt-4">
|
|
496
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-2 rounded-lg border p-4">
|
|
497
|
+
{songs.map((song) => (
|
|
498
|
+
<div
|
|
499
|
+
key={song.title}
|
|
500
|
+
className="hover:bg-fm-surface-primary flex items-center justify-between rounded-md px-2 py-2 transition-colors"
|
|
501
|
+
>
|
|
502
|
+
<div className="flex items-center gap-3">
|
|
503
|
+
<div className="bg-fm-surface-primary border-fm-divider-secondary flex h-9 w-9 shrink-0 items-center justify-center rounded-md border">
|
|
504
|
+
<MusicalNoteIcon className="text-fm-secondary h-4 w-4" />
|
|
505
|
+
</div>
|
|
506
|
+
<div>
|
|
507
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
|
|
508
|
+
{song.title}
|
|
509
|
+
</p>
|
|
510
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
511
|
+
{song.artist}
|
|
512
|
+
</p>
|
|
513
|
+
</div>
|
|
514
|
+
</div>
|
|
515
|
+
<span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
|
|
516
|
+
{song.duration}
|
|
517
|
+
</span>
|
|
518
|
+
</div>
|
|
519
|
+
))}
|
|
1512
520
|
</div>
|
|
1513
|
-
</
|
|
1514
|
-
|
|
1515
|
-
<
|
|
1516
|
-
<div className="
|
|
1517
|
-
|
|
1518
|
-
|
|
521
|
+
</TabsContent>
|
|
522
|
+
|
|
523
|
+
<TabsContent value="albums" className="mt-4">
|
|
524
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-2 rounded-lg border p-4">
|
|
525
|
+
{albums.map((album) => (
|
|
526
|
+
<div
|
|
527
|
+
key={album.title}
|
|
528
|
+
className="hover:bg-fm-surface-primary flex items-center justify-between rounded-md px-2 py-2 transition-colors"
|
|
529
|
+
>
|
|
530
|
+
<div className="flex items-center gap-3">
|
|
531
|
+
<div className="bg-fm-surface-primary border-fm-divider-secondary flex h-12 w-12 shrink-0 items-center justify-center rounded-md border">
|
|
532
|
+
<StarIcon className="text-fm-secondary h-5 w-5" />
|
|
533
|
+
</div>
|
|
534
|
+
<div>
|
|
535
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
|
|
536
|
+
{album.title}
|
|
537
|
+
</p>
|
|
538
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
539
|
+
{album.artist}
|
|
540
|
+
</p>
|
|
541
|
+
</div>
|
|
542
|
+
</div>
|
|
543
|
+
<div className="text-right">
|
|
544
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
545
|
+
{album.tracks} tracks
|
|
546
|
+
</p>
|
|
547
|
+
<p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
|
|
548
|
+
{album.year}
|
|
549
|
+
</p>
|
|
550
|
+
</div>
|
|
551
|
+
</div>
|
|
552
|
+
))}
|
|
1519
553
|
</div>
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
554
|
+
</TabsContent>
|
|
555
|
+
|
|
556
|
+
<TabsContent value="artists" className="mt-4">
|
|
557
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-2 rounded-lg border p-4">
|
|
558
|
+
{artists.map((artist) => (
|
|
559
|
+
<div
|
|
560
|
+
key={artist.name}
|
|
561
|
+
className="hover:bg-fm-surface-primary flex items-center justify-between rounded-md px-2 py-2 transition-colors"
|
|
562
|
+
>
|
|
563
|
+
<div className="flex items-center gap-3">
|
|
564
|
+
<div className="bg-fm-surface-primary border-fm-divider-secondary flex h-10 w-10 shrink-0 items-center justify-center rounded-full border">
|
|
565
|
+
<HeartIcon className="text-fm-secondary h-4 w-4" />
|
|
566
|
+
</div>
|
|
567
|
+
<div>
|
|
568
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
|
|
569
|
+
{artist.name}
|
|
570
|
+
</p>
|
|
571
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
572
|
+
{artist.genre}
|
|
573
|
+
</p>
|
|
574
|
+
</div>
|
|
575
|
+
</div>
|
|
576
|
+
<span className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
|
|
577
|
+
{artist.listeners}
|
|
578
|
+
</span>
|
|
579
|
+
</div>
|
|
580
|
+
))}
|
|
1523
581
|
</div>
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
582
|
+
</TabsContent>
|
|
583
|
+
|
|
584
|
+
<TabsContent value="about" className="mt-4">
|
|
585
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-4 rounded-lg border p-4">
|
|
586
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
587
|
+
Aural is a music streaming platform designed for deep
|
|
588
|
+
listeners. Discover new artists, curate playlists, and
|
|
589
|
+
explore lossless audio quality.
|
|
590
|
+
</p>
|
|
591
|
+
<div className="border-fm-divider-secondary bg-fm-surface-primary rounded-lg border px-4 py-3">
|
|
592
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-xl">
|
|
593
|
+
Version 2.4.1 · Last updated April 2026
|
|
594
|
+
</p>
|
|
595
|
+
</div>
|
|
1527
596
|
</div>
|
|
1528
|
-
</
|
|
1529
|
-
</
|
|
597
|
+
</TabsContent>
|
|
598
|
+
</Tabs>
|
|
1530
599
|
</div>
|
|
1531
|
-
</
|
|
1532
|
-
</Tabs>
|
|
1533
|
-
|
|
1534
|
-
<div className="text-center text-xs text-white/60">
|
|
1535
|
-
<p>
|
|
1536
|
-
Current active tab:{" "}
|
|
1537
|
-
<span className="rounded bg-white/10 px-2 py-0.5 font-mono">
|
|
1538
|
-
{activeTab}
|
|
1539
|
-
</span>
|
|
1540
|
-
</p>
|
|
1541
|
-
{isLoading && <p className="mt-1">Loading state active...</p>}
|
|
600
|
+
</div>
|
|
1542
601
|
</div>
|
|
1543
602
|
</div>
|
|
1544
603
|
)
|
|
@@ -1547,7 +606,7 @@ export const InteractiveStates: Story = {
|
|
|
1547
606
|
docs: {
|
|
1548
607
|
description: {
|
|
1549
608
|
story:
|
|
1550
|
-
"
|
|
609
|
+
"Stateful audio app tab switcher — Songs, Albums, Artists, About — with a left-side preset panel for controlled tab activation and a live preview stage showing each content panel.",
|
|
1551
610
|
},
|
|
1552
611
|
},
|
|
1553
612
|
},
|