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.
- package/dist/assets/api/sonance-ai-edit/route.ts +30 -7
- package/dist/assets/api/sonance-vision-apply/route.ts +33 -8
- package/dist/assets/api/sonance-vision-edit/route.ts +33 -8
- package/dist/assets/components/alert.tsx +35 -9
- package/dist/assets/components/badge.tsx +49 -20
- package/dist/assets/components/button.tsx +29 -20
- package/dist/assets/components/card.tsx +87 -33
- package/dist/assets/components/checkbox.tsx +36 -12
- package/dist/assets/components/dialog.tsx +73 -30
- package/dist/assets/components/dropdown-menu.tsx +57 -20
- package/dist/assets/components/input.tsx +35 -14
- package/dist/assets/components/pagination.tsx +86 -35
- package/dist/assets/components/popover.tsx +80 -36
- package/dist/assets/components/radio-group.tsx +40 -12
- package/dist/assets/components/select.tsx +62 -26
- package/dist/assets/components/switch.tsx +41 -13
- package/dist/assets/components/tabs.tsx +32 -12
- package/dist/assets/components/tooltip.tsx +34 -5
- package/dist/assets/dev-tools/SonanceDevTools.tsx +441 -365
- package/dist/assets/dev-tools/components/ChatHistory.tsx +141 -0
- package/dist/assets/dev-tools/components/ChatInterface.tsx +402 -294
- package/dist/assets/dev-tools/components/ChatTabBar.tsx +82 -0
- package/dist/assets/dev-tools/components/InlineDiffPreview.tsx +204 -0
- package/dist/assets/dev-tools/components/InspectorOverlay.tsx +12 -9
- package/dist/assets/dev-tools/components/PropertiesPanel.tsx +695 -0
- package/dist/assets/dev-tools/components/VisionModeBorder.tsx +16 -7
- package/dist/assets/dev-tools/constants.ts +38 -6
- package/dist/assets/dev-tools/hooks/useComputedStyles.ts +365 -0
- package/dist/assets/dev-tools/index.ts +3 -0
- package/dist/assets/dev-tools/panels/AnalysisPanel.tsx +32 -32
- package/dist/assets/dev-tools/panels/ComponentsPanel.tsx +277 -127
- package/dist/assets/dev-tools/types.ts +51 -2
- package/dist/index.js +22 -3
- package/package.json +2 -1
|
@@ -1,49 +1,90 @@
|
|
|
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 CardState = "default" | "hover" | "focus";
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
const cardVariants = cva(
|
|
8
|
+
"bg-card border border-card-border transition-all duration-200",
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: "hover:border-border-hover hover:bg-card-hover",
|
|
13
|
+
elevated: "shadow-md hover:shadow-lg",
|
|
14
|
+
glass: "bg-card/80 backdrop-blur-sm border-white/10 hover:bg-card/90",
|
|
15
|
+
},
|
|
16
|
+
size: {
|
|
17
|
+
compact: "rounded-lg",
|
|
18
|
+
default: "rounded-xl",
|
|
19
|
+
spacious: "rounded-2xl",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
variant: "default",
|
|
24
|
+
size: "default",
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const cardPaddingSizes = {
|
|
30
|
+
compact: "p-3",
|
|
31
|
+
default: "p-4",
|
|
32
|
+
spacious: "p-6",
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
interface CardProps extends React.HTMLAttributes<HTMLDivElement>,
|
|
36
|
+
VariantProps<typeof cardVariants> {
|
|
8
37
|
/** Visual state for Storybook/Figma documentation */
|
|
9
38
|
state?: CardState;
|
|
10
39
|
}
|
|
11
40
|
|
|
12
41
|
// State styles for Storybook/Figma visualization
|
|
13
|
-
const getStateStyles = (variant: string, state?: CardState) => {
|
|
42
|
+
const getStateStyles = (variant: string | null | undefined, state?: CardState) => {
|
|
14
43
|
if (!state || state === "default") return "";
|
|
15
44
|
|
|
16
45
|
if (variant === "elevated") {
|
|
17
46
|
const stateMap: Record<string, string> = {
|
|
18
47
|
hover: "shadow-lg",
|
|
19
|
-
focus: "ring-2 ring-
|
|
48
|
+
focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
|
|
49
|
+
};
|
|
50
|
+
return stateMap[state] || "";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (variant === "glass") {
|
|
54
|
+
const stateMap: Record<string, string> = {
|
|
55
|
+
hover: "bg-card/90",
|
|
56
|
+
focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
|
|
20
57
|
};
|
|
21
58
|
return stateMap[state] || "";
|
|
22
59
|
}
|
|
23
60
|
|
|
24
61
|
const stateMap: Record<string, string> = {
|
|
25
62
|
hover: "border-border-hover bg-card-hover",
|
|
26
|
-
focus: "ring-2 ring-
|
|
63
|
+
focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
|
|
27
64
|
};
|
|
28
65
|
|
|
29
66
|
return stateMap[state] || "";
|
|
30
67
|
};
|
|
31
68
|
|
|
69
|
+
// Create a context for passing size to children
|
|
70
|
+
import { createContext, useContext } from "react";
|
|
71
|
+
const CardSizeContext = createContext<"compact" | "default" | "spacious">("default");
|
|
72
|
+
|
|
32
73
|
export const Card = forwardRef<HTMLDivElement, CardProps>(
|
|
33
|
-
({ className, variant = "default", state, ...props }, ref) => {
|
|
74
|
+
({ className, variant, size = "default", state, ...props }, ref) => {
|
|
34
75
|
return (
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
76
|
+
<CardSizeContext.Provider value={size || "default"}>
|
|
77
|
+
<div
|
|
78
|
+
data-sonance-name="card"
|
|
79
|
+
ref={ref}
|
|
80
|
+
className={cn(
|
|
81
|
+
cardVariants({ variant, size }),
|
|
82
|
+
getStateStyles(variant, state),
|
|
83
|
+
className
|
|
84
|
+
)}
|
|
85
|
+
{...props}
|
|
86
|
+
/>
|
|
87
|
+
</CardSizeContext.Provider>
|
|
47
88
|
);
|
|
48
89
|
}
|
|
49
90
|
);
|
|
@@ -53,9 +94,12 @@ Card.displayName = "Card";
|
|
|
53
94
|
export const CardHeader = forwardRef<
|
|
54
95
|
HTMLDivElement,
|
|
55
96
|
React.HTMLAttributes<HTMLDivElement>
|
|
56
|
-
>(({ className, ...props }, ref) =>
|
|
57
|
-
|
|
58
|
-
|
|
97
|
+
>(({ className, ...props }, ref) => {
|
|
98
|
+
const size = useContext(CardSizeContext);
|
|
99
|
+
return (
|
|
100
|
+
<div ref={ref} className={cn(cardPaddingSizes[size], className)} data-sonance-name="card" {...props} />
|
|
101
|
+
);
|
|
102
|
+
});
|
|
59
103
|
|
|
60
104
|
CardHeader.displayName = "CardHeader";
|
|
61
105
|
|
|
@@ -66,7 +110,7 @@ export const CardTitle = forwardRef<
|
|
|
66
110
|
<h3
|
|
67
111
|
id="card-title-h3"
|
|
68
112
|
ref={ref}
|
|
69
|
-
className={cn("text-
|
|
113
|
+
className={cn("text-base font-medium text-foreground", className)}
|
|
70
114
|
{...props}
|
|
71
115
|
/>
|
|
72
116
|
));
|
|
@@ -91,22 +135,32 @@ CardDescription.displayName = "CardDescription";
|
|
|
91
135
|
export const CardContent = forwardRef<
|
|
92
136
|
HTMLDivElement,
|
|
93
137
|
React.HTMLAttributes<HTMLDivElement>
|
|
94
|
-
>(({ className, ...props }, ref) =>
|
|
95
|
-
|
|
96
|
-
|
|
138
|
+
>(({ className, ...props }, ref) => {
|
|
139
|
+
const size = useContext(CardSizeContext);
|
|
140
|
+
const paddingClass = size === "compact" ? "px-3 pb-3" : size === "spacious" ? "px-6 pb-6" : "px-4 pb-4";
|
|
141
|
+
return (
|
|
142
|
+
<div ref={ref} className={cn(paddingClass, "pt-0", className)} data-sonance-name="card" {...props} />
|
|
143
|
+
);
|
|
144
|
+
});
|
|
97
145
|
|
|
98
146
|
CardContent.displayName = "CardContent";
|
|
99
147
|
|
|
100
148
|
export const CardFooter = forwardRef<
|
|
101
149
|
HTMLDivElement,
|
|
102
150
|
React.HTMLAttributes<HTMLDivElement>
|
|
103
|
-
>(({ className, ...props }, ref) =>
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
151
|
+
>(({ className, ...props }, ref) => {
|
|
152
|
+
const size = useContext(CardSizeContext);
|
|
153
|
+
const paddingClass = size === "compact" ? "px-3 pb-3" : size === "spacious" ? "px-6 pb-6" : "px-4 pb-4";
|
|
154
|
+
return (
|
|
155
|
+
<div
|
|
156
|
+
ref={ref}
|
|
157
|
+
className={cn("flex items-center pt-0", paddingClass, className)}
|
|
158
|
+
data-sonance-name="card"
|
|
159
|
+
{...props}
|
|
160
|
+
/>
|
|
161
|
+
);
|
|
162
|
+
});
|
|
111
163
|
|
|
112
164
|
CardFooter.displayName = "CardFooter";
|
|
165
|
+
|
|
166
|
+
export { cardVariants };
|
|
@@ -2,11 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
import { forwardRef, useId } from "react";
|
|
4
4
|
import { Check } 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 CheckboxState = "default" | "hover" | "focus" | "checked" | "disabled";
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
const checkboxVariants = cva(
|
|
11
|
+
"peer shrink-0 appearance-none border border-border bg-input transition-all duration-150 hover:border-border-hover checked:border-primary checked:bg-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",
|
|
12
|
+
{
|
|
13
|
+
variants: {
|
|
14
|
+
size: {
|
|
15
|
+
xs: "h-3.5 w-3.5 rounded",
|
|
16
|
+
sm: "h-4 w-4 rounded-md",
|
|
17
|
+
md: "h-5 w-5 rounded-md",
|
|
18
|
+
lg: "h-6 w-6 rounded-lg",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: {
|
|
22
|
+
size: "sm",
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const checkIconSizes = {
|
|
28
|
+
xs: "h-2.5 w-2.5",
|
|
29
|
+
sm: "h-3 w-3",
|
|
30
|
+
md: "h-3.5 w-3.5",
|
|
31
|
+
lg: "h-4 w-4",
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "size">,
|
|
35
|
+
VariantProps<typeof checkboxVariants> {
|
|
10
36
|
label?: string;
|
|
11
37
|
description?: string;
|
|
12
38
|
/** Visual state for Storybook/Figma documentation */
|
|
@@ -21,7 +47,7 @@ const getStateStyles = (state?: CheckboxState) => {
|
|
|
21
47
|
|
|
22
48
|
const stateMap: Record<string, string> = {
|
|
23
49
|
hover: "border-border-hover",
|
|
24
|
-
focus: "ring-2 ring-
|
|
50
|
+
focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
|
|
25
51
|
checked: "border-primary bg-primary",
|
|
26
52
|
disabled: "opacity-50 cursor-not-allowed",
|
|
27
53
|
};
|
|
@@ -30,7 +56,7 @@ const getStateStyles = (state?: CheckboxState) => {
|
|
|
30
56
|
};
|
|
31
57
|
|
|
32
58
|
export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
33
|
-
({ className, label, description, id, state, disabled, checked, defaultChecked, onChange, onCheckedChange, style, ...props }, ref) => {
|
|
59
|
+
({ className, label, description, id, state, disabled, checked, defaultChecked, onChange, onCheckedChange, style, size = "sm", ...props }, ref) => {
|
|
34
60
|
const uniqueId = useId();
|
|
35
61
|
const inputId = id || `checkbox-${uniqueId}`;
|
|
36
62
|
const isDisabled = disabled || state === "disabled";
|
|
@@ -46,7 +72,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
|
46
72
|
};
|
|
47
73
|
|
|
48
74
|
return (
|
|
49
|
-
<label data-sonance-name="checkbox" className="flex items-start gap-
|
|
75
|
+
<label data-sonance-name="checkbox" className="flex items-start gap-2.5 cursor-pointer">
|
|
50
76
|
<div className="relative flex items-center justify-center">
|
|
51
77
|
<input
|
|
52
78
|
type="checkbox"
|
|
@@ -61,12 +87,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
|
61
87
|
)}
|
|
62
88
|
readOnly={isControlled && !onChange && !onCheckedChange}
|
|
63
89
|
className={cn(
|
|
64
|
-
|
|
65
|
-
"hover:border-border-hover",
|
|
66
|
-
"checked:border-primary checked:bg-primary",
|
|
67
|
-
"focus:outline-none focus:ring-2 focus:ring-border-focus focus:ring-offset-2 focus:ring-offset-background",
|
|
68
|
-
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
69
|
-
"transition-colors duration-150",
|
|
90
|
+
checkboxVariants({ size }),
|
|
70
91
|
getStateStyles(state),
|
|
71
92
|
className
|
|
72
93
|
)}
|
|
@@ -74,8 +95,9 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
|
74
95
|
/>
|
|
75
96
|
<Check
|
|
76
97
|
className={cn(
|
|
77
|
-
"pointer-events-none absolute
|
|
78
|
-
|
|
98
|
+
"pointer-events-none absolute text-primary-foreground opacity-0 peer-checked:opacity-100 transition-all duration-150 peer-checked:scale-100 scale-75",
|
|
99
|
+
checkIconSizes[size || "sm"],
|
|
100
|
+
state === "checked" && "opacity-100 scale-100"
|
|
79
101
|
)}
|
|
80
102
|
/>
|
|
81
103
|
</div>
|
|
@@ -100,3 +122,5 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
|
100
122
|
|
|
101
123
|
Checkbox.displayName = "Checkbox";
|
|
102
124
|
|
|
125
|
+
export { checkboxVariants };
|
|
126
|
+
|
|
@@ -7,6 +7,7 @@ import { cn } from "@/lib/utils";
|
|
|
7
7
|
interface DialogContextValue {
|
|
8
8
|
open: boolean;
|
|
9
9
|
onClose: () => void;
|
|
10
|
+
size: "compact" | "default" | "spacious";
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
const DialogContext = createContext<DialogContextValue | null>(null);
|
|
@@ -15,9 +16,11 @@ interface DialogProps {
|
|
|
15
16
|
open: boolean;
|
|
16
17
|
onClose: () => void;
|
|
17
18
|
children: React.ReactNode;
|
|
19
|
+
/** Size variant for padding */
|
|
20
|
+
size?: "compact" | "default" | "spacious";
|
|
18
21
|
}
|
|
19
22
|
|
|
20
|
-
export function Dialog({ open, onClose, children }: DialogProps) {
|
|
23
|
+
export function Dialog({ open, onClose, children, size = "default" }: DialogProps) {
|
|
21
24
|
// Close on escape
|
|
22
25
|
useEffect(() => {
|
|
23
26
|
const handleEscape = (e: KeyboardEvent) => {
|
|
@@ -44,15 +47,15 @@ export function Dialog({ open, onClose, children }: DialogProps) {
|
|
|
44
47
|
if (!open) return null;
|
|
45
48
|
|
|
46
49
|
return (
|
|
47
|
-
<DialogContext.Provider value={{ open, onClose }}>
|
|
50
|
+
<DialogContext.Provider value={{ open, onClose, size }}>
|
|
48
51
|
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
|
49
|
-
{/* Backdrop */}
|
|
52
|
+
{/* Backdrop with blur */}
|
|
50
53
|
<div
|
|
51
|
-
className="absolute inset-0 bg-overlay animate-in fade-in duration-200"
|
|
54
|
+
className="absolute inset-0 bg-overlay/80 backdrop-blur-sm animate-in fade-in duration-200"
|
|
52
55
|
onClick={onClose}
|
|
53
56
|
/>
|
|
54
57
|
{/* Content */}
|
|
55
|
-
<div className="relative z-10 animate-in zoom-in-95 fade-in duration-200">
|
|
58
|
+
<div className="relative z-10 animate-in zoom-in-95 fade-in-0 duration-200">
|
|
56
59
|
{children}
|
|
57
60
|
</div>
|
|
58
61
|
</div>
|
|
@@ -60,6 +63,12 @@ export function Dialog({ open, onClose, children }: DialogProps) {
|
|
|
60
63
|
);
|
|
61
64
|
}
|
|
62
65
|
|
|
66
|
+
const dialogPaddingSizes = {
|
|
67
|
+
compact: { x: "px-4", y: "py-3" },
|
|
68
|
+
default: { x: "px-5", y: "py-4" },
|
|
69
|
+
spacious: { x: "px-6", y: "py-5" },
|
|
70
|
+
};
|
|
71
|
+
|
|
63
72
|
export const DialogContent = forwardRef<
|
|
64
73
|
HTMLDivElement,
|
|
65
74
|
React.HTMLAttributes<HTMLDivElement> & { showClose?: boolean }
|
|
@@ -67,15 +76,22 @@ export const DialogContent = forwardRef<
|
|
|
67
76
|
const context = useContext(DialogContext);
|
|
68
77
|
|
|
69
78
|
return (
|
|
70
|
-
<div
|
|
79
|
+
<div
|
|
80
|
+
data-sonance-name="dialog"
|
|
81
|
+
ref={ref}
|
|
82
|
+
className={cn(
|
|
83
|
+
"relative bg-card/95 backdrop-blur-xl border border-border rounded-2xl shadow-2xl",
|
|
84
|
+
"min-w-[320px] max-w-lg",
|
|
85
|
+
className
|
|
86
|
+
)}
|
|
71
87
|
{...props}
|
|
72
88
|
>
|
|
73
89
|
{showClose && context && (
|
|
74
90
|
<button
|
|
75
91
|
onClick={context.onClose}
|
|
76
|
-
className="absolute right-
|
|
92
|
+
className="absolute right-3 top-3 p-1.5 rounded-lg text-foreground-muted hover:text-foreground hover:bg-secondary-hover transition-all duration-150"
|
|
77
93
|
>
|
|
78
|
-
<X className="h-
|
|
94
|
+
<X className="h-4 w-4" />
|
|
79
95
|
<span id="dialog-content-span-close" className="sr-only">Close</span>
|
|
80
96
|
</button>
|
|
81
97
|
)}
|
|
@@ -89,13 +105,20 @@ DialogContent.displayName = "DialogContent";
|
|
|
89
105
|
export const DialogHeader = forwardRef<
|
|
90
106
|
HTMLDivElement,
|
|
91
107
|
React.HTMLAttributes<HTMLDivElement>
|
|
92
|
-
>(({ className, ...props }, ref) =>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
108
|
+
>(({ className, ...props }, ref) => {
|
|
109
|
+
const context = useContext(DialogContext);
|
|
110
|
+
const size = context?.size || "default";
|
|
111
|
+
const padding = dialogPaddingSizes[size];
|
|
112
|
+
|
|
113
|
+
return (
|
|
114
|
+
<div
|
|
115
|
+
ref={ref}
|
|
116
|
+
className={cn(padding.x, padding.y, "border-b border-border", className)}
|
|
117
|
+
data-sonance-name="dialog"
|
|
118
|
+
{...props}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
});
|
|
99
122
|
|
|
100
123
|
DialogHeader.displayName = "DialogHeader";
|
|
101
124
|
|
|
@@ -106,7 +129,7 @@ export const DialogTitle = forwardRef<
|
|
|
106
129
|
<h2
|
|
107
130
|
id="dialog-title-h2"
|
|
108
131
|
ref={ref}
|
|
109
|
-
className={cn("text-
|
|
132
|
+
className={cn("text-base font-medium text-foreground", className)}
|
|
110
133
|
{...props}
|
|
111
134
|
/>
|
|
112
135
|
));
|
|
@@ -120,7 +143,8 @@ export const DialogDescription = forwardRef<
|
|
|
120
143
|
<p
|
|
121
144
|
id="dialog-description-p"
|
|
122
145
|
ref={ref}
|
|
123
|
-
className={cn("mt-1 text-sm text-foreground-
|
|
146
|
+
className={cn("mt-1 text-sm text-foreground-muted", className)}
|
|
147
|
+
data-sonance-name="dialog"
|
|
124
148
|
{...props}
|
|
125
149
|
/>
|
|
126
150
|
));
|
|
@@ -130,25 +154,44 @@ DialogDescription.displayName = "DialogDescription";
|
|
|
130
154
|
export const DialogBody = forwardRef<
|
|
131
155
|
HTMLDivElement,
|
|
132
156
|
React.HTMLAttributes<HTMLDivElement>
|
|
133
|
-
>(({ className, ...props }, ref) =>
|
|
134
|
-
|
|
135
|
-
|
|
157
|
+
>(({ className, ...props }, ref) => {
|
|
158
|
+
const context = useContext(DialogContext);
|
|
159
|
+
const size = context?.size || "default";
|
|
160
|
+
const padding = dialogPaddingSizes[size];
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<div
|
|
164
|
+
ref={ref}
|
|
165
|
+
className={cn(padding.x, padding.y, className)}
|
|
166
|
+
data-sonance-name="dialog"
|
|
167
|
+
{...props}
|
|
168
|
+
/>
|
|
169
|
+
);
|
|
170
|
+
});
|
|
136
171
|
|
|
137
172
|
DialogBody.displayName = "DialogBody";
|
|
138
173
|
|
|
139
174
|
export const DialogFooter = forwardRef<
|
|
140
175
|
HTMLDivElement,
|
|
141
176
|
React.HTMLAttributes<HTMLDivElement>
|
|
142
|
-
>(({ className, ...props }, ref) =>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
177
|
+
>(({ className, ...props }, ref) => {
|
|
178
|
+
const context = useContext(DialogContext);
|
|
179
|
+
const size = context?.size || "default";
|
|
180
|
+
const padding = dialogPaddingSizes[size];
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<div
|
|
184
|
+
ref={ref}
|
|
185
|
+
className={cn(
|
|
186
|
+
"flex items-center justify-end gap-2.5 border-t border-border",
|
|
187
|
+
padding.x, padding.y,
|
|
188
|
+
className
|
|
189
|
+
)}
|
|
190
|
+
data-sonance-name="dialog"
|
|
191
|
+
{...props}
|
|
192
|
+
/>
|
|
193
|
+
);
|
|
194
|
+
});
|
|
152
195
|
|
|
153
196
|
DialogFooter.displayName = "DialogFooter";
|
|
154
197
|
|
|
@@ -3,8 +3,48 @@
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
5
5
|
import { Check, ChevronRight, Circle } from "lucide-react";
|
|
6
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
6
7
|
import { cn } from "@/lib/utils";
|
|
7
8
|
|
|
9
|
+
const dropdownMenuContentVariants = cva(
|
|
10
|
+
"z-50 min-w-[8rem] overflow-hidden border p-1 text-foreground shadow-xl data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
11
|
+
{
|
|
12
|
+
variants: {
|
|
13
|
+
size: {
|
|
14
|
+
xs: "rounded-lg text-xs",
|
|
15
|
+
sm: "rounded-xl text-xs",
|
|
16
|
+
md: "rounded-xl text-sm",
|
|
17
|
+
lg: "rounded-2xl text-sm",
|
|
18
|
+
},
|
|
19
|
+
menuVariant: {
|
|
20
|
+
default: "bg-card border-border",
|
|
21
|
+
glass: "bg-card/95 border-border/50 backdrop-blur-xl",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
size: "sm",
|
|
26
|
+
menuVariant: "glass",
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const dropdownMenuItemVariants = cva(
|
|
32
|
+
"relative flex cursor-default select-none items-center outline-none transition-all duration-150 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
33
|
+
{
|
|
34
|
+
variants: {
|
|
35
|
+
size: {
|
|
36
|
+
xs: "rounded-md px-2 py-1 text-xs",
|
|
37
|
+
sm: "rounded-lg px-2.5 py-1.5 text-xs",
|
|
38
|
+
md: "rounded-lg px-3 py-2 text-sm",
|
|
39
|
+
lg: "rounded-xl px-3.5 py-2.5 text-sm",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
defaultVariants: {
|
|
43
|
+
size: "sm",
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
|
|
8
48
|
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
9
49
|
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
10
50
|
const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
@@ -21,7 +61,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
|
|
21
61
|
<DropdownMenuPrimitive.SubTrigger
|
|
22
62
|
ref={ref}
|
|
23
63
|
className={cn(
|
|
24
|
-
"flex cursor-default select-none items-center rounded-
|
|
64
|
+
"flex cursor-default select-none items-center rounded-lg px-2.5 py-1.5 text-xs outline-none transition-colors duration-150",
|
|
25
65
|
"focus:bg-secondary-hover focus:text-foreground",
|
|
26
66
|
"data-[state=open]:bg-secondary-hover data-[state=open]:text-foreground",
|
|
27
67
|
inset && "pl-8",
|
|
@@ -30,7 +70,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
|
|
30
70
|
{...props}
|
|
31
71
|
>
|
|
32
72
|
{children}
|
|
33
|
-
<ChevronRight className="ml-auto h-
|
|
73
|
+
<ChevronRight className="ml-auto h-3.5 w-3.5" />
|
|
34
74
|
</DropdownMenuPrimitive.SubTrigger>
|
|
35
75
|
));
|
|
36
76
|
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
@@ -42,7 +82,7 @@ const DropdownMenuSubContent = React.forwardRef<
|
|
|
42
82
|
<DropdownMenuPrimitive.SubContent
|
|
43
83
|
ref={ref}
|
|
44
84
|
className={cn(
|
|
45
|
-
"z-50 min-w-[8rem] overflow-hidden rounded-
|
|
85
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-xl border border-border/50 bg-card/95 backdrop-blur-xl p-1 text-foreground shadow-xl",
|
|
46
86
|
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
47
87
|
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
48
88
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
@@ -57,23 +97,20 @@ const DropdownMenuSubContent = React.forwardRef<
|
|
|
57
97
|
));
|
|
58
98
|
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
59
99
|
|
|
100
|
+
interface DropdownMenuContentProps
|
|
101
|
+
extends React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>,
|
|
102
|
+
VariantProps<typeof dropdownMenuContentVariants> {}
|
|
103
|
+
|
|
60
104
|
const DropdownMenuContent = React.forwardRef<
|
|
61
105
|
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
|
62
|
-
|
|
63
|
-
>(({ className, sideOffset = 4, ...props }, ref) => (
|
|
106
|
+
DropdownMenuContentProps
|
|
107
|
+
>(({ className, sideOffset = 4, size, menuVariant, ...props }, ref) => (
|
|
64
108
|
<DropdownMenuPrimitive.Portal>
|
|
65
109
|
<DropdownMenuPrimitive.Content
|
|
66
110
|
ref={ref}
|
|
67
111
|
sideOffset={sideOffset}
|
|
68
112
|
className={cn(
|
|
69
|
-
|
|
70
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
71
|
-
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
72
|
-
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
73
|
-
"data-[side=bottom]:slide-in-from-top-2",
|
|
74
|
-
"data-[side=left]:slide-in-from-right-2",
|
|
75
|
-
"data-[side=right]:slide-in-from-left-2",
|
|
76
|
-
"data-[side=top]:slide-in-from-bottom-2",
|
|
113
|
+
dropdownMenuContentVariants({ size, menuVariant }),
|
|
77
114
|
className
|
|
78
115
|
)}
|
|
79
116
|
{...props}
|
|
@@ -91,9 +128,8 @@ const DropdownMenuItem = React.forwardRef<
|
|
|
91
128
|
<DropdownMenuPrimitive.Item
|
|
92
129
|
ref={ref}
|
|
93
130
|
className={cn(
|
|
94
|
-
|
|
131
|
+
dropdownMenuItemVariants({ size: "sm" }),
|
|
95
132
|
"focus:bg-secondary-hover focus:text-foreground",
|
|
96
|
-
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
97
133
|
inset && "pl-8",
|
|
98
134
|
className
|
|
99
135
|
)}
|
|
@@ -109,7 +145,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
|
|
109
145
|
<DropdownMenuPrimitive.CheckboxItem
|
|
110
146
|
ref={ref}
|
|
111
147
|
className={cn(
|
|
112
|
-
"relative flex cursor-default select-none items-center rounded-
|
|
148
|
+
"relative flex cursor-default select-none items-center rounded-lg py-1.5 pl-8 pr-2.5 text-xs outline-none transition-all duration-150",
|
|
113
149
|
"focus:bg-secondary-hover focus:text-foreground",
|
|
114
150
|
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
115
151
|
className
|
|
@@ -119,7 +155,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
|
|
119
155
|
>
|
|
120
156
|
<span id="dropdown-menu-checkbox-item-span" className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
|
121
157
|
<DropdownMenuPrimitive.ItemIndicator>
|
|
122
|
-
<Check className="h-
|
|
158
|
+
<Check className="h-3.5 w-3.5" />
|
|
123
159
|
</DropdownMenuPrimitive.ItemIndicator>
|
|
124
160
|
</span>
|
|
125
161
|
{children}
|
|
@@ -134,7 +170,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
|
|
134
170
|
<DropdownMenuPrimitive.RadioItem
|
|
135
171
|
ref={ref}
|
|
136
172
|
className={cn(
|
|
137
|
-
"relative flex cursor-default select-none items-center rounded-
|
|
173
|
+
"relative flex cursor-default select-none items-center rounded-lg py-1.5 pl-8 pr-2.5 text-xs outline-none transition-all duration-150",
|
|
138
174
|
"focus:bg-secondary-hover focus:text-foreground",
|
|
139
175
|
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
140
176
|
className
|
|
@@ -160,7 +196,7 @@ const DropdownMenuLabel = React.forwardRef<
|
|
|
160
196
|
<DropdownMenuPrimitive.Label
|
|
161
197
|
ref={ref}
|
|
162
198
|
className={cn(
|
|
163
|
-
"px-2 py-1.5 text-
|
|
199
|
+
"px-2.5 py-1.5 text-[10px] font-medium uppercase tracking-wide text-foreground-muted",
|
|
164
200
|
inset && "pl-8",
|
|
165
201
|
className
|
|
166
202
|
)}
|
|
@@ -209,5 +245,6 @@ export {
|
|
|
209
245
|
DropdownMenuSubContent,
|
|
210
246
|
DropdownMenuSubTrigger,
|
|
211
247
|
DropdownMenuRadioGroup,
|
|
248
|
+
dropdownMenuContentVariants,
|
|
249
|
+
dropdownMenuItemVariants,
|
|
212
250
|
};
|
|
213
|
-
|