sonance-brand-mcp 1.3.1 → 1.3.3

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 (136) 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 +7 -7
  11. package/dist/assets/components/alert-dialog.tsx +2 -1
  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 +4 -1
  15. package/dist/assets/components/autocomplete.stories.tsx +9 -9
  16. package/dist/assets/components/autocomplete.tsx +3 -3
  17. package/dist/assets/components/avatar.stories.tsx +5 -5
  18. package/dist/assets/components/avatar.tsx +4 -4
  19. package/dist/assets/components/badge.stories.tsx +10 -10
  20. package/dist/assets/components/badge.tsx +3 -3
  21. package/dist/assets/components/breadcrumbs.stories.tsx +7 -7
  22. package/dist/assets/components/breadcrumbs.tsx +13 -8
  23. package/dist/assets/components/button.stories.tsx +74 -74
  24. package/dist/assets/components/button.tsx +2 -0
  25. package/dist/assets/components/calendar.stories.tsx +11 -11
  26. package/dist/assets/components/calendar.tsx +4 -4
  27. package/dist/assets/components/card.stories.tsx +22 -22
  28. package/dist/assets/components/card.tsx +7 -3
  29. package/dist/assets/components/carousel.stories.tsx +6 -6
  30. package/dist/assets/components/carousel.tsx +10 -8
  31. package/dist/assets/components/chart.tsx +5 -5
  32. package/dist/assets/components/checkbox-group.stories.tsx +6 -6
  33. package/dist/assets/components/checkbox-group.tsx +3 -3
  34. package/dist/assets/components/checkbox.stories.tsx +23 -20
  35. package/dist/assets/components/checkbox.tsx +13 -16
  36. package/dist/assets/components/code.stories.tsx +24 -24
  37. package/dist/assets/components/code.tsx +7 -14
  38. package/dist/assets/components/collapsible.stories.tsx +3 -3
  39. package/dist/assets/components/command.stories.tsx +14 -14
  40. package/dist/assets/components/command.tsx +4 -3
  41. package/dist/assets/components/context-menu.stories.tsx +1 -1
  42. package/dist/assets/components/context-menu.tsx +3 -7
  43. package/dist/assets/components/date-input.stories.tsx +9 -9
  44. package/dist/assets/components/date-input.tsx +2 -2
  45. package/dist/assets/components/date-picker.stories.tsx +9 -9
  46. package/dist/assets/components/date-picker.tsx +3 -3
  47. package/dist/assets/components/date-range-picker.stories.tsx +12 -12
  48. package/dist/assets/components/date-range-picker.tsx +3 -3
  49. package/dist/assets/components/dialog.stories.tsx +40 -40
  50. package/dist/assets/components/dialog.tsx +8 -12
  51. package/dist/assets/components/divider.stories.tsx +30 -30
  52. package/dist/assets/components/divider.tsx +4 -8
  53. package/dist/assets/components/drawer.stories.tsx +32 -31
  54. package/dist/assets/components/drawer.tsx +7 -6
  55. package/dist/assets/components/dropdown-menu.tsx +3 -7
  56. package/dist/assets/components/dropdown.stories.tsx +12 -12
  57. package/dist/assets/components/dropdown.tsx +5 -5
  58. package/dist/assets/components/form.stories.tsx +30 -29
  59. package/dist/assets/components/form.tsx +5 -5
  60. package/dist/assets/components/hover-card.stories.tsx +12 -10
  61. package/dist/assets/components/hover-card.tsx +1 -1
  62. package/dist/assets/components/image.stories.tsx +48 -25
  63. package/dist/assets/components/image.tsx +8 -5
  64. package/dist/assets/components/input-otp.stories.tsx +15 -15
  65. package/dist/assets/components/input-otp.tsx +5 -5
  66. package/dist/assets/components/input.stories.tsx +30 -25
  67. package/dist/assets/components/input.tsx +7 -4
  68. package/dist/assets/components/kbd.stories.tsx +34 -34
  69. package/dist/assets/components/kbd.tsx +5 -5
  70. package/dist/assets/components/link.stories.tsx +36 -36
  71. package/dist/assets/components/link.tsx +4 -0
  72. package/dist/assets/components/listbox.stories.tsx +5 -5
  73. package/dist/assets/components/listbox.tsx +4 -4
  74. package/dist/assets/components/menubar.tsx +3 -7
  75. package/dist/assets/components/navbar.stories.tsx +24 -24
  76. package/dist/assets/components/navbar.tsx +8 -14
  77. package/dist/assets/components/navigation-menu.stories.tsx +11 -9
  78. package/dist/assets/components/navigation-menu.tsx +1 -1
  79. package/dist/assets/components/number-input.stories.tsx +11 -11
  80. package/dist/assets/components/number-input.tsx +3 -3
  81. package/dist/assets/components/pagination.stories.tsx +13 -13
  82. package/dist/assets/components/pagination.tsx +6 -6
  83. package/dist/assets/components/popover.stories.tsx +35 -35
  84. package/dist/assets/components/popover.tsx +98 -15
  85. package/dist/assets/components/progress.stories.tsx +5 -5
  86. package/dist/assets/components/progress.tsx +5 -5
  87. package/dist/assets/components/radio-group.stories.tsx +7 -7
  88. package/dist/assets/components/radio-group.tsx +3 -3
  89. package/dist/assets/components/range-calendar.stories.tsx +18 -18
  90. package/dist/assets/components/range-calendar.tsx +3 -3
  91. package/dist/assets/components/resizable.stories.tsx +23 -23
  92. package/dist/assets/components/resizable.tsx +1 -1
  93. package/dist/assets/components/scroll-area.stories.tsx +15 -15
  94. package/dist/assets/components/scroll-area.tsx +1 -1
  95. package/dist/assets/components/scroll-shadow.stories.tsx +17 -17
  96. package/dist/assets/components/scroll-shadow.tsx +2 -2
  97. package/dist/assets/components/select.stories.tsx +20 -19
  98. package/dist/assets/components/select.tsx +10 -6
  99. package/dist/assets/components/separator.tsx +1 -1
  100. package/dist/assets/components/sheet.tsx +3 -7
  101. package/dist/assets/components/sidebar.stories.tsx +30 -30
  102. package/dist/assets/components/sidebar.tsx +24 -27
  103. package/dist/assets/components/skeleton.stories.tsx +3 -3
  104. package/dist/assets/components/skeleton.tsx +2 -2
  105. package/dist/assets/components/slider.stories.tsx +6 -6
  106. package/dist/assets/components/slider.tsx +3 -3
  107. package/dist/assets/components/spacer.stories.tsx +11 -11
  108. package/dist/assets/components/spacer.tsx +2 -2
  109. package/dist/assets/components/spinner.stories.tsx +8 -8
  110. package/dist/assets/components/spinner.tsx +5 -5
  111. package/dist/assets/components/switch.stories.tsx +24 -20
  112. package/dist/assets/components/switch.tsx +14 -6
  113. package/dist/assets/components/table.stories.tsx +7 -7
  114. package/dist/assets/components/table.tsx +8 -8
  115. package/dist/assets/components/tabs.stories.tsx +37 -37
  116. package/dist/assets/components/tabs.tsx +3 -3
  117. package/dist/assets/components/textarea.stories.tsx +13 -12
  118. package/dist/assets/components/textarea.tsx +3 -3
  119. package/dist/assets/components/theme-toggle.stories.tsx +31 -30
  120. package/dist/assets/components/theme-toggle.tsx +2 -2
  121. package/dist/assets/components/time-input.stories.tsx +16 -16
  122. package/dist/assets/components/time-input.tsx +2 -2
  123. package/dist/assets/components/toast.stories.tsx +8 -5
  124. package/dist/assets/components/toast.tsx +6 -6
  125. package/dist/assets/components/toggle-group.tsx +1 -1
  126. package/dist/assets/components/toggle.tsx +1 -1
  127. package/dist/assets/components/tooltip.stories.tsx +49 -27
  128. package/dist/assets/components/tooltip.tsx +1 -1
  129. package/dist/assets/components/user.stories.tsx +23 -23
  130. package/dist/assets/components/user.tsx +7 -4
  131. package/dist/assets/dev-tools/SonanceDevTools.tsx +4201 -0
  132. package/dist/assets/dev-tools/index.ts +10 -0
  133. package/dist/assets/globals.css +9 -0
  134. package/dist/assets/styles/brand-overrides.css +37 -0
  135. package/dist/index.js +1882 -7
  136. package/package.json +1 -1
@@ -45,7 +45,7 @@ export const Default: Story = {
45
45
  <CardDescription>Card description goes here</CardDescription>
46
46
  </CardHeader>
47
47
  <CardContent>
48
- <p className="text-foreground-secondary">
48
+ <p id="default-p-this-is-the-card-con" className="text-foreground-secondary">
49
49
  This is the card content area where you can place any content.
50
50
  </p>
51
51
  </CardContent>
@@ -62,7 +62,7 @@ export const Elevated: Story = {
62
62
  <CardDescription>With shadow effect</CardDescription>
63
63
  </CardHeader>
64
64
  <CardContent>
65
- <p className="text-foreground-secondary">
65
+ <p id="elevated-p-elevated-cards-have-" className="text-foreground-secondary">
66
66
  Elevated cards have a shadow that increases on hover.
67
67
  </p>
68
68
  </CardContent>
@@ -79,13 +79,13 @@ export const WithFooter: Story = {
79
79
  <CardDescription>Includes action buttons in footer</CardDescription>
80
80
  </CardHeader>
81
81
  <CardContent>
82
- <p className="text-foreground-secondary">
82
+ <p id="with-footer-p-cards-can-include-a-" className="text-foreground-secondary">
83
83
  Cards can include a footer section for actions.
84
84
  </p>
85
85
  </CardContent>
86
86
  <CardFooter className="gap-2">
87
- <Button variant="primary" size="sm">Save</Button>
88
- <Button variant="secondary" size="sm">Cancel</Button>
87
+ <Button id="with-footer-button-primary" variant="primary" size="sm">Save</Button>
88
+ <Button id="with-footer-button-secondary" variant="secondary" size="sm">Cancel</Button>
89
89
  </CardFooter>
90
90
  </Card>
91
91
  ),
@@ -96,17 +96,17 @@ export const ProductCard: Story = {
96
96
  render: () => (
97
97
  <Card className="w-72 overflow-hidden">
98
98
  <div className="aspect-square bg-background-secondary flex items-center justify-center">
99
- <span className="text-foreground-muted">Product Image</span>
99
+ <span id="product-card-span-product-image" className="text-foreground-muted">Product Image</span>
100
100
  </div>
101
101
  <CardHeader>
102
102
  <CardTitle>Sonance Speaker</CardTitle>
103
103
  <CardDescription>Premium in-wall speaker</CardDescription>
104
104
  </CardHeader>
105
105
  <CardContent>
106
- <p className="text-2xl font-light text-foreground">$1,299.00</p>
106
+ <p id="product-card-p-129900" className="text-2xl font-light text-foreground">$1,299.00</p>
107
107
  </CardContent>
108
108
  <CardFooter>
109
- <Button className="w-full">Add to Cart</Button>
109
+ <Button id="product-card-button" className="w-full">Add to Cart</Button>
110
110
  </CardFooter>
111
111
  </Card>
112
112
  ),
@@ -123,7 +123,7 @@ export const GridLayout: Story = {
123
123
  <CardDescription>Feature description</CardDescription>
124
124
  </CardHeader>
125
125
  <CardContent>
126
- <p className="text-foreground-secondary text-sm">
126
+ <p id="grid-layout-p-brief-explanation-of" className="text-foreground-secondary text-sm">
127
127
  Brief explanation of this feature and its benefits.
128
128
  </p>
129
129
  </CardContent>
@@ -143,7 +143,7 @@ export const VariantsComparison: Story = {
143
143
  <CardDescription>Subtle border, hover effect</CardDescription>
144
144
  </CardHeader>
145
145
  <CardContent>
146
- <p className="text-foreground-secondary text-sm">
146
+ <p id="variants-comparison-p-best-for-content-lis" className="text-foreground-secondary text-sm">
147
147
  Best for content lists and grids.
148
148
  </p>
149
149
  </CardContent>
@@ -154,7 +154,7 @@ export const VariantsComparison: Story = {
154
154
  <CardDescription>Shadow with hover enhancement</CardDescription>
155
155
  </CardHeader>
156
156
  <CardContent>
157
- <p className="text-foreground-secondary text-sm">
157
+ <p id="variants-comparison-p-best-for-featured-or" className="text-foreground-secondary text-sm">
158
158
  Best for featured or important content.
159
159
  </p>
160
160
  </CardContent>
@@ -170,8 +170,8 @@ export const StateMatrix: Story = {
170
170
  const states: CardState[] = ['default', 'hover', 'focus'];
171
171
 
172
172
  return (
173
- <div className="space-y-8">
174
- <h3 className="text-sm font-medium text-foreground-muted">Card State Matrix</h3>
173
+ <div data-sonance-name="card.stories" className="space-y-8">
174
+ <h3 id="state-matrix-h3-card-state-matrix" className="text-sm font-medium text-foreground-muted">Card State Matrix</h3>
175
175
  <div className="grid grid-cols-4 gap-4">
176
176
  <div></div>
177
177
  {states.map((state) => (
@@ -190,7 +190,7 @@ export const StateMatrix: Story = {
190
190
  <CardDescription>{state} state</CardDescription>
191
191
  </CardHeader>
192
192
  <CardContent>
193
- <p className="text-foreground-secondary text-sm">
193
+ <p id="state-matrix-p-card-content-goes-he" className="text-foreground-secondary text-sm">
194
194
  Card content goes here.
195
195
  </p>
196
196
  </CardContent>
@@ -209,7 +209,7 @@ export const ResponsiveMatrix: Story = {
209
209
  <div className="space-y-8">
210
210
  {/* Mobile */}
211
211
  <div>
212
- <h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
212
+ <h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
213
213
  <div className="w-[375px] border border-dashed border-border p-4 space-y-4">
214
214
  <Card className="w-full">
215
215
  <CardHeader>
@@ -217,17 +217,17 @@ export const ResponsiveMatrix: Story = {
217
217
  <CardDescription>Card description</CardDescription>
218
218
  </CardHeader>
219
219
  <CardContent>
220
- <p className="text-foreground-secondary text-sm">Content that fills the mobile width.</p>
220
+ <p id="responsive-matrix-p-content-that-fills-t" className="text-foreground-secondary text-sm">Content that fills the mobile width.</p>
221
221
  </CardContent>
222
222
  <CardFooter>
223
- <Button className="w-full">Action</Button>
223
+ <Button id="responsive-matrix-button" className="w-full">Action</Button>
224
224
  </CardFooter>
225
225
  </Card>
226
226
  </div>
227
227
  </div>
228
228
  {/* Tablet */}
229
229
  <div>
230
- <h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
230
+ <h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
231
231
  <div className="w-[768px] border border-dashed border-border p-4">
232
232
  <div className="grid grid-cols-2 gap-4">
233
233
  <Card>
@@ -236,7 +236,7 @@ export const ResponsiveMatrix: Story = {
236
236
  <CardDescription>Description</CardDescription>
237
237
  </CardHeader>
238
238
  <CardContent>
239
- <p className="text-foreground-secondary text-sm">Card content for tablet view.</p>
239
+ <p id="responsive-matrix-p-card-content-for-tab" className="text-foreground-secondary text-sm">Card content for tablet view.</p>
240
240
  </CardContent>
241
241
  </Card>
242
242
  <Card>
@@ -245,7 +245,7 @@ export const ResponsiveMatrix: Story = {
245
245
  <CardDescription>Description</CardDescription>
246
246
  </CardHeader>
247
247
  <CardContent>
248
- <p className="text-foreground-secondary text-sm">Card content for tablet view.</p>
248
+ <p id="responsive-matrix-p-card-content-for-tab" className="text-foreground-secondary text-sm">Card content for tablet view.</p>
249
249
  </CardContent>
250
250
  </Card>
251
251
  </div>
@@ -253,7 +253,7 @@ export const ResponsiveMatrix: Story = {
253
253
  </div>
254
254
  {/* Desktop */}
255
255
  <div>
256
- <h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
256
+ <h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
257
257
  <div className="w-[1280px] border border-dashed border-border p-4">
258
258
  <div className="grid grid-cols-4 gap-4">
259
259
  {[1, 2, 3, 4].map((i) => (
@@ -263,7 +263,7 @@ export const ResponsiveMatrix: Story = {
263
263
  <CardDescription>Feature description</CardDescription>
264
264
  </CardHeader>
265
265
  <CardContent>
266
- <p className="text-foreground-secondary text-sm">Card content at desktop width.</p>
266
+ <p id="responsive-matrix-p-card-content-at-desk" className="text-foreground-secondary text-sm">Card content at desktop width.</p>
267
267
  </CardContent>
268
268
  </Card>
269
269
  ))}
@@ -33,6 +33,7 @@ export const Card = forwardRef<HTMLDivElement, CardProps>(
33
33
  ({ className, variant = "default", state, ...props }, ref) => {
34
34
  return (
35
35
  <div
36
+ data-sonance-name="card"
36
37
  ref={ref}
37
38
  className={cn(
38
39
  "bg-card border border-card-border transition-all duration-200",
@@ -53,7 +54,7 @@ export const CardHeader = forwardRef<
53
54
  HTMLDivElement,
54
55
  React.HTMLAttributes<HTMLDivElement>
55
56
  >(({ className, ...props }, ref) => (
56
- <div ref={ref} className={cn("p-6", className)} {...props} />
57
+ <div ref={ref} className={cn("p-6", className)} data-sonance-name="card" {...props} />
57
58
  ));
58
59
 
59
60
  CardHeader.displayName = "CardHeader";
@@ -63,6 +64,7 @@ export const CardTitle = forwardRef<
63
64
  React.HTMLAttributes<HTMLHeadingElement>
64
65
  >(({ className, ...props }, ref) => (
65
66
  <h3
67
+ id="card-title-h3"
66
68
  ref={ref}
67
69
  className={cn("text-lg font-medium text-foreground", className)}
68
70
  {...props}
@@ -76,8 +78,10 @@ export const CardDescription = forwardRef<
76
78
  React.HTMLAttributes<HTMLParagraphElement>
77
79
  >(({ className, ...props }, ref) => (
78
80
  <p
81
+ id="card-description-p"
79
82
  ref={ref}
80
83
  className={cn("mt-1 text-sm text-foreground-muted", className)}
84
+ data-sonance-name="card"
81
85
  {...props}
82
86
  />
83
87
  ));
@@ -88,7 +92,7 @@ export const CardContent = forwardRef<
88
92
  HTMLDivElement,
89
93
  React.HTMLAttributes<HTMLDivElement>
90
94
  >(({ className, ...props }, ref) => (
91
- <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
95
+ <div ref={ref} className={cn("p-6 pt-0", className)} data-sonance-name="card" {...props} />
92
96
  ));
93
97
 
94
98
  CardContent.displayName = "CardContent";
@@ -100,9 +104,9 @@ export const CardFooter = forwardRef<
100
104
  <div
101
105
  ref={ref}
102
106
  className={cn("flex items-center p-6 pt-0", className)}
107
+ data-sonance-name="card"
103
108
  {...props}
104
109
  />
105
110
  ));
106
111
 
107
112
  CardFooter.displayName = "CardFooter";
108
-
@@ -29,7 +29,7 @@ export const Default: Story = {
29
29
  <div className="p-1">
30
30
  <Card>
31
31
  <CardContent className="flex aspect-square items-center justify-center p-6">
32
- <span className="text-4xl font-medium">{index + 1}</span>
32
+ <span id="default-span-index-1" className="text-4xl font-medium">{index + 1}</span>
33
33
  </CardContent>
34
34
  </Card>
35
35
  </div>
@@ -56,7 +56,7 @@ export const Multiple: Story = {
56
56
  <div className="p-1">
57
57
  <Card>
58
58
  <CardContent className="flex aspect-square items-center justify-center p-6">
59
- <span className="text-3xl font-medium">{index + 1}</span>
59
+ <span id="multiple-span-index-1" className="text-3xl font-medium">{index + 1}</span>
60
60
  </CardContent>
61
61
  </Card>
62
62
  </div>
@@ -84,7 +84,7 @@ export const Vertical: Story = {
84
84
  <div className="p-1">
85
85
  <Card>
86
86
  <CardContent className="flex items-center justify-center p-6">
87
- <span className="text-3xl font-medium">{index + 1}</span>
87
+ <span id="vertical-span-index-1" className="text-3xl font-medium">{index + 1}</span>
88
88
  </CardContent>
89
89
  </Card>
90
90
  </div>
@@ -111,10 +111,10 @@ export const ProductGallery: Story = {
111
111
  <div className="p-1">
112
112
  <Card>
113
113
  <CardContent className="flex flex-col aspect-video items-center justify-center p-6 bg-secondary-hover">
114
- <span className="text-foreground-muted text-sm mb-2">
114
+ <span id="product-gallery-span-image-index-1" className="text-foreground-muted text-sm mb-2">
115
115
  Image {index + 1}
116
116
  </span>
117
- <span className="text-lg font-medium text-foreground">
117
+ <span id="product-gallery-span-product" className="text-lg font-medium text-foreground">
118
118
  {product}
119
119
  </span>
120
120
  </CardContent>
@@ -143,7 +143,7 @@ export const Autoplay: Story = {
143
143
  <div className="p-1">
144
144
  <Card>
145
145
  <CardContent className="flex aspect-square items-center justify-center p-6">
146
- <span className="text-4xl font-medium">{index + 1}</span>
146
+ <span id="autoplay-span-index-1" className="text-4xl font-medium">{index + 1}</span>
147
147
  </CardContent>
148
148
  </Card>
149
149
  </div>
@@ -138,7 +138,7 @@ const Carousel = React.forwardRef<
138
138
  onKeyDownCapture={handleKeyDown}
139
139
  className={cn("relative", className)}
140
140
  role="region"
141
- aria-roledescription="carousel"
141
+ aria-roledescription="carousel" data-sonance-name="carousel"
142
142
  {...props}
143
143
  >
144
144
  {children}
@@ -156,14 +156,14 @@ const CarouselContent = React.forwardRef<
156
156
  const { carouselRef, orientation } = useCarousel();
157
157
 
158
158
  return (
159
- <div ref={carouselRef} className="overflow-hidden">
159
+ <div data-sonance-name="carousel" ref={carouselRef} className="overflow-hidden">
160
160
  <div
161
161
  ref={ref}
162
162
  className={cn(
163
163
  "flex",
164
164
  orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
165
165
  className
166
- )}
166
+ )} data-sonance-name="carousel"
167
167
  {...props}
168
168
  />
169
169
  </div>
@@ -186,7 +186,7 @@ const CarouselItem = React.forwardRef<
186
186
  "min-w-0 shrink-0 grow-0 basis-full",
187
187
  orientation === "horizontal" ? "pl-4" : "pt-4",
188
188
  className
189
- )}
189
+ )} data-sonance-name="carousel"
190
190
  {...props}
191
191
  />
192
192
  );
@@ -201,6 +201,7 @@ const CarouselPrevious = React.forwardRef<
201
201
 
202
202
  return (
203
203
  <Button
204
+ id="carousel-previous-button-secondary"
204
205
  ref={ref}
205
206
  variant="secondary"
206
207
  size="sm"
@@ -212,11 +213,11 @@ const CarouselPrevious = React.forwardRef<
212
213
  className
213
214
  )}
214
215
  disabled={!canScrollPrev}
215
- onClick={scrollPrev}
216
+ onClick={scrollPrev} data-sonance-name="carousel"
216
217
  {...props}
217
218
  >
218
219
  <ArrowLeft className="h-4 w-4" />
219
- <span className="sr-only">Previous slide</span>
220
+ <span id="carousel-previous-span-previous-slide" className="sr-only">Previous slide</span>
220
221
  </Button>
221
222
  );
222
223
  });
@@ -230,6 +231,7 @@ const CarouselNext = React.forwardRef<
230
231
 
231
232
  return (
232
233
  <Button
234
+ id="carousel-next-button-secondary"
233
235
  ref={ref}
234
236
  variant="secondary"
235
237
  size="sm"
@@ -241,11 +243,11 @@ const CarouselNext = React.forwardRef<
241
243
  className
242
244
  )}
243
245
  disabled={!canScrollNext}
244
- onClick={scrollNext}
246
+ onClick={scrollNext} data-sonance-name="carousel"
245
247
  {...props}
246
248
  >
247
249
  <ArrowRight className="h-4 w-4" />
248
- <span className="sr-only">Next slide</span>
250
+ <span id="carousel-next-span-next-slide" className="sr-only">Next slide</span>
249
251
  </Button>
250
252
  );
251
253
  });
@@ -53,7 +53,7 @@ const ChartContainer = React.forwardRef<
53
53
  className={cn(
54
54
  "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-foreground-muted [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-secondary-hover [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-secondary-hover [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
55
55
  className
56
- )}
56
+ )} data-sonance-name="chart"
57
57
  {...props}
58
58
  >
59
59
  <ChartStyle id={chartId} config={config} />
@@ -76,7 +76,7 @@ const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
76
76
  }
77
77
 
78
78
  return (
79
- <style
79
+ <style data-sonance-name="chart"
80
80
  dangerouslySetInnerHTML={{
81
81
  __html: Object.entries(THEMES)
82
82
  .map(
@@ -165,7 +165,7 @@ const ChartTooltipContent = React.forwardRef<HTMLDivElement, ChartTooltipContent
165
165
 
166
166
  if (labelFormatter) {
167
167
  return (
168
- <div className={cn("font-medium", labelClassName)}>
168
+ <div data-sonance-name="chart" className={cn("font-medium", labelClassName)}>
169
169
  {labelFormatter(value, payload)}
170
170
  </div>
171
171
  );
@@ -251,12 +251,12 @@ const ChartTooltipContent = React.forwardRef<HTMLDivElement, ChartTooltipContent
251
251
  >
252
252
  <div className="grid gap-1.5">
253
253
  {nestLabel ? tooltipLabel : null}
254
- <span className="text-foreground-muted">
254
+ <span id="span-itemconfiglabel-item" className="text-foreground-muted">
255
255
  {itemConfig?.label || item.name}
256
256
  </span>
257
257
  </div>
258
258
  {item.value && (
259
- <span className="font-mono font-medium tabular-nums text-foreground">
259
+ <span id="span-typeof-itemvalue-num" className="font-mono font-medium tabular-nums text-foreground">
260
260
  {typeof item.value === 'number' ? item.value.toLocaleString() : item.value}
261
261
  </span>
262
262
  )}
@@ -45,7 +45,7 @@ export const Default: Story = {
45
45
  render: () => {
46
46
  const [values, setValues] = useState<string[]>([]);
47
47
  return (
48
- <CheckboxGroup value={values} onValueChange={setValues}>
48
+ <CheckboxGroup data-sonance-name="checkbox-group.stories" value={values} onValueChange={setValues}>
49
49
  <CheckboxGroupItem value="option1" label="Option 1" />
50
50
  <CheckboxGroupItem value="option2" label="Option 2" />
51
51
  <CheckboxGroupItem value="option3" label="Option 3" />
@@ -224,8 +224,8 @@ export const FormExample: Story = {
224
224
  </CheckboxGroup>
225
225
 
226
226
  <div className="text-sm text-foreground-muted">
227
- <p>Interests: {interests.join(', ') || 'None selected'}</p>
228
- <p>Agreements: {agreements.join(', ') || 'None selected'}</p>
227
+ <p id="form-example-p-interests-interestsj">Interests: {interests.join(', ') || 'None selected'}</p>
228
+ <p id="form-example-p-agreements-agreement">Agreements: {agreements.join(', ') || 'None selected'}</p>
229
229
  </div>
230
230
  </div>
231
231
  );
@@ -238,7 +238,7 @@ export const ResponsiveMatrix: Story = {
238
238
  <div className="space-y-8">
239
239
  {/* Mobile */}
240
240
  <div>
241
- <h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
241
+ <h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
242
242
  <div className="w-[375px] border border-dashed border-border p-4">
243
243
  <CheckboxGroup label="Select Options" defaultValue={['option1']}>
244
244
  <CheckboxGroupItem value="option1" label="Option 1" />
@@ -249,7 +249,7 @@ export const ResponsiveMatrix: Story = {
249
249
  </div>
250
250
  {/* Tablet */}
251
251
  <div>
252
- <h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
252
+ <h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
253
253
  <div className="w-[768px] border border-dashed border-border p-4">
254
254
  <CheckboxGroup label="Select Sizes" orientation="horizontal" defaultValue={['medium']}>
255
255
  <CheckboxGroupItem value="small" label="Small" />
@@ -261,7 +261,7 @@ export const ResponsiveMatrix: Story = {
261
261
  </div>
262
262
  {/* Desktop */}
263
263
  <div>
264
- <h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
264
+ <h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
265
265
  <div className="w-[1280px] border border-dashed border-border p-4">
266
266
  <div className="grid grid-cols-2 gap-8">
267
267
  <CheckboxGroup label="Features" defaultValue={['basic']}>
@@ -79,7 +79,7 @@ export function CheckboxGroup({
79
79
  >
80
80
  {children}
81
81
  </div>
82
- {error && <p className="mt-2 text-sm text-error">{error}</p>}
82
+ {error && <p id="checkbox-group-p-error" className="mt-2 text-sm text-error">{error}</p>}
83
83
  </div>
84
84
  </CheckboxGroupContext.Provider>
85
85
  );
@@ -109,7 +109,7 @@ export function CheckboxGroupItem({
109
109
  };
110
110
 
111
111
  return (
112
- <Checkbox
112
+ <Checkbox id="checkbox-group-item-checkbox-checkboxgroup" data-sonance-name="checkbox-group"
113
113
  checked={isChecked}
114
114
  onChange={handleChange}
115
115
  disabled={isDisabled}
@@ -145,7 +145,7 @@ export function CheckboxList({
145
145
  className,
146
146
  }: CheckboxListProps) {
147
147
  return (
148
- <CheckboxGroup
148
+ <CheckboxGroup data-sonance-name="checkbox-group"
149
149
  value={value}
150
150
  defaultValue={defaultValue}
151
151
  onValueChange={onValueChange}
@@ -84,11 +84,11 @@ export const DisabledChecked: Story = {
84
84
  export const AllStates: Story = {
85
85
  render: () => (
86
86
  <div className="space-y-4">
87
- <Checkbox label="Unchecked" />
88
- <Checkbox label="Checked" defaultChecked />
89
- <Checkbox label="With description" description="Additional information about this option" />
90
- <Checkbox label="Disabled" disabled />
91
- <Checkbox label="Disabled checked" disabled defaultChecked />
87
+ <Checkbox id="all-states-checkbox" label="Unchecked" />
88
+ <Checkbox id="all-states-checkbox" label="Checked" defaultChecked />
89
+ <Checkbox id="all-states-checkbox" label="With description" description="Additional information about this option" />
90
+ <Checkbox id="all-states-checkbox" label="Disabled" disabled />
91
+ <Checkbox id="all-states-checkbox" label="Disabled checked" disabled defaultChecked />
92
92
  </div>
93
93
  ),
94
94
  };
@@ -98,17 +98,20 @@ export const FormExample: Story = {
98
98
  render: () => (
99
99
  <div className="space-y-6 w-80">
100
100
  <div className="space-y-4">
101
- <h3 className="text-sm font-medium text-foreground">Notification Preferences</h3>
101
+ <h3 id="form-example-h3-notification-prefere" className="text-sm font-medium text-foreground">Notification Preferences</h3>
102
102
  <Checkbox
103
+ id="form-example-checkbox"
103
104
  label="Email notifications"
104
105
  description="Get notified about account activity via email"
105
106
  defaultChecked
106
107
  />
107
108
  <Checkbox
109
+ id="form-example-checkbox"
108
110
  label="SMS notifications"
109
111
  description="Get notified via text message"
110
112
  />
111
113
  <Checkbox
114
+ id="form-example-checkbox"
112
115
  label="Push notifications"
113
116
  description="Get notified on your mobile device"
114
117
  defaultChecked
@@ -124,34 +127,34 @@ export const ResponsiveMatrix: Story = {
124
127
  <div className="space-y-8">
125
128
  {/* Mobile */}
126
129
  <div>
127
- <h4 className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
130
+ <h4 id="responsive-matrix-h4-mobile-375px" className="text-xs uppercase text-foreground-muted mb-2">Mobile (375px)</h4>
128
131
  <div className="w-[375px] border border-dashed border-border p-4 space-y-4">
129
- <Checkbox label="Accept terms and conditions" />
130
- <Checkbox label="Subscribe to newsletter" description="Receive updates about new features" />
131
- <Checkbox label="Remember me" defaultChecked />
132
+ <Checkbox id="responsive-matrix-checkbox" label="Accept terms and conditions" />
133
+ <Checkbox id="responsive-matrix-checkbox" label="Subscribe to newsletter" description="Receive updates about new features" />
134
+ <Checkbox id="responsive-matrix-checkbox" label="Remember me" defaultChecked />
132
135
  </div>
133
136
  </div>
134
137
  {/* Tablet */}
135
138
  <div>
136
- <h4 className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
139
+ <h4 id="responsive-matrix-h4-tablet-768px" className="text-xs uppercase text-foreground-muted mb-2">Tablet (768px)</h4>
137
140
  <div className="w-[768px] border border-dashed border-border p-4">
138
141
  <div className="grid grid-cols-2 gap-4">
139
- <Checkbox label="Email notifications" description="Get notified via email" defaultChecked />
140
- <Checkbox label="SMS notifications" description="Get notified via text" />
141
- <Checkbox label="Push notifications" description="Mobile app notifications" defaultChecked />
142
- <Checkbox label="Marketing emails" description="Product updates and offers" />
142
+ <Checkbox id="responsive-matrix-checkbox" label="Email notifications" description="Get notified via email" defaultChecked />
143
+ <Checkbox id="responsive-matrix-checkbox" label="SMS notifications" description="Get notified via text" />
144
+ <Checkbox id="responsive-matrix-checkbox" label="Push notifications" description="Mobile app notifications" defaultChecked />
145
+ <Checkbox id="responsive-matrix-checkbox" label="Marketing emails" description="Product updates and offers" />
143
146
  </div>
144
147
  </div>
145
148
  </div>
146
149
  {/* Desktop */}
147
150
  <div>
148
- <h4 className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
151
+ <h4 id="responsive-matrix-h4-desktop-1280px" className="text-xs uppercase text-foreground-muted mb-2">Desktop (1280px)</h4>
149
152
  <div className="w-[1280px] border border-dashed border-border p-4">
150
153
  <div className="grid grid-cols-4 gap-4">
151
- <Checkbox label="Unchecked" />
152
- <Checkbox label="Checked" defaultChecked />
153
- <Checkbox label="Disabled" disabled />
154
- <Checkbox label="Disabled checked" disabled defaultChecked />
154
+ <Checkbox id="responsive-matrix-checkbox" label="Unchecked" />
155
+ <Checkbox id="responsive-matrix-checkbox" label="Checked" defaultChecked />
156
+ <Checkbox id="responsive-matrix-checkbox" label="Disabled" disabled />
157
+ <Checkbox id="responsive-matrix-checkbox" label="Disabled checked" disabled defaultChecked />
155
158
  </div>
156
159
  </div>
157
160
  </div>
@@ -28,31 +28,28 @@ const getStateStyles = (state?: CheckboxState) => {
28
28
  };
29
29
 
30
30
  export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
31
- ({ className, label, description, id, state, disabled, checked, ...props }, ref) => {
31
+ ({ className, label, description, id, state, disabled, checked, defaultChecked, onChange, style, ...props }, ref) => {
32
32
  const uniqueId = useId();
33
33
  const inputId = id || `checkbox-${uniqueId}`;
34
34
  const isDisabled = disabled || state === "disabled";
35
-
36
- // Resolve checked state:
37
- // 1. If visual state is "checked", force true.
38
- // 2. Else use provided checked prop (undefined = uncontrolled).
39
- const isVisualChecked = state === "checked";
40
- const resolvedChecked = isVisualChecked ? true : checked;
41
-
42
- // If visual state forces checked but no handler, mark readOnly to avoid React warnings
43
- const isReadOnly = isVisualChecked && !props.onChange && !props.readOnly;
35
+
36
+ // Determine if we're in controlled mode
37
+ const isControlled = checked !== undefined || onChange !== undefined;
38
+ const isCheckedForState = state === "checked";
44
39
 
45
40
  return (
46
- <div className="flex items-start gap-3">
41
+ <div data-sonance-name="checkbox" className="flex items-start gap-3">
47
42
  <div className="relative flex items-center justify-center">
48
43
  <input
49
- key={isVisualChecked ? "visual-checked" : "normal"}
50
44
  type="checkbox"
51
45
  id={inputId}
52
46
  ref={ref}
53
47
  disabled={isDisabled}
54
- checked={resolvedChecked}
55
- readOnly={isReadOnly || props.readOnly}
48
+ style={style}
49
+ {...(isControlled
50
+ ? { checked: checked || isCheckedForState, onChange }
51
+ : { defaultChecked: defaultChecked || isCheckedForState }
52
+ )}
56
53
  className={cn(
57
54
  "peer h-5 w-5 shrink-0 appearance-none border border-border bg-input",
58
55
  "hover:border-border-hover",
@@ -62,7 +59,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
62
59
  "transition-colors duration-150",
63
60
  getStateStyles(state),
64
61
  className
65
- )}
62
+ )} data-sonance-name="checkbox"
66
63
  {...props}
67
64
  />
68
65
  <Check
@@ -83,7 +80,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
83
80
  </label>
84
81
  )}
85
82
  {description && (
86
- <p className="text-xs text-foreground-muted">{description}</p>
83
+ <p id="p-description" className="text-xs text-foreground-muted">{description}</p>
87
84
  )}
88
85
  </div>
89
86
  )}