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.
Files changed (189) hide show
  1. package/dist/assets/api/sonance-analyze/route.ts +1116 -0
  2. package/dist/assets/api/sonance-assets/route.ts +113 -0
  3. package/dist/assets/api/sonance-components/route.ts +41 -0
  4. package/dist/assets/api/sonance-inject-id/route.ts +363 -0
  5. package/dist/assets/api/sonance-save-logo/route.ts +426 -0
  6. package/dist/assets/api/sonance-theme/route.ts +106 -0
  7. package/dist/assets/brand-system.ts +1265 -0
  8. package/dist/assets/components/accordion.stories.tsx +26 -26
  9. package/dist/assets/components/accordion.tsx +3 -3
  10. package/dist/assets/components/alert-dialog.stories.tsx +142 -0
  11. package/dist/assets/components/alert-dialog.tsx +143 -0
  12. package/dist/assets/components/alert.stories.tsx +3 -3
  13. package/dist/assets/components/alert.tsx +4 -3
  14. package/dist/assets/components/aspect-ratio.stories.tsx +70 -0
  15. package/dist/assets/components/aspect-ratio.tsx +8 -0
  16. package/dist/assets/components/autocomplete.stories.tsx +9 -9
  17. package/dist/assets/components/autocomplete.tsx +3 -3
  18. package/dist/assets/components/avatar.stories.tsx +5 -5
  19. package/dist/assets/components/avatar.tsx +67 -23
  20. package/dist/assets/components/badge.stories.tsx +10 -10
  21. package/dist/assets/components/badge.tsx +3 -3
  22. package/dist/assets/components/breadcrumbs.stories.tsx +7 -7
  23. package/dist/assets/components/breadcrumbs.tsx +13 -8
  24. package/dist/assets/components/button.stories.tsx +74 -74
  25. package/dist/assets/components/button.tsx +2 -0
  26. package/dist/assets/components/calendar.stories.tsx +11 -11
  27. package/dist/assets/components/calendar.tsx +4 -4
  28. package/dist/assets/components/card.stories.tsx +22 -22
  29. package/dist/assets/components/card.tsx +7 -3
  30. package/dist/assets/components/carousel.stories.tsx +158 -0
  31. package/dist/assets/components/carousel.tsx +264 -0
  32. package/dist/assets/components/chart.stories.tsx +376 -0
  33. package/dist/assets/components/chart.tsx +384 -0
  34. package/dist/assets/components/checkbox-group.stories.tsx +6 -6
  35. package/dist/assets/components/checkbox-group.tsx +3 -3
  36. package/dist/assets/components/checkbox.stories.tsx +23 -20
  37. package/dist/assets/components/checkbox.tsx +13 -6
  38. package/dist/assets/components/code.stories.tsx +24 -24
  39. package/dist/assets/components/code.tsx +22 -27
  40. package/dist/assets/components/collapsible.stories.tsx +128 -0
  41. package/dist/assets/components/collapsible.tsx +10 -0
  42. package/dist/assets/components/command.stories.tsx +183 -0
  43. package/dist/assets/components/command.tsx +171 -0
  44. package/dist/assets/components/context-menu.stories.tsx +159 -0
  45. package/dist/assets/components/context-menu.tsx +214 -0
  46. package/dist/assets/components/date-input.stories.tsx +9 -9
  47. package/dist/assets/components/date-input.tsx +2 -2
  48. package/dist/assets/components/date-picker.stories.tsx +9 -9
  49. package/dist/assets/components/date-picker.tsx +3 -3
  50. package/dist/assets/components/date-range-picker.stories.tsx +12 -12
  51. package/dist/assets/components/date-range-picker.tsx +3 -3
  52. package/dist/assets/components/dialog.stories.tsx +40 -40
  53. package/dist/assets/components/dialog.tsx +8 -12
  54. package/dist/assets/components/divider.stories.tsx +30 -30
  55. package/dist/assets/components/divider.tsx +34 -35
  56. package/dist/assets/components/drawer.stories.tsx +32 -31
  57. package/dist/assets/components/drawer.tsx +7 -6
  58. package/dist/assets/components/dropdown-menu.tsx +213 -0
  59. package/dist/assets/components/dropdown.stories.tsx +12 -12
  60. package/dist/assets/components/dropdown.tsx +5 -5
  61. package/dist/assets/components/form.stories.tsx +30 -29
  62. package/dist/assets/components/form.tsx +5 -5
  63. package/dist/assets/components/hover-card.stories.tsx +115 -0
  64. package/dist/assets/components/hover-card.tsx +35 -0
  65. package/dist/assets/components/image.stories.tsx +48 -25
  66. package/dist/assets/components/image.tsx +8 -5
  67. package/dist/assets/components/input-otp.stories.tsx +15 -15
  68. package/dist/assets/components/input-otp.tsx +5 -5
  69. package/dist/assets/components/input.stories.tsx +30 -25
  70. package/dist/assets/components/input.tsx +7 -4
  71. package/dist/assets/components/kbd.stories.tsx +34 -34
  72. package/dist/assets/components/kbd.tsx +9 -9
  73. package/dist/assets/components/link.stories.tsx +36 -36
  74. package/dist/assets/components/link.tsx +4 -0
  75. package/dist/assets/components/listbox.stories.tsx +5 -5
  76. package/dist/assets/components/listbox.tsx +4 -4
  77. package/dist/assets/components/menubar.stories.tsx +208 -0
  78. package/dist/assets/components/menubar.tsx +247 -0
  79. package/dist/assets/components/navbar.stories.tsx +24 -24
  80. package/dist/assets/components/navbar.tsx +8 -14
  81. package/dist/assets/components/navigation-menu.stories.tsx +239 -0
  82. package/dist/assets/components/navigation-menu.tsx +135 -0
  83. package/dist/assets/components/number-input.stories.tsx +11 -11
  84. package/dist/assets/components/number-input.tsx +3 -3
  85. package/dist/assets/components/pagination.stories.tsx +13 -13
  86. package/dist/assets/components/pagination.tsx +6 -6
  87. package/dist/assets/components/popover.stories.tsx +35 -35
  88. package/dist/assets/components/popover.tsx +98 -15
  89. package/dist/assets/components/progress.stories.tsx +5 -5
  90. package/dist/assets/components/progress.tsx +5 -5
  91. package/dist/assets/components/radio-group.stories.tsx +7 -7
  92. package/dist/assets/components/radio-group.tsx +3 -3
  93. package/dist/assets/components/range-calendar.stories.tsx +18 -18
  94. package/dist/assets/components/range-calendar.tsx +3 -3
  95. package/dist/assets/components/resizable.stories.tsx +197 -0
  96. package/dist/assets/components/resizable.tsx +47 -0
  97. package/dist/assets/components/scroll-area.stories.tsx +123 -0
  98. package/dist/assets/components/scroll-area.tsx +48 -0
  99. package/dist/assets/components/scroll-shadow.stories.tsx +17 -17
  100. package/dist/assets/components/scroll-shadow.tsx +31 -9
  101. package/dist/assets/components/select.stories.tsx +20 -19
  102. package/dist/assets/components/select.tsx +10 -6
  103. package/dist/assets/components/separator.tsx +32 -0
  104. package/dist/assets/components/sheet.tsx +137 -0
  105. package/dist/assets/components/sidebar.stories.tsx +351 -0
  106. package/dist/assets/components/sidebar.tsx +757 -0
  107. package/dist/assets/components/skeleton.stories.tsx +3 -3
  108. package/dist/assets/components/skeleton.tsx +2 -2
  109. package/dist/assets/components/slider.stories.tsx +6 -6
  110. package/dist/assets/components/slider.tsx +3 -3
  111. package/dist/assets/components/spacer.stories.tsx +11 -11
  112. package/dist/assets/components/spacer.tsx +2 -2
  113. package/dist/assets/components/spinner.stories.tsx +8 -8
  114. package/dist/assets/components/spinner.tsx +5 -5
  115. package/dist/assets/components/switch.stories.tsx +24 -20
  116. package/dist/assets/components/switch.tsx +14 -6
  117. package/dist/assets/components/table.stories.tsx +7 -7
  118. package/dist/assets/components/table.tsx +8 -8
  119. package/dist/assets/components/tabs.stories.tsx +37 -37
  120. package/dist/assets/components/tabs.tsx +3 -3
  121. package/dist/assets/components/textarea.stories.tsx +13 -12
  122. package/dist/assets/components/textarea.tsx +3 -3
  123. package/dist/assets/components/theme-toggle.stories.tsx +31 -30
  124. package/dist/assets/components/theme-toggle.tsx +2 -2
  125. package/dist/assets/components/time-input.stories.tsx +16 -16
  126. package/dist/assets/components/time-input.tsx +2 -2
  127. package/dist/assets/components/toast.stories.tsx +8 -5
  128. package/dist/assets/components/toast.tsx +6 -6
  129. package/dist/assets/components/toggle-group.stories.tsx +153 -0
  130. package/dist/assets/components/toggle-group.tsx +61 -0
  131. package/dist/assets/components/toggle.stories.tsx +77 -0
  132. package/dist/assets/components/toggle.tsx +46 -0
  133. package/dist/assets/components/tooltip.stories.tsx +49 -27
  134. package/dist/assets/components/tooltip.tsx +23 -90
  135. package/dist/assets/components/user.stories.tsx +23 -23
  136. package/dist/assets/components/user.tsx +7 -4
  137. package/dist/assets/dev-tools/SonanceDevTools.tsx +4201 -0
  138. package/dist/assets/dev-tools/index.ts +10 -0
  139. package/dist/assets/globals.css +39 -0
  140. package/dist/assets/logos/40th-anniversary/Sonance_40_Logo_CMYK_BEAM_BLUE_40_AND_BEAM_DARK.png +0 -0
  141. package/dist/assets/logos/Sonance logo dark mode.png +0 -0
  142. package/dist/assets/logos/Sonance logo light mode.png +0 -0
  143. package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_2C_Light_RGB_05162025.png +0 -0
  144. package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_3C_Dark_RGB_05162025.png +0 -0
  145. package/dist/assets/logos/blaze/BlazeBySonance_Logo_Lockup_White_RGB_05162025.png +0 -0
  146. package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Dark_RGB.png +0 -0
  147. package/dist/assets/logos/iport/IPORT_Sonance_LockUp_2C_Light_RGB.png +0 -0
  148. package/dist/assets/logos/james/James_Logo_Black_CMYK.png +0 -0
  149. package/dist/assets/logos/james/James_Logo_Black_RGB.png +0 -0
  150. package/dist/assets/logos/james/James_Logo_LtGray_CMYK.png +0 -0
  151. package/dist/assets/logos/james/James_Logo_LtGray_RGB.png +0 -0
  152. package/dist/assets/logos/james/James_Logo_Polished_RGB.png +0 -0
  153. package/dist/assets/logos/james/James_Logo_Reverse_CMYK.png +0 -0
  154. package/dist/assets/logos/james/James_Logo_Reverse_RGB.png +0 -0
  155. package/dist/assets/logos/james/James_Logo_White_CMYK.png +0 -0
  156. package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Dark_RGB.png +0 -0
  157. package/dist/assets/logos/life-is-better/Sonance_LifeisBetter_Light_RGB.png +0 -0
  158. package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Dark_RGB.png +0 -0
  159. package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Light_RGB.png +0 -0
  160. package/dist/assets/logos/my-sonance/My.Sonance_Logo_2C_Reverse_RGB.png +0 -0
  161. package/dist/assets/logos/my-sonance/My.Sonance_Logo_Black_RGB.png +0 -0
  162. package/dist/assets/logos/my-sonance/My.Sonance_Logo_Reverse_RGB.png +0 -0
  163. package/dist/assets/logos/sonance/Sonance_Logo_2C_Dark_RGB.png +0 -0
  164. package/dist/assets/logos/sonance/Sonance_Logo_2C_Light_RGB.png +0 -0
  165. package/dist/assets/logos/sonance/Sonance_Logo_2C_Reverse_RGB.png +0 -0
  166. package/dist/assets/logos/sonance/Sonance_Logo_Black_RGB.png +0 -0
  167. package/dist/assets/logos/sonance/Sonance_Logo_Grayscale_RGB.png +0 -0
  168. package/dist/assets/logos/sonance/Sonance_Logo_Reverse_RGB.png +0 -0
  169. package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Dark_CMYK.png +0 -0
  170. package/dist/assets/logos/sonance-academy/SonanceAcademy_Logo_Light_CMYK.png +0 -0
  171. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Dark_RGB.png +0 -0
  172. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Light_RGB.png +0 -0
  173. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_3C_Reverse_RGB.png +0 -0
  174. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Black_RGB.png +0 -0
  175. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Grayscale_RGB.png +0 -0
  176. package/dist/assets/logos/sonance-iport/Sonance_IPORT_LockUp_Reverse_RGB.png +0 -0
  177. package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Dark.png +0 -0
  178. package/dist/assets/logos/sonance-james/Sonance_James_Lockup_Light.png +0 -0
  179. package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Dark.png +0 -0
  180. package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_LockupStacked_Light.png +0 -0
  181. package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Dark.png +0 -0
  182. package/dist/assets/logos/sonance-james-iport/Sonance_James_IPORT_Lockup_Light.png +0 -0
  183. package/dist/assets/logos/trufig/TrufigLogo_Black.png +0 -0
  184. package/dist/assets/logos/trufig/TrufigLogo_Light.png +0 -0
  185. package/dist/assets/logos/trufig/TrufigWatermark_Black.png +0 -0
  186. package/dist/assets/logos/trufig/TrufigWatermark_Light.png +0 -0
  187. package/dist/assets/styles/brand-overrides.css +37 -0
  188. package/dist/index.js +2055 -15
  189. 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
- {...props}
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">&#10003;</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&apos;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
  }