sonance-brand-mcp 1.3.111 → 1.3.113
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-save-image/route.ts +625 -0
- package/dist/assets/api/sonance-vision-apply/image-styling-detection.ts +1360 -0
- package/dist/assets/api/sonance-vision-apply/route.ts +988 -57
- package/dist/assets/api/sonance-vision-apply/styling-detection.ts +730 -0
- package/dist/assets/api/sonance-vision-apply/theme-discovery.ts +1 -1
- package/dist/assets/brand-system.ts +13 -12
- package/dist/assets/components/accordion.tsx +15 -7
- package/dist/assets/components/alert-dialog.tsx +35 -10
- package/dist/assets/components/alert.tsx +11 -10
- package/dist/assets/components/avatar.tsx +4 -4
- package/dist/assets/components/badge.tsx +16 -12
- package/dist/assets/components/button.stories.tsx +3 -3
- package/dist/assets/components/button.tsx +50 -31
- package/dist/assets/components/calendar.tsx +12 -8
- package/dist/assets/components/card.tsx +35 -29
- package/dist/assets/components/checkbox.tsx +9 -8
- package/dist/assets/components/code.tsx +19 -11
- package/dist/assets/components/command.tsx +32 -13
- package/dist/assets/components/context-menu.tsx +37 -16
- package/dist/assets/components/dialog.tsx +8 -5
- package/dist/assets/components/divider.tsx +15 -5
- package/dist/assets/components/drawer.tsx +4 -3
- package/dist/assets/components/dropdown-menu.tsx +15 -13
- package/dist/assets/components/hover-card.tsx +4 -1
- package/dist/assets/components/image.tsx +1 -1
- package/dist/assets/components/input.tsx +29 -14
- package/dist/assets/components/kbd.stories.tsx +3 -3
- package/dist/assets/components/kbd.tsx +29 -13
- package/dist/assets/components/listbox.tsx +8 -8
- package/dist/assets/components/menubar.tsx +50 -23
- package/dist/assets/components/navbar.stories.tsx +140 -13
- package/dist/assets/components/navbar.tsx +22 -5
- package/dist/assets/components/navigation-menu.tsx +28 -6
- package/dist/assets/components/pagination.tsx +10 -10
- package/dist/assets/components/popover.tsx +10 -8
- package/dist/assets/components/progress.tsx +6 -4
- package/dist/assets/components/radio-group.tsx +5 -5
- package/dist/assets/components/select.tsx +49 -29
- package/dist/assets/components/separator.tsx +3 -3
- package/dist/assets/components/sheet.tsx +4 -4
- package/dist/assets/components/sidebar.tsx +10 -10
- package/dist/assets/components/skeleton.tsx +13 -5
- package/dist/assets/components/slider.tsx +12 -10
- package/dist/assets/components/switch.tsx +4 -4
- package/dist/assets/components/table.tsx +5 -5
- package/dist/assets/components/tabs.tsx +8 -8
- package/dist/assets/components/textarea.tsx +11 -9
- package/dist/assets/components/toast.tsx +7 -7
- package/dist/assets/components/toggle.tsx +27 -7
- package/dist/assets/components/tooltip.tsx +10 -8
- package/dist/assets/components/user.tsx +8 -6
- package/dist/assets/dev-tools/SonanceDevTools.tsx +429 -362
- package/dist/assets/dev-tools/components/ApplyFirstPreview.tsx +10 -10
- package/dist/assets/dev-tools/components/ChatHistory.tsx +11 -7
- package/dist/assets/dev-tools/components/ChatInterface.tsx +61 -20
- package/dist/assets/dev-tools/components/ChatTabBar.tsx +1 -1
- package/dist/assets/dev-tools/components/DiffPreview.tsx +1 -1
- package/dist/assets/dev-tools/components/InlineDiffPreview.tsx +360 -36
- package/dist/assets/dev-tools/components/InspectorOverlay.tsx +9 -9
- package/dist/assets/dev-tools/components/PropertiesPanel.tsx +743 -93
- package/dist/assets/dev-tools/components/ScreenshotAnnotator.tsx +1 -1
- package/dist/assets/dev-tools/components/SectionHighlight.tsx +1 -1
- package/dist/assets/dev-tools/components/VisionDiffPreview.tsx +7 -7
- package/dist/assets/dev-tools/components/VisionModeBorder.tsx +4 -64
- package/dist/assets/dev-tools/hooks/index.ts +69 -0
- package/dist/assets/dev-tools/hooks/useComponentDetection.ts +132 -0
- package/dist/assets/dev-tools/hooks/useComputedStyles.ts +171 -65
- package/dist/assets/dev-tools/hooks/useContentHash.ts +212 -0
- package/dist/assets/dev-tools/hooks/useElementScanner.ts +398 -0
- package/dist/assets/dev-tools/hooks/useImageDetection.ts +162 -0
- package/dist/assets/dev-tools/hooks/useTextDetection.ts +217 -0
- package/dist/assets/dev-tools/panels/ComponentsPanel.tsx +160 -57
- package/dist/assets/dev-tools/panels/TextPanel.tsx +10 -10
- package/dist/assets/dev-tools/types.ts +42 -0
- package/dist/assets/globals.css +225 -9
- package/dist/assets/styles/brand-overrides.css +3 -2
- package/dist/assets/utils.ts +2 -1
- package/dist/index.js +32 -1
- package/package.json +1 -1
|
@@ -677,7 +677,7 @@ function getColorDescription(value: string, name: string): string {
|
|
|
677
677
|
const rgb = parseColorToRgb(value);
|
|
678
678
|
if (!rgb) return "";
|
|
679
679
|
|
|
680
|
-
const luminance = getLuminance(rgb);
|
|
680
|
+
const luminance = getLuminance(rgb.r, rgb.g, rgb.b);
|
|
681
681
|
const baseName = name.replace(/^--/, "");
|
|
682
682
|
|
|
683
683
|
// Very light colors (like white)
|
|
@@ -11,7 +11,7 @@ export interface ThemeConfig {
|
|
|
11
11
|
accentColor: string;
|
|
12
12
|
|
|
13
13
|
// Radius
|
|
14
|
-
radius: 'none' | 'sm' | 'md' | 'lg';
|
|
14
|
+
radius: 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
15
15
|
|
|
16
16
|
// Typography
|
|
17
17
|
headingWeight: 400 | 500 | 600 | 700;
|
|
@@ -57,7 +57,7 @@ export interface ComponentSnippet {
|
|
|
57
57
|
export const defaultThemeConfig: ThemeConfig = {
|
|
58
58
|
baseColor: '#333F48', // Sonance Charcoal
|
|
59
59
|
accentColor: '#00A3E1', // Sonance Blue
|
|
60
|
-
radius: '
|
|
60
|
+
radius: 'md', // Liquid Glass default
|
|
61
61
|
headingWeight: 600,
|
|
62
62
|
bodyWeight: 400,
|
|
63
63
|
typographyScale: 'default',
|
|
@@ -74,7 +74,7 @@ export const brandPresets: BrandPreset[] = [
|
|
|
74
74
|
config: {
|
|
75
75
|
baseColor: '#333F48', // Sonance Charcoal
|
|
76
76
|
accentColor: '#00A3E1', // Sonance Blue
|
|
77
|
-
radius: '
|
|
77
|
+
radius: 'md', // Liquid Glass
|
|
78
78
|
headingWeight: 600,
|
|
79
79
|
bodyWeight: 400,
|
|
80
80
|
typographyScale: 'default',
|
|
@@ -88,7 +88,7 @@ export const brandPresets: BrandPreset[] = [
|
|
|
88
88
|
config: {
|
|
89
89
|
baseColor: '#FC4C02', // IPORT Orange
|
|
90
90
|
accentColor: '#0F161D', // IPORT Dark
|
|
91
|
-
radius: '
|
|
91
|
+
radius: 'md', // Liquid Glass
|
|
92
92
|
headingWeight: 700,
|
|
93
93
|
bodyWeight: 400,
|
|
94
94
|
typographyScale: 'default',
|
|
@@ -102,7 +102,7 @@ export const brandPresets: BrandPreset[] = [
|
|
|
102
102
|
config: {
|
|
103
103
|
baseColor: '#00A3E1', // Blaze Blue
|
|
104
104
|
accentColor: '#28282B', // Blaze Dark Gray
|
|
105
|
-
radius: '
|
|
105
|
+
radius: 'md', // Liquid Glass
|
|
106
106
|
headingWeight: 600,
|
|
107
107
|
bodyWeight: 400,
|
|
108
108
|
typographyScale: 'default',
|
|
@@ -133,9 +133,9 @@ export const brandLogos: Record<BrandId, BrandLogos> = {
|
|
|
133
133
|
|
|
134
134
|
// Logo dimension overrides
|
|
135
135
|
export const logoSizes: Record<string, { width?: number; height?: number; scale?: number }> = {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
'Sonance_James_IPORT_Lockup_Light': {
|
|
137
|
+
scale: 0.9
|
|
138
|
+
}
|
|
139
139
|
|
|
140
140
|
|
|
141
141
|
|
|
@@ -168,9 +168,10 @@ export const colorPresets: ColorPreset[] = [
|
|
|
168
168
|
|
|
169
169
|
export const radiusValues: Record<ThemeConfig['radius'], string> = {
|
|
170
170
|
none: '0px',
|
|
171
|
-
sm: '
|
|
172
|
-
md: '
|
|
173
|
-
lg: '
|
|
171
|
+
sm: '8px',
|
|
172
|
+
md: '12px',
|
|
173
|
+
lg: '16px',
|
|
174
|
+
xl: '20px',
|
|
174
175
|
};
|
|
175
176
|
|
|
176
177
|
export const typographyScales: Record<ThemeConfig['typographyScale'], number> = {
|
|
@@ -325,7 +326,7 @@ export function generateRandomTheme(): ThemeConfig {
|
|
|
325
326
|
const accentColors = colorPresets.filter(c => c.value !== randomColor.value);
|
|
326
327
|
const randomAccent = accentColors[Math.floor(Math.random() * accentColors.length)];
|
|
327
328
|
|
|
328
|
-
const radiusOptions: ThemeConfig['radius'][] = ['none', 'sm', 'md', 'lg'];
|
|
329
|
+
const radiusOptions: ThemeConfig['radius'][] = ['none', 'sm', 'md', 'lg', 'xl'];
|
|
329
330
|
const headingWeights: ThemeConfig['headingWeight'][] = [400, 500, 600, 700];
|
|
330
331
|
const bodyWeights: ThemeConfig['bodyWeight'][] = [300, 400, 500];
|
|
331
332
|
const typographyScaleOptions: ThemeConfig['typographyScale'][] = ['compact', 'default', 'large'];
|
|
@@ -11,9 +11,9 @@ const getStateStyles = (state?: AccordionTriggerState) => {
|
|
|
11
11
|
if (!state || state === "default") return "";
|
|
12
12
|
|
|
13
13
|
const stateMap: Record<string, string> = {
|
|
14
|
-
hover: "text-foreground-
|
|
15
|
-
focus: "ring-2 ring-
|
|
16
|
-
expanded: "",
|
|
14
|
+
hover: "text-foreground bg-white/50 dark:bg-white/5",
|
|
15
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
16
|
+
expanded: "bg-white/30 dark:bg-white/[0.02]",
|
|
17
17
|
disabled: "opacity-50 cursor-not-allowed",
|
|
18
18
|
};
|
|
19
19
|
|
|
@@ -65,7 +65,12 @@ export function Accordion({
|
|
|
65
65
|
|
|
66
66
|
return (
|
|
67
67
|
<AccordionContext.Provider value={{ openItems, toggleItem, type }}>
|
|
68
|
-
<div data-sonance-name="accordion" className={cn(
|
|
68
|
+
<div data-sonance-name="accordion" className={cn(
|
|
69
|
+
"w-full divide-y divide-black/8 dark:divide-white/8",
|
|
70
|
+
"bg-white/60 dark:bg-white/[0.02] backdrop-blur-sm",
|
|
71
|
+
"border border-black/8 dark:border-white/8 rounded-xl overflow-hidden",
|
|
72
|
+
className
|
|
73
|
+
)}>
|
|
69
74
|
{children}
|
|
70
75
|
</div>
|
|
71
76
|
</AccordionContext.Provider>
|
|
@@ -119,8 +124,11 @@ export const AccordionTrigger = forwardRef<HTMLButtonElement, AccordionTriggerPr
|
|
|
119
124
|
onClick={() => !isDisabled && accordionContext.toggleItem(itemContext.value)}
|
|
120
125
|
disabled={isDisabled}
|
|
121
126
|
className={cn(
|
|
122
|
-
"flex w-full items-center justify-between py-4 text-left font-medium text-foreground",
|
|
123
|
-
"transition-
|
|
127
|
+
"flex w-full items-center justify-between px-4 py-4 text-left font-medium text-foreground",
|
|
128
|
+
"transition-all duration-200",
|
|
129
|
+
"hover:bg-white/50 dark:hover:bg-white/5 hover:text-foreground",
|
|
130
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--sonance-blue)]/30 focus-visible:ring-inset",
|
|
131
|
+
isExpanded && "bg-white/30 dark:bg-white/[0.02]",
|
|
124
132
|
isDisabled && "opacity-50 cursor-not-allowed",
|
|
125
133
|
getStateStyles(state),
|
|
126
134
|
className
|
|
@@ -158,7 +166,7 @@ export const AccordionContent = forwardRef<
|
|
|
158
166
|
className={cn(
|
|
159
167
|
"overflow-hidden text-sm text-foreground-secondary",
|
|
160
168
|
"transition-all duration-200",
|
|
161
|
-
itemContext.isOpen ? "pb-4" : "h-0",
|
|
169
|
+
itemContext.isOpen ? "px-4 pb-4" : "h-0",
|
|
162
170
|
className
|
|
163
171
|
)}
|
|
164
172
|
aria-hidden={!itemContext.isOpen} data-sonance-name="accordion"
|
|
@@ -14,7 +14,9 @@ const AlertDialogOverlay = React.forwardRef<
|
|
|
14
14
|
>(({ className, ...props }, ref) => (
|
|
15
15
|
<AlertDialogPrimitive.Overlay
|
|
16
16
|
className={cn(
|
|
17
|
-
"fixed inset-0 z-50 bg-
|
|
17
|
+
"fixed inset-0 z-50 bg-black/40 dark:bg-black/60 backdrop-blur-md",
|
|
18
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
19
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
18
20
|
className
|
|
19
21
|
)}
|
|
20
22
|
{...props}
|
|
@@ -31,10 +33,19 @@ const AlertDialogContent = React.forwardRef<
|
|
|
31
33
|
<AlertDialogOverlay />
|
|
32
34
|
<AlertDialogPrimitive.Content
|
|
33
35
|
ref={ref}
|
|
36
|
+
data-sonance-name="alert-dialog"
|
|
34
37
|
className={cn(
|
|
35
|
-
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
+
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 p-6",
|
|
39
|
+
"backdrop-blur-xl rounded-3xl",
|
|
40
|
+
"bg-white/80 dark:bg-black/60",
|
|
41
|
+
"border border-black/10 dark:border-white/10",
|
|
42
|
+
"shadow-[0_16px_48px_rgba(0,0,0,0.15)] dark:shadow-[0_16px_48px_rgba(0,0,0,0.5)]",
|
|
43
|
+
"duration-200",
|
|
44
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
45
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
46
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
47
|
+
"data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
|
|
48
|
+
"data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
|
|
38
49
|
className
|
|
39
50
|
)}
|
|
40
51
|
{...props}
|
|
@@ -64,9 +75,10 @@ const AlertDialogFooter = ({
|
|
|
64
75
|
}: React.HTMLAttributes<HTMLDivElement>) => (
|
|
65
76
|
<div
|
|
66
77
|
className={cn(
|
|
67
|
-
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
|
78
|
+
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2.5",
|
|
68
79
|
className
|
|
69
|
-
)}
|
|
80
|
+
)}
|
|
81
|
+
data-sonance-name="alert-dialog"
|
|
70
82
|
{...props}
|
|
71
83
|
/>
|
|
72
84
|
);
|
|
@@ -90,7 +102,7 @@ const AlertDialogDescription = React.forwardRef<
|
|
|
90
102
|
>(({ className, ...props }, ref) => (
|
|
91
103
|
<AlertDialogPrimitive.Description
|
|
92
104
|
ref={ref}
|
|
93
|
-
className={cn("text-sm text-foreground-
|
|
105
|
+
className={cn("text-sm text-foreground-muted", className)}
|
|
94
106
|
{...props}
|
|
95
107
|
/>
|
|
96
108
|
));
|
|
@@ -104,7 +116,14 @@ const AlertDialogAction = React.forwardRef<
|
|
|
104
116
|
<AlertDialogPrimitive.Action
|
|
105
117
|
ref={ref}
|
|
106
118
|
className={cn(
|
|
107
|
-
"inline-flex h-
|
|
119
|
+
"inline-flex h-9 items-center justify-center px-5 text-sm font-medium uppercase tracking-wide",
|
|
120
|
+
"rounded-xl backdrop-blur-sm transition-all duration-200",
|
|
121
|
+
"bg-[color:var(--sonance-blue)]/90 text-white",
|
|
122
|
+
"border border-white/20",
|
|
123
|
+
"hover:bg-[color:var(--sonance-blue)]/80 hover:shadow-[0_0_25px_var(--glow-primary-intense)]",
|
|
124
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--sonance-blue)]/30 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
125
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
126
|
+
"active:scale-[0.98]",
|
|
108
127
|
className
|
|
109
128
|
)}
|
|
110
129
|
{...props}
|
|
@@ -119,7 +138,14 @@ const AlertDialogCancel = React.forwardRef<
|
|
|
119
138
|
<AlertDialogPrimitive.Cancel
|
|
120
139
|
ref={ref}
|
|
121
140
|
className={cn(
|
|
122
|
-
"mt-2 inline-flex h-
|
|
141
|
+
"mt-2 sm:mt-0 inline-flex h-9 items-center justify-center px-5 text-sm font-medium uppercase tracking-wide",
|
|
142
|
+
"rounded-xl backdrop-blur-sm transition-all duration-200",
|
|
143
|
+
"bg-white/60 dark:bg-white/5 text-foreground",
|
|
144
|
+
"border border-black/10 dark:border-white/10",
|
|
145
|
+
"hover:bg-white/70 dark:hover:bg-white/8 hover:shadow-[0_0_15px_var(--glow-primary-subtle)]",
|
|
146
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--sonance-blue)]/30 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
147
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
148
|
+
"active:scale-[0.98]",
|
|
123
149
|
className
|
|
124
150
|
)}
|
|
125
151
|
{...props}
|
|
@@ -140,4 +166,3 @@ export {
|
|
|
140
166
|
AlertDialogAction,
|
|
141
167
|
AlertDialogCancel,
|
|
142
168
|
};
|
|
143
|
-
|
|
@@ -6,21 +6,22 @@ import { cn } from "@/lib/utils";
|
|
|
6
6
|
export type AlertState = "default" | "hover" | "focus";
|
|
7
7
|
|
|
8
8
|
const alertVariants = cva(
|
|
9
|
-
"relative flex w-full items-start border transition-all duration-200",
|
|
9
|
+
"relative flex w-full items-start border transition-all duration-200 backdrop-blur-md",
|
|
10
10
|
{
|
|
11
11
|
variants: {
|
|
12
12
|
variant: {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
// Glass morphism alerts
|
|
14
|
+
default: "border-black/8 dark:border-white/8 bg-white/70 dark:bg-white/5 text-foreground",
|
|
15
|
+
success: "border-success/20 bg-success/10 dark:bg-success/15 text-success",
|
|
16
|
+
error: "border-error/20 bg-error/10 dark:bg-error/15 text-error",
|
|
17
|
+
warning: "border-warning/20 bg-warning/10 dark:bg-warning/15 text-warning",
|
|
18
|
+
info: "border-info/20 bg-info/10 dark:bg-info/15 text-info",
|
|
18
19
|
},
|
|
19
20
|
size: {
|
|
20
|
-
xs: "gap-2 p-2 rounded-
|
|
21
|
-
sm: "gap-2.5 p-3 rounded-
|
|
22
|
-
md: "gap-3 p-4 rounded-
|
|
23
|
-
lg: "gap-4 p-5 rounded-
|
|
21
|
+
xs: "gap-2 p-2 rounded-xl text-xs",
|
|
22
|
+
sm: "gap-2.5 p-3 rounded-2xl text-xs",
|
|
23
|
+
md: "gap-3 p-4 rounded-2xl text-sm",
|
|
24
|
+
lg: "gap-4 p-5 rounded-3xl text-sm",
|
|
24
25
|
},
|
|
25
26
|
},
|
|
26
27
|
defaultVariants: {
|
|
@@ -7,7 +7,7 @@ import { User } from "lucide-react";
|
|
|
7
7
|
import { cn } from "@/lib/utils";
|
|
8
8
|
|
|
9
9
|
const avatarVariants = cva(
|
|
10
|
-
"relative inline-flex shrink-0 items-center justify-center overflow-hidden bg-
|
|
10
|
+
"relative inline-flex shrink-0 items-center justify-center overflow-hidden bg-white/60 dark:bg-white/5 backdrop-blur-sm border border-black/8 dark:border-white/8",
|
|
11
11
|
{
|
|
12
12
|
variants: {
|
|
13
13
|
size: {
|
|
@@ -19,7 +19,7 @@ const avatarVariants = cva(
|
|
|
19
19
|
},
|
|
20
20
|
shape: {
|
|
21
21
|
circle: "rounded-full",
|
|
22
|
-
square: "rounded-
|
|
22
|
+
square: "rounded-xl",
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
25
|
defaultVariants: {
|
|
@@ -104,7 +104,7 @@ const AvatarFallback = React.forwardRef<
|
|
|
104
104
|
<AvatarPrimitive.Fallback
|
|
105
105
|
ref={ref}
|
|
106
106
|
className={cn(
|
|
107
|
-
"flex h-full w-full items-center justify-center
|
|
107
|
+
"flex h-full w-full items-center justify-center bg-white/50 dark:bg-white/5",
|
|
108
108
|
className
|
|
109
109
|
)}
|
|
110
110
|
{...props}
|
|
@@ -136,7 +136,7 @@ function AvatarGroup({ children, max, size = "md", className }: AvatarGroupProps
|
|
|
136
136
|
<div data-sonance-name="avatar"
|
|
137
137
|
className={cn(
|
|
138
138
|
avatarVariants({ size, shape: "circle" }),
|
|
139
|
-
"ring-2 ring-background bg-
|
|
139
|
+
"ring-2 ring-background bg-white/70 dark:bg-white/10"
|
|
140
140
|
)}
|
|
141
141
|
>
|
|
142
142
|
<span id="avatar-group-span-excess" className="text-xs font-medium text-foreground-muted">+{excess}</span>
|
|
@@ -4,23 +4,27 @@ import { cn } from "@/lib/utils";
|
|
|
4
4
|
export type BadgeState = "default" | "hover";
|
|
5
5
|
|
|
6
6
|
const badgeVariants = cva(
|
|
7
|
-
"inline-flex items-center font-medium transition-all duration-150",
|
|
7
|
+
"inline-flex items-center font-medium transition-all duration-150 backdrop-blur-sm",
|
|
8
8
|
{
|
|
9
9
|
variants: {
|
|
10
10
|
variant: {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
// Glass morphism - default style
|
|
12
|
+
default: "bg-white/60 dark:bg-white/10 text-foreground border border-black/8 dark:border-white/10 hover:bg-white/70 dark:hover:bg-white/15",
|
|
13
|
+
primary: "bg-[color:var(--sonance-blue)]/20 text-[color:var(--sonance-blue)] dark:text-[color:var(--sonance-blue)] border border-[color:var(--sonance-blue)]/30 hover:bg-[color:var(--sonance-blue)]/30",
|
|
14
|
+
secondary: "bg-white/50 dark:bg-white/5 text-foreground-secondary border border-black/5 dark:border-white/5 hover:bg-white/60 dark:hover:bg-white/10",
|
|
15
|
+
success: "bg-success/20 text-success border border-success/30 hover:bg-success/30",
|
|
16
|
+
error: "bg-error/20 text-error border border-error/30 hover:bg-error/30",
|
|
17
|
+
warning: "bg-warning/20 text-warning border border-warning/30 hover:bg-warning/30",
|
|
18
|
+
info: "bg-info/20 text-info border border-info/30 hover:bg-info/30",
|
|
19
|
+
outline: "border border-black/15 dark:border-white/15 text-foreground bg-transparent hover:bg-white/50 dark:hover:bg-white/5",
|
|
20
|
+
// Non-glass solid variants
|
|
21
|
+
"solid-primary": "bg-primary text-primary-foreground hover:bg-primary-hover backdrop-blur-none",
|
|
22
|
+
"solid-success": "bg-success text-white hover:bg-success/90 backdrop-blur-none",
|
|
23
|
+
"solid-error": "bg-error text-white hover:bg-error/90 backdrop-blur-none",
|
|
20
24
|
},
|
|
21
25
|
size: {
|
|
22
|
-
xs: "px-1.5 py-0.5 text-[10px] rounded-
|
|
23
|
-
sm: "px-2 py-0.5 text-xs rounded-
|
|
26
|
+
xs: "px-1.5 py-0.5 text-[10px] rounded-lg",
|
|
27
|
+
sm: "px-2 py-0.5 text-xs rounded-xl",
|
|
24
28
|
md: "px-2.5 py-0.5 text-xs rounded-full",
|
|
25
29
|
lg: "px-3 py-1 text-sm rounded-full",
|
|
26
30
|
},
|
|
@@ -84,8 +84,8 @@ export const Ghost: Story = {
|
|
|
84
84
|
|
|
85
85
|
export const Inverted: Story = {
|
|
86
86
|
args: {
|
|
87
|
-
children: '
|
|
88
|
-
variant: '
|
|
87
|
+
children: 'Outline on Dark',
|
|
88
|
+
variant: 'outline',
|
|
89
89
|
},
|
|
90
90
|
parameters: {
|
|
91
91
|
backgrounds: {
|
|
@@ -139,7 +139,7 @@ export const AllVariants: Story = {
|
|
|
139
139
|
<Button id="all-variants-button-secondary" variant="secondary">Secondary</Button>
|
|
140
140
|
<Button id="all-variants-button-ghost" variant="ghost">Ghost</Button>
|
|
141
141
|
<div className="bg-sonance-charcoal p-2 rounded">
|
|
142
|
-
<Button id="all-variants-button-
|
|
142
|
+
<Button id="all-variants-button-outline-dark" variant="outline">Outline</Button>
|
|
143
143
|
</div>
|
|
144
144
|
</div>
|
|
145
145
|
),
|
|
@@ -5,30 +5,37 @@ import { forwardRef } from "react";
|
|
|
5
5
|
export type ButtonState = "default" | "hover" | "active" | "focus" | "disabled";
|
|
6
6
|
|
|
7
7
|
const buttonVariants = cva(
|
|
8
|
-
"inline-flex items-center justify-center font-medium uppercase tracking-wide transition-all duration-200 ease-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
8
|
+
"inline-flex items-center justify-center font-medium uppercase tracking-wide transition-all duration-200 ease-out backdrop-blur-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--sonance-blue)]/30 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 active:scale-[0.98]",
|
|
9
9
|
{
|
|
10
10
|
variants: {
|
|
11
11
|
variant: {
|
|
12
|
+
// Glass morphism - default style
|
|
13
|
+
default:
|
|
14
|
+
"bg-white/70 dark:bg-white/5 text-foreground border border-black/8 dark:border-white/10 hover:bg-white/80 dark:hover:bg-white/8 hover:border-black/12 dark:hover:border-white/15 hover:shadow-[0_0_20px_var(--glow-primary)] shadow-sm",
|
|
12
15
|
primary:
|
|
13
|
-
"bg-
|
|
16
|
+
"bg-[color:var(--sonance-blue)]/90 text-white border border-white/20 hover:bg-[color:var(--sonance-blue)]/80 hover:shadow-[0_0_25px_var(--glow-primary-intense)] shadow-lg",
|
|
14
17
|
secondary:
|
|
15
|
-
"bg-
|
|
16
|
-
ghost:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
"bg-white/60 dark:bg-white/5 text-foreground border border-black/10 dark:border-white/10 hover:bg-white/70 dark:hover:bg-white/8 hover:shadow-[0_0_15px_var(--glow-primary-subtle)]",
|
|
19
|
+
ghost:
|
|
20
|
+
"text-foreground hover:bg-white/50 dark:hover:bg-white/5 border border-transparent hover:border-black/5 dark:hover:border-white/5",
|
|
21
|
+
outline:
|
|
22
|
+
"bg-transparent text-foreground border border-black/15 dark:border-white/15 hover:bg-white/50 dark:hover:bg-white/5 hover:border-black/20 dark:hover:border-white/20 hover:shadow-[0_0_15px_var(--glow-primary-subtle)]",
|
|
23
|
+
// Non-glass solid variants for fallback
|
|
24
|
+
solid:
|
|
25
|
+
"bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active shadow-sm hover:shadow-md backdrop-blur-none",
|
|
26
|
+
"solid-secondary":
|
|
27
|
+
"bg-secondary text-secondary-foreground border border-border hover:bg-secondary-hover hover:border-border-hover shadow-sm hover:shadow-md backdrop-blur-none",
|
|
21
28
|
},
|
|
22
29
|
size: {
|
|
23
|
-
xs: "h-
|
|
24
|
-
sm: "h-8 px-
|
|
25
|
-
md: "h-9 px-
|
|
26
|
-
lg: "h-10 px-
|
|
30
|
+
xs: "h-7 px-3 text-[10px] rounded-lg",
|
|
31
|
+
sm: "h-8 px-4 text-xs rounded-xl",
|
|
32
|
+
md: "h-9 px-5 text-sm rounded-xl",
|
|
33
|
+
lg: "h-10 px-6 text-sm rounded-2xl",
|
|
27
34
|
icon: "h-9 w-9 rounded-full",
|
|
28
35
|
},
|
|
29
36
|
},
|
|
30
37
|
defaultVariants: {
|
|
31
|
-
variant: "
|
|
38
|
+
variant: "default",
|
|
32
39
|
size: "sm",
|
|
33
40
|
},
|
|
34
41
|
}
|
|
@@ -39,39 +46,51 @@ const getStateStyles = (variant: string | null | undefined, state?: ButtonState)
|
|
|
39
46
|
if (!state || state === "default") return "";
|
|
40
47
|
|
|
41
48
|
const stateMap: Record<string, Record<string, string>> = {
|
|
49
|
+
default: {
|
|
50
|
+
hover: "bg-white/80 dark:bg-white/8 border-black/12 dark:border-white/15 shadow-[0_0_20px_var(--glow-primary)]",
|
|
51
|
+
active: "bg-white/90 dark:bg-white/10 scale-[0.98]",
|
|
52
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
53
|
+
disabled: "opacity-50 pointer-events-none",
|
|
54
|
+
},
|
|
42
55
|
primary: {
|
|
43
|
-
hover: "bg-
|
|
44
|
-
active: "bg-
|
|
45
|
-
focus: "ring-2 ring-
|
|
56
|
+
hover: "bg-[color:var(--sonance-blue)]/80 shadow-[0_0_25px_var(--glow-primary-intense)]",
|
|
57
|
+
active: "bg-[color:var(--sonance-blue)]/70 scale-[0.98]",
|
|
58
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
46
59
|
disabled: "opacity-50 pointer-events-none",
|
|
47
60
|
},
|
|
48
61
|
secondary: {
|
|
49
|
-
hover: "bg-
|
|
50
|
-
active: "bg-
|
|
51
|
-
focus: "ring-2 ring-
|
|
62
|
+
hover: "bg-white/70 dark:bg-white/8 shadow-[0_0_15px_var(--glow-primary-subtle)]",
|
|
63
|
+
active: "bg-white/80 dark:bg-white/10 scale-[0.98]",
|
|
64
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
52
65
|
disabled: "opacity-50 pointer-events-none",
|
|
53
66
|
},
|
|
54
67
|
ghost: {
|
|
55
|
-
hover: "bg-
|
|
56
|
-
active: "bg-
|
|
57
|
-
focus: "ring-2 ring-
|
|
68
|
+
hover: "bg-white/50 dark:bg-white/5",
|
|
69
|
+
active: "bg-white/60 dark:bg-white/8 scale-[0.98]",
|
|
70
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
58
71
|
disabled: "opacity-50 pointer-events-none",
|
|
59
72
|
},
|
|
60
|
-
|
|
61
|
-
hover: "
|
|
62
|
-
active: "
|
|
63
|
-
focus: "ring-2 ring-
|
|
73
|
+
outline: {
|
|
74
|
+
hover: "bg-white/50 dark:bg-white/5 border-black/20 dark:border-white/20 shadow-[0_0_15px_var(--glow-primary-subtle)]",
|
|
75
|
+
active: "bg-white/60 dark:bg-white/8 scale-[0.98]",
|
|
76
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
64
77
|
disabled: "opacity-50 pointer-events-none",
|
|
65
78
|
},
|
|
66
|
-
|
|
67
|
-
hover: "bg-primary
|
|
68
|
-
active: "bg-primary
|
|
69
|
-
focus: "ring-2 ring-
|
|
79
|
+
solid: {
|
|
80
|
+
hover: "bg-primary-hover shadow-md",
|
|
81
|
+
active: "bg-primary-active scale-[0.98]",
|
|
82
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
83
|
+
disabled: "opacity-50 pointer-events-none",
|
|
84
|
+
},
|
|
85
|
+
"solid-secondary": {
|
|
86
|
+
hover: "bg-secondary-hover border-border-hover shadow-md",
|
|
87
|
+
active: "bg-secondary-hover scale-[0.98]",
|
|
88
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
70
89
|
disabled: "opacity-50 pointer-events-none",
|
|
71
90
|
},
|
|
72
91
|
};
|
|
73
92
|
|
|
74
|
-
return stateMap[variant || "
|
|
93
|
+
return stateMap[variant || "default"]?.[state] || "";
|
|
75
94
|
};
|
|
76
95
|
|
|
77
96
|
interface ButtonProps
|
|
@@ -62,13 +62,17 @@ export function Calendar({
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
return (
|
|
65
|
-
<div data-sonance-name="calendar" className={cn(
|
|
65
|
+
<div data-sonance-name="calendar" className={cn(
|
|
66
|
+
"p-4 bg-white/70 dark:bg-white/[0.03] backdrop-blur-lg",
|
|
67
|
+
"border border-black/8 dark:border-white/8 rounded-2xl",
|
|
68
|
+
className
|
|
69
|
+
)}>
|
|
66
70
|
{/* Header */}
|
|
67
71
|
<div className="flex items-center justify-between mb-4">
|
|
68
72
|
<button
|
|
69
73
|
type="button"
|
|
70
74
|
onClick={handlePreviousMonth}
|
|
71
|
-
className="p-1.5 hover:bg-
|
|
75
|
+
className="p-1.5 hover:bg-white/50 dark:hover:bg-white/10 rounded-xl transition-colors"
|
|
72
76
|
aria-label="Previous month"
|
|
73
77
|
>
|
|
74
78
|
<ChevronLeft className="h-4 w-4 text-foreground" />
|
|
@@ -79,7 +83,7 @@ export function Calendar({
|
|
|
79
83
|
<button
|
|
80
84
|
type="button"
|
|
81
85
|
onClick={handleNextMonth}
|
|
82
|
-
className="p-1.5 hover:bg-
|
|
86
|
+
className="p-1.5 hover:bg-white/50 dark:hover:bg-white/10 rounded-xl transition-colors"
|
|
83
87
|
aria-label="Next month"
|
|
84
88
|
>
|
|
85
89
|
<ChevronRight className="h-4 w-4 text-foreground" />
|
|
@@ -113,16 +117,16 @@ export function Calendar({
|
|
|
113
117
|
onClick={() => handleSelectDate(day)}
|
|
114
118
|
disabled={isDisabled}
|
|
115
119
|
className={cn(
|
|
116
|
-
"h-8 w-8 flex items-center justify-center text-sm rounded-
|
|
120
|
+
"h-8 w-8 flex items-center justify-center text-sm rounded-xl transition-all duration-200",
|
|
117
121
|
isSelected
|
|
118
|
-
? "bg-
|
|
122
|
+
? "bg-[color:var(--sonance-blue)] text-white shadow-[0_0_12px_var(--glow-primary)]"
|
|
119
123
|
: isDisabled
|
|
120
124
|
? "text-foreground-subtle cursor-not-allowed"
|
|
121
125
|
: !isCurrentMonth
|
|
122
|
-
? "text-foreground-subtle hover:bg-
|
|
126
|
+
? "text-foreground-subtle hover:bg-white/50 dark:hover:bg-white/10"
|
|
123
127
|
: isTodayDate
|
|
124
|
-
? "bg-
|
|
125
|
-
: "text-foreground hover:bg-
|
|
128
|
+
? "bg-white/50 dark:bg-white/10 text-foreground font-medium hover:bg-white/60 dark:hover:bg-white/15"
|
|
129
|
+
: "text-foreground hover:bg-white/50 dark:hover:bg-white/10"
|
|
126
130
|
)}
|
|
127
131
|
>
|
|
128
132
|
{format(day, "d")}
|
|
@@ -1,22 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
4
|
import { cn } from "@/lib/utils";
|
|
3
|
-
import { forwardRef } from "react";
|
|
5
|
+
import { forwardRef, createContext, useContext } from "react";
|
|
4
6
|
|
|
5
7
|
export type CardState = "default" | "hover" | "focus";
|
|
6
8
|
|
|
7
9
|
const cardVariants = cva(
|
|
8
|
-
"
|
|
10
|
+
"transition-all duration-200 backdrop-blur-lg",
|
|
9
11
|
{
|
|
10
12
|
variants: {
|
|
11
13
|
variant: {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
// Glass morphism - default style
|
|
15
|
+
default:
|
|
16
|
+
"bg-white/70 dark:bg-white/[0.03] border border-black/8 dark:border-white/8 shadow-[0_4px_16px_rgba(0,0,0,0.08)] dark:shadow-[0_8px_32px_rgba(0,0,0,0.3)] hover:bg-white/80 dark:hover:bg-white/[0.05] hover:border-black/10 dark:hover:border-white/10 hover:shadow-[0_0_20px_var(--glow-primary-subtle)]",
|
|
17
|
+
elevated:
|
|
18
|
+
"bg-white/80 dark:bg-white/[0.05] border border-black/10 dark:border-white/10 shadow-lg hover:shadow-xl hover:shadow-[0_0_30px_var(--glow-primary)] dark:hover:shadow-[0_0_30px_var(--glow-primary)]",
|
|
19
|
+
subtle:
|
|
20
|
+
"bg-white/50 dark:bg-white/[0.02] border border-black/5 dark:border-white/5 hover:bg-white/60 dark:hover:bg-white/[0.04] hover:border-black/8 dark:hover:border-white/8",
|
|
21
|
+
// Non-glass solid variant for fallback
|
|
22
|
+
solid:
|
|
23
|
+
"bg-card border-card-border hover:border-border-hover hover:bg-card-hover backdrop-blur-none",
|
|
15
24
|
},
|
|
16
25
|
size: {
|
|
17
|
-
compact: "rounded-
|
|
18
|
-
default: "rounded-
|
|
19
|
-
spacious: "rounded-
|
|
26
|
+
compact: "rounded-xl",
|
|
27
|
+
default: "rounded-2xl",
|
|
28
|
+
spacious: "rounded-3xl",
|
|
20
29
|
},
|
|
21
30
|
},
|
|
22
31
|
defaultVariants: {
|
|
@@ -42,32 +51,29 @@ interface CardProps extends React.HTMLAttributes<HTMLDivElement>,
|
|
|
42
51
|
const getStateStyles = (variant: string | null | undefined, state?: CardState) => {
|
|
43
52
|
if (!state || state === "default") return "";
|
|
44
53
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
hover: "shadow-
|
|
48
|
-
focus: "ring-2 ring-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
hover: "bg-
|
|
56
|
-
focus: "ring-2 ring-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
hover: "border-border-hover bg-card-hover",
|
|
63
|
-
focus: "ring-2 ring-primary/20 ring-offset-2 ring-offset-background",
|
|
54
|
+
const stateMap: Record<string, Record<string, string>> = {
|
|
55
|
+
default: {
|
|
56
|
+
hover: "bg-white/80 dark:bg-white/[0.05] border-black/10 dark:border-white/10 shadow-[0_0_20px_var(--glow-primary-subtle)]",
|
|
57
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
58
|
+
},
|
|
59
|
+
elevated: {
|
|
60
|
+
hover: "shadow-xl shadow-[0_0_30px_var(--glow-primary)]",
|
|
61
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
62
|
+
},
|
|
63
|
+
subtle: {
|
|
64
|
+
hover: "bg-white/60 dark:bg-white/[0.04] border-black/8 dark:border-white/8",
|
|
65
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
66
|
+
},
|
|
67
|
+
solid: {
|
|
68
|
+
hover: "border-border-hover bg-card-hover",
|
|
69
|
+
focus: "ring-2 ring-[color:var(--sonance-blue)]/30 ring-offset-2 ring-offset-background",
|
|
70
|
+
},
|
|
64
71
|
};
|
|
65
72
|
|
|
66
|
-
return stateMap[state] || "";
|
|
73
|
+
return stateMap[variant || "default"]?.[state] || "";
|
|
67
74
|
};
|
|
68
75
|
|
|
69
76
|
// Create a context for passing size to children
|
|
70
|
-
import { createContext, useContext } from "react";
|
|
71
77
|
const CardSizeContext = createContext<"compact" | "default" | "spacious">("default");
|
|
72
78
|
|
|
73
79
|
export const Card = forwardRef<HTMLDivElement, CardProps>(
|