sonance-brand-mcp 1.3.109 → 1.3.111

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 (34) hide show
  1. package/dist/assets/api/sonance-ai-edit/route.ts +30 -7
  2. package/dist/assets/api/sonance-vision-apply/route.ts +33 -8
  3. package/dist/assets/api/sonance-vision-edit/route.ts +33 -8
  4. package/dist/assets/components/alert.tsx +35 -9
  5. package/dist/assets/components/badge.tsx +49 -20
  6. package/dist/assets/components/button.tsx +29 -20
  7. package/dist/assets/components/card.tsx +87 -33
  8. package/dist/assets/components/checkbox.tsx +36 -12
  9. package/dist/assets/components/dialog.tsx +73 -30
  10. package/dist/assets/components/dropdown-menu.tsx +57 -20
  11. package/dist/assets/components/input.tsx +35 -14
  12. package/dist/assets/components/pagination.tsx +86 -35
  13. package/dist/assets/components/popover.tsx +80 -36
  14. package/dist/assets/components/radio-group.tsx +40 -12
  15. package/dist/assets/components/select.tsx +62 -26
  16. package/dist/assets/components/switch.tsx +41 -13
  17. package/dist/assets/components/tabs.tsx +32 -12
  18. package/dist/assets/components/tooltip.tsx +34 -5
  19. package/dist/assets/dev-tools/SonanceDevTools.tsx +441 -365
  20. package/dist/assets/dev-tools/components/ChatHistory.tsx +141 -0
  21. package/dist/assets/dev-tools/components/ChatInterface.tsx +402 -294
  22. package/dist/assets/dev-tools/components/ChatTabBar.tsx +82 -0
  23. package/dist/assets/dev-tools/components/InlineDiffPreview.tsx +204 -0
  24. package/dist/assets/dev-tools/components/InspectorOverlay.tsx +12 -9
  25. package/dist/assets/dev-tools/components/PropertiesPanel.tsx +695 -0
  26. package/dist/assets/dev-tools/components/VisionModeBorder.tsx +16 -7
  27. package/dist/assets/dev-tools/constants.ts +38 -6
  28. package/dist/assets/dev-tools/hooks/useComputedStyles.ts +365 -0
  29. package/dist/assets/dev-tools/index.ts +3 -0
  30. package/dist/assets/dev-tools/panels/AnalysisPanel.tsx +32 -32
  31. package/dist/assets/dev-tools/panels/ComponentsPanel.tsx +277 -127
  32. package/dist/assets/dev-tools/types.ts +51 -2
  33. package/dist/index.js +22 -3
  34. package/package.json +2 -1
@@ -1,9 +1,33 @@
1
+ import { cva, type VariantProps } from "class-variance-authority";
1
2
  import { cn } from "@/lib/utils";
2
3
  import { forwardRef } from "react";
3
4
 
4
5
  export type InputState = "default" | "hover" | "focus" | "error" | "disabled";
5
6
 
6
- interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
7
+ const inputVariants = cva(
8
+ "w-full border border-input-border bg-input text-foreground placeholder:text-input-placeholder transition-all duration-200 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-secondary",
9
+ {
10
+ variants: {
11
+ size: {
12
+ xs: "h-7 px-2.5 text-xs rounded-md",
13
+ sm: "h-8 px-3 text-sm rounded-lg",
14
+ md: "h-9 px-3.5 text-sm rounded-lg",
15
+ lg: "h-10 px-4 text-sm rounded-xl",
16
+ },
17
+ inputVariant: {
18
+ default: "hover:border-border-hover focus:border-input-focus focus:ring-2 focus:ring-primary/10",
19
+ glass: "bg-input/80 backdrop-blur-sm hover:border-border-hover focus:border-input-focus focus:ring-2 focus:ring-primary/20",
20
+ },
21
+ },
22
+ defaultVariants: {
23
+ size: "sm",
24
+ inputVariant: "default",
25
+ },
26
+ }
27
+ );
28
+
29
+ interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">,
30
+ VariantProps<typeof inputVariants> {
7
31
  label?: string;
8
32
  error?: string;
9
33
  /** Visual state for Storybook/Figma documentation */
@@ -17,9 +41,9 @@ const getStateStyles = (state?: InputState) => {
17
41
  if (!state || state === "default") return "";
18
42
 
19
43
  const stateMap: Record<string, string> = {
20
- hover: "border-border-hover bg-input",
21
- focus: "border-input-focus",
22
- error: "border-error",
44
+ hover: "border-border-hover",
45
+ focus: "border-input-focus ring-2 ring-primary/10",
46
+ error: "border-error ring-2 ring-error/10",
23
47
  disabled: "opacity-50 cursor-not-allowed bg-secondary",
24
48
  };
25
49
 
@@ -27,14 +51,14 @@ const getStateStyles = (state?: InputState) => {
27
51
  };
28
52
 
29
53
  export const Input = forwardRef<HTMLInputElement, InputProps>(
30
- ({ className, label, error, state, disabled, style, wrapperStyle, ...props }, ref) => {
54
+ ({ className, label, error, state, disabled, style, wrapperStyle, size, inputVariant, ...props }, ref) => {
31
55
  const isDisabled = disabled || state === "disabled";
32
56
  const hasError = error || state === "error";
33
57
 
34
58
  return (
35
59
  <div data-sonance-name="input" className="w-full" style={wrapperStyle}>
36
60
  {label && (
37
- <label className="mb-2 block text-xs font-medium uppercase tracking-widest text-foreground-muted">
61
+ <label className="mb-1.5 block text-[11px] font-medium uppercase tracking-wide text-foreground-muted">
38
62
  {label}
39
63
  </label>
40
64
  )}
@@ -43,19 +67,14 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
43
67
  disabled={isDisabled}
44
68
  style={style}
45
69
  className={cn(
46
- "w-full border border-input-border bg-input px-4 py-3",
47
- "text-foreground placeholder:text-input-placeholder",
48
- "transition-colors duration-200",
49
- "hover:border-border-hover",
50
- "focus:border-input-focus focus:outline-none",
51
- "disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-secondary",
52
- hasError && "border-error",
70
+ inputVariants({ size, inputVariant }),
71
+ hasError && "border-error ring-2 ring-error/10",
53
72
  getStateStyles(state),
54
73
  className
55
74
  )} data-sonance-name="input"
56
75
  {...props}
57
76
  />
58
- {error && <p id="input-p-error" className="mt-1 text-sm text-error">{error}</p>}
77
+ {error && <p id="input-p-error" className="mt-1 text-xs text-error">{error}</p>}
59
78
  </div>
60
79
  );
61
80
  }
@@ -63,3 +82,5 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
63
82
 
64
83
  Input.displayName = "Input";
65
84
 
85
+ export { inputVariants };
86
+
@@ -1,18 +1,36 @@
1
1
  "use client";
2
2
 
3
- import { forwardRef } from "react";
3
+ import { forwardRef, createContext, useContext, useMemo } from "react";
4
4
  import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
5
+ import { cva, type VariantProps } from "class-variance-authority";
5
6
  import { cn } from "@/lib/utils";
6
7
 
7
8
  export type PaginationButtonState = "default" | "hover" | "focus" | "active" | "disabled";
8
9
 
10
+ const paginationButtonVariants = cva(
11
+ "flex items-center justify-center font-medium border transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:ring-offset-2",
12
+ {
13
+ variants: {
14
+ size: {
15
+ xs: "h-6 min-w-6 px-1.5 text-[10px] rounded-md",
16
+ sm: "h-7 min-w-7 px-2 text-xs rounded-lg",
17
+ md: "h-8 min-w-8 px-2.5 text-sm rounded-lg",
18
+ lg: "h-9 min-w-9 px-3 text-sm rounded-xl",
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ size: "sm",
23
+ },
24
+ }
25
+ );
26
+
9
27
  // State styles for Storybook/Figma visualization
10
28
  const getButtonStateStyles = (state?: PaginationButtonState) => {
11
29
  if (!state || state === "default") return "";
12
30
 
13
31
  const stateMap: Record<string, string> = {
14
32
  hover: "bg-secondary-hover",
15
- focus: "ring-2 ring-border-focus ring-offset-2",
33
+ focus: "ring-2 ring-primary/20 ring-offset-2",
16
34
  active: "bg-primary text-primary-foreground border-primary",
17
35
  disabled: "opacity-50 cursor-not-allowed",
18
36
  };
@@ -20,6 +38,22 @@ const getButtonStateStyles = (state?: PaginationButtonState) => {
20
38
  return stateMap[state] || "";
21
39
  };
22
40
 
41
+ const PaginationSizeContext = createContext<"xs" | "sm" | "md" | "lg">("sm");
42
+
43
+ const ellipsisSizes = {
44
+ xs: "h-6 w-6 text-[10px]",
45
+ sm: "h-7 w-7 text-xs",
46
+ md: "h-8 w-8 text-sm",
47
+ lg: "h-9 w-9 text-sm",
48
+ };
49
+
50
+ const iconSizes = {
51
+ xs: "h-3 w-3",
52
+ sm: "h-3.5 w-3.5",
53
+ md: "h-4 w-4",
54
+ lg: "h-4 w-4",
55
+ };
56
+
23
57
  interface PaginationProps {
24
58
  currentPage: number;
25
59
  totalPages: number;
@@ -27,6 +61,8 @@ interface PaginationProps {
27
61
  siblingCount?: number;
28
62
  showFirstLast?: boolean;
29
63
  className?: string;
64
+ /** Size variant for pagination buttons */
65
+ size?: "xs" | "sm" | "md" | "lg";
30
66
  }
31
67
 
32
68
  function generatePaginationRange(
@@ -76,6 +112,7 @@ export function Pagination({
76
112
  siblingCount = 1,
77
113
  showFirstLast = true,
78
114
  className,
115
+ size = "sm",
79
116
  }: PaginationProps) {
80
117
  const pages = generatePaginationRange(currentPage, totalPages, siblingCount);
81
118
 
@@ -83,18 +120,19 @@ export function Pagination({
83
120
  const canGoNext = currentPage < totalPages;
84
121
 
85
122
  return (
86
- <nav data-sonance-name="pagination"
87
- role="navigation"
88
- aria-label="Pagination"
89
- className={cn("flex items-center gap-1", className)}
90
- >
123
+ <PaginationSizeContext.Provider value={size}>
124
+ <nav data-sonance-name="pagination"
125
+ role="navigation"
126
+ aria-label="Pagination"
127
+ className={cn("flex items-center gap-1", className)}
128
+ >
91
129
  {/* Previous button */}
92
130
  <PaginationButton
93
131
  onClick={() => canGoPrevious && onPageChange(currentPage - 1)}
94
132
  disabled={!canGoPrevious}
95
133
  aria-label="Go to previous page"
96
134
  >
97
- <ChevronLeft className="h-4 w-4" />
135
+ <ChevronLeft className={iconSizes[size]} />
98
136
  </PaginationButton>
99
137
 
100
138
  {/* Page numbers */}
@@ -103,9 +141,9 @@ export function Pagination({
103
141
  return (
104
142
  <span id="pagination-span" data-sonance-name="pagination"
105
143
  key={`ellipsis-${index}`}
106
- className="flex h-9 w-9 items-center justify-center text-foreground-muted"
144
+ className={cn("flex items-center justify-center text-foreground-muted", ellipsisSizes[size])}
107
145
  >
108
- <MoreHorizontal className="h-4 w-4" />
146
+ <MoreHorizontal className={iconSizes[size]} />
109
147
  </span>
110
148
  );
111
149
  }
@@ -129,9 +167,10 @@ export function Pagination({
129
167
  disabled={!canGoNext}
130
168
  aria-label="Go to next page"
131
169
  >
132
- <ChevronRight className="h-4 w-4" />
170
+ <ChevronRight className={iconSizes[size]} />
133
171
  </PaginationButton>
134
- </nav>
172
+ </nav>
173
+ </PaginationSizeContext.Provider>
135
174
  );
136
175
  }
137
176
 
@@ -143,6 +182,7 @@ interface PaginationButtonProps extends React.ButtonHTMLAttributes<HTMLButtonEle
143
182
 
144
183
  const PaginationButton = forwardRef<HTMLButtonElement, PaginationButtonProps>(
145
184
  ({ className, active, disabled, state, children, ...props }, ref) => {
185
+ const size = useContext(PaginationSizeContext);
146
186
  const isActive = active || state === "active";
147
187
  const isDisabled = disabled || state === "disabled";
148
188
 
@@ -152,9 +192,7 @@ const PaginationButton = forwardRef<HTMLButtonElement, PaginationButtonProps>(
152
192
  type="button"
153
193
  disabled={isDisabled}
154
194
  className={cn(
155
- "flex h-9 min-w-9 items-center justify-center px-3 text-sm font-medium",
156
- "border transition-colors",
157
- "focus:outline-none focus:ring-2 focus:ring-border-focus focus:ring-offset-2",
195
+ paginationButtonVariants({ size }),
158
196
  isActive
159
197
  ? "bg-primary text-primary-foreground border-primary"
160
198
  : isDisabled
@@ -179,37 +217,50 @@ interface CompactPaginationProps {
179
217
  totalPages: number;
180
218
  onPageChange: (page: number) => void;
181
219
  className?: string;
220
+ /** Size variant for compact pagination */
221
+ size?: "xs" | "sm" | "md" | "lg";
182
222
  }
183
223
 
224
+ const compactTextSizes = {
225
+ xs: "text-[10px]",
226
+ sm: "text-xs",
227
+ md: "text-sm",
228
+ lg: "text-sm",
229
+ };
230
+
184
231
  export function CompactPagination({
185
232
  currentPage,
186
233
  totalPages,
187
234
  onPageChange,
188
235
  className,
236
+ size = "sm",
189
237
  }: CompactPaginationProps) {
190
238
  return (
191
- <div className={cn("flex items-center gap-4", className)}>
192
- <PaginationButton
193
- onClick={() => currentPage > 1 && onPageChange(currentPage - 1)}
194
- disabled={currentPage <= 1}
195
- aria-label="Go to previous page"
196
- >
197
- <ChevronLeft className="h-4 w-4" />
198
- </PaginationButton>
239
+ <PaginationSizeContext.Provider value={size}>
240
+ <div className={cn("flex items-center gap-3", className)}>
241
+ <PaginationButton
242
+ onClick={() => currentPage > 1 && onPageChange(currentPage - 1)}
243
+ disabled={currentPage <= 1}
244
+ aria-label="Go to previous page"
245
+ >
246
+ <ChevronLeft className={iconSizes[size]} />
247
+ </PaginationButton>
199
248
 
200
- <span id="compact-pagination-span" className="text-sm text-foreground-secondary">
201
- Page <span id="compact-pagination-span-currentpage" className="font-medium text-foreground">{currentPage}</span> of{" "}
202
- <span id="compact-pagination-span-totalpages" className="font-medium text-foreground">{totalPages}</span>
203
- </span>
249
+ <span id="compact-pagination-span" className={cn("text-foreground-secondary", compactTextSizes[size])}>
250
+ Page <span id="compact-pagination-span-currentpage" className="font-medium text-foreground">{currentPage}</span> of{" "}
251
+ <span id="compact-pagination-span-totalpages" className="font-medium text-foreground">{totalPages}</span>
252
+ </span>
204
253
 
205
- <PaginationButton
206
- onClick={() => currentPage < totalPages && onPageChange(currentPage + 1)}
207
- disabled={currentPage >= totalPages}
208
- aria-label="Go to next page"
209
- >
210
- <ChevronRight className="h-4 w-4" />
211
- </PaginationButton>
212
- </div>
254
+ <PaginationButton
255
+ onClick={() => currentPage < totalPages && onPageChange(currentPage + 1)}
256
+ disabled={currentPage >= totalPages}
257
+ aria-label="Go to next page"
258
+ >
259
+ <ChevronRight className={iconSizes[size]} />
260
+ </PaginationButton>
261
+ </div>
262
+ </PaginationSizeContext.Provider>
213
263
  );
214
264
  }
215
265
 
266
+ export { paginationButtonVariants };
@@ -1,12 +1,44 @@
1
1
  "use client";
2
2
 
3
- import { useState, useRef, useEffect, useCallback } from "react";
3
+ import { useState, useRef, useEffect, useCallback, createContext, useContext } from "react";
4
4
  import { createPortal } from "react-dom";
5
+ import { cva, type VariantProps } from "class-variance-authority";
5
6
  import { cn } from "@/lib/utils";
6
7
 
7
8
  type PopoverPosition = "top" | "bottom" | "left" | "right";
8
-
9
- interface PopoverProps {
9
+ type PopoverSize = "compact" | "default" | "spacious";
10
+ type PopoverVariant = "default" | "glass";
11
+
12
+ const PopoverContext = createContext<{ size: PopoverSize }>({ size: "default" });
13
+
14
+ const popoverVariants = cva(
15
+ "fixed z-50 min-w-[200px] border shadow-xl animate-in fade-in zoom-in-95 duration-150",
16
+ {
17
+ variants: {
18
+ size: {
19
+ compact: "rounded-lg",
20
+ default: "rounded-xl",
21
+ spacious: "rounded-2xl",
22
+ },
23
+ popoverVariant: {
24
+ default: "bg-card border-border",
25
+ glass: "bg-card/95 border-border/50 backdrop-blur-xl",
26
+ },
27
+ },
28
+ defaultVariants: {
29
+ size: "default",
30
+ popoverVariant: "glass",
31
+ },
32
+ }
33
+ );
34
+
35
+ const popoverContentPadding = {
36
+ compact: "p-3",
37
+ default: "p-4",
38
+ spacious: "p-5",
39
+ };
40
+
41
+ interface PopoverProps extends VariantProps<typeof popoverVariants> {
10
42
  trigger: React.ReactNode;
11
43
  children: React.ReactNode;
12
44
  position?: PopoverPosition;
@@ -25,6 +57,8 @@ export function Popover({
25
57
  position = "bottom",
26
58
  triggerOn = "click",
27
59
  className,
60
+ size = "default",
61
+ popoverVariant = "glass",
28
62
  }: PopoverProps) {
29
63
  const [isOpen, setIsOpen] = useState(false);
30
64
  const [portalPosition, setPortalPosition] = useState<PortalPosition>({ top: 0, left: 0 });
@@ -144,41 +178,42 @@ export function Popover({
144
178
  };
145
179
 
146
180
  return (
147
- <div data-sonance-name="popover"
148
- ref={containerRef}
149
- className="relative inline-block"
150
- onMouseEnter={handleMouseEnter}
151
- onMouseLeave={handleMouseLeave}
152
- >
153
- <div
154
- ref={triggerRef}
155
- onClick={triggerOn === "click" ? () => setIsOpen(!isOpen) : undefined}
156
- className="cursor-pointer"
181
+ <PopoverContext.Provider value={{ size }}>
182
+ <div data-sonance-name="popover"
183
+ ref={containerRef}
184
+ className="relative inline-block"
185
+ onMouseEnter={handleMouseEnter}
186
+ onMouseLeave={handleMouseLeave}
157
187
  >
158
- {trigger}
159
- </div>
160
- {mounted && isOpen && createPortal(
161
188
  <div
162
- ref={popoverRef}
163
- className={cn(
164
- "fixed z-50 min-w-[200px] bg-card border border-border shadow-lg",
165
- "animate-in fade-in zoom-in-95 duration-150",
166
- position === "left" || position === "right" ? "-translate-y-1/2" : "",
167
- className
168
- )}
169
- style={{
170
- top: portalPosition.top,
171
- left: portalPosition.left,
172
- transformOrigin: transformOrigin[position],
173
- }}
174
- onMouseEnter={handleMouseEnter}
175
- onMouseLeave={handleMouseLeave}
189
+ ref={triggerRef}
190
+ onClick={triggerOn === "click" ? () => setIsOpen(!isOpen) : undefined}
191
+ className="cursor-pointer"
176
192
  >
177
- {children}
178
- </div>,
179
- document.body
180
- )}
181
- </div>
193
+ {trigger}
194
+ </div>
195
+ {mounted && isOpen && createPortal(
196
+ <div
197
+ ref={popoverRef}
198
+ className={cn(
199
+ popoverVariants({ size, popoverVariant }),
200
+ position === "left" || position === "right" ? "-translate-y-1/2" : "",
201
+ className
202
+ )}
203
+ style={{
204
+ top: portalPosition.top,
205
+ left: portalPosition.left,
206
+ transformOrigin: transformOrigin[position],
207
+ }}
208
+ onMouseEnter={handleMouseEnter}
209
+ onMouseLeave={handleMouseLeave}
210
+ >
211
+ {children}
212
+ </div>,
213
+ document.body
214
+ )}
215
+ </div>
216
+ </PopoverContext.Provider>
182
217
  );
183
218
  }
184
219
 
@@ -189,6 +224,15 @@ export function PopoverContent({
189
224
  className?: string;
190
225
  children: React.ReactNode;
191
226
  }) {
192
- return <div data-sonance-name="popover" className={cn("p-4", className)}>{children}</div>;
227
+ const { size } = useContext(PopoverContext);
228
+ return (
229
+ <div
230
+ data-sonance-name="popover"
231
+ className={cn(popoverContentPadding[size], className)}
232
+ >
233
+ {children}
234
+ </div>
235
+ );
193
236
  }
194
237
 
238
+ export { popoverVariants };
@@ -1,17 +1,42 @@
1
1
  "use client";
2
2
 
3
3
  import { forwardRef, createContext, useContext, useState, useId } from "react";
4
+ import { cva, type VariantProps } from "class-variance-authority";
4
5
  import { cn } from "@/lib/utils";
5
6
 
6
7
  export type RadioGroupItemState = "default" | "hover" | "focus" | "checked" | "disabled";
7
8
 
9
+ const radioItemVariants = cva(
10
+ "peer shrink-0 appearance-none rounded-full border border-border bg-input transition-all duration-150 hover:border-border-hover checked:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20 focus:ring-offset-2 focus:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",
11
+ {
12
+ variants: {
13
+ size: {
14
+ xs: "h-3.5 w-3.5",
15
+ sm: "h-4 w-4",
16
+ md: "h-5 w-5",
17
+ lg: "h-6 w-6",
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ size: "sm",
22
+ },
23
+ }
24
+ );
25
+
26
+ const radioIndicatorSizes = {
27
+ xs: "h-1.5 w-1.5",
28
+ sm: "h-2 w-2",
29
+ md: "h-2.5 w-2.5",
30
+ lg: "h-3 w-3",
31
+ };
32
+
8
33
  // State styles for Storybook/Figma visualization
9
34
  const getStateStyles = (state?: RadioGroupItemState) => {
10
35
  if (!state || state === "default") return "";
11
36
 
12
37
  const stateMap: Record<string, string> = {
13
38
  hover: "border-border-hover",
14
- focus: "ring-2 ring-border-focus ring-offset-2 ring-offset-background",
39
+ focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
15
40
  checked: "border-primary",
16
41
  disabled: "opacity-50 cursor-not-allowed",
17
42
  };
@@ -23,6 +48,7 @@ interface RadioGroupContextValue {
23
48
  value: string;
24
49
  onChange: (value: string) => void;
25
50
  name: string;
51
+ size: "xs" | "sm" | "md" | "lg";
26
52
  }
27
53
 
28
54
  const RadioGroupContext = createContext<RadioGroupContextValue | null>(null);
@@ -35,6 +61,8 @@ interface RadioGroupProps {
35
61
  className?: string;
36
62
  children: React.ReactNode;
37
63
  orientation?: "horizontal" | "vertical";
64
+ /** Size variant for radio items */
65
+ size?: "xs" | "sm" | "md" | "lg";
38
66
  }
39
67
 
40
68
  export function RadioGroup({
@@ -45,6 +73,7 @@ export function RadioGroup({
45
73
  className,
46
74
  children,
47
75
  orientation = "vertical",
76
+ size = "sm",
48
77
  }: RadioGroupProps) {
49
78
  const [internalValue, setInternalValue] = useState(defaultValue);
50
79
  const value = controlledValue ?? internalValue;
@@ -57,12 +86,12 @@ export function RadioGroup({
57
86
  };
58
87
 
59
88
  return (
60
- <RadioGroupContext.Provider value={{ value, onChange, name: groupName }}>
89
+ <RadioGroupContext.Provider value={{ value, onChange, name: groupName, size }}>
61
90
  <div
62
91
  role="radiogroup"
63
92
  className={cn(
64
93
  "flex",
65
- orientation === "vertical" ? "flex-col gap-3" : "flex-row gap-6",
94
+ orientation === "vertical" ? "flex-col gap-2.5" : "flex-row gap-5",
66
95
  className
67
96
  )}
68
97
  >
@@ -87,13 +116,13 @@ export const RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(
87
116
  throw new Error("RadioGroupItem must be used within a RadioGroup");
88
117
  }
89
118
 
90
- const { value: groupValue, onChange, name } = context;
119
+ const { value: groupValue, onChange, name, size } = context;
91
120
  const inputId = id || `radio-${value}`;
92
121
  const isChecked = groupValue === value || state === "checked";
93
122
  const isDisabled = disabled || state === "disabled";
94
123
 
95
124
  return (
96
- <div data-sonance-name="radio-group" className="flex items-start gap-3">
125
+ <div data-sonance-name="radio-group" className="flex items-start gap-2.5">
97
126
  <div className="relative flex items-center justify-center">
98
127
  <input
99
128
  type="radio"
@@ -105,11 +134,7 @@ export const RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(
105
134
  onChange={() => onChange(value)}
106
135
  disabled={isDisabled}
107
136
  className={cn(
108
- "peer h-5 w-5 shrink-0 appearance-none rounded-full border border-border bg-input",
109
- "checked:border-primary",
110
- "focus:outline-none focus:ring-2 focus:ring-border-focus focus:ring-offset-2 focus:ring-offset-background",
111
- "disabled:cursor-not-allowed disabled:opacity-50",
112
- "transition-colors duration-150",
137
+ radioItemVariants({ size }),
113
138
  getStateStyles(state),
114
139
  className
115
140
  )}
@@ -117,8 +142,9 @@ export const RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(
117
142
  />
118
143
  <div data-sonance-name="radio-group"
119
144
  className={cn(
120
- "pointer-events-none absolute h-2.5 w-2.5 rounded-full bg-primary",
121
- "scale-0 transition-transform duration-150",
145
+ "pointer-events-none absolute rounded-full bg-primary",
146
+ "scale-0 transition-all duration-150",
147
+ radioIndicatorSizes[size],
122
148
  isChecked && "scale-100"
123
149
  )}
124
150
  />
@@ -145,3 +171,5 @@ export const RadioGroupItem = forwardRef<HTMLInputElement, RadioGroupItemProps>(
145
171
 
146
172
  RadioGroupItem.displayName = "RadioGroupItem";
147
173
 
174
+ export { radioItemVariants };
175
+