sonance-brand-mcp 1.2.5 → 1.3.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/api/sonance-analyze/route.ts +1116 -0
- package/dist/assets/api/sonance-assets/route.ts +113 -0
- package/dist/assets/api/sonance-components/route.ts +41 -0
- package/dist/assets/api/sonance-inject-id/route.ts +363 -0
- package/dist/assets/api/sonance-save-logo/route.ts +426 -0
- package/dist/assets/api/sonance-theme/route.ts +106 -0
- package/dist/assets/brand-system.ts +1265 -0
- package/dist/assets/components/accordion.stories.tsx +26 -26
- package/dist/assets/components/accordion.tsx +3 -3
- package/dist/assets/components/alert-dialog.stories.tsx +142 -0
- package/dist/assets/components/alert-dialog.tsx +143 -0
- package/dist/assets/components/alert.stories.tsx +3 -3
- package/dist/assets/components/alert.tsx +4 -3
- package/dist/assets/components/aspect-ratio.stories.tsx +70 -0
- package/dist/assets/components/aspect-ratio.tsx +8 -0
- package/dist/assets/components/autocomplete.stories.tsx +9 -9
- package/dist/assets/components/autocomplete.tsx +3 -3
- package/dist/assets/components/avatar.stories.tsx +5 -5
- package/dist/assets/components/avatar.tsx +67 -23
- package/dist/assets/components/badge.stories.tsx +10 -10
- package/dist/assets/components/badge.tsx +3 -3
- package/dist/assets/components/breadcrumbs.stories.tsx +7 -7
- package/dist/assets/components/breadcrumbs.tsx +13 -8
- package/dist/assets/components/button.stories.tsx +74 -74
- package/dist/assets/components/button.tsx +2 -0
- package/dist/assets/components/calendar.stories.tsx +11 -11
- package/dist/assets/components/calendar.tsx +4 -4
- package/dist/assets/components/card.stories.tsx +22 -22
- package/dist/assets/components/card.tsx +7 -3
- package/dist/assets/components/carousel.stories.tsx +158 -0
- package/dist/assets/components/carousel.tsx +264 -0
- package/dist/assets/components/chart.stories.tsx +376 -0
- package/dist/assets/components/chart.tsx +384 -0
- package/dist/assets/components/checkbox-group.stories.tsx +6 -6
- package/dist/assets/components/checkbox-group.tsx +3 -3
- package/dist/assets/components/checkbox.stories.tsx +23 -20
- package/dist/assets/components/checkbox.tsx +13 -6
- package/dist/assets/components/code.stories.tsx +24 -24
- package/dist/assets/components/code.tsx +22 -27
- package/dist/assets/components/collapsible.stories.tsx +128 -0
- package/dist/assets/components/collapsible.tsx +10 -0
- package/dist/assets/components/command.stories.tsx +183 -0
- package/dist/assets/components/command.tsx +171 -0
- package/dist/assets/components/context-menu.stories.tsx +159 -0
- package/dist/assets/components/context-menu.tsx +214 -0
- package/dist/assets/components/date-input.stories.tsx +9 -9
- package/dist/assets/components/date-input.tsx +2 -2
- package/dist/assets/components/date-picker.stories.tsx +9 -9
- package/dist/assets/components/date-picker.tsx +3 -3
- package/dist/assets/components/date-range-picker.stories.tsx +12 -12
- package/dist/assets/components/date-range-picker.tsx +3 -3
- package/dist/assets/components/dialog.stories.tsx +40 -40
- package/dist/assets/components/dialog.tsx +8 -12
- package/dist/assets/components/divider.stories.tsx +30 -30
- package/dist/assets/components/divider.tsx +34 -35
- package/dist/assets/components/drawer.stories.tsx +32 -31
- package/dist/assets/components/drawer.tsx +7 -6
- package/dist/assets/components/dropdown-menu.tsx +213 -0
- package/dist/assets/components/dropdown.stories.tsx +12 -12
- package/dist/assets/components/dropdown.tsx +5 -5
- package/dist/assets/components/form.stories.tsx +30 -29
- package/dist/assets/components/form.tsx +5 -5
- package/dist/assets/components/hover-card.stories.tsx +115 -0
- package/dist/assets/components/hover-card.tsx +35 -0
- package/dist/assets/components/image.stories.tsx +48 -25
- package/dist/assets/components/image.tsx +8 -5
- package/dist/assets/components/input-otp.stories.tsx +15 -15
- package/dist/assets/components/input-otp.tsx +5 -5
- package/dist/assets/components/input.stories.tsx +30 -25
- package/dist/assets/components/input.tsx +7 -4
- package/dist/assets/components/kbd.stories.tsx +34 -34
- package/dist/assets/components/kbd.tsx +9 -9
- package/dist/assets/components/link.stories.tsx +36 -36
- package/dist/assets/components/link.tsx +4 -0
- package/dist/assets/components/listbox.stories.tsx +5 -5
- package/dist/assets/components/listbox.tsx +4 -4
- package/dist/assets/components/menubar.stories.tsx +208 -0
- package/dist/assets/components/menubar.tsx +247 -0
- package/dist/assets/components/navbar.stories.tsx +24 -24
- package/dist/assets/components/navbar.tsx +8 -14
- package/dist/assets/components/navigation-menu.stories.tsx +239 -0
- package/dist/assets/components/navigation-menu.tsx +135 -0
- package/dist/assets/components/number-input.stories.tsx +11 -11
- package/dist/assets/components/number-input.tsx +3 -3
- package/dist/assets/components/pagination.stories.tsx +13 -13
- package/dist/assets/components/pagination.tsx +6 -6
- package/dist/assets/components/popover.stories.tsx +35 -35
- package/dist/assets/components/popover.tsx +98 -15
- package/dist/assets/components/progress.stories.tsx +5 -5
- package/dist/assets/components/progress.tsx +5 -5
- package/dist/assets/components/radio-group.stories.tsx +7 -7
- package/dist/assets/components/radio-group.tsx +3 -3
- package/dist/assets/components/range-calendar.stories.tsx +18 -18
- package/dist/assets/components/range-calendar.tsx +3 -3
- package/dist/assets/components/resizable.stories.tsx +197 -0
- package/dist/assets/components/resizable.tsx +47 -0
- package/dist/assets/components/scroll-area.stories.tsx +123 -0
- package/dist/assets/components/scroll-area.tsx +48 -0
- package/dist/assets/components/scroll-shadow.stories.tsx +17 -17
- package/dist/assets/components/scroll-shadow.tsx +31 -9
- package/dist/assets/components/select.stories.tsx +20 -19
- package/dist/assets/components/select.tsx +10 -6
- package/dist/assets/components/separator.tsx +32 -0
- package/dist/assets/components/sheet.tsx +137 -0
- package/dist/assets/components/sidebar.stories.tsx +351 -0
- package/dist/assets/components/sidebar.tsx +757 -0
- package/dist/assets/components/skeleton.stories.tsx +3 -3
- package/dist/assets/components/skeleton.tsx +2 -2
- package/dist/assets/components/slider.stories.tsx +6 -6
- package/dist/assets/components/slider.tsx +3 -3
- package/dist/assets/components/spacer.stories.tsx +11 -11
- package/dist/assets/components/spacer.tsx +2 -2
- package/dist/assets/components/spinner.stories.tsx +8 -8
- package/dist/assets/components/spinner.tsx +5 -5
- package/dist/assets/components/switch.stories.tsx +24 -20
- package/dist/assets/components/switch.tsx +14 -6
- package/dist/assets/components/table.stories.tsx +7 -7
- package/dist/assets/components/table.tsx +8 -8
- package/dist/assets/components/tabs.stories.tsx +37 -37
- package/dist/assets/components/tabs.tsx +3 -3
- package/dist/assets/components/textarea.stories.tsx +13 -12
- package/dist/assets/components/textarea.tsx +3 -3
- package/dist/assets/components/theme-toggle.stories.tsx +31 -30
- package/dist/assets/components/theme-toggle.tsx +2 -2
- package/dist/assets/components/time-input.stories.tsx +16 -16
- package/dist/assets/components/time-input.tsx +2 -2
- package/dist/assets/components/toast.stories.tsx +8 -5
- package/dist/assets/components/toast.tsx +6 -6
- package/dist/assets/components/toggle-group.stories.tsx +153 -0
- package/dist/assets/components/toggle-group.tsx +61 -0
- package/dist/assets/components/toggle.stories.tsx +77 -0
- package/dist/assets/components/toggle.tsx +46 -0
- package/dist/assets/components/tooltip.stories.tsx +49 -27
- package/dist/assets/components/tooltip.tsx +23 -90
- package/dist/assets/components/user.stories.tsx +23 -23
- package/dist/assets/components/user.tsx +7 -4
- package/dist/assets/dev-tools/SonanceDevTools.tsx +4201 -0
- package/dist/assets/dev-tools/index.ts +10 -0
- package/dist/assets/globals.css +39 -0
- package/dist/assets/logos/40th-anniversary/Sonance_40_Logo_CMYK_BEAM_BLUE_40_AND_BEAM_DARK.png +0 -0
- package/dist/assets/logos/Sonance logo dark mode.png +0 -0
- package/dist/assets/logos/Sonance logo light mode.png +0 -0
- package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_2C_Light_RGB_05162025.png +0 -0
- package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_3C_Dark_RGB_05162025.png +0 -0
- package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_White_RGB_05162025.png +0 -0
- package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Dark_RGB.png +0 -0
- package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Light_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_Black_CMYK.png +0 -0
- package/dist/assets/logos/james/James_Logo_Black_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_LtGray_CMYK.png +0 -0
- package/dist/assets/logos/james/James_Logo_LtGray_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_Polished_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_Reverse_CMYK.png +0 -0
- package/dist/assets/logos/james/James_Logo_Reverse_RGB.png +0 -0
- package/dist/assets/logos/james/James_Logo_White_CMYK.png +0 -0
- package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Dark_RGB.png +0 -0
- package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Light_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Dark_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Light_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Reverse_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_Black_RGB.png +0 -0
- package/dist/assets/logos/my-sonance/My.Sonance_Logo_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_2C_Dark_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_2C_Light_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_2C_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_Black_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_Grayscale_RGB.png +0 -0
- package/dist/assets/logos/sonance/Sonance_Logo_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Dark_CMYK.png +0 -0
- package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Light_CMYK.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Dark_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Light_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Black_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Grayscale_RGB.png +0 -0
- package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Reverse_RGB.png +0 -0
- package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Dark.png +0 -0
- package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Light.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Dark.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Light.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Dark.png +0 -0
- package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Light.png +0 -0
- package/dist/assets/logos/trufig/TrufigLogo_Black.png +0 -0
- package/dist/assets/logos/trufig/TrufigLogo_Light.png +0 -0
- package/dist/assets/logos/trufig/TrufigWatermark_Black.png +0 -0
- package/dist/assets/logos/trufig/TrufigWatermark_Light.png +0 -0
- package/dist/assets/styles/brand-overrides.css +37 -0
- package/dist/index.js +2055 -15
- package/package.json +1 -1
|
@@ -35,6 +35,7 @@ export const Default: Story = {
|
|
|
35
35
|
render: () => (
|
|
36
36
|
<div className="w-64">
|
|
37
37
|
<Image
|
|
38
|
+
id="default-speaker-system"
|
|
38
39
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop"
|
|
39
40
|
alt="Speaker system"
|
|
40
41
|
/>
|
|
@@ -46,8 +47,9 @@ export const AspectRatios: Story = {
|
|
|
46
47
|
render: () => (
|
|
47
48
|
<div className="grid grid-cols-2 gap-4 max-w-2xl">
|
|
48
49
|
<div>
|
|
49
|
-
<p className="text-xs text-foreground-muted mb-2">Auto</p>
|
|
50
|
+
<p id="aspect-ratios-p-auto" className="text-xs text-foreground-muted mb-2">Auto</p>
|
|
50
51
|
<Image
|
|
52
|
+
id="aspect-ratios-auto-aspect"
|
|
51
53
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop"
|
|
52
54
|
alt="Auto aspect"
|
|
53
55
|
aspectRatio="auto"
|
|
@@ -55,8 +57,9 @@ export const AspectRatios: Story = {
|
|
|
55
57
|
/>
|
|
56
58
|
</div>
|
|
57
59
|
<div>
|
|
58
|
-
<p className="text-xs text-foreground-muted mb-2">Square</p>
|
|
60
|
+
<p id="aspect-ratios-p-square" className="text-xs text-foreground-muted mb-2">Square</p>
|
|
59
61
|
<Image
|
|
62
|
+
id="aspect-ratios-square-aspect"
|
|
60
63
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=400&fit=crop"
|
|
61
64
|
alt="Square aspect"
|
|
62
65
|
aspectRatio="square"
|
|
@@ -64,8 +67,9 @@ export const AspectRatios: Story = {
|
|
|
64
67
|
/>
|
|
65
68
|
</div>
|
|
66
69
|
<div>
|
|
67
|
-
<p className="text-xs text-foreground-muted mb-2">Video (16:9)</p>
|
|
70
|
+
<p id="aspect-ratios-p-video-169" className="text-xs text-foreground-muted mb-2">Video (16:9)</p>
|
|
68
71
|
<Image
|
|
72
|
+
id="aspect-ratios-video-aspect"
|
|
69
73
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=800&h=450&fit=crop"
|
|
70
74
|
alt="Video aspect"
|
|
71
75
|
aspectRatio="video"
|
|
@@ -73,8 +77,9 @@ export const AspectRatios: Story = {
|
|
|
73
77
|
/>
|
|
74
78
|
</div>
|
|
75
79
|
<div>
|
|
76
|
-
<p className="text-xs text-foreground-muted mb-2">Wide (21:9)</p>
|
|
80
|
+
<p id="aspect-ratios-p-wide-219" className="text-xs text-foreground-muted mb-2">Wide (21:9)</p>
|
|
77
81
|
<Image
|
|
82
|
+
id="aspect-ratios-wide-aspect"
|
|
78
83
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=800&h=343&fit=crop"
|
|
79
84
|
alt="Wide aspect"
|
|
80
85
|
aspectRatio="wide"
|
|
@@ -89,8 +94,9 @@ export const ObjectFit: Story = {
|
|
|
89
94
|
render: () => (
|
|
90
95
|
<div className="grid grid-cols-3 gap-4 max-w-3xl">
|
|
91
96
|
<div>
|
|
92
|
-
<p className="text-xs text-foreground-muted mb-2">Cover</p>
|
|
97
|
+
<p id="object-fit-p-cover" className="text-xs text-foreground-muted mb-2">Cover</p>
|
|
93
98
|
<Image
|
|
99
|
+
id="object-fit-cover-fit"
|
|
94
100
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=200&fit=crop"
|
|
95
101
|
alt="Cover fit"
|
|
96
102
|
aspectRatio="square"
|
|
@@ -99,8 +105,9 @@ export const ObjectFit: Story = {
|
|
|
99
105
|
/>
|
|
100
106
|
</div>
|
|
101
107
|
<div>
|
|
102
|
-
<p className="text-xs text-foreground-muted mb-2">Contain</p>
|
|
108
|
+
<p id="object-fit-p-contain" className="text-xs text-foreground-muted mb-2">Contain</p>
|
|
103
109
|
<Image
|
|
110
|
+
id="object-fit-contain-fit"
|
|
104
111
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=200&fit=crop"
|
|
105
112
|
alt="Contain fit"
|
|
106
113
|
aspectRatio="square"
|
|
@@ -109,8 +116,9 @@ export const ObjectFit: Story = {
|
|
|
109
116
|
/>
|
|
110
117
|
</div>
|
|
111
118
|
<div>
|
|
112
|
-
<p className="text-xs text-foreground-muted mb-2">Fill</p>
|
|
119
|
+
<p id="object-fit-p-fill" className="text-xs text-foreground-muted mb-2">Fill</p>
|
|
113
120
|
<Image
|
|
121
|
+
id="object-fit-fill-fit"
|
|
114
122
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=200&fit=crop"
|
|
115
123
|
alt="Fill fit"
|
|
116
124
|
aspectRatio="square"
|
|
@@ -126,8 +134,9 @@ export const BorderRadius: Story = {
|
|
|
126
134
|
render: () => (
|
|
127
135
|
<div className="flex gap-4 flex-wrap">
|
|
128
136
|
<div>
|
|
129
|
-
<p className="text-xs text-foreground-muted mb-2">None</p>
|
|
137
|
+
<p id="border-radius-p-none" className="text-xs text-foreground-muted mb-2">None</p>
|
|
130
138
|
<Image
|
|
139
|
+
id="border-radius-no-radius"
|
|
131
140
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=150&h=150&fit=crop"
|
|
132
141
|
alt="No radius"
|
|
133
142
|
aspectRatio="square"
|
|
@@ -136,8 +145,9 @@ export const BorderRadius: Story = {
|
|
|
136
145
|
/>
|
|
137
146
|
</div>
|
|
138
147
|
<div>
|
|
139
|
-
<p className="text-xs text-foreground-muted mb-2">Small</p>
|
|
148
|
+
<p id="border-radius-p-small" className="text-xs text-foreground-muted mb-2">Small</p>
|
|
140
149
|
<Image
|
|
150
|
+
id="border-radius-small-radius"
|
|
141
151
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=150&h=150&fit=crop"
|
|
142
152
|
alt="Small radius"
|
|
143
153
|
aspectRatio="square"
|
|
@@ -146,8 +156,9 @@ export const BorderRadius: Story = {
|
|
|
146
156
|
/>
|
|
147
157
|
</div>
|
|
148
158
|
<div>
|
|
149
|
-
<p className="text-xs text-foreground-muted mb-2">Medium</p>
|
|
159
|
+
<p id="border-radius-p-medium" className="text-xs text-foreground-muted mb-2">Medium</p>
|
|
150
160
|
<Image
|
|
161
|
+
id="border-radius-medium-radius"
|
|
151
162
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=150&h=150&fit=crop"
|
|
152
163
|
alt="Medium radius"
|
|
153
164
|
aspectRatio="square"
|
|
@@ -156,8 +167,9 @@ export const BorderRadius: Story = {
|
|
|
156
167
|
/>
|
|
157
168
|
</div>
|
|
158
169
|
<div>
|
|
159
|
-
<p className="text-xs text-foreground-muted mb-2">Large</p>
|
|
170
|
+
<p id="border-radius-p-large" className="text-xs text-foreground-muted mb-2">Large</p>
|
|
160
171
|
<Image
|
|
172
|
+
id="border-radius-large-radius"
|
|
161
173
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=150&h=150&fit=crop"
|
|
162
174
|
alt="Large radius"
|
|
163
175
|
aspectRatio="square"
|
|
@@ -166,8 +178,9 @@ export const BorderRadius: Story = {
|
|
|
166
178
|
/>
|
|
167
179
|
</div>
|
|
168
180
|
<div>
|
|
169
|
-
<p className="text-xs text-foreground-muted mb-2">Full</p>
|
|
181
|
+
<p id="border-radius-p-full" className="text-xs text-foreground-muted mb-2">Full</p>
|
|
170
182
|
<Image
|
|
183
|
+
id="border-radius-full-radius"
|
|
171
184
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=150&h=150&fit=crop"
|
|
172
185
|
alt="Full radius"
|
|
173
186
|
aspectRatio="square"
|
|
@@ -183,6 +196,7 @@ export const ErrorState: Story = {
|
|
|
183
196
|
render: () => (
|
|
184
197
|
<div className="w-64">
|
|
185
198
|
<Image
|
|
199
|
+
id="error-state-failed-image"
|
|
186
200
|
src="https://invalid-url-that-will-fail.com/image.jpg"
|
|
187
201
|
alt="Failed image"
|
|
188
202
|
aspectRatio="video"
|
|
@@ -195,13 +209,14 @@ export const CustomFallback: Story = {
|
|
|
195
209
|
render: () => (
|
|
196
210
|
<div className="w-64">
|
|
197
211
|
<Image
|
|
212
|
+
id="custom-fallback-failed-image"
|
|
198
213
|
src="https://invalid-url-that-will-fail.com/image.jpg"
|
|
199
214
|
alt="Failed image"
|
|
200
215
|
aspectRatio="video"
|
|
201
216
|
fallback={
|
|
202
217
|
<div className="flex flex-col items-center gap-2 text-foreground-muted">
|
|
203
|
-
<span className="text-3xl">📷</span>
|
|
204
|
-
<span className="text-sm">Image not available</span>
|
|
218
|
+
<span id="custom-fallback-span" className="text-3xl">📷</span>
|
|
219
|
+
<span id="custom-fallback-span-image-not-available" className="text-sm">Image not available</span>
|
|
205
220
|
</div>
|
|
206
221
|
}
|
|
207
222
|
/>
|
|
@@ -213,6 +228,7 @@ export const WithoutSkeleton: Story = {
|
|
|
213
228
|
render: () => (
|
|
214
229
|
<div className="w-64">
|
|
215
230
|
<Image
|
|
231
|
+
id="without-skeleton-no-skeleton"
|
|
216
232
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop"
|
|
217
233
|
alt="No skeleton"
|
|
218
234
|
showSkeleton={false}
|
|
@@ -225,6 +241,7 @@ export const ZoomOnHover: Story = {
|
|
|
225
241
|
render: () => (
|
|
226
242
|
<div className="w-64">
|
|
227
243
|
<ZoomImage
|
|
244
|
+
id="zoom-on-hover"
|
|
228
245
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=400&fit=crop"
|
|
229
246
|
alt="Zoom on hover"
|
|
230
247
|
aspectRatio="square"
|
|
@@ -238,6 +255,7 @@ export const Gallery: Story = {
|
|
|
238
255
|
render: () => (
|
|
239
256
|
<div className="max-w-2xl">
|
|
240
257
|
<ImageGallery
|
|
258
|
+
id="gallery"
|
|
241
259
|
images={[
|
|
242
260
|
{ src: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=400&fit=crop', alt: 'Product 1' },
|
|
243
261
|
{ src: 'https://images.unsplash.com/photo-1545454675-3531b543be5d?w=400&h=400&fit=crop', alt: 'Product 2' },
|
|
@@ -263,14 +281,14 @@ export const GalleryColumns: Story = {
|
|
|
263
281
|
];
|
|
264
282
|
|
|
265
283
|
return (
|
|
266
|
-
<div className="space-y-8">
|
|
284
|
+
<div data-sonance-name="image.stories" className="space-y-8">
|
|
267
285
|
<div>
|
|
268
|
-
<p className="text-xs text-foreground-muted mb-2">2 Columns</p>
|
|
269
|
-
<ImageGallery images={images} columns={2} />
|
|
286
|
+
<p id="gallery-columns-p-2-columns" className="text-xs text-foreground-muted mb-2">2 Columns</p>
|
|
287
|
+
<ImageGallery id="gallery-columns" images={images} columns={2} />
|
|
270
288
|
</div>
|
|
271
289
|
<div>
|
|
272
|
-
<p className="text-xs text-foreground-muted mb-2">4 Columns</p>
|
|
273
|
-
<ImageGallery images={images} columns={4} />
|
|
290
|
+
<p id="gallery-columns-p-4-columns" className="text-xs text-foreground-muted mb-2">4 Columns</p>
|
|
291
|
+
<ImageGallery id="gallery-columns" images={images} columns={4} />
|
|
274
292
|
</div>
|
|
275
293
|
</div>
|
|
276
294
|
);
|
|
@@ -281,14 +299,15 @@ export const ProductImage: Story = {
|
|
|
281
299
|
render: () => (
|
|
282
300
|
<div className="w-80 border border-border">
|
|
283
301
|
<Image
|
|
302
|
+
id="product-image-vp66-tl-inwall-speak"
|
|
284
303
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=600&h=400&fit=crop"
|
|
285
304
|
alt="VP66 TL In-Wall Speaker"
|
|
286
305
|
aspectRatio="video"
|
|
287
306
|
/>
|
|
288
307
|
<div className="p-4">
|
|
289
|
-
<h3 className="font-medium text-foreground">VP66 TL</h3>
|
|
290
|
-
<p className="text-sm text-foreground-muted">In-Wall Speaker</p>
|
|
291
|
-
<p className="text-lg font-medium text-foreground mt-2">$1,299.00</p>
|
|
308
|
+
<h3 id="product-image-h3-vp66-tl" className="font-medium text-foreground">VP66 TL</h3>
|
|
309
|
+
<p id="product-image-p-inwall-speaker" className="text-sm text-foreground-muted">In-Wall Speaker</p>
|
|
310
|
+
<p id="product-image-p-129900" className="text-lg font-medium text-foreground mt-2">$1,299.00</p>
|
|
292
311
|
</div>
|
|
293
312
|
</div>
|
|
294
313
|
),
|
|
@@ -300,9 +319,10 @@ export const ResponsiveMatrix: Story = {
|
|
|
300
319
|
<div className="space-y-8">
|
|
301
320
|
{/* Mobile */}
|
|
302
321
|
<div>
|
|
303
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
322
|
+
<h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
304
323
|
<div className="w-[375px] border border-dashed border-border p-4">
|
|
305
324
|
<Image
|
|
325
|
+
id="responsive-matrix-speaker"
|
|
306
326
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=300&fit=crop"
|
|
307
327
|
alt="Speaker"
|
|
308
328
|
aspectRatio="video"
|
|
@@ -311,15 +331,17 @@ export const ResponsiveMatrix: Story = {
|
|
|
311
331
|
</div>
|
|
312
332
|
{/* Tablet */}
|
|
313
333
|
<div>
|
|
314
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
334
|
+
<h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
315
335
|
<div className="w-[768px] border border-dashed border-border p-4">
|
|
316
336
|
<div className="grid grid-cols-2 gap-4">
|
|
317
337
|
<Image
|
|
338
|
+
id="responsive-matrix-square"
|
|
318
339
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=400&fit=crop"
|
|
319
340
|
alt="Square"
|
|
320
341
|
aspectRatio="square"
|
|
321
342
|
/>
|
|
322
343
|
<Image
|
|
344
|
+
id="responsive-matrix-video"
|
|
323
345
|
src="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=600&h=400&fit=crop"
|
|
324
346
|
alt="Video"
|
|
325
347
|
aspectRatio="video"
|
|
@@ -329,9 +351,10 @@ export const ResponsiveMatrix: Story = {
|
|
|
329
351
|
</div>
|
|
330
352
|
{/* Desktop */}
|
|
331
353
|
<div>
|
|
332
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
354
|
+
<h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
333
355
|
<div className="w-[1280px] border border-dashed border-border p-4">
|
|
334
356
|
<ImageGallery
|
|
357
|
+
id="responsive-matrix"
|
|
335
358
|
images={[
|
|
336
359
|
{ src: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=400&h=400&fit=crop', alt: 'Product 1' },
|
|
337
360
|
{ src: 'https://images.unsplash.com/photo-1545454675-3531b543be5d?w=400&h=400&fit=crop', alt: 'Product 2' },
|
|
@@ -74,11 +74,11 @@ export const Image = forwardRef<HTMLImageElement, ImageProps>(
|
|
|
74
74
|
|
|
75
75
|
if (status === "error") {
|
|
76
76
|
return (
|
|
77
|
-
<div className={cn(containerClasses, "flex items-center justify-center")}>
|
|
77
|
+
<div data-sonance-name="image" className={cn(containerClasses, "flex items-center justify-center")}>
|
|
78
78
|
{fallback || (
|
|
79
79
|
<div className="flex flex-col items-center gap-2 text-foreground-muted">
|
|
80
80
|
<ImageOff className="h-8 w-8" />
|
|
81
|
-
<span className="text-xs">Failed to load</span>
|
|
81
|
+
<span id="span-failed-to-load" className="text-xs">Failed to load</span>
|
|
82
82
|
</div>
|
|
83
83
|
)}
|
|
84
84
|
</div>
|
|
@@ -86,11 +86,12 @@ export const Image = forwardRef<HTMLImageElement, ImageProps>(
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
return (
|
|
89
|
-
<div className={containerClasses}>
|
|
89
|
+
<div data-sonance-name="image" className={containerClasses}>
|
|
90
90
|
{status === "loading" && showSkeleton && (
|
|
91
91
|
<Skeleton className="absolute inset-0 w-full h-full" />
|
|
92
92
|
)}
|
|
93
93
|
<img
|
|
94
|
+
id="image"
|
|
94
95
|
ref={ref}
|
|
95
96
|
src={src}
|
|
96
97
|
alt={alt}
|
|
@@ -100,7 +101,7 @@ export const Image = forwardRef<HTMLImageElement, ImageProps>(
|
|
|
100
101
|
"w-full h-full transition-opacity duration-300",
|
|
101
102
|
objectFitClasses[objectFit],
|
|
102
103
|
status === "loading" ? "opacity-0" : "opacity-100"
|
|
103
|
-
)}
|
|
104
|
+
)} data-sonance-name="image"
|
|
104
105
|
{...props}
|
|
105
106
|
/>
|
|
106
107
|
</div>
|
|
@@ -119,7 +120,8 @@ export function ZoomImage({ zoomScale = 1.1, className, ...props }: ZoomImagePro
|
|
|
119
120
|
return (
|
|
120
121
|
<div className={cn("overflow-hidden", className)}>
|
|
121
122
|
<Image
|
|
122
|
-
|
|
123
|
+
id="zoom-image"
|
|
124
|
+
data-sonance-name="image" {...props}
|
|
123
125
|
className={cn(
|
|
124
126
|
"transition-transform duration-300 hover:scale-[var(--zoom-scale)]"
|
|
125
127
|
)}
|
|
@@ -159,6 +161,7 @@ export function ImageGallery({
|
|
|
159
161
|
<div className={cn("grid", columnClasses[columns], gapClasses[gap], className)}>
|
|
160
162
|
{images.map((image, index) => (
|
|
161
163
|
<Image
|
|
164
|
+
id="image-gallery"
|
|
162
165
|
key={index}
|
|
163
166
|
src={image.src}
|
|
164
167
|
alt={image.alt}
|
|
@@ -56,13 +56,13 @@ export const Default: Story = {
|
|
|
56
56
|
render: () => {
|
|
57
57
|
const [value, setValue] = useState('');
|
|
58
58
|
return (
|
|
59
|
-
<div className="space-y-4">
|
|
59
|
+
<div data-sonance-name="input-otp.stories" className="space-y-4">
|
|
60
60
|
<InputOTP
|
|
61
61
|
value={value}
|
|
62
62
|
onValueChange={setValue}
|
|
63
63
|
onComplete={(code) => console.log('Complete:', code)}
|
|
64
64
|
/>
|
|
65
|
-
<p className="text-sm text-foreground-muted">
|
|
65
|
+
<p id="default-p-value-value-empty" className="text-sm text-foreground-muted">
|
|
66
66
|
Value: {value || 'empty'}
|
|
67
67
|
</p>
|
|
68
68
|
</div>
|
|
@@ -154,7 +154,7 @@ export const AutoFocus: Story = {
|
|
|
154
154
|
value={value}
|
|
155
155
|
onValueChange={setValue}
|
|
156
156
|
/>
|
|
157
|
-
<p className="text-sm text-foreground-muted">
|
|
157
|
+
<p id="auto-focus-p-the-first-input-is-a" className="text-sm text-foreground-muted">
|
|
158
158
|
The first input is automatically focused
|
|
159
159
|
</p>
|
|
160
160
|
</div>
|
|
@@ -192,10 +192,10 @@ export const WithCompletionHandler: Story = {
|
|
|
192
192
|
error={status === 'error' ? 'Invalid code. Try 123456' : undefined}
|
|
193
193
|
/>
|
|
194
194
|
{status === 'verifying' && (
|
|
195
|
-
<p className="text-sm text-foreground-muted">Verifying...</p>
|
|
195
|
+
<p id="with-completion-handler-p-verifying" className="text-sm text-foreground-muted">Verifying...</p>
|
|
196
196
|
)}
|
|
197
197
|
{status === 'success' && (
|
|
198
|
-
<p className="text-sm text-success">Code verified successfully!</p>
|
|
198
|
+
<p id="with-completion-handler-p-code-verified-succes" className="text-sm text-success">Code verified successfully!</p>
|
|
199
199
|
)}
|
|
200
200
|
</div>
|
|
201
201
|
);
|
|
@@ -220,8 +220,8 @@ export const VerificationFlowExample: Story = {
|
|
|
220
220
|
return (
|
|
221
221
|
<div className="w-80 p-6 border border-success rounded-sm text-center space-y-2">
|
|
222
222
|
<div className="text-success text-2xl">✓</div>
|
|
223
|
-
<h3 className="font-medium">Verified!</h3>
|
|
224
|
-
<p className="text-sm text-foreground-muted">
|
|
223
|
+
<h3 id="verification-flow-example-h3-verified" className="font-medium">Verified!</h3>
|
|
224
|
+
<p id="verification-flow-example-p-your-phone-number-ha" className="text-sm text-foreground-muted">
|
|
225
225
|
Your phone number has been verified.
|
|
226
226
|
</p>
|
|
227
227
|
<button
|
|
@@ -240,8 +240,8 @@ export const VerificationFlowExample: Story = {
|
|
|
240
240
|
return (
|
|
241
241
|
<div className="w-80 space-y-4">
|
|
242
242
|
<div className="text-center space-y-1">
|
|
243
|
-
<h3 className="font-medium">Verify your phone</h3>
|
|
244
|
-
<p className="text-sm text-foreground-muted">
|
|
243
|
+
<h3 id="verification-flow-example-h3-verify-your-phone" className="font-medium">Verify your phone</h3>
|
|
244
|
+
<p id="verification-flow-example-p-we-sent-a-code-to-1-" className="text-sm text-foreground-muted">
|
|
245
245
|
We sent a code to +1 (555) ***-1234
|
|
246
246
|
</p>
|
|
247
247
|
</div>
|
|
@@ -251,7 +251,7 @@ export const VerificationFlowExample: Story = {
|
|
|
251
251
|
onComplete={handleComplete}
|
|
252
252
|
autoFocus
|
|
253
253
|
/>
|
|
254
|
-
<p className="text-center text-sm text-foreground-muted">
|
|
254
|
+
<p id="verification-flow-example-p" className="text-center text-sm text-foreground-muted">
|
|
255
255
|
Didn't receive a code?{' '}
|
|
256
256
|
<button className="text-primary hover:underline">Resend</button>
|
|
257
257
|
</p>
|
|
@@ -279,11 +279,11 @@ export const StateMatrix: Story = {
|
|
|
279
279
|
const states: InputOTPState[] = ['default', 'hover', 'focus', 'error', 'disabled'];
|
|
280
280
|
return (
|
|
281
281
|
<div className="space-y-6">
|
|
282
|
-
<h3 className="text-sm font-medium text-foreground-muted">InputOTP States</h3>
|
|
282
|
+
<h3 id="state-matrix-h3-inputotp-states" className="text-sm font-medium text-foreground-muted">InputOTP States</h3>
|
|
283
283
|
<div className="space-y-4">
|
|
284
284
|
{states.map((state) => (
|
|
285
285
|
<div key={state}>
|
|
286
|
-
<span className="text-xs font-medium text-foreground-muted uppercase">{state}</span>
|
|
286
|
+
<span id="state-matrix-span-state" className="text-xs font-medium text-foreground-muted uppercase">{state}</span>
|
|
287
287
|
<InputOTP
|
|
288
288
|
state={state}
|
|
289
289
|
length={6}
|
|
@@ -304,14 +304,14 @@ export const ResponsiveMatrix: Story = {
|
|
|
304
304
|
<div className="space-y-8">
|
|
305
305
|
{/* Mobile */}
|
|
306
306
|
<div>
|
|
307
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
307
|
+
<h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
308
308
|
<div className="w-[375px] border border-dashed border-border p-4">
|
|
309
309
|
<InputOTP label="Verification Code" length={6} />
|
|
310
310
|
</div>
|
|
311
311
|
</div>
|
|
312
312
|
{/* Tablet */}
|
|
313
313
|
<div>
|
|
314
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
314
|
+
<h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
315
315
|
<div className="w-[768px] border border-dashed border-border p-4">
|
|
316
316
|
<div className="flex gap-8">
|
|
317
317
|
<InputOTP label="4-Digit PIN" length={4} />
|
|
@@ -321,7 +321,7 @@ export const ResponsiveMatrix: Story = {
|
|
|
321
321
|
</div>
|
|
322
322
|
{/* Desktop */}
|
|
323
323
|
<div>
|
|
324
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
324
|
+
<h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
325
325
|
<div className="w-[1280px] border border-dashed border-border p-4">
|
|
326
326
|
<div className="flex gap-8">
|
|
327
327
|
<InputOTP label="Default" />
|
|
@@ -126,7 +126,7 @@ export function InputOTP({
|
|
|
126
126
|
};
|
|
127
127
|
|
|
128
128
|
return (
|
|
129
|
-
<div className={cn("w-full", className)}>
|
|
129
|
+
<div data-sonance-name="input-otp" className={cn("w-full", className)}>
|
|
130
130
|
{label && (
|
|
131
131
|
<label className="mb-2 block text-xs font-medium uppercase tracking-widest text-foreground-muted">
|
|
132
132
|
{label}
|
|
@@ -162,7 +162,7 @@ export function InputOTP({
|
|
|
162
162
|
/>
|
|
163
163
|
))}
|
|
164
164
|
</div>
|
|
165
|
-
{error && <p className="mt-2 text-sm text-error">{error}</p>}
|
|
165
|
+
{error && <p id="p-error" className="mt-2 text-sm text-error">{error}</p>}
|
|
166
166
|
</div>
|
|
167
167
|
);
|
|
168
168
|
}
|
|
@@ -181,12 +181,12 @@ export function InputOTPGrouped({
|
|
|
181
181
|
const groups = Math.ceil(length / groupSize);
|
|
182
182
|
|
|
183
183
|
return (
|
|
184
|
-
<div className={cn("flex items-center gap-3", className)}>
|
|
184
|
+
<div data-sonance-name="input-otp" className={cn("flex items-center gap-3", className)}>
|
|
185
185
|
{Array.from({ length: groups }).map((_, groupIndex) => (
|
|
186
186
|
<div key={groupIndex} className="flex items-center gap-3">
|
|
187
|
-
{groupIndex > 0 && <span className="text-foreground-muted">–</span>}
|
|
187
|
+
{groupIndex > 0 && <span id="input-o-t-p-grouped-span" className="text-foreground-muted">–</span>}
|
|
188
188
|
<InputOTP
|
|
189
|
-
{...props}
|
|
189
|
+
data-sonance-name="input-otp" {...props}
|
|
190
190
|
length={Math.min(groupSize, length - groupIndex * groupSize)}
|
|
191
191
|
className="flex-shrink-0"
|
|
192
192
|
/>
|
|
@@ -96,20 +96,23 @@ export const Password: Story = {
|
|
|
96
96
|
export const AllStates: Story = {
|
|
97
97
|
render: () => (
|
|
98
98
|
<div className="space-y-6 w-80">
|
|
99
|
-
<Input placeholder="Default input" />
|
|
100
|
-
<Input label="With Label" placeholder="Enter text..." />
|
|
99
|
+
<Input id="all-states-input-default-input" placeholder="Default input" />
|
|
100
|
+
<Input id="all-states-input-enter-text" label="With Label" placeholder="Enter text..." />
|
|
101
101
|
<Input
|
|
102
|
+
id="all-states-input-enter-email"
|
|
102
103
|
label="With Error"
|
|
103
104
|
placeholder="Enter email..."
|
|
104
105
|
error="This field is required"
|
|
105
106
|
defaultValue="invalid"
|
|
106
107
|
/>
|
|
107
108
|
<Input
|
|
109
|
+
id="all-states-input-cannot-edit"
|
|
108
110
|
label="Disabled"
|
|
109
111
|
placeholder="Cannot edit..."
|
|
110
112
|
disabled
|
|
111
113
|
/>
|
|
112
114
|
<Input
|
|
115
|
+
id="all-states-input"
|
|
113
116
|
label="With Value"
|
|
114
117
|
defaultValue="Pre-filled value"
|
|
115
118
|
/>
|
|
@@ -121,10 +124,10 @@ export const AllStates: Story = {
|
|
|
121
124
|
export const FormExample: Story = {
|
|
122
125
|
render: () => (
|
|
123
126
|
<form className="space-y-4 w-80">
|
|
124
|
-
<Input label="First Name" placeholder="John" />
|
|
125
|
-
<Input label="Last Name" placeholder="Doe" />
|
|
126
|
-
<Input label="Email" type="email" placeholder="john@example.com" />
|
|
127
|
-
<Input label="Phone" type="tel" placeholder="+1 (555) 000-0000" />
|
|
127
|
+
<Input id="form-example-input-john" label="First Name" placeholder="John" />
|
|
128
|
+
<Input id="form-example-input-doe" label="Last Name" placeholder="Doe" />
|
|
129
|
+
<Input id="form-example-input-johnexamplecom" label="Email" type="email" placeholder="john@example.com" />
|
|
130
|
+
<Input id="form-example-input-1-555-0000000" label="Phone" type="tel" placeholder="+1 (555) 000-0000" />
|
|
128
131
|
</form>
|
|
129
132
|
),
|
|
130
133
|
};
|
|
@@ -135,13 +138,14 @@ export const StateMatrix: Story = {
|
|
|
135
138
|
const states: InputState[] = ['default', 'hover', 'focus', 'error', 'disabled'];
|
|
136
139
|
|
|
137
140
|
return (
|
|
138
|
-
<div className="space-y-6 w-96">
|
|
139
|
-
<h3 className="text-sm font-medium text-foreground-muted">Input States</h3>
|
|
141
|
+
<div data-sonance-name="input.stories" className="space-y-6 w-96">
|
|
142
|
+
<h3 id="state-matrix-h3-input-states" className="text-sm font-medium text-foreground-muted">Input States</h3>
|
|
140
143
|
<div className="grid grid-cols-1 gap-4">
|
|
141
144
|
{states.map((state) => (
|
|
142
145
|
<div key={state} className="flex items-center gap-4">
|
|
143
|
-
<span className="text-xs font-medium text-foreground-muted uppercase w-20">{state}</span>
|
|
146
|
+
<span id="state-matrix-span-state" className="text-xs font-medium text-foreground-muted uppercase w-20">{state}</span>
|
|
144
147
|
<Input
|
|
148
|
+
id="state-matrix-input"
|
|
145
149
|
state={state}
|
|
146
150
|
placeholder={`${state} state`}
|
|
147
151
|
defaultValue={state !== 'default' ? 'Input value' : ''}
|
|
@@ -161,18 +165,19 @@ export const LabeledStateMatrix: Story = {
|
|
|
161
165
|
|
|
162
166
|
return (
|
|
163
167
|
<div className="space-y-6">
|
|
164
|
-
<h3 className="text-sm font-medium text-foreground-muted">Input with Label - All States</h3>
|
|
168
|
+
<h3 id="labeled-state-matrix-h3-input-with-label-all" className="text-sm font-medium text-foreground-muted">Input with Label - All States</h3>
|
|
165
169
|
<div className="grid grid-cols-5 gap-4">
|
|
166
170
|
{states.map((state) => (
|
|
167
171
|
<div key={state} className="text-center">
|
|
168
172
|
<Input
|
|
173
|
+
id="labeled-state-matrix-input-nameexamplecom"
|
|
169
174
|
label="Email"
|
|
170
175
|
state={state}
|
|
171
176
|
placeholder="name@example.com"
|
|
172
177
|
defaultValue={state !== 'default' ? 'user@email.com' : ''}
|
|
173
178
|
error={state === 'error' ? 'Invalid email' : undefined}
|
|
174
179
|
/>
|
|
175
|
-
<p className="text-xs text-foreground-muted mt-2 uppercase">{state}</p>
|
|
180
|
+
<p id="labeled-state-matrix-p-state" className="text-xs text-foreground-muted mt-2 uppercase">{state}</p>
|
|
176
181
|
</div>
|
|
177
182
|
))}
|
|
178
183
|
</div>
|
|
@@ -187,34 +192,34 @@ export const ResponsiveMatrix: Story = {
|
|
|
187
192
|
<div className="space-y-8">
|
|
188
193
|
{/* Mobile */}
|
|
189
194
|
<div>
|
|
190
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
195
|
+
<h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
|
|
191
196
|
<div className="w-[375px] border border-dashed border-border p-4 space-y-4">
|
|
192
|
-
<Input label="Email" placeholder="name@example.com" />
|
|
193
|
-
<Input label="Password" type="password" placeholder="Enter password" />
|
|
194
|
-
<Input label="Error State" error="This field is required" defaultValue="Invalid" />
|
|
197
|
+
<Input id="responsive-matrix-input-nameexamplecom" label="Email" placeholder="name@example.com" />
|
|
198
|
+
<Input id="responsive-matrix-input-enter-password" label="Password" type="password" placeholder="Enter password" />
|
|
199
|
+
<Input id="responsive-matrix-input" label="Error State" error="This field is required" defaultValue="Invalid" />
|
|
195
200
|
</div>
|
|
196
201
|
</div>
|
|
197
202
|
{/* Tablet */}
|
|
198
203
|
<div>
|
|
199
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
204
|
+
<h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
|
|
200
205
|
<div className="w-[768px] border border-dashed border-border p-4">
|
|
201
206
|
<div className="grid grid-cols-2 gap-4">
|
|
202
|
-
<Input label="First Name" placeholder="John" />
|
|
203
|
-
<Input label="Last Name" placeholder="Doe" />
|
|
204
|
-
<Input label="Email" type="email" placeholder="john@example.com" />
|
|
205
|
-
<Input label="Phone" type="tel" placeholder="+1 (555) 000-0000" />
|
|
207
|
+
<Input id="responsive-matrix-input-john" label="First Name" placeholder="John" />
|
|
208
|
+
<Input id="responsive-matrix-input-doe" label="Last Name" placeholder="Doe" />
|
|
209
|
+
<Input id="responsive-matrix-input-johnexamplecom" label="Email" type="email" placeholder="john@example.com" />
|
|
210
|
+
<Input id="responsive-matrix-input-1-555-0000000" label="Phone" type="tel" placeholder="+1 (555) 000-0000" />
|
|
206
211
|
</div>
|
|
207
212
|
</div>
|
|
208
213
|
</div>
|
|
209
214
|
{/* Desktop */}
|
|
210
215
|
<div>
|
|
211
|
-
<h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
216
|
+
<h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
|
|
212
217
|
<div className="w-[1280px] border border-dashed border-border p-4">
|
|
213
218
|
<div className="grid grid-cols-4 gap-4">
|
|
214
|
-
<Input label="First Name" placeholder="John" />
|
|
215
|
-
<Input label="Last Name" placeholder="Doe" />
|
|
216
|
-
<Input label="Email" type="email" placeholder="john@example.com" />
|
|
217
|
-
<Input label="Phone" type="tel" placeholder="+1 (555) 000-0000" />
|
|
219
|
+
<Input id="responsive-matrix-input-john" label="First Name" placeholder="John" />
|
|
220
|
+
<Input id="responsive-matrix-input-doe" label="Last Name" placeholder="Doe" />
|
|
221
|
+
<Input id="responsive-matrix-input-johnexamplecom" label="Email" type="email" placeholder="john@example.com" />
|
|
222
|
+
<Input id="responsive-matrix-input-1-555-0000000" label="Phone" type="tel" placeholder="+1 (555) 000-0000" />
|
|
218
223
|
</div>
|
|
219
224
|
</div>
|
|
220
225
|
</div>
|
|
@@ -8,6 +8,8 @@ interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
|
8
8
|
error?: string;
|
|
9
9
|
/** Visual state for Storybook/Figma documentation */
|
|
10
10
|
state?: InputState;
|
|
11
|
+
/** Container style for the wrapper div */
|
|
12
|
+
wrapperStyle?: React.CSSProperties;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
// State styles for Storybook/Figma visualization
|
|
@@ -25,12 +27,12 @@ const getStateStyles = (state?: InputState) => {
|
|
|
25
27
|
};
|
|
26
28
|
|
|
27
29
|
export const Input = forwardRef<HTMLInputElement, InputProps>(
|
|
28
|
-
({ className, label, error, state, disabled, ...props }, ref) => {
|
|
30
|
+
({ className, label, error, state, disabled, style, wrapperStyle, ...props }, ref) => {
|
|
29
31
|
const isDisabled = disabled || state === "disabled";
|
|
30
32
|
const hasError = error || state === "error";
|
|
31
33
|
|
|
32
34
|
return (
|
|
33
|
-
<div className="w-full">
|
|
35
|
+
<div data-sonance-name="input" className="w-full" style={wrapperStyle}>
|
|
34
36
|
{label && (
|
|
35
37
|
<label className="mb-2 block text-xs font-medium uppercase tracking-widest text-foreground-muted">
|
|
36
38
|
{label}
|
|
@@ -39,6 +41,7 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
|
|
|
39
41
|
<input
|
|
40
42
|
ref={ref}
|
|
41
43
|
disabled={isDisabled}
|
|
44
|
+
style={style}
|
|
42
45
|
className={cn(
|
|
43
46
|
"w-full border border-input-border bg-input px-4 py-3",
|
|
44
47
|
"text-foreground placeholder:text-input-placeholder",
|
|
@@ -49,10 +52,10 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
|
|
|
49
52
|
hasError && "border-error",
|
|
50
53
|
getStateStyles(state),
|
|
51
54
|
className
|
|
52
|
-
)}
|
|
55
|
+
)} data-sonance-name="input"
|
|
53
56
|
{...props}
|
|
54
57
|
/>
|
|
55
|
-
{error && <p className="mt-1 text-sm text-error">{error}</p>}
|
|
58
|
+
{error && <p id="input-p-error" className="mt-1 text-sm text-error">{error}</p>}
|
|
56
59
|
</div>
|
|
57
60
|
);
|
|
58
61
|
}
|