sonance-brand-mcp 1.1.4 → 1.2.2
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/assets/BRAND_GUIDELINES.md +0 -8
- package/dist/assets/components/accordion.stories.tsx +310 -0
- package/dist/assets/components/accordion.tsx +56 -30
- package/dist/assets/components/alert.stories.tsx +199 -0
- package/dist/assets/components/autocomplete.stories.tsx +307 -0
- package/dist/assets/components/autocomplete.tsx +28 -4
- package/dist/assets/components/avatar.stories.tsx +175 -0
- package/dist/assets/components/badge.stories.tsx +258 -0
- package/dist/assets/components/breadcrumbs.stories.tsx +175 -0
- package/dist/assets/components/button.stories.tsx +362 -0
- package/dist/assets/components/button.tsx +48 -3
- package/dist/assets/components/calendar.stories.tsx +247 -0
- package/dist/assets/components/card.stories.tsx +275 -0
- package/dist/assets/components/card.tsx +26 -1
- package/dist/assets/components/checkbox-group.stories.tsx +281 -0
- package/dist/assets/components/checkbox.stories.tsx +160 -0
- package/dist/assets/components/checkbox.tsx +32 -4
- package/dist/assets/components/code.stories.tsx +265 -0
- package/dist/assets/components/date-input.stories.tsx +278 -0
- package/dist/assets/components/date-input.tsx +24 -2
- package/dist/assets/components/date-picker.stories.tsx +337 -0
- package/dist/assets/components/date-picker.tsx +28 -4
- package/dist/assets/components/date-range-picker.stories.tsx +340 -0
- package/dist/assets/components/dialog.stories.tsx +285 -0
- package/dist/assets/components/divider.stories.tsx +176 -0
- package/dist/assets/components/drawer.stories.tsx +216 -0
- package/dist/assets/components/dropdown.stories.tsx +342 -0
- package/dist/assets/components/dropdown.tsx +55 -10
- package/dist/assets/components/form.stories.tsx +372 -0
- package/dist/assets/components/image.stories.tsx +348 -0
- package/dist/assets/components/input-otp.stories.tsx +336 -0
- package/dist/assets/components/input-otp.tsx +24 -2
- package/dist/assets/components/input.stories.tsx +223 -0
- package/dist/assets/components/input.tsx +27 -2
- package/dist/assets/components/kbd.stories.tsx +272 -0
- package/dist/assets/components/link.stories.tsx +199 -0
- package/dist/assets/components/link.tsx +50 -1
- package/dist/assets/components/listbox.stories.tsx +287 -0
- package/dist/assets/components/listbox.tsx +30 -7
- package/dist/assets/components/navbar.stories.tsx +218 -0
- package/dist/assets/components/number-input.stories.tsx +295 -0
- package/dist/assets/components/number-input.tsx +30 -8
- package/dist/assets/components/pagination.stories.tsx +280 -0
- package/dist/assets/components/pagination.tsx +45 -21
- package/dist/assets/components/popover.stories.tsx +219 -0
- package/dist/assets/components/progress.stories.tsx +153 -0
- package/dist/assets/components/radio-group.stories.tsx +187 -0
- package/dist/assets/components/radio-group.tsx +30 -6
- package/dist/assets/components/range-calendar.stories.tsx +334 -0
- package/dist/assets/components/scroll-shadow.stories.tsx +335 -0
- package/dist/assets/components/select.stories.tsx +192 -0
- package/dist/assets/components/select.tsx +54 -7
- package/dist/assets/components/skeleton.stories.tsx +166 -0
- package/dist/assets/components/slider.stories.tsx +145 -0
- package/dist/assets/components/slider.tsx +43 -8
- package/dist/assets/components/spacer.stories.tsx +216 -0
- package/dist/assets/components/spinner.stories.tsx +149 -0
- package/dist/assets/components/switch.stories.tsx +170 -0
- package/dist/assets/components/switch.tsx +29 -4
- package/dist/assets/components/table.stories.tsx +322 -0
- package/dist/assets/components/tabs.stories.tsx +306 -0
- package/dist/assets/components/tabs.tsx +25 -4
- package/dist/assets/components/textarea.stories.tsx +103 -0
- package/dist/assets/components/textarea.tsx +27 -3
- package/dist/assets/components/theme-toggle.stories.tsx +248 -0
- package/dist/assets/components/time-input.stories.tsx +365 -0
- package/dist/assets/components/time-input.tsx +25 -3
- package/dist/assets/components/toast.stories.tsx +195 -0
- package/dist/assets/components/tooltip.stories.tsx +226 -0
- package/dist/assets/components/user.stories.tsx +274 -0
- package/dist/assets/logo-manifest.json +0 -18
- package/dist/index.js +2142 -85
- package/package.json +1 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
|
2
|
+
import { Toast, ToastProvider, useToast } from './toast';
|
|
3
|
+
import { Button } from './button';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Toast> = {
|
|
6
|
+
title: 'Components/Feedback/Toast',
|
|
7
|
+
component: Toast,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component: 'Toast notifications for displaying brief messages. Includes multiple variants and a provider for managing toasts.',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
argTypes: {
|
|
17
|
+
variant: {
|
|
18
|
+
control: 'select',
|
|
19
|
+
options: ['default', 'success', 'error', 'warning', 'info'],
|
|
20
|
+
},
|
|
21
|
+
title: { control: 'text' },
|
|
22
|
+
description: { control: 'text' },
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default meta;
|
|
27
|
+
type Story = StoryObj<typeof meta>;
|
|
28
|
+
|
|
29
|
+
export const Default: Story = {
|
|
30
|
+
args: {
|
|
31
|
+
title: 'Notification',
|
|
32
|
+
description: 'This is a default toast notification.',
|
|
33
|
+
onClose: () => {},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const Success: Story = {
|
|
38
|
+
args: {
|
|
39
|
+
variant: 'success',
|
|
40
|
+
title: 'Success',
|
|
41
|
+
description: 'Your changes have been saved successfully.',
|
|
42
|
+
onClose: () => {},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const Error: Story = {
|
|
47
|
+
args: {
|
|
48
|
+
variant: 'error',
|
|
49
|
+
title: 'Error',
|
|
50
|
+
description: 'Something went wrong. Please try again.',
|
|
51
|
+
onClose: () => {},
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const Warning: Story = {
|
|
56
|
+
args: {
|
|
57
|
+
variant: 'warning',
|
|
58
|
+
title: 'Warning',
|
|
59
|
+
description: 'Your session will expire in 5 minutes.',
|
|
60
|
+
onClose: () => {},
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const Info: Story = {
|
|
65
|
+
args: {
|
|
66
|
+
variant: 'info',
|
|
67
|
+
title: 'Information',
|
|
68
|
+
description: 'A new version is available.',
|
|
69
|
+
onClose: () => {},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const AllVariants: Story = {
|
|
74
|
+
render: () => (
|
|
75
|
+
<div className="space-y-4 w-96">
|
|
76
|
+
<Toast variant="default" title="Default" description="Default notification" onClose={() => {}} />
|
|
77
|
+
<Toast variant="success" title="Success" description="Operation completed" onClose={() => {}} />
|
|
78
|
+
<Toast variant="error" title="Error" description="Something went wrong" onClose={() => {}} />
|
|
79
|
+
<Toast variant="warning" title="Warning" description="Please review" onClose={() => {}} />
|
|
80
|
+
<Toast variant="info" title="Info" description="New update available" onClose={() => {}} />
|
|
81
|
+
</div>
|
|
82
|
+
),
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const WithAction: Story = {
|
|
86
|
+
args: {
|
|
87
|
+
variant: 'info',
|
|
88
|
+
title: 'New version available',
|
|
89
|
+
description: 'A new version of the app is ready to install.',
|
|
90
|
+
onClose: () => {},
|
|
91
|
+
action: (
|
|
92
|
+
<Button size="sm" variant="secondary">
|
|
93
|
+
Update now
|
|
94
|
+
</Button>
|
|
95
|
+
),
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const TitleOnly: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
title: 'File uploaded successfully',
|
|
102
|
+
onClose: () => {},
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Interactive demo with ToastProvider
|
|
107
|
+
function ToastDemo() {
|
|
108
|
+
const { addToast } = useToast();
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<div className="space-y-4">
|
|
112
|
+
<Button
|
|
113
|
+
onClick={() =>
|
|
114
|
+
addToast({
|
|
115
|
+
title: 'Success',
|
|
116
|
+
description: 'Your changes have been saved.',
|
|
117
|
+
variant: 'success',
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
>
|
|
121
|
+
Show Success Toast
|
|
122
|
+
</Button>
|
|
123
|
+
<Button
|
|
124
|
+
variant="secondary"
|
|
125
|
+
onClick={() =>
|
|
126
|
+
addToast({
|
|
127
|
+
title: 'Error',
|
|
128
|
+
description: 'Failed to save changes.',
|
|
129
|
+
variant: 'error',
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
>
|
|
133
|
+
Show Error Toast
|
|
134
|
+
</Button>
|
|
135
|
+
<Button
|
|
136
|
+
variant="ghost"
|
|
137
|
+
onClick={() =>
|
|
138
|
+
addToast({
|
|
139
|
+
title: 'Info',
|
|
140
|
+
description: 'New message received.',
|
|
141
|
+
variant: 'info',
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
>
|
|
145
|
+
Show Info Toast
|
|
146
|
+
</Button>
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const InteractiveDemo: Story = {
|
|
152
|
+
render: () => (
|
|
153
|
+
<ToastProvider position="bottom-right">
|
|
154
|
+
<ToastDemo />
|
|
155
|
+
</ToastProvider>
|
|
156
|
+
),
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Responsive Matrix - Mobile, Tablet, Desktop
|
|
160
|
+
export const ResponsiveMatrix: Story = {
|
|
161
|
+
render: () => (
|
|
162
|
+
<div className="space-y-8">
|
|
163
|
+
{/* Mobile */}
|
|
164
|
+
<div>
|
|
165
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
166
|
+
<div className="w-[375px] border border-dashed border-border p-4 space-y-2">
|
|
167
|
+
<Toast variant="success" title="Success" description="Changes saved." onClose={() => {}} />
|
|
168
|
+
<Toast variant="error" title="Error" description="Failed to save." onClose={() => {}} />
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
{/* Tablet */}
|
|
172
|
+
<div>
|
|
173
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
174
|
+
<div className="w-[768px] border border-dashed border-border p-4">
|
|
175
|
+
<div className="flex gap-4">
|
|
176
|
+
<Toast variant="success" title="Success" description="Your changes have been saved." onClose={() => {}} />
|
|
177
|
+
<Toast variant="warning" title="Warning" description="Session expires soon." onClose={() => {}} />
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
{/* Desktop */}
|
|
182
|
+
<div>
|
|
183
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
184
|
+
<div className="w-[1280px] border border-dashed border-border p-4">
|
|
185
|
+
<div className="flex gap-4">
|
|
186
|
+
<Toast variant="default" title="Notification" description="Default toast notification." onClose={() => {}} />
|
|
187
|
+
<Toast variant="success" title="Success" description="Operation completed." onClose={() => {}} />
|
|
188
|
+
<Toast variant="error" title="Error" description="Something went wrong." onClose={() => {}} />
|
|
189
|
+
<Toast variant="info" title="Info" description="New update available." onClose={() => {}} />
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
),
|
|
195
|
+
};
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
|
2
|
+
import { Tooltip } from './tooltip';
|
|
3
|
+
import { Button } from './button';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Tooltip> = {
|
|
6
|
+
title: 'Components/Overlays/Tooltip',
|
|
7
|
+
component: Tooltip,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component: 'A tooltip component for displaying additional information on hover. Supports multiple positions.',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
layout: 'centered',
|
|
16
|
+
},
|
|
17
|
+
argTypes: {
|
|
18
|
+
side: {
|
|
19
|
+
control: 'select',
|
|
20
|
+
options: ['top', 'bottom', 'left', 'right'],
|
|
21
|
+
description: 'Position of the tooltip relative to the trigger',
|
|
22
|
+
table: {
|
|
23
|
+
defaultValue: { summary: 'top' },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
delay: {
|
|
27
|
+
control: 'number',
|
|
28
|
+
description: 'Delay before showing tooltip (ms)',
|
|
29
|
+
table: {
|
|
30
|
+
defaultValue: { summary: '200' },
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
content: {
|
|
34
|
+
control: 'text',
|
|
35
|
+
description: 'Tooltip content',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default meta;
|
|
41
|
+
type Story = StoryObj<typeof meta>;
|
|
42
|
+
|
|
43
|
+
// Default
|
|
44
|
+
export const Default: Story = {
|
|
45
|
+
render: () => (
|
|
46
|
+
<Tooltip content="This is a tooltip">
|
|
47
|
+
<Button variant="secondary">Hover me</Button>
|
|
48
|
+
</Tooltip>
|
|
49
|
+
),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Top Position
|
|
53
|
+
export const Top: Story = {
|
|
54
|
+
render: () => (
|
|
55
|
+
<Tooltip content="Tooltip on top" side="top">
|
|
56
|
+
<Button variant="secondary">Top</Button>
|
|
57
|
+
</Tooltip>
|
|
58
|
+
),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Bottom Position
|
|
62
|
+
export const Bottom: Story = {
|
|
63
|
+
render: () => (
|
|
64
|
+
<Tooltip content="Tooltip on bottom" side="bottom">
|
|
65
|
+
<Button variant="secondary">Bottom</Button>
|
|
66
|
+
</Tooltip>
|
|
67
|
+
),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Left Position
|
|
71
|
+
export const Left: Story = {
|
|
72
|
+
render: () => (
|
|
73
|
+
<Tooltip content="Tooltip on left" side="left">
|
|
74
|
+
<Button variant="secondary">Left</Button>
|
|
75
|
+
</Tooltip>
|
|
76
|
+
),
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Right Position
|
|
80
|
+
export const Right: Story = {
|
|
81
|
+
render: () => (
|
|
82
|
+
<Tooltip content="Tooltip on right" side="right">
|
|
83
|
+
<Button variant="secondary">Right</Button>
|
|
84
|
+
</Tooltip>
|
|
85
|
+
),
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// All Positions
|
|
89
|
+
export const AllPositions: Story = {
|
|
90
|
+
render: () => (
|
|
91
|
+
<div className="flex items-center gap-8 p-8">
|
|
92
|
+
<Tooltip content="Top tooltip" side="top">
|
|
93
|
+
<Button variant="secondary">Top</Button>
|
|
94
|
+
</Tooltip>
|
|
95
|
+
<Tooltip content="Bottom tooltip" side="bottom">
|
|
96
|
+
<Button variant="secondary">Bottom</Button>
|
|
97
|
+
</Tooltip>
|
|
98
|
+
<Tooltip content="Left tooltip" side="left">
|
|
99
|
+
<Button variant="secondary">Left</Button>
|
|
100
|
+
</Tooltip>
|
|
101
|
+
<Tooltip content="Right tooltip" side="right">
|
|
102
|
+
<Button variant="secondary">Right</Button>
|
|
103
|
+
</Tooltip>
|
|
104
|
+
</div>
|
|
105
|
+
),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// With Delay
|
|
109
|
+
export const WithDelay: Story = {
|
|
110
|
+
render: () => (
|
|
111
|
+
<div className="flex gap-4">
|
|
112
|
+
<Tooltip content="No delay (0ms)" delay={0}>
|
|
113
|
+
<Button variant="secondary">Instant</Button>
|
|
114
|
+
</Tooltip>
|
|
115
|
+
<Tooltip content="Default delay (200ms)" delay={200}>
|
|
116
|
+
<Button variant="secondary">Default</Button>
|
|
117
|
+
</Tooltip>
|
|
118
|
+
<Tooltip content="Slow delay (500ms)" delay={500}>
|
|
119
|
+
<Button variant="secondary">Slow</Button>
|
|
120
|
+
</Tooltip>
|
|
121
|
+
</div>
|
|
122
|
+
),
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// On Icon Button
|
|
126
|
+
export const OnIconButton: Story = {
|
|
127
|
+
render: () => (
|
|
128
|
+
<div className="flex gap-4">
|
|
129
|
+
<Tooltip content="Edit item">
|
|
130
|
+
<button className="p-2 text-foreground-muted hover:text-foreground transition-colors">
|
|
131
|
+
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
132
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
|
133
|
+
</svg>
|
|
134
|
+
</button>
|
|
135
|
+
</Tooltip>
|
|
136
|
+
<Tooltip content="Delete item">
|
|
137
|
+
<button className="p-2 text-foreground-muted hover:text-error transition-colors">
|
|
138
|
+
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
139
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
|
140
|
+
</svg>
|
|
141
|
+
</button>
|
|
142
|
+
</Tooltip>
|
|
143
|
+
<Tooltip content="Share item">
|
|
144
|
+
<button className="p-2 text-foreground-muted hover:text-foreground transition-colors">
|
|
145
|
+
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
146
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" />
|
|
147
|
+
</svg>
|
|
148
|
+
</button>
|
|
149
|
+
</Tooltip>
|
|
150
|
+
</div>
|
|
151
|
+
),
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
// Long Content
|
|
155
|
+
export const LongContent: Story = {
|
|
156
|
+
render: () => (
|
|
157
|
+
<Tooltip content="This is a tooltip with longer content that explains something in more detail">
|
|
158
|
+
<Button variant="secondary">Hover for details</Button>
|
|
159
|
+
</Tooltip>
|
|
160
|
+
),
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// On Text
|
|
164
|
+
export const OnText: Story = {
|
|
165
|
+
render: () => (
|
|
166
|
+
<p className="text-foreground-secondary">
|
|
167
|
+
Hover over the{' '}
|
|
168
|
+
<Tooltip content="This is additional information">
|
|
169
|
+
<span className="text-foreground border-b border-dashed border-foreground-muted cursor-help">
|
|
170
|
+
underlined text
|
|
171
|
+
</span>
|
|
172
|
+
</Tooltip>{' '}
|
|
173
|
+
to see more information.
|
|
174
|
+
</p>
|
|
175
|
+
),
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
// Responsive Matrix - Mobile, Tablet, Desktop
|
|
179
|
+
export const ResponsiveMatrix: Story = {
|
|
180
|
+
render: () => (
|
|
181
|
+
<div className="space-y-8">
|
|
182
|
+
{/* Mobile */}
|
|
183
|
+
<div>
|
|
184
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
185
|
+
<div className="w-[375px] border border-dashed border-border p-4 flex justify-center">
|
|
186
|
+
<Tooltip content="Mobile tooltip">
|
|
187
|
+
<Button variant="secondary" size="sm">Hover me</Button>
|
|
188
|
+
</Tooltip>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
{/* Tablet */}
|
|
192
|
+
<div>
|
|
193
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
194
|
+
<div className="w-[768px] border border-dashed border-border p-4 flex justify-center gap-4">
|
|
195
|
+
<Tooltip content="Top" side="top">
|
|
196
|
+
<Button variant="secondary">Top</Button>
|
|
197
|
+
</Tooltip>
|
|
198
|
+
<Tooltip content="Bottom" side="bottom">
|
|
199
|
+
<Button variant="secondary">Bottom</Button>
|
|
200
|
+
</Tooltip>
|
|
201
|
+
<Tooltip content="Left" side="left">
|
|
202
|
+
<Button variant="secondary">Left</Button>
|
|
203
|
+
</Tooltip>
|
|
204
|
+
<Tooltip content="Right" side="right">
|
|
205
|
+
<Button variant="secondary">Right</Button>
|
|
206
|
+
</Tooltip>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
{/* Desktop */}
|
|
210
|
+
<div>
|
|
211
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
212
|
+
<div className="w-[1280px] border border-dashed border-border p-4 flex justify-between items-center">
|
|
213
|
+
<Tooltip content="Edit item">
|
|
214
|
+
<Button variant="ghost" size="sm">Edit</Button>
|
|
215
|
+
</Tooltip>
|
|
216
|
+
<Tooltip content="This is a longer tooltip with more detailed explanation">
|
|
217
|
+
<Button variant="secondary">Hover for details</Button>
|
|
218
|
+
</Tooltip>
|
|
219
|
+
<Tooltip content="Delete permanently" side="left">
|
|
220
|
+
<Button variant="ghost" size="sm">Delete</Button>
|
|
221
|
+
</Tooltip>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
),
|
|
226
|
+
};
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
|
|
2
|
+
import { User, UserCard, UserListItem } from './user';
|
|
3
|
+
import { Button } from './button';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof User> = {
|
|
6
|
+
title: 'Components/Data Display/User',
|
|
7
|
+
component: User,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: {
|
|
12
|
+
component: 'Components for displaying user information with avatars and metadata.',
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
argTypes: {
|
|
17
|
+
size: {
|
|
18
|
+
control: 'select',
|
|
19
|
+
options: ['sm', 'md', 'lg'],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default meta;
|
|
25
|
+
type Story = StoryObj<typeof meta>;
|
|
26
|
+
|
|
27
|
+
export const Default: Story = {
|
|
28
|
+
args: {
|
|
29
|
+
name: 'John Doe',
|
|
30
|
+
description: 'Product Designer',
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const WithAvatar: Story = {
|
|
35
|
+
args: {
|
|
36
|
+
name: 'Jane Smith',
|
|
37
|
+
description: 'Engineering Lead',
|
|
38
|
+
avatarSrc: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=100&h=100&fit=crop',
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const Sizes: Story = {
|
|
43
|
+
render: () => (
|
|
44
|
+
<div className="space-y-4">
|
|
45
|
+
<div>
|
|
46
|
+
<p className="text-xs text-foreground-muted mb-2">Small</p>
|
|
47
|
+
<User name="John Doe" description="Designer" size="sm" />
|
|
48
|
+
</div>
|
|
49
|
+
<div>
|
|
50
|
+
<p className="text-xs text-foreground-muted mb-2">Medium (default)</p>
|
|
51
|
+
<User name="John Doe" description="Designer" size="md" />
|
|
52
|
+
</div>
|
|
53
|
+
<div>
|
|
54
|
+
<p className="text-xs text-foreground-muted mb-2">Large</p>
|
|
55
|
+
<User name="John Doe" description="Designer" size="lg" />
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const NameOnly: Story = {
|
|
62
|
+
args: {
|
|
63
|
+
name: 'Alex Johnson',
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const WithFallback: Story = {
|
|
68
|
+
args: {
|
|
69
|
+
name: 'Michael Brown',
|
|
70
|
+
description: 'Sales Manager',
|
|
71
|
+
avatarFallback: 'MB',
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const Card: Story = {
|
|
76
|
+
render: () => (
|
|
77
|
+
<div className="w-80">
|
|
78
|
+
<UserCard
|
|
79
|
+
name="Sarah Wilson"
|
|
80
|
+
description="sarah@sonance.com"
|
|
81
|
+
avatarSrc="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop"
|
|
82
|
+
actions={<Button size="sm" variant="secondary">Follow</Button>}
|
|
83
|
+
/>
|
|
84
|
+
</div>
|
|
85
|
+
),
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const CardVariations: Story = {
|
|
89
|
+
render: () => (
|
|
90
|
+
<div className="space-y-4 w-80">
|
|
91
|
+
<UserCard
|
|
92
|
+
name="David Lee"
|
|
93
|
+
description="Architect"
|
|
94
|
+
actions={<Button size="sm" variant="secondary">Message</Button>}
|
|
95
|
+
/>
|
|
96
|
+
<UserCard
|
|
97
|
+
name="Emily Chen"
|
|
98
|
+
description="emily.chen@sonance.com"
|
|
99
|
+
avatarSrc="https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=100&h=100&fit=crop"
|
|
100
|
+
actions={
|
|
101
|
+
<div className="flex gap-2">
|
|
102
|
+
<Button size="sm" variant="ghost">Ignore</Button>
|
|
103
|
+
<Button size="sm">Accept</Button>
|
|
104
|
+
</div>
|
|
105
|
+
}
|
|
106
|
+
/>
|
|
107
|
+
</div>
|
|
108
|
+
),
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export const ListItem: Story = {
|
|
112
|
+
render: () => (
|
|
113
|
+
<div className="w-80 border border-border">
|
|
114
|
+
<UserListItem
|
|
115
|
+
name="Chris Taylor"
|
|
116
|
+
description="chris@example.com"
|
|
117
|
+
onClick={() => console.log('Clicked Chris')}
|
|
118
|
+
/>
|
|
119
|
+
<UserListItem
|
|
120
|
+
name="Sam Anderson"
|
|
121
|
+
description="sam@example.com"
|
|
122
|
+
selected
|
|
123
|
+
onClick={() => console.log('Clicked Sam')}
|
|
124
|
+
/>
|
|
125
|
+
<UserListItem
|
|
126
|
+
name="Jordan Martinez"
|
|
127
|
+
description="jordan@example.com"
|
|
128
|
+
onClick={() => console.log('Clicked Jordan')}
|
|
129
|
+
/>
|
|
130
|
+
</div>
|
|
131
|
+
),
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const ListWithActions: Story = {
|
|
135
|
+
render: () => (
|
|
136
|
+
<div className="w-96 border border-border">
|
|
137
|
+
<UserListItem
|
|
138
|
+
name="Alice Brown"
|
|
139
|
+
description="Project Manager"
|
|
140
|
+
avatarSrc="https://images.unsplash.com/photo-1580489944761-15a19d654956?w=100&h=100&fit=crop"
|
|
141
|
+
actions={<Button size="sm" variant="ghost">Remove</Button>}
|
|
142
|
+
/>
|
|
143
|
+
<UserListItem
|
|
144
|
+
name="Bob Johnson"
|
|
145
|
+
description="Developer"
|
|
146
|
+
actions={<Button size="sm" variant="ghost">Remove</Button>}
|
|
147
|
+
/>
|
|
148
|
+
<UserListItem
|
|
149
|
+
name="Carol White"
|
|
150
|
+
description="Designer"
|
|
151
|
+
actions={<Button size="sm" variant="ghost">Remove</Button>}
|
|
152
|
+
/>
|
|
153
|
+
</div>
|
|
154
|
+
),
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export const TeamList: Story = {
|
|
158
|
+
render: () => {
|
|
159
|
+
const team = [
|
|
160
|
+
{ name: 'Mark Thompson', role: 'CEO', avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop' },
|
|
161
|
+
{ name: 'Lisa Wang', role: 'CTO', avatar: 'https://images.unsplash.com/photo-1573497019940-1c28c88b4f3e?w=100&h=100&fit=crop' },
|
|
162
|
+
{ name: 'James Miller', role: 'Head of Design', avatar: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop' },
|
|
163
|
+
{ name: 'Nina Patel', role: 'Head of Engineering', avatar: 'https://images.unsplash.com/photo-1580489944761-15a19d654956?w=100&h=100&fit=crop' },
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<div className="w-80">
|
|
168
|
+
<h3 className="text-sm font-medium text-foreground mb-4">Leadership Team</h3>
|
|
169
|
+
<div className="space-y-3">
|
|
170
|
+
{team.map((member) => (
|
|
171
|
+
<User
|
|
172
|
+
key={member.name}
|
|
173
|
+
name={member.name}
|
|
174
|
+
description={member.role}
|
|
175
|
+
avatarSrc={member.avatar}
|
|
176
|
+
/>
|
|
177
|
+
))}
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
);
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export const AllVariants: Story = {
|
|
185
|
+
render: () => (
|
|
186
|
+
<div className="space-y-8">
|
|
187
|
+
<div>
|
|
188
|
+
<h3 className="text-sm font-medium text-foreground mb-4">User Component</h3>
|
|
189
|
+
<User name="Alex Johnson" description="Product Designer" />
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<div>
|
|
193
|
+
<h3 className="text-sm font-medium text-foreground mb-4">User Card</h3>
|
|
194
|
+
<UserCard
|
|
195
|
+
name="Sarah Wilson"
|
|
196
|
+
description="sarah@sonance.com"
|
|
197
|
+
actions={<Button size="sm" variant="secondary">Follow</Button>}
|
|
198
|
+
className="w-80"
|
|
199
|
+
/>
|
|
200
|
+
</div>
|
|
201
|
+
|
|
202
|
+
<div>
|
|
203
|
+
<h3 className="text-sm font-medium text-foreground mb-4">User List Items</h3>
|
|
204
|
+
<div className="w-80 border border-border">
|
|
205
|
+
<UserListItem name="Chris Taylor" description="chris@example.com" />
|
|
206
|
+
<UserListItem name="Sam Anderson" description="sam@example.com" selected />
|
|
207
|
+
<UserListItem name="Jordan Martinez" description="jordan@example.com" />
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
),
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// Responsive Matrix - Mobile, Tablet, Desktop
|
|
215
|
+
export const ResponsiveMatrix: Story = {
|
|
216
|
+
render: () => (
|
|
217
|
+
<div className="space-y-8">
|
|
218
|
+
{/* Mobile */}
|
|
219
|
+
<div>
|
|
220
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
221
|
+
<div className="w-[375px] border border-dashed border-border p-4">
|
|
222
|
+
<User name="John Doe" description="Product Designer" size="md" />
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
{/* Tablet */}
|
|
226
|
+
<div>
|
|
227
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
228
|
+
<div className="w-[768px] border border-dashed border-border p-4">
|
|
229
|
+
<div className="grid grid-cols-2 gap-4">
|
|
230
|
+
<UserCard
|
|
231
|
+
name="Sarah Wilson"
|
|
232
|
+
description="sarah@sonance.com"
|
|
233
|
+
actions={<Button size="sm" variant="secondary">Follow</Button>}
|
|
234
|
+
/>
|
|
235
|
+
<UserCard
|
|
236
|
+
name="James Miller"
|
|
237
|
+
description="james@sonance.com"
|
|
238
|
+
actions={<Button size="sm" variant="secondary">Follow</Button>}
|
|
239
|
+
/>
|
|
240
|
+
</div>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
{/* Desktop */}
|
|
244
|
+
<div>
|
|
245
|
+
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
246
|
+
<div className="w-[1280px] border border-dashed border-border p-4">
|
|
247
|
+
<div className="grid grid-cols-3 gap-4">
|
|
248
|
+
<div className="border border-border">
|
|
249
|
+
<UserListItem name="Chris Taylor" description="chris@example.com" />
|
|
250
|
+
<UserListItem name="Sam Anderson" description="sam@example.com" selected />
|
|
251
|
+
<UserListItem name="Jordan Martinez" description="jordan@example.com" />
|
|
252
|
+
</div>
|
|
253
|
+
<UserCard
|
|
254
|
+
name="Emily Chen"
|
|
255
|
+
description="emily@sonance.com"
|
|
256
|
+
avatarSrc="https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=100&h=100&fit=crop"
|
|
257
|
+
actions={
|
|
258
|
+
<div className="flex gap-2">
|
|
259
|
+
<Button size="sm" variant="ghost">Ignore</Button>
|
|
260
|
+
<Button size="sm">Accept</Button>
|
|
261
|
+
</div>
|
|
262
|
+
}
|
|
263
|
+
/>
|
|
264
|
+
<div className="space-y-3">
|
|
265
|
+
<User name="User Small" description="Designer" size="sm" />
|
|
266
|
+
<User name="User Medium" description="Developer" size="md" />
|
|
267
|
+
<User name="User Large" description="Manager" size="lg" />
|
|
268
|
+
</div>
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
</div>
|
|
273
|
+
),
|
|
274
|
+
};
|