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,15 +1,9 @@
|
|
|
1
1
|
import React from "react"
|
|
2
2
|
import { Button } from "@components/button"
|
|
3
|
-
import {
|
|
4
|
-
AlertIcon,
|
|
5
|
-
EditBigIcon,
|
|
6
|
-
FileChartIcon,
|
|
7
|
-
PlusIcon,
|
|
8
|
-
SearchIcon,
|
|
9
|
-
TickCircleIcon,
|
|
10
|
-
} from "@icons/index"
|
|
11
3
|
import type { Meta, StoryObj } from "@storybook/react-vite"
|
|
12
4
|
|
|
5
|
+
import { AuralComponentDocsPage } from "src/ui/story-spec/components/component-story-docs-page"
|
|
6
|
+
|
|
13
7
|
import { HoverCard, HoverCardContent, HoverCardTrigger } from "."
|
|
14
8
|
|
|
15
9
|
const meta: Meta<typeof HoverCard> = {
|
|
@@ -17,151 +11,40 @@ const meta: Meta<typeof HoverCard> = {
|
|
|
17
11
|
component: HoverCard,
|
|
18
12
|
parameters: {
|
|
19
13
|
layout: "centered",
|
|
20
|
-
backgrounds: {
|
|
21
|
-
default: "dark",
|
|
22
|
-
values: [
|
|
23
|
-
{ name: "dark", value: "#0a0a0a" },
|
|
24
|
-
{ name: "light", value: "#ffffff" },
|
|
25
|
-
],
|
|
26
|
-
},
|
|
27
14
|
docs: {
|
|
28
15
|
description: {
|
|
29
|
-
component:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
A rich contextual preview component built on top of Radix UI's HoverCard primitive, providing detailed information that appears on hover with a slight delay.
|
|
33
|
-
|
|
34
|
-
## Components
|
|
35
|
-
|
|
36
|
-
### Core Components
|
|
37
|
-
- **HoverCard**: Root component that manages the hover state and timing
|
|
38
|
-
- **HoverCardTrigger**: The element that triggers the hover card display
|
|
39
|
-
- **HoverCardContent**: The content container with positioning and styling
|
|
40
|
-
|
|
41
|
-
## Features
|
|
42
|
-
|
|
43
|
-
- **Smart Positioning**: Automatically positions to stay within viewport
|
|
44
|
-
- **Hover Delay**: Configurable delay before showing content
|
|
45
|
-
- **Rich Content**: Supports complex layouts with images, text, and actions
|
|
46
|
-
- **Keyboard Accessible**: Full keyboard navigation support
|
|
47
|
-
- **Portal Rendering**: Renders in a portal to avoid z-index issues
|
|
48
|
-
- **Responsive**: Adapts to different screen sizes
|
|
49
|
-
- **Design System**: Integrated with design tokens and themes
|
|
50
|
-
- **Animation**: Smooth enter/exit animations
|
|
51
|
-
|
|
52
|
-
## Usage Examples
|
|
53
|
-
|
|
54
|
-
### Basic HoverCard
|
|
55
|
-
\`\`\`tsx
|
|
56
|
-
<HoverCard>
|
|
57
|
-
<HoverCardTrigger>
|
|
58
|
-
<Button variant="link">Hover me</Button>
|
|
59
|
-
</HoverCardTrigger>
|
|
60
|
-
<HoverCardContent>
|
|
61
|
-
<div className="space-y-2">
|
|
62
|
-
<h4 className="text-sm font-semibold">Quick Info</h4>
|
|
63
|
-
<p className="text-sm text-muted-foreground">
|
|
64
|
-
This is a hover card with basic information.
|
|
65
|
-
</p>
|
|
66
|
-
</div>
|
|
67
|
-
</HoverCardContent>
|
|
68
|
-
</HoverCard>
|
|
69
|
-
\`\`\`
|
|
70
|
-
|
|
71
|
-
### User Profile Card
|
|
72
|
-
\`\`\`tsx
|
|
73
|
-
<HoverCard>
|
|
74
|
-
<HoverCardTrigger>
|
|
75
|
-
<Button variant="link">@username</Button>
|
|
76
|
-
</HoverCardTrigger>
|
|
77
|
-
<HoverCardContent className="w-80">
|
|
78
|
-
<div className="flex justify-between space-x-4">
|
|
79
|
-
<div className="space-y-1">
|
|
80
|
-
<h4 className="text-sm font-semibold">@username</h4>
|
|
81
|
-
<p className="text-sm">
|
|
82
|
-
Full Name - Software Developer
|
|
83
|
-
</p>
|
|
84
|
-
<div className="flex items-center pt-2">
|
|
85
|
-
<CalendarIcon className="mr-2 h-4 w-4" />
|
|
86
|
-
<span className="text-xs text-muted-foreground">
|
|
87
|
-
Joined December 2021
|
|
88
|
-
</span>
|
|
89
|
-
</div>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
</HoverCardContent>
|
|
93
|
-
</HoverCard>
|
|
94
|
-
\`\`\`
|
|
95
|
-
|
|
96
|
-
### Product Preview
|
|
97
|
-
\`\`\`tsx
|
|
98
|
-
<HoverCard>
|
|
99
|
-
<HoverCardTrigger>
|
|
100
|
-
<img src="product.jpg" alt="Product" />
|
|
101
|
-
</HoverCardTrigger>
|
|
102
|
-
<HoverCardContent>
|
|
103
|
-
<div className="space-y-3">
|
|
104
|
-
<div>
|
|
105
|
-
<h4 className="font-semibold">Product Name</h4>
|
|
106
|
-
<p className="text-sm text-muted-foreground">
|
|
107
|
-
Product description with key features
|
|
108
|
-
</p>
|
|
109
|
-
</div>
|
|
110
|
-
<div className="flex items-center justify-between">
|
|
111
|
-
<span className="text-lg font-bold">$99.99</span>
|
|
112
|
-
<Button size="sm">Add to Cart</Button>
|
|
113
|
-
</div>
|
|
114
|
-
</div>
|
|
115
|
-
</HoverCardContent>
|
|
116
|
-
</HoverCard>
|
|
117
|
-
\`\`\`
|
|
118
|
-
|
|
119
|
-
## Positioning
|
|
120
|
-
|
|
121
|
-
The hover card automatically positions itself:
|
|
122
|
-
- **side**: "top" | "right" | "bottom" | "left"
|
|
123
|
-
- **align**: "start" | "center" | "end"
|
|
124
|
-
- **sideOffset**: Distance from the trigger (default: 4px)
|
|
125
|
-
- **alignOffset**: Offset along the alignment axis
|
|
126
|
-
|
|
127
|
-
## Accessibility
|
|
128
|
-
|
|
129
|
-
- **ARIA Support**: Proper ARIA attributes for screen readers
|
|
130
|
-
- **Keyboard Navigation**: Accessible via keyboard focus
|
|
131
|
-
- **Focus Management**: Proper focus handling
|
|
132
|
-
- **Delayed Appearance**: Prevents accidental triggers
|
|
133
|
-
- **Screen Reader**: Content is announced when card appears
|
|
134
|
-
|
|
135
|
-
## Design Tokens
|
|
136
|
-
|
|
137
|
-
- \`bg-fm-surface-frosted/20\`: Translucent background
|
|
138
|
-
- \`text-fm-primary\`: Primary text color
|
|
139
|
-
- \`rounded-md\`: Border radius
|
|
140
|
-
- \`border\`: Border styling
|
|
141
|
-
- \`shadow-md\`: Drop shadow
|
|
142
|
-
- \`p-4\`: Default padding
|
|
143
|
-
|
|
144
|
-
## Best Practices
|
|
145
|
-
|
|
146
|
-
- Use for supplementary information, not critical content
|
|
147
|
-
- Keep content concise and scannable
|
|
148
|
-
- Provide clear visual hierarchy
|
|
149
|
-
- Test with keyboard navigation
|
|
150
|
-
- Consider mobile users (hover cards don't work on touch)
|
|
151
|
-
- Don't nest interactive elements unnecessarily
|
|
152
|
-
`,
|
|
16
|
+
component:
|
|
17
|
+
"A rich contextual preview that appears on hover after a configurable delay. Composed of HoverCard (root state manager), HoverCardTrigger (the hovered element), and HoverCardContent (the floating panel). Supports align, sideOffset, openDelay, and closeDelay props.",
|
|
153
18
|
},
|
|
19
|
+
page: () => (
|
|
20
|
+
<AuralComponentDocsPage
|
|
21
|
+
features={[
|
|
22
|
+
{
|
|
23
|
+
title: "Hover Preview",
|
|
24
|
+
description: "Configurable open delay",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: "Compound Parts",
|
|
28
|
+
description: "Trigger and content",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
title: "Alignment Control",
|
|
32
|
+
description: "align and sideOffset",
|
|
33
|
+
},
|
|
34
|
+
]}
|
|
35
|
+
/>
|
|
36
|
+
),
|
|
154
37
|
},
|
|
155
38
|
},
|
|
156
39
|
tags: ["autodocs"],
|
|
157
40
|
argTypes: {
|
|
158
41
|
openDelay: {
|
|
159
42
|
control: { type: "number", min: 0, max: 2000, step: 100 },
|
|
160
|
-
description: "Delay before
|
|
43
|
+
description: "Delay in ms before the card opens",
|
|
161
44
|
},
|
|
162
45
|
closeDelay: {
|
|
163
46
|
control: { type: "number", min: 0, max: 2000, step: 100 },
|
|
164
|
-
description: "Delay before
|
|
47
|
+
description: "Delay in ms before the card closes",
|
|
165
48
|
},
|
|
166
49
|
},
|
|
167
50
|
}
|
|
@@ -169,1160 +52,374 @@ The hover card automatically positions itself:
|
|
|
169
52
|
export default meta
|
|
170
53
|
type Story = StoryObj<typeof HoverCard>
|
|
171
54
|
|
|
172
|
-
//
|
|
173
|
-
export const Basic: Story = {
|
|
174
|
-
render: () => (
|
|
175
|
-
<div className="p-8">
|
|
176
|
-
<HoverCard>
|
|
177
|
-
<HoverCardTrigger asChild>
|
|
178
|
-
<Button variant="text">Hover for more info</Button>
|
|
179
|
-
</HoverCardTrigger>
|
|
180
|
-
<HoverCardContent>
|
|
181
|
-
<div className="space-y-2">
|
|
182
|
-
<h4 className="text-sm font-semibold text-white">
|
|
183
|
-
Quick Information
|
|
184
|
-
</h4>
|
|
185
|
-
<p className="text-sm text-white/70">
|
|
186
|
-
This is a basic hover card that provides additional context when
|
|
187
|
-
you hover over the trigger element.
|
|
188
|
-
</p>
|
|
189
|
-
</div>
|
|
190
|
-
</HoverCardContent>
|
|
191
|
-
</HoverCard>
|
|
192
|
-
</div>
|
|
193
|
-
),
|
|
194
|
-
parameters: {
|
|
195
|
-
docs: {
|
|
196
|
-
description: {
|
|
197
|
-
story:
|
|
198
|
-
"A simple hover card that appears when hovering over a trigger element.",
|
|
199
|
-
},
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// 2. User Profile Cards
|
|
205
|
-
export const UserProfiles: Story = {
|
|
206
|
-
render: () => (
|
|
207
|
-
<div className="space-y-8 p-8">
|
|
208
|
-
<h3 className="text-center text-lg font-medium text-white">
|
|
209
|
-
User Profile Cards
|
|
210
|
-
</h3>
|
|
55
|
+
// ─── Parts ───────────────────────────────────────────────────────────────────
|
|
211
56
|
|
|
212
|
-
|
|
213
|
-
{/* Basic Profile */}
|
|
214
|
-
<div className="space-y-4">
|
|
215
|
-
<h4 className="text-sm font-medium text-white/70">Basic Profile</h4>
|
|
216
|
-
<div className="text-center">
|
|
217
|
-
<HoverCard>
|
|
218
|
-
<HoverCardTrigger asChild>
|
|
219
|
-
<Button variant="text" className="text-blue-400">
|
|
220
|
-
@johndoe
|
|
221
|
-
</Button>
|
|
222
|
-
</HoverCardTrigger>
|
|
223
|
-
<HoverCardContent className="w-80">
|
|
224
|
-
<div className="flex space-x-4">
|
|
225
|
-
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-gradient-to-br from-blue-500 to-purple-600">
|
|
226
|
-
<span className="font-semibold text-white">JD</span>
|
|
227
|
-
</div>
|
|
228
|
-
<div className="flex-1 space-y-1">
|
|
229
|
-
<h4 className="text-sm font-semibold text-white">
|
|
230
|
-
John Doe
|
|
231
|
-
</h4>
|
|
232
|
-
<p className="text-sm text-white/70">
|
|
233
|
-
Senior Software Engineer
|
|
234
|
-
</p>
|
|
235
|
-
<p className="text-xs text-white/50">
|
|
236
|
-
Building amazing user experiences with React and
|
|
237
|
-
TypeScript
|
|
238
|
-
</p>
|
|
239
|
-
<div className="flex items-center gap-4 pt-2 text-xs text-white/60">
|
|
240
|
-
<span>👥 1.2k followers</span>
|
|
241
|
-
<span>📍 San Francisco</span>
|
|
242
|
-
</div>
|
|
243
|
-
</div>
|
|
244
|
-
</div>
|
|
245
|
-
</HoverCardContent>
|
|
246
|
-
</HoverCard>
|
|
247
|
-
</div>
|
|
248
|
-
</div>
|
|
249
|
-
|
|
250
|
-
{/* Detailed Profile */}
|
|
251
|
-
<div className="space-y-4">
|
|
252
|
-
<h4 className="text-sm font-medium text-white/70">
|
|
253
|
-
Detailed Profile
|
|
254
|
-
</h4>
|
|
255
|
-
<div className="text-center">
|
|
256
|
-
<HoverCard>
|
|
257
|
-
<HoverCardTrigger asChild>
|
|
258
|
-
<Button variant="text" className="text-green-400">
|
|
259
|
-
@sarahsmith
|
|
260
|
-
</Button>
|
|
261
|
-
</HoverCardTrigger>
|
|
262
|
-
<HoverCardContent className="w-96">
|
|
263
|
-
<div className="space-y-3">
|
|
264
|
-
<div className="flex space-x-4">
|
|
265
|
-
<div className="flex h-16 w-16 items-center justify-center rounded-full bg-gradient-to-br from-green-500 to-teal-600">
|
|
266
|
-
<span className="text-lg font-semibold text-white">
|
|
267
|
-
SS
|
|
268
|
-
</span>
|
|
269
|
-
</div>
|
|
270
|
-
<div className="flex-1 space-y-1">
|
|
271
|
-
<h4 className="text-base font-semibold text-white">
|
|
272
|
-
Sarah Smith
|
|
273
|
-
</h4>
|
|
274
|
-
<p className="text-sm text-white/70">
|
|
275
|
-
UX Designer & Product Manager
|
|
276
|
-
</p>
|
|
277
|
-
<div className="flex items-center gap-2 text-xs text-white/60">
|
|
278
|
-
<TickCircleIcon className="h-3 w-3" />
|
|
279
|
-
<span>Verified Account</span>
|
|
280
|
-
</div>
|
|
281
|
-
</div>
|
|
282
|
-
</div>
|
|
283
|
-
|
|
284
|
-
<p className="text-sm text-white/70">
|
|
285
|
-
Passionate about creating intuitive digital experiences.
|
|
286
|
-
Currently working on design systems and user research.
|
|
287
|
-
</p>
|
|
288
|
-
|
|
289
|
-
<div className="grid grid-cols-3 gap-4 pt-2 text-center">
|
|
290
|
-
<div>
|
|
291
|
-
<div className="text-lg font-semibold text-white">
|
|
292
|
-
248
|
|
293
|
-
</div>
|
|
294
|
-
<div className="text-xs text-white/60">Posts</div>
|
|
295
|
-
</div>
|
|
296
|
-
<div>
|
|
297
|
-
<div className="text-lg font-semibold text-white">
|
|
298
|
-
2.8k
|
|
299
|
-
</div>
|
|
300
|
-
<div className="text-xs text-white/60">Followers</div>
|
|
301
|
-
</div>
|
|
302
|
-
<div>
|
|
303
|
-
<div className="text-lg font-semibold text-white">
|
|
304
|
-
892
|
|
305
|
-
</div>
|
|
306
|
-
<div className="text-xs text-white/60">Following</div>
|
|
307
|
-
</div>
|
|
308
|
-
</div>
|
|
309
|
-
|
|
310
|
-
<div className="flex gap-2 pt-2">
|
|
311
|
-
<Button size="sm" className="flex-1">
|
|
312
|
-
Follow
|
|
313
|
-
</Button>
|
|
314
|
-
<Button size="sm" variant="outline">
|
|
315
|
-
Message
|
|
316
|
-
</Button>
|
|
317
|
-
</div>
|
|
318
|
-
</div>
|
|
319
|
-
</HoverCardContent>
|
|
320
|
-
</HoverCard>
|
|
321
|
-
</div>
|
|
322
|
-
</div>
|
|
323
|
-
</div>
|
|
324
|
-
</div>
|
|
325
|
-
),
|
|
57
|
+
export const Parts: Story = {
|
|
326
58
|
parameters: {
|
|
327
59
|
docs: {
|
|
328
60
|
description: {
|
|
329
61
|
story:
|
|
330
|
-
"
|
|
62
|
+
"Each sub-component shown with its role. HoverCardTrigger wraps the hovered element; HoverCardContent hosts the floating preview panel.",
|
|
331
63
|
},
|
|
332
64
|
},
|
|
333
65
|
},
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// 3. Product Previews
|
|
337
|
-
export const ProductPreviews: Story = {
|
|
338
66
|
render: () => (
|
|
339
|
-
<div className="space-y-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
<span className="text-lg font-bold text-white">$29/mo</span>
|
|
368
|
-
<Button size="sm">
|
|
369
|
-
<PlusIcon className="mr-1 h-3 w-3" />
|
|
370
|
-
Add
|
|
371
|
-
</Button>
|
|
372
|
-
</div>
|
|
373
|
-
</div>
|
|
374
|
-
</HoverCardContent>
|
|
375
|
-
</HoverCard>
|
|
376
|
-
</div>
|
|
377
|
-
</div>
|
|
378
|
-
|
|
379
|
-
{/* Detailed Product */}
|
|
380
|
-
<div className="space-y-4">
|
|
381
|
-
<h4 className="text-sm font-medium text-white/70">
|
|
382
|
-
Detailed Product
|
|
383
|
-
</h4>
|
|
384
|
-
<div className="text-center">
|
|
385
|
-
<HoverCard>
|
|
386
|
-
<HoverCardTrigger asChild>
|
|
387
|
-
<div className="cursor-pointer rounded-lg border border-white/10 bg-white/5 p-4 transition-colors hover:bg-white/10">
|
|
388
|
-
<div className="mx-auto mb-2 flex h-20 w-20 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-cyan-600">
|
|
389
|
-
<SearchIcon className="h-8 w-8 text-white" />
|
|
390
|
-
</div>
|
|
391
|
-
<p className="text-sm text-white">Search Engine</p>
|
|
392
|
-
</div>
|
|
393
|
-
</HoverCardTrigger>
|
|
394
|
-
<HoverCardContent className="w-80">
|
|
395
|
-
<div className="space-y-4">
|
|
396
|
-
<div className="flex space-x-3">
|
|
397
|
-
<div className="flex h-16 w-16 flex-shrink-0 items-center justify-center rounded-lg bg-gradient-to-br from-blue-500 to-cyan-600">
|
|
398
|
-
<SearchIcon className="h-8 w-8 text-white" />
|
|
399
|
-
</div>
|
|
400
|
-
<div className="space-y-1">
|
|
401
|
-
<h4 className="font-semibold text-white">
|
|
402
|
-
Advanced Search Engine
|
|
403
|
-
</h4>
|
|
404
|
-
<p className="text-sm text-white/70">
|
|
405
|
-
AI-powered search with natural language processing
|
|
406
|
-
</p>
|
|
407
|
-
<div className="flex items-center gap-2">
|
|
408
|
-
<div className="flex">
|
|
409
|
-
{[1, 2, 3, 4, 5].map((star) => (
|
|
410
|
-
<span
|
|
411
|
-
key={star}
|
|
412
|
-
className="text-xs text-yellow-400"
|
|
413
|
-
>
|
|
414
|
-
★
|
|
415
|
-
</span>
|
|
416
|
-
))}
|
|
417
|
-
</div>
|
|
418
|
-
<span className="text-xs text-white/60">
|
|
419
|
-
(124 reviews)
|
|
420
|
-
</span>
|
|
421
|
-
</div>
|
|
422
|
-
</div>
|
|
423
|
-
</div>
|
|
424
|
-
|
|
425
|
-
<div className="space-y-2">
|
|
426
|
-
<div className="flex justify-between text-sm">
|
|
427
|
-
<span className="text-white/70">Features:</span>
|
|
428
|
-
</div>
|
|
429
|
-
<ul className="space-y-1 text-xs text-white/60">
|
|
430
|
-
<li>• Real-time search suggestions</li>
|
|
431
|
-
<li>• Advanced filtering options</li>
|
|
432
|
-
<li>• Analytics and insights</li>
|
|
433
|
-
<li>• API access included</li>
|
|
434
|
-
</ul>
|
|
435
|
-
</div>
|
|
436
|
-
|
|
437
|
-
<div className="flex items-center justify-between border-t border-white/10 pt-2">
|
|
438
|
-
<div>
|
|
439
|
-
<span className="text-xs text-white/60 line-through">
|
|
440
|
-
$99/mo
|
|
441
|
-
</span>
|
|
442
|
-
<span className="ml-2 text-lg font-bold text-white">
|
|
443
|
-
$79/mo
|
|
444
|
-
</span>
|
|
445
|
-
</div>
|
|
446
|
-
<Button size="sm">Start Trial</Button>
|
|
447
|
-
</div>
|
|
448
|
-
</div>
|
|
449
|
-
</HoverCardContent>
|
|
450
|
-
</HoverCard>
|
|
451
|
-
</div>
|
|
452
|
-
</div>
|
|
453
|
-
|
|
454
|
-
{/* Feature Product */}
|
|
455
|
-
<div className="space-y-4">
|
|
456
|
-
<h4 className="text-sm font-medium text-white/70">Feature Product</h4>
|
|
457
|
-
<div className="text-center">
|
|
458
|
-
<HoverCard>
|
|
459
|
-
<HoverCardTrigger asChild>
|
|
460
|
-
<div className="cursor-pointer rounded-lg border border-white/10 bg-white/5 p-4 transition-colors hover:bg-white/10">
|
|
461
|
-
<div className="mx-auto mb-2 flex h-20 w-20 items-center justify-center rounded-lg bg-gradient-to-br from-orange-500 to-red-600">
|
|
462
|
-
<EditBigIcon className="h-8 w-8 text-white" />
|
|
463
|
-
</div>
|
|
464
|
-
<p className="text-sm text-white">Editor Pro</p>
|
|
465
|
-
</div>
|
|
466
|
-
</HoverCardTrigger>
|
|
467
|
-
<HoverCardContent className="w-72">
|
|
468
|
-
<div className="space-y-3">
|
|
469
|
-
<div className="flex items-start space-x-3">
|
|
470
|
-
<div className="flex h-12 w-12 items-center justify-center rounded-lg bg-gradient-to-br from-orange-500 to-red-600">
|
|
471
|
-
<EditBigIcon className="h-6 w-6 text-white" />
|
|
472
|
-
</div>
|
|
473
|
-
<div>
|
|
474
|
-
<h4 className="font-semibold text-white">Editor Pro</h4>
|
|
475
|
-
<p className="text-sm text-white/70">
|
|
476
|
-
Professional code editor
|
|
477
|
-
</p>
|
|
478
|
-
<div className="mt-1 flex items-center gap-1">
|
|
479
|
-
<span className="rounded bg-orange-500/20 px-2 py-0.5 text-xs text-orange-300">
|
|
480
|
-
Popular
|
|
481
|
-
</span>
|
|
482
|
-
<span className="rounded bg-green-500/20 px-2 py-0.5 text-xs text-green-300">
|
|
483
|
-
New
|
|
484
|
-
</span>
|
|
485
|
-
</div>
|
|
486
|
-
</div>
|
|
487
|
-
</div>
|
|
488
|
-
|
|
489
|
-
<div className="grid grid-cols-2 gap-3 text-xs">
|
|
490
|
-
<div className="space-y-1">
|
|
491
|
-
<div className="text-white/70">Languages:</div>
|
|
492
|
-
<div className="text-white/60">20+ supported</div>
|
|
493
|
-
</div>
|
|
494
|
-
<div className="space-y-1">
|
|
495
|
-
<div className="text-white/70">Themes:</div>
|
|
496
|
-
<div className="text-white/60">50+ themes</div>
|
|
497
|
-
</div>
|
|
498
|
-
</div>
|
|
499
|
-
|
|
500
|
-
<div className="flex items-center justify-between">
|
|
501
|
-
<span className="text-lg font-bold text-white">Free</span>
|
|
502
|
-
<Button size="sm" variant="outline">
|
|
503
|
-
Download
|
|
504
|
-
</Button>
|
|
505
|
-
</div>
|
|
506
|
-
</div>
|
|
507
|
-
</HoverCardContent>
|
|
508
|
-
</HoverCard>
|
|
509
|
-
</div>
|
|
67
|
+
<div className="w-full max-w-2xl space-y-10">
|
|
68
|
+
{/* HoverCardTrigger */}
|
|
69
|
+
<div className="space-y-3">
|
|
70
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
71
|
+
HoverCardTrigger
|
|
72
|
+
</h4>
|
|
73
|
+
<HoverCard>
|
|
74
|
+
<HoverCardTrigger asChild>
|
|
75
|
+
<Button variant="text">@aural_artist</Button>
|
|
76
|
+
</HoverCardTrigger>
|
|
77
|
+
<HoverCardContent>
|
|
78
|
+
<div className="space-y-1">
|
|
79
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
|
|
80
|
+
Aural Artist
|
|
81
|
+
</p>
|
|
82
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
83
|
+
Hover the trigger above to see this card.
|
|
84
|
+
</p>
|
|
85
|
+
</div>
|
|
86
|
+
</HoverCardContent>
|
|
87
|
+
</HoverCard>
|
|
88
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
89
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
90
|
+
Wraps any element and attaches hover event listeners. Pass{" "}
|
|
91
|
+
<code>asChild</code> to render the child element directly rather
|
|
92
|
+
than adding an extra DOM node. Must be a direct child of the{" "}
|
|
93
|
+
<code>HoverCard</code> root.
|
|
94
|
+
</p>
|
|
510
95
|
</div>
|
|
511
96
|
</div>
|
|
512
|
-
</div>
|
|
513
|
-
),
|
|
514
|
-
parameters: {
|
|
515
|
-
docs: {
|
|
516
|
-
description: {
|
|
517
|
-
story:
|
|
518
|
-
"Product preview cards showing different levels of detail and information architecture.",
|
|
519
|
-
},
|
|
520
|
-
},
|
|
521
|
-
},
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
// 4. Documentation Links
|
|
525
|
-
export const DocumentationLinks: Story = {
|
|
526
|
-
render: () => (
|
|
527
|
-
<div className="space-y-8 p-8">
|
|
528
|
-
<h3 className="text-center text-lg font-medium text-white">
|
|
529
|
-
Documentation Links
|
|
530
|
-
</h3>
|
|
531
97
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
<
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
<
|
|
539
|
-
<
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
</
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
<h4 className="text-sm font-semibold text-white">
|
|
553
|
-
REST API
|
|
554
|
-
</h4>
|
|
555
|
-
<p className="text-sm text-white/70">
|
|
556
|
-
Our REST API provides programmatic access to all platform
|
|
557
|
-
features.
|
|
558
|
-
</p>
|
|
559
|
-
<div className="space-y-1 text-xs text-white/60">
|
|
560
|
-
<div>• Rate limit: 1000 requests/hour</div>
|
|
561
|
-
<div>• Authentication: API Key required</div>
|
|
562
|
-
<div>• Response format: JSON</div>
|
|
563
|
-
</div>
|
|
564
|
-
<Button size="sm" className="mt-2 w-full">
|
|
565
|
-
View Documentation
|
|
566
|
-
</Button>
|
|
567
|
-
</div>
|
|
568
|
-
</HoverCardContent>
|
|
569
|
-
</HoverCard>{" "}
|
|
570
|
-
and{" "}
|
|
571
|
-
<HoverCard>
|
|
572
|
-
<HoverCardTrigger asChild>
|
|
573
|
-
<Button
|
|
574
|
-
variant="text"
|
|
575
|
-
className="h-auto p-0 font-normal text-blue-400"
|
|
576
|
-
>
|
|
577
|
-
GraphQL endpoint
|
|
578
|
-
</Button>
|
|
579
|
-
</HoverCardTrigger>
|
|
580
|
-
<HoverCardContent>
|
|
581
|
-
<div className="space-y-2">
|
|
582
|
-
<h4 className="text-sm font-semibold text-white">
|
|
583
|
-
GraphQL API
|
|
584
|
-
</h4>
|
|
585
|
-
<p className="text-sm text-white/70">
|
|
586
|
-
Query exactly the data you need with our GraphQL API.
|
|
587
|
-
</p>
|
|
588
|
-
<div className="space-y-1 text-xs text-white/60">
|
|
589
|
-
<div>• Single endpoint for all queries</div>
|
|
590
|
-
<div>• Type-safe schema</div>
|
|
591
|
-
<div>• Real-time subscriptions</div>
|
|
592
|
-
</div>
|
|
593
|
-
<div className="mt-2 flex gap-2">
|
|
594
|
-
<Button size="sm" className="flex-1">
|
|
595
|
-
Playground
|
|
596
|
-
</Button>
|
|
597
|
-
<Button size="sm" variant="outline" className="flex-1">
|
|
598
|
-
Schema
|
|
599
|
-
</Button>
|
|
600
|
-
</div>
|
|
601
|
-
</div>
|
|
602
|
-
</HoverCardContent>
|
|
603
|
-
</HoverCard>
|
|
604
|
-
.
|
|
605
|
-
</p>
|
|
606
|
-
</div>
|
|
607
|
-
</div>
|
|
608
|
-
|
|
609
|
-
{/* Configuration Options */}
|
|
610
|
-
<div className="space-y-4">
|
|
611
|
-
<h4 className="text-sm font-medium text-white/70">
|
|
612
|
-
Configuration Options
|
|
613
|
-
</h4>
|
|
614
|
-
<div className="rounded-lg border border-white/10 bg-white/5 p-4">
|
|
615
|
-
<div className="space-y-3 text-sm">
|
|
616
|
-
<div className="flex items-center justify-between">
|
|
617
|
-
<span className="text-white">Enable notifications</span>
|
|
618
|
-
<HoverCard>
|
|
619
|
-
<HoverCardTrigger asChild>
|
|
620
|
-
<Button variant="outline" size="sm" className="h-6 w-6 p-0">
|
|
621
|
-
<AlertIcon className="h-4 w-4" />
|
|
622
|
-
</Button>
|
|
623
|
-
</HoverCardTrigger>
|
|
624
|
-
<HoverCardContent className="w-72">
|
|
625
|
-
<div className="space-y-2">
|
|
626
|
-
<h4 className="text-sm font-semibold text-white">
|
|
627
|
-
Notification Settings
|
|
628
|
-
</h4>
|
|
629
|
-
<p className="text-sm text-white/70">
|
|
630
|
-
Control when and how you receive notifications from the
|
|
631
|
-
platform.
|
|
632
|
-
</p>
|
|
633
|
-
<div className="space-y-2">
|
|
634
|
-
<div className="text-xs text-white/60">
|
|
635
|
-
Available notification types:
|
|
636
|
-
</div>
|
|
637
|
-
<ul className="ml-2 space-y-1 text-xs text-white/60">
|
|
638
|
-
<li>• Email notifications</li>
|
|
639
|
-
<li>• Push notifications</li>
|
|
640
|
-
<li>• In-app notifications</li>
|
|
641
|
-
<li>• SMS alerts (premium)</li>
|
|
642
|
-
</ul>
|
|
643
|
-
</div>
|
|
644
|
-
</div>
|
|
645
|
-
</HoverCardContent>
|
|
646
|
-
</HoverCard>
|
|
647
|
-
</div>
|
|
648
|
-
|
|
649
|
-
<div className="flex items-center justify-between">
|
|
650
|
-
<span className="text-white">Auto-save frequency</span>
|
|
651
|
-
<HoverCard>
|
|
652
|
-
<HoverCardTrigger asChild>
|
|
653
|
-
<Button variant="outline" size="sm" className="h-6 w-6 p-0">
|
|
654
|
-
<TickCircleIcon className="h-4 w-4" />
|
|
655
|
-
</Button>
|
|
656
|
-
</HoverCardTrigger>
|
|
657
|
-
<HoverCardContent>
|
|
658
|
-
<div className="space-y-2">
|
|
659
|
-
<h4 className="text-sm font-semibold text-white">
|
|
660
|
-
Auto-save Settings
|
|
661
|
-
</h4>
|
|
662
|
-
<p className="text-sm text-white/70">
|
|
663
|
-
Automatically save your work at regular intervals.
|
|
664
|
-
</p>
|
|
665
|
-
<div className="space-y-1 text-xs text-white/60">
|
|
666
|
-
<div>• Every 30 seconds (recommended)</div>
|
|
667
|
-
<div>• Every 1 minute</div>
|
|
668
|
-
<div>• Every 5 minutes</div>
|
|
669
|
-
<div>• Disabled</div>
|
|
670
|
-
</div>
|
|
671
|
-
</div>
|
|
672
|
-
</HoverCardContent>
|
|
673
|
-
</HoverCard>
|
|
674
|
-
</div>
|
|
98
|
+
{/* HoverCardContent */}
|
|
99
|
+
<div className="space-y-3">
|
|
100
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
101
|
+
HoverCardContent
|
|
102
|
+
</h4>
|
|
103
|
+
<HoverCard defaultOpen>
|
|
104
|
+
<HoverCardTrigger asChild>
|
|
105
|
+
<Button variant="text">Hover card open</Button>
|
|
106
|
+
</HoverCardTrigger>
|
|
107
|
+
<HoverCardContent>
|
|
108
|
+
<div className="space-y-2">
|
|
109
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
|
|
110
|
+
Frosted glass panel
|
|
111
|
+
</p>
|
|
112
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
113
|
+
Backdrop-blurred container with{" "}
|
|
114
|
+
<code>bg-fm-surface-frosted/20</code>. Accepts{" "}
|
|
115
|
+
<code>align</code>, <code>sideOffset</code>, and all Radix
|
|
116
|
+
Content props.
|
|
117
|
+
</p>
|
|
675
118
|
</div>
|
|
676
|
-
</
|
|
119
|
+
</HoverCardContent>
|
|
120
|
+
</HoverCard>
|
|
121
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-lg border p-4">
|
|
122
|
+
<p className="text-fm-secondary font-fm-text text-fm-md leading-fm-xl">
|
|
123
|
+
The floating panel rendered in a portal. Uses a frosted-glass
|
|
124
|
+
backdrop with <code>text-fm-primary</code> text and{" "}
|
|
125
|
+
<code>w-64</code> default width. Positioning is controlled by{" "}
|
|
126
|
+
<code>align</code> and <code>sideOffset</code>.
|
|
127
|
+
</p>
|
|
677
128
|
</div>
|
|
678
129
|
</div>
|
|
679
130
|
</div>
|
|
680
131
|
),
|
|
681
|
-
parameters: {
|
|
682
|
-
docs: {
|
|
683
|
-
description: {
|
|
684
|
-
story:
|
|
685
|
-
"Documentation and help text hover cards for providing contextual information about features and settings.",
|
|
686
|
-
},
|
|
687
|
-
},
|
|
688
|
-
},
|
|
689
132
|
}
|
|
690
133
|
|
|
691
|
-
//
|
|
692
|
-
export const InteractiveElements: Story = {
|
|
693
|
-
render: () => {
|
|
694
|
-
const [selectedUser, setSelectedUser] = React.useState<string | null>(null)
|
|
695
|
-
const [hoveredProduct, setHoveredProduct] = React.useState<string | null>(
|
|
696
|
-
null
|
|
697
|
-
)
|
|
698
|
-
|
|
699
|
-
const users = [
|
|
700
|
-
{ id: "1", name: "Alice Johnson", role: "Designer", status: "online" },
|
|
701
|
-
{ id: "2", name: "Bob Smith", role: "Developer", status: "away" },
|
|
702
|
-
{ id: "3", name: "Carol Davis", role: "Manager", status: "offline" },
|
|
703
|
-
]
|
|
704
|
-
|
|
705
|
-
const products = [
|
|
706
|
-
{ id: "1", name: "Dashboard Pro", price: "$49", sales: 1234 },
|
|
707
|
-
{ id: "2", name: "Analytics Suite", price: "$79", sales: 856 },
|
|
708
|
-
{ id: "3", name: "Report Builder", price: "$29", sales: 2341 },
|
|
709
|
-
]
|
|
710
|
-
|
|
711
|
-
return (
|
|
712
|
-
<div className="space-y-8 p-8">
|
|
713
|
-
<h3 className="text-center text-lg font-medium text-white">
|
|
714
|
-
Interactive Elements
|
|
715
|
-
</h3>
|
|
716
|
-
|
|
717
|
-
<div className="grid grid-cols-1 gap-8 lg:grid-cols-2">
|
|
718
|
-
{/* Team Members */}
|
|
719
|
-
<div className="space-y-4">
|
|
720
|
-
<h4 className="text-sm font-medium text-white/70">Team Members</h4>
|
|
721
|
-
<div className="space-y-2">
|
|
722
|
-
{users.map((user) => (
|
|
723
|
-
<HoverCard key={user.id}>
|
|
724
|
-
<HoverCardTrigger asChild>
|
|
725
|
-
<div
|
|
726
|
-
className={`flex cursor-pointer items-center space-x-3 rounded-lg border p-3 transition-colors ${
|
|
727
|
-
selectedUser === user.id
|
|
728
|
-
? "border-blue-500 bg-blue-500/10"
|
|
729
|
-
: "border-white/10 bg-white/5 hover:bg-white/10"
|
|
730
|
-
}`}
|
|
731
|
-
onClick={() =>
|
|
732
|
-
setSelectedUser(
|
|
733
|
-
selectedUser === user.id ? null : user.id
|
|
734
|
-
)
|
|
735
|
-
}
|
|
736
|
-
>
|
|
737
|
-
<div
|
|
738
|
-
className={`flex h-8 w-8 items-center justify-center rounded-full ${
|
|
739
|
-
user.status === "online"
|
|
740
|
-
? "bg-green-500"
|
|
741
|
-
: user.status === "away"
|
|
742
|
-
? "bg-yellow-500"
|
|
743
|
-
: "bg-gray-500"
|
|
744
|
-
}`}
|
|
745
|
-
>
|
|
746
|
-
<span className="text-xs font-semibold text-white">
|
|
747
|
-
{user.name
|
|
748
|
-
.split(" ")
|
|
749
|
-
.map((n) => n[0])
|
|
750
|
-
.join("")}
|
|
751
|
-
</span>
|
|
752
|
-
</div>
|
|
753
|
-
<div className="flex-1">
|
|
754
|
-
<div className="text-sm font-medium text-white">
|
|
755
|
-
{user.name}
|
|
756
|
-
</div>
|
|
757
|
-
<div className="text-xs text-white/60">{user.role}</div>
|
|
758
|
-
</div>
|
|
759
|
-
<div
|
|
760
|
-
className={`h-2 w-2 rounded-full ${
|
|
761
|
-
user.status === "online"
|
|
762
|
-
? "bg-green-500"
|
|
763
|
-
: user.status === "away"
|
|
764
|
-
? "bg-yellow-500"
|
|
765
|
-
: "bg-gray-500"
|
|
766
|
-
}`}
|
|
767
|
-
/>
|
|
768
|
-
</div>
|
|
769
|
-
</HoverCardTrigger>
|
|
770
|
-
<HoverCardContent className="w-80">
|
|
771
|
-
<div className="space-y-3">
|
|
772
|
-
<div className="flex space-x-4">
|
|
773
|
-
<div
|
|
774
|
-
className={`flex h-16 w-16 items-center justify-center rounded-full ${
|
|
775
|
-
user.status === "online"
|
|
776
|
-
? "bg-green-500"
|
|
777
|
-
: user.status === "away"
|
|
778
|
-
? "bg-yellow-500"
|
|
779
|
-
: "bg-gray-500"
|
|
780
|
-
}`}
|
|
781
|
-
>
|
|
782
|
-
<span className="font-semibold text-white">
|
|
783
|
-
{user.name
|
|
784
|
-
.split(" ")
|
|
785
|
-
.map((n) => n[0])
|
|
786
|
-
.join("")}
|
|
787
|
-
</span>
|
|
788
|
-
</div>
|
|
789
|
-
<div className="space-y-1">
|
|
790
|
-
<h4 className="text-sm font-semibold text-white">
|
|
791
|
-
{user.name}
|
|
792
|
-
</h4>
|
|
793
|
-
<p className="text-sm text-white/70">{user.role}</p>
|
|
794
|
-
<div className="flex items-center gap-2 text-xs">
|
|
795
|
-
<div
|
|
796
|
-
className={`h-2 w-2 rounded-full ${
|
|
797
|
-
user.status === "online"
|
|
798
|
-
? "bg-green-500"
|
|
799
|
-
: user.status === "away"
|
|
800
|
-
? "bg-yellow-500"
|
|
801
|
-
: "bg-gray-500"
|
|
802
|
-
}`}
|
|
803
|
-
/>
|
|
804
|
-
<span className="text-white/60 capitalize">
|
|
805
|
-
{user.status}
|
|
806
|
-
</span>
|
|
807
|
-
</div>
|
|
808
|
-
</div>
|
|
809
|
-
</div>
|
|
810
|
-
|
|
811
|
-
<div className="text-sm text-white/70">
|
|
812
|
-
{user.status === "online"
|
|
813
|
-
? "Available for collaboration"
|
|
814
|
-
: user.status === "away"
|
|
815
|
-
? "Away - will respond later"
|
|
816
|
-
: "Last seen 2 hours ago"}
|
|
817
|
-
</div>
|
|
134
|
+
// ─── Configurations ──────────────────────────────────────────────────────────
|
|
818
135
|
|
|
819
|
-
|
|
820
|
-
<Button size="sm" className="flex-1">
|
|
821
|
-
Message
|
|
822
|
-
</Button>
|
|
823
|
-
<Button size="sm" variant="outline" className="flex-1">
|
|
824
|
-
Profile
|
|
825
|
-
</Button>
|
|
826
|
-
</div>
|
|
827
|
-
</div>
|
|
828
|
-
</HoverCardContent>
|
|
829
|
-
</HoverCard>
|
|
830
|
-
))}
|
|
831
|
-
</div>
|
|
832
|
-
</div>
|
|
833
|
-
|
|
834
|
-
{/* Product Analytics */}
|
|
835
|
-
<div className="space-y-4">
|
|
836
|
-
<h4 className="text-sm font-medium text-white/70">
|
|
837
|
-
Product Analytics
|
|
838
|
-
</h4>
|
|
839
|
-
<div className="space-y-2">
|
|
840
|
-
{products.map((product) => (
|
|
841
|
-
<HoverCard key={product.id}>
|
|
842
|
-
<HoverCardTrigger asChild>
|
|
843
|
-
<div
|
|
844
|
-
className={`cursor-pointer rounded-lg border p-3 transition-colors ${
|
|
845
|
-
hoveredProduct === product.id
|
|
846
|
-
? "border-purple-500 bg-purple-500/10"
|
|
847
|
-
: "border-white/10 bg-white/5 hover:bg-white/10"
|
|
848
|
-
}`}
|
|
849
|
-
onMouseEnter={() => setHoveredProduct(product.id)}
|
|
850
|
-
onMouseLeave={() => setHoveredProduct(null)}
|
|
851
|
-
>
|
|
852
|
-
<div className="flex items-center justify-between">
|
|
853
|
-
<div>
|
|
854
|
-
<div className="text-sm font-medium text-white">
|
|
855
|
-
{product.name}
|
|
856
|
-
</div>
|
|
857
|
-
<div className="text-xs text-white/60">
|
|
858
|
-
{product.sales} sales
|
|
859
|
-
</div>
|
|
860
|
-
</div>
|
|
861
|
-
<div className="text-right">
|
|
862
|
-
<div className="text-sm font-semibold text-white">
|
|
863
|
-
{product.price}
|
|
864
|
-
</div>
|
|
865
|
-
<div className="text-xs text-green-400">↗ +12%</div>
|
|
866
|
-
</div>
|
|
867
|
-
</div>
|
|
868
|
-
</div>
|
|
869
|
-
</HoverCardTrigger>
|
|
870
|
-
<HoverCardContent className="w-96">
|
|
871
|
-
<div className="space-y-4">
|
|
872
|
-
<div className="flex items-start justify-between">
|
|
873
|
-
<div>
|
|
874
|
-
<h4 className="font-semibold text-white">
|
|
875
|
-
{product.name}
|
|
876
|
-
</h4>
|
|
877
|
-
<p className="text-sm text-white/70">
|
|
878
|
-
Detailed product analytics
|
|
879
|
-
</p>
|
|
880
|
-
</div>
|
|
881
|
-
<span className="text-lg font-bold text-white">
|
|
882
|
-
{product.price}
|
|
883
|
-
</span>
|
|
884
|
-
</div>
|
|
885
|
-
|
|
886
|
-
<div className="grid grid-cols-2 gap-4">
|
|
887
|
-
<div className="space-y-1">
|
|
888
|
-
<div className="text-xs text-white/60">
|
|
889
|
-
Total Sales
|
|
890
|
-
</div>
|
|
891
|
-
<div className="text-lg font-semibold text-white">
|
|
892
|
-
{product.sales}
|
|
893
|
-
</div>
|
|
894
|
-
<div className="text-xs text-green-400">
|
|
895
|
-
+12% vs last month
|
|
896
|
-
</div>
|
|
897
|
-
</div>
|
|
898
|
-
<div className="space-y-1">
|
|
899
|
-
<div className="text-xs text-white/60">Revenue</div>
|
|
900
|
-
<div className="text-lg font-semibold text-white">
|
|
901
|
-
$
|
|
902
|
-
{(
|
|
903
|
-
parseInt(product.price.slice(1)) * product.sales
|
|
904
|
-
).toLocaleString()}
|
|
905
|
-
</div>
|
|
906
|
-
<div className="text-xs text-green-400">
|
|
907
|
-
+8% vs last month
|
|
908
|
-
</div>
|
|
909
|
-
</div>
|
|
910
|
-
</div>
|
|
911
|
-
|
|
912
|
-
<div className="space-y-2">
|
|
913
|
-
<div className="text-xs text-white/60">Top Markets</div>
|
|
914
|
-
<div className="space-y-1">
|
|
915
|
-
<div className="flex justify-between text-xs">
|
|
916
|
-
<span className="text-white/70">North America</span>
|
|
917
|
-
<span className="text-white">45%</span>
|
|
918
|
-
</div>
|
|
919
|
-
<div className="flex justify-between text-xs">
|
|
920
|
-
<span className="text-white/70">Europe</span>
|
|
921
|
-
<span className="text-white">32%</span>
|
|
922
|
-
</div>
|
|
923
|
-
<div className="flex justify-between text-xs">
|
|
924
|
-
<span className="text-white/70">Asia Pacific</span>
|
|
925
|
-
<span className="text-white">23%</span>
|
|
926
|
-
</div>
|
|
927
|
-
</div>
|
|
928
|
-
</div>
|
|
929
|
-
|
|
930
|
-
<Button size="sm" className="w-full">
|
|
931
|
-
<FileChartIcon className="mr-2 h-3 w-3" />
|
|
932
|
-
View Full Report
|
|
933
|
-
</Button>
|
|
934
|
-
</div>
|
|
935
|
-
</HoverCardContent>
|
|
936
|
-
</HoverCard>
|
|
937
|
-
))}
|
|
938
|
-
</div>
|
|
939
|
-
</div>
|
|
940
|
-
</div>
|
|
941
|
-
</div>
|
|
942
|
-
)
|
|
943
|
-
},
|
|
136
|
+
export const Configurations: Story = {
|
|
944
137
|
parameters: {
|
|
945
138
|
docs: {
|
|
946
139
|
description: {
|
|
947
140
|
story:
|
|
948
|
-
"
|
|
141
|
+
"Demonstrates align (start / center / end), sideOffset variations, and delay timing. Hover each trigger to see the positioning difference.",
|
|
949
142
|
},
|
|
950
143
|
},
|
|
951
144
|
},
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
// 6. Positioning & Timing
|
|
955
|
-
export const PositioningAndTiming: Story = {
|
|
956
145
|
render: () => (
|
|
957
|
-
<div className="space-y-8
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
Different Positions
|
|
967
|
-
</h4>
|
|
968
|
-
<div className="grid grid-cols-2 place-items-center gap-8 lg:grid-cols-4">
|
|
969
|
-
{/* Top */}
|
|
970
|
-
<div className="flex flex-col items-center gap-4">
|
|
971
|
-
<span className="text-sm text-white/70">Top</span>
|
|
972
|
-
<HoverCard>
|
|
973
|
-
<HoverCardTrigger asChild>
|
|
974
|
-
<Button variant="outline" size="sm">
|
|
975
|
-
Top
|
|
976
|
-
</Button>
|
|
977
|
-
</HoverCardTrigger>
|
|
978
|
-
<HoverCardContent side="top">
|
|
979
|
-
<div className="space-y-2">
|
|
980
|
-
<h4 className="text-sm font-semibold text-white">
|
|
981
|
-
Top Position
|
|
982
|
-
</h4>
|
|
983
|
-
<p className="text-sm text-white/70">
|
|
984
|
-
Card positioned above the trigger
|
|
985
|
-
</p>
|
|
986
|
-
</div>
|
|
987
|
-
</HoverCardContent>
|
|
988
|
-
</HoverCard>
|
|
989
|
-
</div>
|
|
990
|
-
|
|
991
|
-
{/* Right */}
|
|
992
|
-
<div className="flex flex-col items-center gap-4">
|
|
993
|
-
<span className="text-sm text-white/70">Right</span>
|
|
146
|
+
<div className="w-full max-w-3xl space-y-8">
|
|
147
|
+
{/* Alignment */}
|
|
148
|
+
<div className="space-y-4">
|
|
149
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
150
|
+
Alignment — align prop
|
|
151
|
+
</h4>
|
|
152
|
+
<div className="flex flex-wrap justify-center gap-6">
|
|
153
|
+
{(["start", "center", "end"] as const).map((align) => (
|
|
154
|
+
<div key={align} className="space-y-2 text-center">
|
|
994
155
|
<HoverCard>
|
|
995
156
|
<HoverCardTrigger asChild>
|
|
996
|
-
<Button variant="outline"
|
|
997
|
-
Right
|
|
998
|
-
</Button>
|
|
157
|
+
<Button variant="outline">align="{align}"</Button>
|
|
999
158
|
</HoverCardTrigger>
|
|
1000
|
-
<HoverCardContent
|
|
1001
|
-
<
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
</h4>
|
|
1005
|
-
<p className="text-sm text-white/70">
|
|
1006
|
-
Card positioned to the right
|
|
1007
|
-
</p>
|
|
1008
|
-
</div>
|
|
159
|
+
<HoverCardContent align={align}>
|
|
160
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
161
|
+
Content aligned to <strong>{align}</strong> of trigger.
|
|
162
|
+
</p>
|
|
1009
163
|
</HoverCardContent>
|
|
1010
164
|
</HoverCard>
|
|
165
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
166
|
+
{align}
|
|
167
|
+
</p>
|
|
1011
168
|
</div>
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
1012
172
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
173
|
+
{/* sideOffset */}
|
|
174
|
+
<div className="space-y-4">
|
|
175
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
176
|
+
Side Offset — sideOffset prop
|
|
177
|
+
</h4>
|
|
178
|
+
<div className="flex flex-wrap justify-center gap-6">
|
|
179
|
+
{[0, 8, 16, 24].map((offset) => (
|
|
180
|
+
<div key={offset} className="space-y-2 text-center">
|
|
1016
181
|
<HoverCard>
|
|
1017
182
|
<HoverCardTrigger asChild>
|
|
1018
|
-
<Button variant="outline"
|
|
1019
|
-
Bottom
|
|
1020
|
-
</Button>
|
|
183
|
+
<Button variant="outline">offset {offset}px</Button>
|
|
1021
184
|
</HoverCardTrigger>
|
|
1022
|
-
<HoverCardContent
|
|
1023
|
-
<
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
</h4>
|
|
1027
|
-
<p className="text-sm text-white/70">
|
|
1028
|
-
Card positioned below the trigger
|
|
1029
|
-
</p>
|
|
1030
|
-
</div>
|
|
185
|
+
<HoverCardContent sideOffset={offset}>
|
|
186
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
187
|
+
sideOffset={offset}
|
|
188
|
+
</p>
|
|
1031
189
|
</HoverCardContent>
|
|
1032
190
|
</HoverCard>
|
|
191
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
192
|
+
{offset}px gap
|
|
193
|
+
</p>
|
|
1033
194
|
</div>
|
|
195
|
+
))}
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
1034
198
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
199
|
+
{/* Delay timing */}
|
|
200
|
+
<div className="space-y-4">
|
|
201
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
202
|
+
Delay Timing — openDelay / closeDelay
|
|
203
|
+
</h4>
|
|
204
|
+
<div className="flex flex-wrap justify-center gap-6">
|
|
205
|
+
{[
|
|
206
|
+
{ label: "Instant", openDelay: 0, closeDelay: 0 },
|
|
207
|
+
{ label: "Default (700ms)", openDelay: 700, closeDelay: 300 },
|
|
208
|
+
{ label: "Slow (1200ms)", openDelay: 1200, closeDelay: 600 },
|
|
209
|
+
].map(({ label, openDelay, closeDelay }) => (
|
|
210
|
+
<div key={label} className="space-y-2 text-center">
|
|
211
|
+
<HoverCard openDelay={openDelay} closeDelay={closeDelay}>
|
|
1039
212
|
<HoverCardTrigger asChild>
|
|
1040
|
-
<Button variant="outline"
|
|
1041
|
-
Left
|
|
1042
|
-
</Button>
|
|
213
|
+
<Button variant="outline">{label}</Button>
|
|
1043
214
|
</HoverCardTrigger>
|
|
1044
|
-
<HoverCardContent
|
|
1045
|
-
<
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
</h4>
|
|
1049
|
-
<p className="text-sm text-white/70">
|
|
1050
|
-
Card positioned to the left
|
|
1051
|
-
</p>
|
|
1052
|
-
</div>
|
|
215
|
+
<HoverCardContent>
|
|
216
|
+
<p className="text-fm-primary font-fm-text text-fm-sm leading-fm-sm">
|
|
217
|
+
Open: {openDelay}ms · Close: {closeDelay}ms
|
|
218
|
+
</p>
|
|
1053
219
|
</HoverCardContent>
|
|
1054
220
|
</HoverCard>
|
|
221
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
222
|
+
open {openDelay}ms
|
|
223
|
+
</p>
|
|
1055
224
|
</div>
|
|
1056
|
-
|
|
1057
|
-
</div>
|
|
1058
|
-
|
|
1059
|
-
{/* Timing */}
|
|
1060
|
-
<div className="space-y-4">
|
|
1061
|
-
<h4 className="text-center text-sm font-medium text-white/70">
|
|
1062
|
-
Different Delays
|
|
1063
|
-
</h4>
|
|
1064
|
-
<div className="flex justify-center gap-4">
|
|
1065
|
-
<HoverCard openDelay={0}>
|
|
1066
|
-
<HoverCardTrigger asChild>
|
|
1067
|
-
<Button variant="outline" size="sm">
|
|
1068
|
-
Instant
|
|
1069
|
-
</Button>
|
|
1070
|
-
</HoverCardTrigger>
|
|
1071
|
-
<HoverCardContent>
|
|
1072
|
-
<div className="space-y-2">
|
|
1073
|
-
<h4 className="text-sm font-semibold text-white">No Delay</h4>
|
|
1074
|
-
<p className="text-sm text-white/70">
|
|
1075
|
-
Appears immediately on hover
|
|
1076
|
-
</p>
|
|
1077
|
-
</div>
|
|
1078
|
-
</HoverCardContent>
|
|
1079
|
-
</HoverCard>
|
|
1080
|
-
|
|
1081
|
-
<HoverCard openDelay={500}>
|
|
1082
|
-
<HoverCardTrigger asChild>
|
|
1083
|
-
<Button variant="outline" size="sm">
|
|
1084
|
-
Medium
|
|
1085
|
-
</Button>
|
|
1086
|
-
</HoverCardTrigger>
|
|
1087
|
-
<HoverCardContent>
|
|
1088
|
-
<div className="space-y-2">
|
|
1089
|
-
<h4 className="text-sm font-semibold text-white">
|
|
1090
|
-
Medium Delay
|
|
1091
|
-
</h4>
|
|
1092
|
-
<p className="text-sm text-white/70">
|
|
1093
|
-
500ms delay before appearing
|
|
1094
|
-
</p>
|
|
1095
|
-
</div>
|
|
1096
|
-
</HoverCardContent>
|
|
1097
|
-
</HoverCard>
|
|
1098
|
-
|
|
1099
|
-
<HoverCard openDelay={1000}>
|
|
1100
|
-
<HoverCardTrigger asChild>
|
|
1101
|
-
<Button variant="outline" size="sm">
|
|
1102
|
-
Slow
|
|
1103
|
-
</Button>
|
|
1104
|
-
</HoverCardTrigger>
|
|
1105
|
-
<HoverCardContent>
|
|
1106
|
-
<div className="space-y-2">
|
|
1107
|
-
<h4 className="text-sm font-semibold text-white">
|
|
1108
|
-
Long Delay
|
|
1109
|
-
</h4>
|
|
1110
|
-
<p className="text-sm text-white/70">
|
|
1111
|
-
1000ms delay before appearing
|
|
1112
|
-
</p>
|
|
1113
|
-
</div>
|
|
1114
|
-
</HoverCardContent>
|
|
1115
|
-
</HoverCard>
|
|
1116
|
-
</div>
|
|
1117
|
-
</div>
|
|
1118
|
-
|
|
1119
|
-
{/* Size Variations */}
|
|
1120
|
-
<div className="space-y-4">
|
|
1121
|
-
<h4 className="text-center text-sm font-medium text-white/70">
|
|
1122
|
-
Different Sizes
|
|
1123
|
-
</h4>
|
|
1124
|
-
<div className="flex justify-center gap-4">
|
|
1125
|
-
<HoverCard>
|
|
1126
|
-
<HoverCardTrigger asChild>
|
|
1127
|
-
<Button variant="outline" size="sm">
|
|
1128
|
-
Small
|
|
1129
|
-
</Button>
|
|
1130
|
-
</HoverCardTrigger>
|
|
1131
|
-
<HoverCardContent className="w-48">
|
|
1132
|
-
<div className="space-y-2">
|
|
1133
|
-
<h4 className="text-sm font-semibold text-white">
|
|
1134
|
-
Small Card
|
|
1135
|
-
</h4>
|
|
1136
|
-
<p className="text-sm text-white/70">Compact information</p>
|
|
1137
|
-
</div>
|
|
1138
|
-
</HoverCardContent>
|
|
1139
|
-
</HoverCard>
|
|
1140
|
-
|
|
1141
|
-
<HoverCard>
|
|
1142
|
-
<HoverCardTrigger asChild>
|
|
1143
|
-
<Button variant="outline" size="sm">
|
|
1144
|
-
Medium
|
|
1145
|
-
</Button>
|
|
1146
|
-
</HoverCardTrigger>
|
|
1147
|
-
<HoverCardContent className="w-80">
|
|
1148
|
-
<div className="space-y-2">
|
|
1149
|
-
<h4 className="text-sm font-semibold text-white">
|
|
1150
|
-
Medium Card
|
|
1151
|
-
</h4>
|
|
1152
|
-
<p className="text-sm text-white/70">
|
|
1153
|
-
Medium-sized card with more detailed information and
|
|
1154
|
-
multiple lines of text.
|
|
1155
|
-
</p>
|
|
1156
|
-
</div>
|
|
1157
|
-
</HoverCardContent>
|
|
1158
|
-
</HoverCard>
|
|
1159
|
-
|
|
1160
|
-
<HoverCard>
|
|
1161
|
-
<HoverCardTrigger asChild>
|
|
1162
|
-
<Button variant="outline" size="sm">
|
|
1163
|
-
Large
|
|
1164
|
-
</Button>
|
|
1165
|
-
</HoverCardTrigger>
|
|
1166
|
-
<HoverCardContent className="w-96">
|
|
1167
|
-
<div className="space-y-3">
|
|
1168
|
-
<h4 className="text-sm font-semibold text-white">
|
|
1169
|
-
Large Card
|
|
1170
|
-
</h4>
|
|
1171
|
-
<p className="text-sm text-white/70">
|
|
1172
|
-
Large card with extensive information, multiple sections,
|
|
1173
|
-
and complex layouts. Perfect for detailed previews and
|
|
1174
|
-
comprehensive information displays.
|
|
1175
|
-
</p>
|
|
1176
|
-
<div className="border-t border-white/10 pt-2">
|
|
1177
|
-
<Button size="sm" className="w-full">
|
|
1178
|
-
Learn More
|
|
1179
|
-
</Button>
|
|
1180
|
-
</div>
|
|
1181
|
-
</div>
|
|
1182
|
-
</HoverCardContent>
|
|
1183
|
-
</HoverCard>
|
|
1184
|
-
</div>
|
|
225
|
+
))}
|
|
1185
226
|
</div>
|
|
1186
227
|
</div>
|
|
1187
228
|
</div>
|
|
1188
229
|
),
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ─── UseCases ────────────────────────────────────────────────────────────────
|
|
233
|
+
|
|
234
|
+
export const UseCases: Story = {
|
|
1189
235
|
parameters: {
|
|
1190
236
|
docs: {
|
|
1191
237
|
description: {
|
|
1192
238
|
story:
|
|
1193
|
-
"
|
|
239
|
+
"Real product-shaped examples: artist profile preview on hover, album info card, and user mention preview — all in an audio streaming context.",
|
|
1194
240
|
},
|
|
1195
241
|
},
|
|
1196
242
|
},
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
// 7. Accessibility Demo
|
|
1200
|
-
export const AccessibilityDemo: Story = {
|
|
1201
243
|
render: () => (
|
|
1202
|
-
<div className="space-y-8 p-8">
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
<div className="
|
|
1209
|
-
<
|
|
1210
|
-
|
|
1211
|
-
</h4>
|
|
1212
|
-
<p className="mb-2 text-xs text-blue-200/70">
|
|
1213
|
-
Try these keyboard interactions:
|
|
244
|
+
<div className="mx-auto max-w-3xl space-y-8 p-8">
|
|
245
|
+
{/* Artist profile preview */}
|
|
246
|
+
<div className="space-y-4">
|
|
247
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
248
|
+
Artist Profile Preview
|
|
249
|
+
</h4>
|
|
250
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-2 rounded-xl border p-5">
|
|
251
|
+
<p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
|
|
252
|
+
Now playing from
|
|
1214
253
|
</p>
|
|
1215
|
-
<
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
hover card triggers
|
|
1219
|
-
</li>
|
|
1220
|
-
<li>• Hover card appears automatically on focus</li>
|
|
1221
|
-
<li>
|
|
1222
|
-
• <kbd className="rounded bg-white/10 px-1">Escape</kbd> to
|
|
1223
|
-
dismiss hover card
|
|
1224
|
-
</li>
|
|
1225
|
-
<li>• Content is announced by screen readers</li>
|
|
1226
|
-
</ul>
|
|
1227
|
-
</div>
|
|
1228
|
-
|
|
1229
|
-
{/* Keyboard Accessible Examples */}
|
|
1230
|
-
<div className="space-y-4">
|
|
1231
|
-
<h4 className="text-sm font-medium text-white/70">
|
|
1232
|
-
Keyboard Accessible Hover Cards
|
|
1233
|
-
</h4>
|
|
1234
|
-
<div className="flex flex-wrap gap-4">
|
|
1235
|
-
<HoverCard>
|
|
1236
|
-
<HoverCardTrigger asChild>
|
|
1237
|
-
<Button>Focusable Button</Button>
|
|
1238
|
-
</HoverCardTrigger>
|
|
1239
|
-
<HoverCardContent>
|
|
1240
|
-
<div className="space-y-2">
|
|
1241
|
-
<h4 className="text-sm font-semibold text-white">
|
|
1242
|
-
Keyboard Accessible
|
|
1243
|
-
</h4>
|
|
1244
|
-
<p className="text-sm text-white/70">
|
|
1245
|
-
This hover card appears on both hover and keyboard focus.
|
|
1246
|
-
</p>
|
|
1247
|
-
</div>
|
|
1248
|
-
</HoverCardContent>
|
|
1249
|
-
</HoverCard>
|
|
1250
|
-
|
|
1251
|
-
<HoverCard>
|
|
1252
|
-
<HoverCardTrigger asChild>
|
|
1253
|
-
<a
|
|
1254
|
-
href="#"
|
|
1255
|
-
className="inline-flex items-center gap-2 rounded px-3 py-2 text-sm text-blue-400 hover:text-blue-300 focus:ring-2 focus:ring-blue-500 focus:outline-none"
|
|
1256
|
-
onClick={(e) => e.preventDefault()}
|
|
1257
|
-
>
|
|
1258
|
-
<AlertIcon className="h-4 w-4" />
|
|
1259
|
-
Documentation Link
|
|
1260
|
-
</a>
|
|
1261
|
-
</HoverCardTrigger>
|
|
1262
|
-
<HoverCardContent>
|
|
1263
|
-
<div className="space-y-2">
|
|
1264
|
-
<h4 className="text-sm font-semibold text-white">
|
|
1265
|
-
Documentation
|
|
1266
|
-
</h4>
|
|
1267
|
-
<p className="text-sm text-white/70">
|
|
1268
|
-
Comprehensive guides and API reference for developers.
|
|
1269
|
-
</p>
|
|
1270
|
-
<Button size="sm" className="w-full">
|
|
1271
|
-
View Docs
|
|
1272
|
-
</Button>
|
|
1273
|
-
</div>
|
|
1274
|
-
</HoverCardContent>
|
|
1275
|
-
</HoverCard>
|
|
1276
|
-
|
|
1277
|
-
<HoverCard>
|
|
254
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md">
|
|
255
|
+
Midnights ·{" "}
|
|
256
|
+
<HoverCard openDelay={300} closeDelay={150}>
|
|
1278
257
|
<HoverCardTrigger asChild>
|
|
1279
|
-
<button className="
|
|
1280
|
-
|
|
1281
|
-
Status Check
|
|
258
|
+
<button className="text-fm-primary cursor-pointer font-semibold underline underline-offset-2 outline-none">
|
|
259
|
+
Taylor Swift
|
|
1282
260
|
</button>
|
|
1283
261
|
</HoverCardTrigger>
|
|
1284
|
-
<HoverCardContent>
|
|
1285
|
-
<div className="space-y-
|
|
1286
|
-
<
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
<div className="h-2 w-2 rounded-full bg-green-500"></div>
|
|
1292
|
-
<span>All systems operational</span>
|
|
262
|
+
<HoverCardContent className="w-72">
|
|
263
|
+
<div className="space-y-3">
|
|
264
|
+
<div className="flex items-center gap-3">
|
|
265
|
+
<div className="bg-fm-surface-primary border-fm-divider-secondary flex h-12 w-12 shrink-0 items-center justify-center rounded-full border">
|
|
266
|
+
<span className="text-fm-primary font-fm-brand text-fm-md leading-fm-md font-semibold">
|
|
267
|
+
TS
|
|
268
|
+
</span>
|
|
1293
269
|
</div>
|
|
1294
|
-
<div className="
|
|
1295
|
-
|
|
270
|
+
<div className="space-y-0.5">
|
|
271
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
|
|
272
|
+
Taylor Swift
|
|
273
|
+
</p>
|
|
274
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
275
|
+
Pop · Country
|
|
276
|
+
</p>
|
|
1296
277
|
</div>
|
|
1297
278
|
</div>
|
|
279
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
280
|
+
11 studio albums · 85M+ monthly listeners
|
|
281
|
+
</p>
|
|
282
|
+
<div className="text-fm-tertiary font-fm-text text-fm-xs leading-fm-xs flex gap-2">
|
|
283
|
+
<span className="border-fm-divider-secondary rounded border px-2 py-0.5">
|
|
284
|
+
Pop
|
|
285
|
+
</span>
|
|
286
|
+
<span className="border-fm-divider-secondary rounded border px-2 py-0.5">
|
|
287
|
+
Country
|
|
288
|
+
</span>
|
|
289
|
+
<span className="border-fm-divider-secondary rounded border px-2 py-0.5">
|
|
290
|
+
Indie
|
|
291
|
+
</span>
|
|
292
|
+
</div>
|
|
1298
293
|
</div>
|
|
1299
294
|
</HoverCardContent>
|
|
1300
295
|
</HoverCard>
|
|
296
|
+
</p>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
|
|
300
|
+
{/* Album info card */}
|
|
301
|
+
<div className="space-y-4">
|
|
302
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
303
|
+
Album Info Card
|
|
304
|
+
</h4>
|
|
305
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary rounded-xl border p-5">
|
|
306
|
+
<p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm mb-3">
|
|
307
|
+
Recently played albums
|
|
308
|
+
</p>
|
|
309
|
+
<div className="flex flex-wrap gap-3">
|
|
310
|
+
{[
|
|
311
|
+
{
|
|
312
|
+
name: "Midnights",
|
|
313
|
+
artist: "Taylor Swift",
|
|
314
|
+
year: "2022",
|
|
315
|
+
tracks: 13,
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
name: "Renaissance",
|
|
319
|
+
artist: "Beyoncé",
|
|
320
|
+
year: "2022",
|
|
321
|
+
tracks: 16,
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
name: "Harry's House",
|
|
325
|
+
artist: "Harry Styles",
|
|
326
|
+
year: "2022",
|
|
327
|
+
tracks: 13,
|
|
328
|
+
},
|
|
329
|
+
].map((album) => (
|
|
330
|
+
<HoverCard key={album.name} openDelay={400}>
|
|
331
|
+
<HoverCardTrigger asChild>
|
|
332
|
+
<div className="bg-fm-surface-primary border-fm-divider-secondary hover:border-fm-divider-primary flex h-16 w-16 cursor-pointer items-center justify-center rounded-lg border transition-colors">
|
|
333
|
+
<span className="text-fm-tertiary font-fm-text text-fm-xs leading-fm-xs px-1 text-center">
|
|
334
|
+
{album.name.slice(0, 3)}
|
|
335
|
+
</span>
|
|
336
|
+
</div>
|
|
337
|
+
</HoverCardTrigger>
|
|
338
|
+
<HoverCardContent className="w-64">
|
|
339
|
+
<div className="space-y-2">
|
|
340
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
|
|
341
|
+
{album.name}
|
|
342
|
+
</p>
|
|
343
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
344
|
+
{album.artist}
|
|
345
|
+
</p>
|
|
346
|
+
<div className="text-fm-tertiary font-fm-text text-fm-xs leading-fm-xs flex gap-4 pt-1">
|
|
347
|
+
<span>{album.year}</span>
|
|
348
|
+
<span>{album.tracks} tracks</span>
|
|
349
|
+
</div>
|
|
350
|
+
</div>
|
|
351
|
+
</HoverCardContent>
|
|
352
|
+
</HoverCard>
|
|
353
|
+
))}
|
|
1301
354
|
</div>
|
|
1302
355
|
</div>
|
|
356
|
+
</div>
|
|
1303
357
|
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
358
|
+
{/* User mention preview */}
|
|
359
|
+
<div className="space-y-4">
|
|
360
|
+
<h4 className="text-fm-secondary font-fm-text text-fm-md leading-fm-md font-medium">
|
|
361
|
+
User Mention Preview
|
|
362
|
+
</h4>
|
|
363
|
+
<div className="border-fm-divider-secondary bg-fm-surface-secondary space-y-3 rounded-xl border p-5">
|
|
364
|
+
<p className="text-fm-tertiary font-fm-text text-fm-sm leading-fm-sm">
|
|
365
|
+
Activity feed
|
|
366
|
+
</p>
|
|
367
|
+
{[
|
|
368
|
+
{
|
|
369
|
+
handle: "@mikejameson",
|
|
370
|
+
action: "shared a playlist with you",
|
|
371
|
+
initials: "MJ",
|
|
372
|
+
name: "Mike Jameson",
|
|
373
|
+
role: "Music Producer",
|
|
374
|
+
followers: "4.1k",
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
handle: "@luna_beats",
|
|
378
|
+
action: "liked your track",
|
|
379
|
+
initials: "LB",
|
|
380
|
+
name: "Luna Beats",
|
|
381
|
+
role: "DJ · Electronic",
|
|
382
|
+
followers: "12k",
|
|
383
|
+
},
|
|
384
|
+
].map(({ handle, action, initials, name, role, followers }) => (
|
|
385
|
+
<div
|
|
386
|
+
key={handle}
|
|
387
|
+
className="text-fm-primary font-fm-text text-fm-md leading-fm-md flex items-center gap-2"
|
|
388
|
+
>
|
|
389
|
+
<HoverCard openDelay={300} closeDelay={200}>
|
|
390
|
+
<HoverCardTrigger asChild>
|
|
391
|
+
<button className="text-fm-primary cursor-pointer font-semibold underline underline-offset-2 outline-none">
|
|
392
|
+
{handle}
|
|
393
|
+
</button>
|
|
394
|
+
</HoverCardTrigger>
|
|
395
|
+
<HoverCardContent className="w-64">
|
|
396
|
+
<div className="space-y-3">
|
|
397
|
+
<div className="flex items-center gap-3">
|
|
398
|
+
<div className="bg-fm-surface-primary border-fm-divider-secondary flex h-10 w-10 shrink-0 items-center justify-center rounded-full border">
|
|
399
|
+
<span className="text-fm-primary font-fm-brand text-fm-sm leading-fm-sm font-semibold">
|
|
400
|
+
{initials}
|
|
401
|
+
</span>
|
|
402
|
+
</div>
|
|
403
|
+
<div>
|
|
404
|
+
<p className="text-fm-primary font-fm-text text-fm-md leading-fm-md font-semibold">
|
|
405
|
+
{name}
|
|
406
|
+
</p>
|
|
407
|
+
<p className="text-fm-secondary font-fm-text text-fm-sm leading-fm-sm">
|
|
408
|
+
{role}
|
|
409
|
+
</p>
|
|
410
|
+
</div>
|
|
411
|
+
</div>
|
|
412
|
+
<p className="text-fm-tertiary font-fm-text text-fm-xs leading-fm-xs">
|
|
413
|
+
{followers} followers
|
|
414
|
+
</p>
|
|
415
|
+
</div>
|
|
416
|
+
</HoverCardContent>
|
|
417
|
+
</HoverCard>
|
|
418
|
+
<span className="text-fm-secondary">{action}</span>
|
|
419
|
+
</div>
|
|
420
|
+
))}
|
|
1316
421
|
</div>
|
|
1317
422
|
</div>
|
|
1318
423
|
</div>
|
|
1319
424
|
),
|
|
1320
|
-
parameters: {
|
|
1321
|
-
docs: {
|
|
1322
|
-
description: {
|
|
1323
|
-
story:
|
|
1324
|
-
"Accessibility features including keyboard navigation, focus management, and best practices for inclusive design.",
|
|
1325
|
-
},
|
|
1326
|
-
},
|
|
1327
|
-
},
|
|
1328
425
|
}
|