@sdods/ui 0.1.0 → 0.2.0
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/index.d.ts +94 -56
- package/dist/index.js +278 -277
- package/dist/index.js.map +1 -0
- package/package.json +37 -27
- package/src/styles/ui.css +44 -0
- package/dist/index.d.mts +0 -66
- package/dist/index.mjs +0 -270
package/dist/index.d.ts
CHANGED
|
@@ -1,66 +1,104 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ClassValue } from 'clsx';
|
|
2
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
2
3
|
import * as React from 'react';
|
|
4
|
+
import { VariantProps } from 'class-variance-authority';
|
|
5
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
6
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
7
|
+
import * as SwitchPrimitives from '@radix-ui/react-switch';
|
|
8
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
9
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
3
10
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
18
|
-
fonts: {
|
|
19
|
-
sans: string;
|
|
20
|
-
mono: string;
|
|
21
|
-
};
|
|
22
|
-
radii: {
|
|
23
|
-
sm: string;
|
|
24
|
-
md: string;
|
|
25
|
-
lg: string;
|
|
26
|
-
full: string;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
declare const themes: Record<string, Theme>;
|
|
30
|
-
interface ThemeProviderProps {
|
|
31
|
-
theme?: Theme | keyof typeof themes;
|
|
32
|
-
children: React.ReactNode;
|
|
33
|
-
}
|
|
34
|
-
declare function ThemeProvider({ theme, children }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
|
|
35
|
-
declare function useTheme(): Theme;
|
|
36
|
-
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
37
|
-
variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';
|
|
38
|
-
size?: 'sm' | 'md' | 'lg';
|
|
39
|
-
loading?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* cn() - Class Name utility
|
|
13
|
+
* Combines clsx for conditional classes + tailwind-merge for conflict resolution
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
17
|
+
|
|
18
|
+
declare const buttonVariants: (props?: ({
|
|
19
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
|
|
20
|
+
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
|
|
21
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
22
|
+
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
23
|
+
asChild?: boolean;
|
|
40
24
|
}
|
|
41
25
|
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Input Component
|
|
29
|
+
* Accessible text input with consistent styling
|
|
30
|
+
*/
|
|
31
|
+
|
|
46
32
|
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
47
|
-
error?: string;
|
|
48
|
-
label?: string;
|
|
49
33
|
}
|
|
50
34
|
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
35
|
+
|
|
36
|
+
declare const Label: React.ForwardRefExoticComponent<Omit<LabelPrimitive.LabelProps & React.RefAttributes<HTMLLabelElement>, "ref"> & VariantProps<(props?: class_variance_authority_types.ClassProp | undefined) => string> & React.RefAttributes<HTMLLabelElement>>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Separator Component
|
|
40
|
+
* Visual divider via Radix
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
declare const Separator: React.ForwardRefExoticComponent<Omit<SeparatorPrimitive.SeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Switch Component
|
|
47
|
+
* Accessible toggle switch via Radix
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
declare const Switch: React.ForwardRefExoticComponent<Omit<SwitchPrimitives.SwitchProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Card Component
|
|
54
|
+
* Container for content with consistent styling
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
declare const Card: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
58
|
+
declare const CardHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
59
|
+
declare const CardTitle: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLHeadingElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
60
|
+
declare const CardDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
|
|
61
|
+
declare const CardContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
62
|
+
declare const CardFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & React.RefAttributes<HTMLDivElement>>;
|
|
63
|
+
|
|
64
|
+
declare const Dialog: React.FC<DialogPrimitive.DialogProps>;
|
|
65
|
+
declare const DialogTrigger: React.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
66
|
+
declare const DialogPortal: React.FC<DialogPrimitive.DialogPortalProps>;
|
|
67
|
+
declare const DialogClose: React.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
|
|
68
|
+
declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
69
|
+
declare const DialogContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
70
|
+
declare const DialogHeader: {
|
|
71
|
+
({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
72
|
+
displayName: string;
|
|
73
|
+
};
|
|
74
|
+
declare const DialogFooter: {
|
|
75
|
+
({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
76
|
+
displayName: string;
|
|
77
|
+
};
|
|
78
|
+
declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
|
|
79
|
+
declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
|
|
80
|
+
|
|
81
|
+
interface GoogleOneTapProps {
|
|
82
|
+
clientId: string;
|
|
83
|
+
onSuccess?: (response: {
|
|
84
|
+
credential: string;
|
|
85
|
+
}) => void;
|
|
86
|
+
onError?: (error: Error) => void;
|
|
87
|
+
onDismiss?: () => void;
|
|
88
|
+
autoPrompt?: boolean;
|
|
89
|
+
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
57
90
|
className?: string;
|
|
58
91
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Manual One Tap UI (for when you want custom styling)
|
|
94
|
+
*/
|
|
95
|
+
declare function GoogleOneTapPrompt({ email, avatarUrl, onContinue, onDismiss, position, className, }: {
|
|
96
|
+
email: string;
|
|
97
|
+
avatarUrl?: string;
|
|
98
|
+
onContinue: () => void;
|
|
99
|
+
onDismiss: () => void;
|
|
100
|
+
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
101
|
+
className?: string;
|
|
102
|
+
}): react_jsx_runtime.JSX.Element;
|
|
65
103
|
|
|
66
|
-
export {
|
|
104
|
+
export { Button, type ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, GoogleOneTapPrompt as GoogleOneTap, GoogleOneTapPrompt, type GoogleOneTapProps, Input, type InputProps, Label, Separator, Switch, buttonVariants, cn };
|
package/dist/index.js
CHANGED
|
@@ -1,313 +1,314 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
1
|
+
import { clsx } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
import * as React6 from 'react';
|
|
4
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
8
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
9
|
+
import * as SwitchPrimitives from '@radix-ui/react-switch';
|
|
10
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
11
|
+
import { X } from 'lucide-react';
|
|
29
12
|
|
|
30
|
-
// src/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
secondary: "#7C3AED",
|
|
53
|
-
accent: "#06B6D4",
|
|
54
|
-
background: "#0F172A",
|
|
55
|
-
foreground: "#F8FAFC",
|
|
56
|
-
muted: "#64748B",
|
|
57
|
-
border: "#334155",
|
|
58
|
-
error: "#EF4444",
|
|
59
|
-
success: "#22C55E",
|
|
60
|
-
warning: "#F59E0B"
|
|
61
|
-
},
|
|
62
|
-
fonts: {
|
|
63
|
-
sans: "Inter, system-ui, sans-serif",
|
|
64
|
-
mono: "JetBrains Mono, monospace"
|
|
65
|
-
},
|
|
66
|
-
radii: {
|
|
67
|
-
sm: "0.25rem",
|
|
68
|
-
md: "0.5rem",
|
|
69
|
-
lg: "1rem",
|
|
70
|
-
full: "9999px"
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
light: {
|
|
74
|
-
name: "light",
|
|
75
|
-
colors: {
|
|
76
|
-
primary: "#2563EB",
|
|
77
|
-
secondary: "#7C3AED",
|
|
78
|
-
accent: "#06B6D4",
|
|
79
|
-
background: "#FFFFFF",
|
|
80
|
-
foreground: "#0F172A",
|
|
81
|
-
muted: "#64748B",
|
|
82
|
-
border: "#E2E8F0",
|
|
83
|
-
error: "#EF4444",
|
|
84
|
-
success: "#22C55E",
|
|
85
|
-
warning: "#F59E0B"
|
|
86
|
-
},
|
|
87
|
-
fonts: {
|
|
88
|
-
sans: "Inter, system-ui, sans-serif",
|
|
89
|
-
mono: "JetBrains Mono, monospace"
|
|
13
|
+
// src/lib/cn.ts
|
|
14
|
+
function cn(...inputs) {
|
|
15
|
+
return twMerge(clsx(inputs));
|
|
16
|
+
}
|
|
17
|
+
var buttonVariants = cva(
|
|
18
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
19
|
+
{
|
|
20
|
+
variants: {
|
|
21
|
+
variant: {
|
|
22
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
23
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
24
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
25
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
26
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
27
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
28
|
+
},
|
|
29
|
+
size: {
|
|
30
|
+
default: "h-10 px-4 py-2",
|
|
31
|
+
sm: "h-9 rounded-md px-3",
|
|
32
|
+
lg: "h-11 rounded-md px-8",
|
|
33
|
+
icon: "h-10 w-10"
|
|
34
|
+
}
|
|
90
35
|
},
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
lg: "1rem",
|
|
95
|
-
full: "9999px"
|
|
36
|
+
defaultVariants: {
|
|
37
|
+
variant: "default",
|
|
38
|
+
size: "default"
|
|
96
39
|
}
|
|
97
40
|
}
|
|
98
|
-
|
|
99
|
-
var
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{
|
|
105
|
-
style: {
|
|
106
|
-
"--color-primary": resolvedTheme.colors.primary,
|
|
107
|
-
"--color-secondary": resolvedTheme.colors.secondary,
|
|
108
|
-
"--color-accent": resolvedTheme.colors.accent,
|
|
109
|
-
"--color-background": resolvedTheme.colors.background,
|
|
110
|
-
"--color-foreground": resolvedTheme.colors.foreground,
|
|
111
|
-
"--color-muted": resolvedTheme.colors.muted,
|
|
112
|
-
"--color-border": resolvedTheme.colors.border,
|
|
113
|
-
"--color-error": resolvedTheme.colors.error,
|
|
114
|
-
"--color-success": resolvedTheme.colors.success,
|
|
115
|
-
"--color-warning": resolvedTheme.colors.warning,
|
|
116
|
-
"--font-sans": resolvedTheme.fonts.sans,
|
|
117
|
-
"--font-mono": resolvedTheme.fonts.mono,
|
|
118
|
-
"--radius-sm": resolvedTheme.radii.sm,
|
|
119
|
-
"--radius-md": resolvedTheme.radii.md,
|
|
120
|
-
"--radius-lg": resolvedTheme.radii.lg,
|
|
121
|
-
"--radius-full": resolvedTheme.radii.full
|
|
122
|
-
},
|
|
123
|
-
children
|
|
124
|
-
}
|
|
125
|
-
) });
|
|
126
|
-
}
|
|
127
|
-
function useTheme() {
|
|
128
|
-
return React.useContext(ThemeContext);
|
|
129
|
-
}
|
|
130
|
-
var Button = React.forwardRef(
|
|
131
|
-
({ variant = "primary", size = "md", loading, className, children, disabled, ...props }, ref) => {
|
|
132
|
-
const baseStyles = "inline-flex items-center justify-center font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none";
|
|
133
|
-
const variants = {
|
|
134
|
-
primary: "bg-[var(--color-primary)] text-white hover:opacity-90 focus:ring-[var(--color-primary)]",
|
|
135
|
-
secondary: "bg-[var(--color-secondary)] text-white hover:opacity-90 focus:ring-[var(--color-secondary)]",
|
|
136
|
-
outline: "border border-[var(--color-border)] bg-transparent hover:bg-[var(--color-muted)]/10",
|
|
137
|
-
ghost: "bg-transparent hover:bg-[var(--color-muted)]/10",
|
|
138
|
-
destructive: "bg-[var(--color-error)] text-white hover:opacity-90 focus:ring-[var(--color-error)]"
|
|
139
|
-
};
|
|
140
|
-
const sizes = {
|
|
141
|
-
sm: "h-8 px-3 text-sm rounded-[var(--radius-sm)]",
|
|
142
|
-
md: "h-10 px-4 text-base rounded-[var(--radius-md)]",
|
|
143
|
-
lg: "h-12 px-6 text-lg rounded-[var(--radius-md)]"
|
|
144
|
-
};
|
|
145
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
146
|
-
"button",
|
|
41
|
+
);
|
|
42
|
+
var Button = React6.forwardRef(
|
|
43
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
44
|
+
const Comp = asChild ? Slot : "button";
|
|
45
|
+
return /* @__PURE__ */ jsx(
|
|
46
|
+
Comp,
|
|
147
47
|
{
|
|
48
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
148
49
|
ref,
|
|
149
|
-
|
|
150
|
-
disabled: disabled || loading,
|
|
151
|
-
...props,
|
|
152
|
-
children: [
|
|
153
|
-
loading && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4", fill: "none", viewBox: "0 0 24 24", children: [
|
|
154
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
155
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
156
|
-
] }),
|
|
157
|
-
children
|
|
158
|
-
]
|
|
50
|
+
...props
|
|
159
51
|
}
|
|
160
52
|
);
|
|
161
53
|
}
|
|
162
54
|
);
|
|
163
55
|
Button.displayName = "Button";
|
|
164
|
-
var
|
|
165
|
-
({
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
elevated: "bg-[var(--color-background)] shadow-lg",
|
|
169
|
-
outlined: "bg-transparent border-2 border-[var(--color-border)]"
|
|
170
|
-
};
|
|
171
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
172
|
-
"div",
|
|
56
|
+
var Input = React6.forwardRef(
|
|
57
|
+
({ className, type, ...props }, ref) => {
|
|
58
|
+
return /* @__PURE__ */ jsx(
|
|
59
|
+
"input",
|
|
173
60
|
{
|
|
174
|
-
|
|
175
|
-
className: (
|
|
176
|
-
"rounded-
|
|
177
|
-
variants[variant],
|
|
61
|
+
type,
|
|
62
|
+
className: cn(
|
|
63
|
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
178
64
|
className
|
|
179
65
|
),
|
|
180
|
-
|
|
181
|
-
|
|
66
|
+
ref,
|
|
67
|
+
...props
|
|
182
68
|
}
|
|
183
69
|
);
|
|
184
70
|
}
|
|
185
71
|
);
|
|
186
|
-
|
|
187
|
-
var
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
id: inputId,
|
|
197
|
-
className: (0, import_clsx.clsx)(
|
|
198
|
-
"h-10 px-3 rounded-[var(--radius-md)] border bg-[var(--color-background)] text-[var(--color-foreground)]",
|
|
199
|
-
"focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]",
|
|
200
|
-
error ? "border-[var(--color-error)]" : "border-[var(--color-border)]",
|
|
201
|
-
className
|
|
202
|
-
),
|
|
203
|
-
...props
|
|
204
|
-
}
|
|
205
|
-
),
|
|
206
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm text-[var(--color-error)]", children: error })
|
|
207
|
-
] });
|
|
72
|
+
Input.displayName = "Input";
|
|
73
|
+
var labelVariants = cva(
|
|
74
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
75
|
+
);
|
|
76
|
+
var Label = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
77
|
+
LabelPrimitive.Root,
|
|
78
|
+
{
|
|
79
|
+
ref,
|
|
80
|
+
className: cn(labelVariants(), className),
|
|
81
|
+
...props
|
|
208
82
|
}
|
|
83
|
+
));
|
|
84
|
+
Label.displayName = LabelPrimitive.Root.displayName;
|
|
85
|
+
var Separator = React6.forwardRef(
|
|
86
|
+
({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
87
|
+
SeparatorPrimitive.Root,
|
|
88
|
+
{
|
|
89
|
+
ref,
|
|
90
|
+
decorative,
|
|
91
|
+
orientation,
|
|
92
|
+
className: cn(
|
|
93
|
+
"shrink-0 bg-border",
|
|
94
|
+
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
|
95
|
+
className
|
|
96
|
+
),
|
|
97
|
+
...props
|
|
98
|
+
}
|
|
99
|
+
)
|
|
209
100
|
);
|
|
210
|
-
|
|
211
|
-
var
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
101
|
+
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
|
102
|
+
var Switch = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
103
|
+
SwitchPrimitives.Root,
|
|
104
|
+
{
|
|
105
|
+
className: cn(
|
|
106
|
+
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
|
107
|
+
className
|
|
108
|
+
),
|
|
109
|
+
...props,
|
|
110
|
+
ref,
|
|
111
|
+
children: /* @__PURE__ */ jsx(
|
|
112
|
+
SwitchPrimitives.Thumb,
|
|
222
113
|
{
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
variants[variant],
|
|
227
|
-
className
|
|
228
|
-
),
|
|
229
|
-
...props
|
|
114
|
+
className: cn(
|
|
115
|
+
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
|
|
116
|
+
)
|
|
230
117
|
}
|
|
231
|
-
)
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
));
|
|
121
|
+
Switch.displayName = SwitchPrimitives.Root.displayName;
|
|
122
|
+
var Card = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
123
|
+
"div",
|
|
124
|
+
{
|
|
125
|
+
ref,
|
|
126
|
+
className: cn(
|
|
127
|
+
"rounded-lg border bg-card text-card-foreground shadow-sm",
|
|
128
|
+
className
|
|
129
|
+
),
|
|
130
|
+
...props
|
|
131
|
+
}
|
|
132
|
+
));
|
|
133
|
+
Card.displayName = "Card";
|
|
134
|
+
var CardHeader = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
135
|
+
"div",
|
|
136
|
+
{
|
|
137
|
+
ref,
|
|
138
|
+
className: cn("flex flex-col space-y-1.5 p-6", className),
|
|
139
|
+
...props
|
|
140
|
+
}
|
|
141
|
+
));
|
|
142
|
+
CardHeader.displayName = "CardHeader";
|
|
143
|
+
var CardTitle = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
144
|
+
"h3",
|
|
145
|
+
{
|
|
146
|
+
ref,
|
|
147
|
+
className: cn("text-2xl font-semibold leading-none tracking-tight", className),
|
|
148
|
+
...props
|
|
149
|
+
}
|
|
150
|
+
));
|
|
151
|
+
CardTitle.displayName = "CardTitle";
|
|
152
|
+
var CardDescription = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
153
|
+
"p",
|
|
154
|
+
{
|
|
155
|
+
ref,
|
|
156
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
157
|
+
...props
|
|
158
|
+
}
|
|
159
|
+
));
|
|
160
|
+
CardDescription.displayName = "CardDescription";
|
|
161
|
+
var CardContent = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
|
|
162
|
+
CardContent.displayName = "CardContent";
|
|
163
|
+
var CardFooter = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
164
|
+
"div",
|
|
165
|
+
{
|
|
166
|
+
ref,
|
|
167
|
+
className: cn("flex items-center p-6 pt-0", className),
|
|
168
|
+
...props
|
|
169
|
+
}
|
|
170
|
+
));
|
|
171
|
+
CardFooter.displayName = "CardFooter";
|
|
172
|
+
var Dialog = DialogPrimitive.Root;
|
|
173
|
+
var DialogTrigger = DialogPrimitive.Trigger;
|
|
174
|
+
var DialogPortal = DialogPrimitive.Portal;
|
|
175
|
+
var DialogClose = DialogPrimitive.Close;
|
|
176
|
+
var DialogOverlay = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
177
|
+
DialogPrimitive.Overlay,
|
|
178
|
+
{
|
|
179
|
+
ref,
|
|
180
|
+
className: cn(
|
|
181
|
+
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
182
|
+
className
|
|
183
|
+
),
|
|
184
|
+
...props
|
|
185
|
+
}
|
|
186
|
+
));
|
|
187
|
+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
188
|
+
var DialogContent = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
|
|
189
|
+
/* @__PURE__ */ jsx(DialogOverlay, {}),
|
|
190
|
+
/* @__PURE__ */ jsxs(
|
|
191
|
+
DialogPrimitive.Content,
|
|
192
|
+
{
|
|
193
|
+
ref,
|
|
194
|
+
className: cn(
|
|
195
|
+
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
|
196
|
+
className
|
|
197
|
+
),
|
|
198
|
+
...props,
|
|
199
|
+
children: [
|
|
200
|
+
children,
|
|
201
|
+
/* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
|
|
202
|
+
/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }),
|
|
203
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
|
|
204
|
+
] })
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
)
|
|
208
|
+
] }));
|
|
209
|
+
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
210
|
+
var DialogHeader = ({
|
|
211
|
+
className,
|
|
212
|
+
...props
|
|
213
|
+
}) => /* @__PURE__ */ jsx(
|
|
214
|
+
"div",
|
|
215
|
+
{
|
|
216
|
+
className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className),
|
|
217
|
+
...props
|
|
218
|
+
}
|
|
219
|
+
);
|
|
220
|
+
DialogHeader.displayName = "DialogHeader";
|
|
221
|
+
var DialogFooter = ({
|
|
222
|
+
className,
|
|
223
|
+
...props
|
|
224
|
+
}) => /* @__PURE__ */ jsx(
|
|
225
|
+
"div",
|
|
226
|
+
{
|
|
227
|
+
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
228
|
+
...props
|
|
232
229
|
}
|
|
233
230
|
);
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
231
|
+
DialogFooter.displayName = "DialogFooter";
|
|
232
|
+
var DialogTitle = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
233
|
+
DialogPrimitive.Title,
|
|
234
|
+
{
|
|
235
|
+
ref,
|
|
236
|
+
className: cn("text-lg font-semibold leading-none tracking-tight", className),
|
|
237
|
+
...props
|
|
238
|
+
}
|
|
239
|
+
));
|
|
240
|
+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
241
|
+
var DialogDescription = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
242
|
+
DialogPrimitive.Description,
|
|
243
|
+
{
|
|
244
|
+
ref,
|
|
245
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
246
|
+
...props
|
|
247
|
+
}
|
|
248
|
+
));
|
|
249
|
+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
250
|
+
function GoogleOneTapPrompt({
|
|
251
|
+
email,
|
|
252
|
+
avatarUrl,
|
|
253
|
+
onContinue,
|
|
254
|
+
onDismiss,
|
|
255
|
+
position = "top-right",
|
|
256
|
+
className
|
|
257
|
+
}) {
|
|
258
|
+
const positionClasses = {
|
|
259
|
+
"top-right": "top-4 right-4",
|
|
260
|
+
"top-left": "top-4 left-4",
|
|
261
|
+
"bottom-right": "bottom-4 right-4",
|
|
262
|
+
"bottom-left": "bottom-4 left-4"
|
|
240
263
|
};
|
|
241
|
-
return /* @__PURE__ */
|
|
242
|
-
"
|
|
264
|
+
return /* @__PURE__ */ jsxs(
|
|
265
|
+
"div",
|
|
243
266
|
{
|
|
244
|
-
className: (
|
|
245
|
-
|
|
246
|
-
|
|
267
|
+
className: cn(
|
|
268
|
+
"fixed z-50 w-80 bg-background border rounded-lg shadow-2xl p-4 animate-in slide-in-from-right-5 fade-in-0",
|
|
269
|
+
positionClasses[position],
|
|
270
|
+
className
|
|
271
|
+
),
|
|
247
272
|
children: [
|
|
248
|
-
/* @__PURE__ */
|
|
249
|
-
"
|
|
273
|
+
/* @__PURE__ */ jsx(
|
|
274
|
+
"button",
|
|
250
275
|
{
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
stroke: "currentColor",
|
|
256
|
-
strokeWidth: "4"
|
|
276
|
+
onClick: onDismiss,
|
|
277
|
+
className: "absolute top-2 right-2 p-1 text-muted-foreground hover:text-foreground rounded-full hover:bg-accent transition-colors",
|
|
278
|
+
"aria-label": "Dismiss",
|
|
279
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
257
280
|
}
|
|
258
281
|
),
|
|
259
|
-
/* @__PURE__ */ (
|
|
260
|
-
"
|
|
282
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
283
|
+
/* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", children: [
|
|
284
|
+
/* @__PURE__ */ jsx("path", { fill: "#4285F4", d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" }),
|
|
285
|
+
/* @__PURE__ */ jsx("path", { fill: "#34A853", d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" }),
|
|
286
|
+
/* @__PURE__ */ jsx("path", { fill: "#FBBC05", d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" }),
|
|
287
|
+
/* @__PURE__ */ jsx("path", { fill: "#EA4335", d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" })
|
|
288
|
+
] }),
|
|
289
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Sign in with Google" })
|
|
290
|
+
] }),
|
|
291
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 p-3 bg-accent/50 rounded-lg mb-3", children: [
|
|
292
|
+
avatarUrl ? /* @__PURE__ */ jsx("img", { src: avatarUrl, alt: "", className: "w-10 h-10 rounded-full" }) : /* @__PURE__ */ jsx("div", { className: "w-10 h-10 rounded-full bg-primary flex items-center justify-center text-primary-foreground font-medium", children: email.charAt(0).toUpperCase() }),
|
|
293
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("div", { className: "text-sm font-medium truncate", children: email }) })
|
|
294
|
+
] }),
|
|
295
|
+
/* @__PURE__ */ jsxs(
|
|
296
|
+
"button",
|
|
261
297
|
{
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
298
|
+
onClick: onContinue,
|
|
299
|
+
className: "w-full py-2.5 px-4 bg-primary text-primary-foreground rounded-md font-medium hover:bg-primary/90 transition-colors",
|
|
300
|
+
children: [
|
|
301
|
+
"Continue as ",
|
|
302
|
+
email.split("@")[0]
|
|
303
|
+
]
|
|
265
304
|
}
|
|
266
|
-
)
|
|
267
|
-
]
|
|
268
|
-
}
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
function Avatar({ size = "md", fallback, src, alt, className, ...props }) {
|
|
272
|
-
const [error, setError] = React.useState(false);
|
|
273
|
-
const sizes = {
|
|
274
|
-
sm: "h-8 w-8 text-xs",
|
|
275
|
-
md: "h-10 w-10 text-sm",
|
|
276
|
-
lg: "h-16 w-16 text-lg"
|
|
277
|
-
};
|
|
278
|
-
if (error || !src) {
|
|
279
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
280
|
-
"div",
|
|
281
|
-
{
|
|
282
|
-
className: (0, import_clsx.clsx)(
|
|
283
|
-
"flex items-center justify-center rounded-[var(--radius-full)] bg-[var(--color-primary)] text-white font-medium",
|
|
284
|
-
sizes[size],
|
|
285
|
-
className
|
|
286
305
|
),
|
|
287
|
-
children:
|
|
288
|
-
|
|
289
|
-
);
|
|
290
|
-
}
|
|
291
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
292
|
-
"img",
|
|
293
|
-
{
|
|
294
|
-
src,
|
|
295
|
-
alt,
|
|
296
|
-
onError: () => setError(true),
|
|
297
|
-
className: (0, import_clsx.clsx)("rounded-[var(--radius-full)] object-cover", sizes[size], className),
|
|
298
|
-
...props
|
|
306
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-3 leading-relaxed", children: "To create your account, Google will share your name, email address, and profile picture." })
|
|
307
|
+
]
|
|
299
308
|
}
|
|
300
309
|
);
|
|
301
310
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
Button,
|
|
307
|
-
Card,
|
|
308
|
-
Input,
|
|
309
|
-
Spinner,
|
|
310
|
-
ThemeProvider,
|
|
311
|
-
themes,
|
|
312
|
-
useTheme
|
|
313
|
-
});
|
|
311
|
+
|
|
312
|
+
export { Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, GoogleOneTapPrompt as GoogleOneTap, GoogleOneTapPrompt, Input, Label, Separator, Switch, buttonVariants, cn };
|
|
313
|
+
//# sourceMappingURL=index.js.map
|
|
314
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/cn.ts","../src/components/primitives/button.tsx","../src/components/primitives/input.tsx","../src/components/primitives/label.tsx","../src/components/primitives/separator.tsx","../src/components/primitives/switch.tsx","../src/components/primitives/card.tsx","../src/components/primitives/dialog.tsx","../src/components/patterns/google-one-tap.tsx"],"names":["React","React2","jsx","cva","React3","React4","React5","React7","jsxs","X"],"mappings":";;;;;;;;;;;;;AAOO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACAA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,mUAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,wDAAA;AAAA,QACT,WAAA,EAAa,oEAAA;AAAA,QACb,OAAA,EAAS,gFAAA;AAAA,QACT,SAAA,EAAW,8DAAA;AAAA,QACX,KAAA,EAAO,8CAAA;AAAA,QACP,IAAA,EAAM;AAAA,OACR;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,gBAAA;AAAA,QACT,EAAA,EAAI,qBAAA;AAAA,QACJ,EAAA,EAAI,sBAAA;AAAA,QACJ,IAAA,EAAM;AAAA;AACR,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAQA,IAAM,MAAA,GAAeA,MAAA,CAAA,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,OAAA,EAAS,IAAA,EAAM,UAAU,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAChE,IAAA,MAAM,IAAA,GAAO,UAAU,IAAA,GAAO,QAAA;AAC9B,IAAA,uBACE,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,QAC1D,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA;AC5CrB,IAAM,KAAA,GAAcC,MAAA,CAAA,UAAA;AAAA,EAClB,CAAC,EAAE,SAAA,EAAW,MAAM,GAAG,KAAA,IAAS,GAAA,KAAQ;AACtC,IAAA,uBACEC,GAAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,mXAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA;ACfpB,IAAM,aAAA,GAAgBC,GAAAA;AAAA,EACpB;AACF,CAAA;AAEA,IAAM,KAAA,GAAcC,kBAIlB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BF,GAAAA;AAAA,EAAgB,cAAA,CAAA,IAAA;AAAA,EAAf;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,aAAA,EAAc,EAAG,SAAS,CAAA;AAAA,IACvC,GAAG;AAAA;AACN,CACD;AACD,KAAA,CAAM,cAA6B,cAAA,CAAA,IAAA,CAAK,WAAA;AChBxC,IAAM,SAAA,GAAkBG,MAAA,CAAA,UAAA;AAAA,EAItB,CACE,EAAE,SAAA,EAAW,WAAA,GAAc,YAAA,EAAc,UAAA,GAAa,IAAA,EAAM,GAAG,KAAA,EAAM,EACrE,GAAA,qBAEAH,GAAAA;AAAA,IAAoB,kBAAA,CAAA,IAAA;AAAA,IAAnB;AAAA,MACC,GAAA;AAAA,MACA,UAAA;AAAA,MACA,WAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,oBAAA;AAAA,QACA,WAAA,KAAgB,eAAe,gBAAA,GAAmB,gBAAA;AAAA,QAClD;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA;AAGV;AACA,SAAA,CAAU,cAAiC,kBAAA,CAAA,IAAA,CAAK,WAAA;ACrBhD,IAAM,MAAA,GAAeI,kBAGnB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BJ,GAAAA;AAAA,EAAkB,gBAAA,CAAA,IAAA;AAAA,EAAjB;AAAA,IACC,SAAA,EAAW,EAAA;AAAA,MACT,oXAAA;AAAA,MACA;AAAA,KACF;AAAA,IACC,GAAG,KAAA;AAAA,IACJ,GAAA;AAAA,IAEA,QAAA,kBAAAA,GAAAA;AAAA,MAAkB,gBAAA,CAAA,KAAA;AAAA,MAAjB;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT;AAAA;AACF;AAAA;AACF;AACF,CACD;AACD,MAAA,CAAO,cAA+B,gBAAA,CAAA,IAAA,CAAK,WAAA;ACpB3C,IAAM,IAAA,GAAa,kBAGjB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACT,0DAAA;AAAA,MACA;AAAA,KACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,IAAA,CAAK,WAAA,GAAc,MAAA;AAEnB,IAAM,UAAA,GAAmB,kBAGvB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,IACvD,GAAG;AAAA;AACN,CACD;AACD,UAAA,CAAW,WAAA,GAAc,YAAA;AAEzB,IAAM,SAAA,GAAkB,kBAGtB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAC,IAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,oDAAA,EAAsD,SAAS,CAAA;AAAA,IAC5E,GAAG;AAAA;AACN,CACD;AACD,SAAA,CAAU,WAAA,GAAc,WAAA;AAExB,IAAM,eAAA,GAAwB,kBAG5B,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAC,GAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,IACvD,GAAG;AAAA;AACN,CACD;AACD,eAAA,CAAgB,WAAA,GAAc,iBAAA;AAE9B,IAAM,WAAA,GAAoB,kBAGxB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC1BA,IAAC,KAAA,EAAA,EAAI,GAAA,EAAU,WAAW,EAAA,CAAG,UAAA,EAAY,SAAS,CAAA,EAAI,GAAG,OAAO,CACjE;AACD,WAAA,CAAY,WAAA,GAAc,aAAA;AAE1B,IAAM,UAAA,GAAmB,kBAGvB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BA,GAAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,4BAAA,EAA8B,SAAS,CAAA;AAAA,IACpD,GAAG;AAAA;AACN,CACD;AACD,UAAA,CAAW,WAAA,GAAc,YAAA;ACnEzB,IAAM,MAAA,GAAyB,eAAA,CAAA;AAC/B,IAAM,aAAA,GAAgC,eAAA,CAAA;AACtC,IAAM,YAAA,GAA+B,eAAA,CAAA;AACrC,IAAM,WAAA,GAA8B,eAAA,CAAA;AAEpC,IAAM,aAAA,GAAsBK,kBAG1B,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BL,GAAAA;AAAA,EAAiB,eAAA,CAAA,OAAA;AAAA,EAAhB;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA;AAAA,MACT,wJAAA;AAAA,MACA;AAAA,KACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,aAAA,CAAc,cAA8B,eAAA,CAAA,OAAA,CAAQ,WAAA;AAEpD,IAAM,aAAA,GAAsBK,MAAA,CAAA,UAAA,CAG1B,CAAC,EAAE,SAAA,EAAW,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,qBACpC,IAAA,CAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,kBAAAL,IAAC,aAAA,EAAA,EAAc,CAAA;AAAA,kBACf,IAAA;AAAA,IAAiB,eAAA,CAAA,OAAA;AAAA,IAAhB;AAAA,MACC,GAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,6fAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACD,IAAA,CAAiB,eAAA,CAAA,KAAA,EAAhB,EAAsB,SAAA,EAAU,+QAAA,EAC/B,QAAA,EAAA;AAAA,0BAAAA,GAAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,SAAA,EAAU,CAAA;AAAA,0BACvBA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,WAAU,QAAA,EAAA,OAAA,EAAK;AAAA,SAAA,EACjC;AAAA;AAAA;AAAA;AACF,CAAA,EACF,CACD;AACD,aAAA,CAAc,cAA8B,eAAA,CAAA,OAAA,CAAQ,WAAA;AAEpD,IAAM,eAAe,CAAC;AAAA,EACpB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,qBACEA,GAAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,SAAA,EAAW,EAAA,CAAG,oDAAA,EAAsD,SAAS,CAAA;AAAA,IAC5E,GAAG;AAAA;AACN;AAEF,YAAA,CAAa,WAAA,GAAc,cAAA;AAE3B,IAAM,eAAe,CAAC;AAAA,EACpB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,qBACEA,GAAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,SAAA,EAAW,EAAA,CAAG,+DAAA,EAAiE,SAAS,CAAA;AAAA,IACvF,GAAG;AAAA;AACN;AAEF,YAAA,CAAa,WAAA,GAAc,cAAA;AAE3B,IAAM,WAAA,GAAoBK,kBAGxB,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BL,GAAAA;AAAA,EAAiB,eAAA,CAAA,KAAA;AAAA,EAAhB;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,mDAAA,EAAqD,SAAS,CAAA;AAAA,IAC3E,GAAG;AAAA;AACN,CACD;AACD,WAAA,CAAY,cAA8B,eAAA,CAAA,KAAA,CAAM,WAAA;AAEhD,IAAM,iBAAA,GAA0BK,kBAG9B,CAAC,EAAE,WAAW,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1BL,GAAAA;AAAA,EAAiB,eAAA,CAAA,WAAA;AAAA,EAAhB;AAAA,IACC,GAAA;AAAA,IACA,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,IACvD,GAAG;AAAA;AACN,CACD;AACD,iBAAA,CAAkB,cAA8B,eAAA,CAAA,WAAA,CAAY,WAAA;AC7ErD,SAAS,kBAAA,CAAmB;AAAA,EACjC,KAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA,GAAW,WAAA;AAAA,EACX;AACF,CAAA,EAOG;AACD,EAAA,MAAM,eAAA,GAAkB;AAAA,IACtB,WAAA,EAAa,eAAA;AAAA,IACb,UAAA,EAAY,cAAA;AAAA,IACZ,cAAA,EAAgB,kBAAA;AAAA,IAChB,aAAA,EAAe;AAAA,GACjB;AAEA,EAAA,uBACEM,IAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA;AAAA,QACT,2GAAA;AAAA,QACA,gBAAgB,QAAQ,CAAA;AAAA,QACxB;AAAA,OACF;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAAN,GAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,SAAA;AAAA,YACT,SAAA,EAAU,uHAAA;AAAA,YACV,YAAA,EAAW,SAAA;AAAA,YAEX,QAAA,kBAAAA,GAAAA,CAACO,CAAAA,EAAA,EAAE,WAAU,SAAA,EAAU;AAAA;AAAA,SACzB;AAAA,wBAEAD,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,IAAAA,CAAC,KAAA,EAAA,EAAI,OAAA,EAAQ,WAAA,EAAY,WAAU,SAAA,EACjC,QAAA,EAAA;AAAA,4BAAAN,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,SAAA,EAAU,GAAE,yHAAA,EAAyH,CAAA;AAAA,4BAChJA,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,SAAA,EAAU,GAAE,uIAAA,EAAuI,CAAA;AAAA,4BAC9JA,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,SAAA,EAAU,GAAE,+HAAA,EAA+H,CAAA;AAAA,4BACtJA,GAAAA,CAAC,MAAA,EAAA,EAAK,IAAA,EAAK,SAAA,EAAU,GAAE,qIAAA,EAAqI;AAAA,WAAA,EAC9J,CAAA;AAAA,0BACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAgC,QAAA,EAAA,qBAAA,EAAmB;AAAA,SAAA,EACrE,CAAA;AAAA,wBAEAM,IAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,0DAAA,EACZ,QAAA,EAAA;AAAA,UAAA,SAAA,mBACCN,IAAC,KAAA,EAAA,EAAI,GAAA,EAAK,WAAW,GAAA,EAAI,EAAA,EAAG,WAAU,wBAAA,EAAyB,CAAA,mBAE/DA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,wGAAA,EACZ,QAAA,EAAA,KAAA,CAAM,OAAO,CAAC,CAAA,CAAE,aAAY,EAC/B,CAAA;AAAA,0BAEFA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8BAAA,EAAgC,QAAA,EAAA,KAAA,EAAM,CAAA,EACvD;AAAA,SAAA,EACF,CAAA;AAAA,wBAEAM,IAAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,OAAA,EAAS,UAAA;AAAA,YACT,SAAA,EAAU,oHAAA;AAAA,YACX,QAAA,EAAA;AAAA,cAAA,cAAA;AAAA,cACc,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC;AAAA;AAAA;AAAA,SACjC;AAAA,wBAEAN,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sDAAqD,QAAA,EAAA,0FAAA,EAElE;AAAA;AAAA;AAAA,GACF;AAEJ","file":"index.js","sourcesContent":["/**\n * cn() - Class Name utility\n * Combines clsx for conditional classes + tailwind-merge for conflict resolution\n */\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","/**\n * Button Component\n * Accessible button with variants via CVA\n */\nimport * as React from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../lib/cn';\n\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 px-4 py-2',\n sm: 'h-9 rounded-md px-3',\n lg: 'h-11 rounded-md px-8',\n icon: 'h-10 w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n }\n);\nButton.displayName = 'Button';\n\nexport { Button, buttonVariants };\n","/**\n * Input Component\n * Accessible text input with consistent styling\n */\nimport * as React from 'react';\nimport { cn } from '../../lib/cn';\n\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n 'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n ref={ref}\n {...props}\n />\n );\n }\n);\nInput.displayName = 'Input';\n\nexport { Input };\n","/**\n * Label Component\n * Accessible form label via Radix\n */\nimport * as React from 'react';\nimport * as LabelPrimitive from '@radix-ui/react-label';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../lib/cn';\n\nconst labelVariants = cva(\n 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'\n);\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &\n VariantProps<typeof labelVariants>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root\n ref={ref}\n className={cn(labelVariants(), className)}\n {...props}\n />\n));\nLabel.displayName = LabelPrimitive.Root.displayName;\n\nexport { Label };\n","/**\n * Separator Component\n * Visual divider via Radix\n */\nimport * as React from 'react';\nimport * as SeparatorPrimitive from '@radix-ui/react-separator';\nimport { cn } from '../../lib/cn';\n\nconst Separator = React.forwardRef<\n React.ElementRef<typeof SeparatorPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>\n>(\n (\n { className, orientation = 'horizontal', decorative = true, ...props },\n ref\n ) => (\n <SeparatorPrimitive.Root\n ref={ref}\n decorative={decorative}\n orientation={orientation}\n className={cn(\n 'shrink-0 bg-border',\n orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',\n className\n )}\n {...props}\n />\n )\n);\nSeparator.displayName = SeparatorPrimitive.Root.displayName;\n\nexport { Separator };\n","/**\n * Switch Component\n * Accessible toggle switch via Radix\n */\nimport * as React from 'react';\nimport * as SwitchPrimitives from '@radix-ui/react-switch';\nimport { cn } from '../../lib/cn';\n\nconst Switch = React.forwardRef<\n React.ElementRef<typeof SwitchPrimitives.Root>,\n React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>\n>(({ className, ...props }, ref) => (\n <SwitchPrimitives.Root\n className={cn(\n 'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',\n className\n )}\n {...props}\n ref={ref}\n >\n <SwitchPrimitives.Thumb\n className={cn(\n 'pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0'\n )}\n />\n </SwitchPrimitives.Root>\n));\nSwitch.displayName = SwitchPrimitives.Root.displayName;\n\nexport { Switch };\n","/**\n * Card Component\n * Container for content with consistent styling\n */\nimport * as React from 'react';\nimport { cn } from '../../lib/cn';\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'rounded-lg border bg-card text-card-foreground shadow-sm',\n className\n )}\n {...props}\n />\n));\nCard.displayName = 'Card';\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex flex-col space-y-1.5 p-6', className)}\n {...props}\n />\n));\nCardHeader.displayName = 'CardHeader';\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn('text-2xl font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nCardTitle.displayName = 'CardTitle';\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nCardDescription.displayName = 'CardDescription';\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn('p-6 pt-0', className)} {...props} />\n));\nCardContent.displayName = 'CardContent';\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center p-6 pt-0', className)}\n {...props}\n />\n));\nCardFooter.displayName = 'CardFooter';\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };\n","/**\n * Dialog Component\n * Accessible modal dialog via Radix\n */\nimport * as React from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { X } from 'lucide-react';\nimport { cn } from '../../lib/cn';\n\nconst Dialog = DialogPrimitive.Root;\nconst DialogTrigger = DialogPrimitive.Trigger;\nconst DialogPortal = DialogPrimitive.Portal;\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n className={cn(\n 'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n className\n )}\n {...props}\n />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>\n>(({ className, children, ...props }, ref) => (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n className={cn(\n 'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',\n className\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground\">\n <X className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </DialogPortal>\n));\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)}\n {...props}\n />\n);\nDialogHeader.displayName = 'DialogHeader';\n\nconst DialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}\n {...props}\n />\n);\nDialogFooter.displayName = 'DialogFooter';\n\nconst DialogTitle = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n React.ElementRef<typeof DialogPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n","/**\n * Google One Tap Pattern\n * Floating login prompt in corner (like Mailchimp)\n */\nimport { cn } from '../../lib/cn';\nimport { X } from 'lucide-react';\n\nexport interface GoogleOneTapProps {\n clientId: string;\n onSuccess?: (response: { credential: string }) => void;\n onError?: (error: Error) => void;\n onDismiss?: () => void;\n autoPrompt?: boolean;\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';\n className?: string;\n}\n\n/**\n * Manual One Tap UI (for when you want custom styling)\n */\nexport function GoogleOneTapPrompt({\n email,\n avatarUrl,\n onContinue,\n onDismiss,\n position = 'top-right',\n className,\n}: {\n email: string;\n avatarUrl?: string;\n onContinue: () => void;\n onDismiss: () => void;\n position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';\n className?: string;\n}) {\n const positionClasses = {\n 'top-right': 'top-4 right-4',\n 'top-left': 'top-4 left-4',\n 'bottom-right': 'bottom-4 right-4',\n 'bottom-left': 'bottom-4 left-4',\n };\n\n return (\n <div\n className={cn(\n 'fixed z-50 w-80 bg-background border rounded-lg shadow-2xl p-4 animate-in slide-in-from-right-5 fade-in-0',\n positionClasses[position],\n className\n )}\n >\n <button\n onClick={onDismiss}\n className=\"absolute top-2 right-2 p-1 text-muted-foreground hover:text-foreground rounded-full hover:bg-accent transition-colors\"\n aria-label=\"Dismiss\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n\n <div className=\"flex items-center gap-2 mb-3\">\n <svg viewBox=\"0 0 24 24\" className=\"h-5 w-5\">\n <path fill=\"#4285F4\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"/>\n <path fill=\"#34A853\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/>\n <path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"/>\n <path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/>\n </svg>\n <span className=\"text-sm text-muted-foreground\">Sign in with Google</span>\n </div>\n\n <div className=\"flex items-center gap-3 p-3 bg-accent/50 rounded-lg mb-3\">\n {avatarUrl ? (\n <img src={avatarUrl} alt=\"\" className=\"w-10 h-10 rounded-full\" />\n ) : (\n <div className=\"w-10 h-10 rounded-full bg-primary flex items-center justify-center text-primary-foreground font-medium\">\n {email.charAt(0).toUpperCase()}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium truncate\">{email}</div>\n </div>\n </div>\n\n <button\n onClick={onContinue}\n className=\"w-full py-2.5 px-4 bg-primary text-primary-foreground rounded-md font-medium hover:bg-primary/90 transition-colors\"\n >\n Continue as {email.split('@')[0]}\n </button>\n\n <p className=\"text-xs text-muted-foreground mt-3 leading-relaxed\">\n To create your account, Google will share your name, email address, and profile picture.\n </p>\n </div>\n );\n}\n\nexport { GoogleOneTapPrompt as GoogleOneTap };\n"]}
|
package/package.json
CHANGED
|
@@ -1,49 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdods/ui",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Portable, accessible UI components built on Radix + Tailwind",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"main": "./dist/index.js",
|
|
6
|
-
"module": "./dist/index.
|
|
7
|
+
"module": "./dist/index.js",
|
|
7
8
|
"types": "./dist/index.d.ts",
|
|
8
9
|
"exports": {
|
|
9
10
|
".": {
|
|
10
|
-
"import": "./dist/index.
|
|
11
|
-
"require": "./dist/index.js",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
12
|
"types": "./dist/index.d.ts"
|
|
13
13
|
},
|
|
14
|
-
"./styles
|
|
14
|
+
"./styles": "./src/styles/ui.css"
|
|
15
15
|
},
|
|
16
|
-
"files": [
|
|
17
|
-
"dist"
|
|
18
|
-
],
|
|
19
16
|
"sideEffects": [
|
|
20
|
-
"
|
|
17
|
+
"*.css"
|
|
18
|
+
],
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"src/styles"
|
|
21
22
|
],
|
|
22
23
|
"scripts": {
|
|
23
|
-
"build": "tsup
|
|
24
|
-
"dev": "tsup
|
|
25
|
-
"
|
|
26
|
-
"typecheck": "tsc --noEmit"
|
|
27
|
-
"clean": "rm -rf dist"
|
|
28
|
-
},
|
|
29
|
-
"dependencies": {
|
|
30
|
-
"@sdods/core": "workspace:*",
|
|
31
|
-
"clsx": "^2.1.0"
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"dev": "tsup --watch",
|
|
26
|
+
"lint": "eslint src/",
|
|
27
|
+
"typecheck": "tsc --noEmit"
|
|
32
28
|
},
|
|
33
29
|
"peerDependencies": {
|
|
34
30
|
"react": ">=18.0.0",
|
|
35
31
|
"react-dom": ">=18.0.0"
|
|
36
32
|
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@radix-ui/react-dialog": "^1.1.4",
|
|
35
|
+
"@radix-ui/react-dropdown-menu": "^2.1.4",
|
|
36
|
+
"@radix-ui/react-label": "^2.1.0",
|
|
37
|
+
"@radix-ui/react-popover": "^1.1.4",
|
|
38
|
+
"@radix-ui/react-select": "^2.1.4",
|
|
39
|
+
"@radix-ui/react-separator": "^1.1.0",
|
|
40
|
+
"@radix-ui/react-slot": "^1.1.0",
|
|
41
|
+
"@radix-ui/react-switch": "^1.1.1",
|
|
42
|
+
"@radix-ui/react-tabs": "^1.1.1",
|
|
43
|
+
"@radix-ui/react-toast": "^1.2.4",
|
|
44
|
+
"@radix-ui/react-tooltip": "^1.1.5",
|
|
45
|
+
"class-variance-authority": "^0.7.1",
|
|
46
|
+
"clsx": "^2.1.1",
|
|
47
|
+
"lucide-react": "^0.468.0",
|
|
48
|
+
"tailwind-merge": "^2.6.0"
|
|
49
|
+
},
|
|
37
50
|
"devDependencies": {
|
|
38
|
-
"@types/react": "^18.
|
|
39
|
-
"@types/react-dom": "^18.
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"tsup": "^8.0.0",
|
|
43
|
-
"typescript": "^5.4.0",
|
|
44
|
-
"vitest": "^2.0.0"
|
|
51
|
+
"@types/react": "^18.3.0",
|
|
52
|
+
"@types/react-dom": "^18.3.0",
|
|
53
|
+
"tsup": "^8.3.0",
|
|
54
|
+
"typescript": "^5.7.0"
|
|
45
55
|
},
|
|
46
|
-
"keywords": ["
|
|
56
|
+
"keywords": ["ui", "components", "react", "radix", "tailwind", "accessible"],
|
|
47
57
|
"license": "MIT",
|
|
48
58
|
"repository": {
|
|
49
59
|
"type": "git",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sdods/ui Base Styles
|
|
3
|
+
* Minimal CSS that complements Tailwind
|
|
4
|
+
* Token references from @sdods/themes
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
@layer base {
|
|
8
|
+
* {
|
|
9
|
+
border-color: hsl(var(--border));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
body {
|
|
13
|
+
background-color: hsl(var(--background));
|
|
14
|
+
color: hsl(var(--foreground));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@layer utilities {
|
|
19
|
+
/* Touch manipulation for mobile */
|
|
20
|
+
.touch-manipulation {
|
|
21
|
+
touch-action: manipulation;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Animations for dialogs/modals */
|
|
26
|
+
@keyframes fadeIn {
|
|
27
|
+
from { opacity: 0; }
|
|
28
|
+
to { opacity: 1; }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@keyframes fadeOut {
|
|
32
|
+
from { opacity: 1; }
|
|
33
|
+
to { opacity: 0; }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@keyframes slideIn {
|
|
37
|
+
from { transform: translate(-50%, -48%) scale(0.95); }
|
|
38
|
+
to { transform: translate(-50%, -50%) scale(1); }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@keyframes slideOut {
|
|
42
|
+
from { transform: translate(-50%, -50%) scale(1); }
|
|
43
|
+
to { transform: translate(-50%, -48%) scale(0.95); }
|
|
44
|
+
}
|
package/dist/index.d.mts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import * as React from 'react';
|
|
3
|
-
|
|
4
|
-
interface Theme {
|
|
5
|
-
name: string;
|
|
6
|
-
colors: {
|
|
7
|
-
primary: string;
|
|
8
|
-
secondary: string;
|
|
9
|
-
accent: string;
|
|
10
|
-
background: string;
|
|
11
|
-
foreground: string;
|
|
12
|
-
muted: string;
|
|
13
|
-
border: string;
|
|
14
|
-
error: string;
|
|
15
|
-
success: string;
|
|
16
|
-
warning: string;
|
|
17
|
-
};
|
|
18
|
-
fonts: {
|
|
19
|
-
sans: string;
|
|
20
|
-
mono: string;
|
|
21
|
-
};
|
|
22
|
-
radii: {
|
|
23
|
-
sm: string;
|
|
24
|
-
md: string;
|
|
25
|
-
lg: string;
|
|
26
|
-
full: string;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
declare const themes: Record<string, Theme>;
|
|
30
|
-
interface ThemeProviderProps {
|
|
31
|
-
theme?: Theme | keyof typeof themes;
|
|
32
|
-
children: React.ReactNode;
|
|
33
|
-
}
|
|
34
|
-
declare function ThemeProvider({ theme, children }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
|
|
35
|
-
declare function useTheme(): Theme;
|
|
36
|
-
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
37
|
-
variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive';
|
|
38
|
-
size?: 'sm' | 'md' | 'lg';
|
|
39
|
-
loading?: boolean;
|
|
40
|
-
}
|
|
41
|
-
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
42
|
-
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
43
|
-
variant?: 'default' | 'elevated' | 'outlined';
|
|
44
|
-
}
|
|
45
|
-
declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement>>;
|
|
46
|
-
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
47
|
-
error?: string;
|
|
48
|
-
label?: string;
|
|
49
|
-
}
|
|
50
|
-
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
|
|
51
|
-
interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
52
|
-
variant?: 'default' | 'primary' | 'success' | 'warning' | 'error';
|
|
53
|
-
}
|
|
54
|
-
declare const Badge: React.ForwardRefExoticComponent<BadgeProps & React.RefAttributes<HTMLSpanElement>>;
|
|
55
|
-
interface SpinnerProps {
|
|
56
|
-
size?: 'sm' | 'md' | 'lg';
|
|
57
|
-
className?: string;
|
|
58
|
-
}
|
|
59
|
-
declare function Spinner({ size, className }: SpinnerProps): react_jsx_runtime.JSX.Element;
|
|
60
|
-
interface AvatarProps extends React.ImgHTMLAttributes<HTMLImageElement> {
|
|
61
|
-
size?: 'sm' | 'md' | 'lg';
|
|
62
|
-
fallback?: string;
|
|
63
|
-
}
|
|
64
|
-
declare function Avatar({ size, fallback, src, alt, className, ...props }: AvatarProps): react_jsx_runtime.JSX.Element;
|
|
65
|
-
|
|
66
|
-
export { Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Input, type InputProps, Spinner, type SpinnerProps, type Theme, ThemeProvider, type ThemeProviderProps, themes, useTheme };
|
package/dist/index.mjs
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
// src/index.tsx
|
|
2
|
-
import * as React from "react";
|
|
3
|
-
import { clsx } from "clsx";
|
|
4
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
var themes = {
|
|
6
|
-
yarlis: {
|
|
7
|
-
name: "yarlis",
|
|
8
|
-
colors: {
|
|
9
|
-
primary: "#316FA7",
|
|
10
|
-
secondary: "#7C3AED",
|
|
11
|
-
accent: "#06B6D4",
|
|
12
|
-
background: "#0F172A",
|
|
13
|
-
foreground: "#F8FAFC",
|
|
14
|
-
muted: "#64748B",
|
|
15
|
-
border: "#334155",
|
|
16
|
-
error: "#EF4444",
|
|
17
|
-
success: "#22C55E",
|
|
18
|
-
warning: "#F59E0B"
|
|
19
|
-
},
|
|
20
|
-
fonts: {
|
|
21
|
-
sans: "Inter, system-ui, sans-serif",
|
|
22
|
-
mono: "JetBrains Mono, monospace"
|
|
23
|
-
},
|
|
24
|
-
radii: {
|
|
25
|
-
sm: "0.25rem",
|
|
26
|
-
md: "0.5rem",
|
|
27
|
-
lg: "1rem",
|
|
28
|
-
full: "9999px"
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
light: {
|
|
32
|
-
name: "light",
|
|
33
|
-
colors: {
|
|
34
|
-
primary: "#2563EB",
|
|
35
|
-
secondary: "#7C3AED",
|
|
36
|
-
accent: "#06B6D4",
|
|
37
|
-
background: "#FFFFFF",
|
|
38
|
-
foreground: "#0F172A",
|
|
39
|
-
muted: "#64748B",
|
|
40
|
-
border: "#E2E8F0",
|
|
41
|
-
error: "#EF4444",
|
|
42
|
-
success: "#22C55E",
|
|
43
|
-
warning: "#F59E0B"
|
|
44
|
-
},
|
|
45
|
-
fonts: {
|
|
46
|
-
sans: "Inter, system-ui, sans-serif",
|
|
47
|
-
mono: "JetBrains Mono, monospace"
|
|
48
|
-
},
|
|
49
|
-
radii: {
|
|
50
|
-
sm: "0.25rem",
|
|
51
|
-
md: "0.5rem",
|
|
52
|
-
lg: "1rem",
|
|
53
|
-
full: "9999px"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
var ThemeContext = React.createContext(themes.yarlis);
|
|
58
|
-
function ThemeProvider({ theme = "yarlis", children }) {
|
|
59
|
-
const resolvedTheme = typeof theme === "string" ? themes[theme] : theme;
|
|
60
|
-
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: resolvedTheme, children: /* @__PURE__ */ jsx(
|
|
61
|
-
"div",
|
|
62
|
-
{
|
|
63
|
-
style: {
|
|
64
|
-
"--color-primary": resolvedTheme.colors.primary,
|
|
65
|
-
"--color-secondary": resolvedTheme.colors.secondary,
|
|
66
|
-
"--color-accent": resolvedTheme.colors.accent,
|
|
67
|
-
"--color-background": resolvedTheme.colors.background,
|
|
68
|
-
"--color-foreground": resolvedTheme.colors.foreground,
|
|
69
|
-
"--color-muted": resolvedTheme.colors.muted,
|
|
70
|
-
"--color-border": resolvedTheme.colors.border,
|
|
71
|
-
"--color-error": resolvedTheme.colors.error,
|
|
72
|
-
"--color-success": resolvedTheme.colors.success,
|
|
73
|
-
"--color-warning": resolvedTheme.colors.warning,
|
|
74
|
-
"--font-sans": resolvedTheme.fonts.sans,
|
|
75
|
-
"--font-mono": resolvedTheme.fonts.mono,
|
|
76
|
-
"--radius-sm": resolvedTheme.radii.sm,
|
|
77
|
-
"--radius-md": resolvedTheme.radii.md,
|
|
78
|
-
"--radius-lg": resolvedTheme.radii.lg,
|
|
79
|
-
"--radius-full": resolvedTheme.radii.full
|
|
80
|
-
},
|
|
81
|
-
children
|
|
82
|
-
}
|
|
83
|
-
) });
|
|
84
|
-
}
|
|
85
|
-
function useTheme() {
|
|
86
|
-
return React.useContext(ThemeContext);
|
|
87
|
-
}
|
|
88
|
-
var Button = React.forwardRef(
|
|
89
|
-
({ variant = "primary", size = "md", loading, className, children, disabled, ...props }, ref) => {
|
|
90
|
-
const baseStyles = "inline-flex items-center justify-center font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none";
|
|
91
|
-
const variants = {
|
|
92
|
-
primary: "bg-[var(--color-primary)] text-white hover:opacity-90 focus:ring-[var(--color-primary)]",
|
|
93
|
-
secondary: "bg-[var(--color-secondary)] text-white hover:opacity-90 focus:ring-[var(--color-secondary)]",
|
|
94
|
-
outline: "border border-[var(--color-border)] bg-transparent hover:bg-[var(--color-muted)]/10",
|
|
95
|
-
ghost: "bg-transparent hover:bg-[var(--color-muted)]/10",
|
|
96
|
-
destructive: "bg-[var(--color-error)] text-white hover:opacity-90 focus:ring-[var(--color-error)]"
|
|
97
|
-
};
|
|
98
|
-
const sizes = {
|
|
99
|
-
sm: "h-8 px-3 text-sm rounded-[var(--radius-sm)]",
|
|
100
|
-
md: "h-10 px-4 text-base rounded-[var(--radius-md)]",
|
|
101
|
-
lg: "h-12 px-6 text-lg rounded-[var(--radius-md)]"
|
|
102
|
-
};
|
|
103
|
-
return /* @__PURE__ */ jsxs(
|
|
104
|
-
"button",
|
|
105
|
-
{
|
|
106
|
-
ref,
|
|
107
|
-
className: clsx(baseStyles, variants[variant], sizes[size], className),
|
|
108
|
-
disabled: disabled || loading,
|
|
109
|
-
...props,
|
|
110
|
-
children: [
|
|
111
|
-
loading && /* @__PURE__ */ jsxs("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4", fill: "none", viewBox: "0 0 24 24", children: [
|
|
112
|
-
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
113
|
-
/* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
114
|
-
] }),
|
|
115
|
-
children
|
|
116
|
-
]
|
|
117
|
-
}
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
);
|
|
121
|
-
Button.displayName = "Button";
|
|
122
|
-
var Card = React.forwardRef(
|
|
123
|
-
({ variant = "default", className, children, ...props }, ref) => {
|
|
124
|
-
const variants = {
|
|
125
|
-
default: "bg-[var(--color-background)] border border-[var(--color-border)]",
|
|
126
|
-
elevated: "bg-[var(--color-background)] shadow-lg",
|
|
127
|
-
outlined: "bg-transparent border-2 border-[var(--color-border)]"
|
|
128
|
-
};
|
|
129
|
-
return /* @__PURE__ */ jsx(
|
|
130
|
-
"div",
|
|
131
|
-
{
|
|
132
|
-
ref,
|
|
133
|
-
className: clsx(
|
|
134
|
-
"rounded-[var(--radius-lg)] p-6",
|
|
135
|
-
variants[variant],
|
|
136
|
-
className
|
|
137
|
-
),
|
|
138
|
-
...props,
|
|
139
|
-
children
|
|
140
|
-
}
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
);
|
|
144
|
-
Card.displayName = "Card";
|
|
145
|
-
var Input = React.forwardRef(
|
|
146
|
-
({ error, label, className, id, ...props }, ref) => {
|
|
147
|
-
const inputId = id || React.useId();
|
|
148
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
149
|
-
label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "text-sm font-medium text-[var(--color-foreground)]", children: label }),
|
|
150
|
-
/* @__PURE__ */ jsx(
|
|
151
|
-
"input",
|
|
152
|
-
{
|
|
153
|
-
ref,
|
|
154
|
-
id: inputId,
|
|
155
|
-
className: clsx(
|
|
156
|
-
"h-10 px-3 rounded-[var(--radius-md)] border bg-[var(--color-background)] text-[var(--color-foreground)]",
|
|
157
|
-
"focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]",
|
|
158
|
-
error ? "border-[var(--color-error)]" : "border-[var(--color-border)]",
|
|
159
|
-
className
|
|
160
|
-
),
|
|
161
|
-
...props
|
|
162
|
-
}
|
|
163
|
-
),
|
|
164
|
-
error && /* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--color-error)]", children: error })
|
|
165
|
-
] });
|
|
166
|
-
}
|
|
167
|
-
);
|
|
168
|
-
Input.displayName = "Input";
|
|
169
|
-
var Badge = React.forwardRef(
|
|
170
|
-
({ variant = "default", className, ...props }, ref) => {
|
|
171
|
-
const variants = {
|
|
172
|
-
default: "bg-[var(--color-muted)]/20 text-[var(--color-foreground)]",
|
|
173
|
-
primary: "bg-[var(--color-primary)]/20 text-[var(--color-primary)]",
|
|
174
|
-
success: "bg-[var(--color-success)]/20 text-[var(--color-success)]",
|
|
175
|
-
warning: "bg-[var(--color-warning)]/20 text-[var(--color-warning)]",
|
|
176
|
-
error: "bg-[var(--color-error)]/20 text-[var(--color-error)]"
|
|
177
|
-
};
|
|
178
|
-
return /* @__PURE__ */ jsx(
|
|
179
|
-
"span",
|
|
180
|
-
{
|
|
181
|
-
ref,
|
|
182
|
-
className: clsx(
|
|
183
|
-
"inline-flex items-center px-2 py-1 text-xs font-medium rounded-[var(--radius-full)]",
|
|
184
|
-
variants[variant],
|
|
185
|
-
className
|
|
186
|
-
),
|
|
187
|
-
...props
|
|
188
|
-
}
|
|
189
|
-
);
|
|
190
|
-
}
|
|
191
|
-
);
|
|
192
|
-
Badge.displayName = "Badge";
|
|
193
|
-
function Spinner({ size = "md", className }) {
|
|
194
|
-
const sizes = {
|
|
195
|
-
sm: "h-4 w-4",
|
|
196
|
-
md: "h-8 w-8",
|
|
197
|
-
lg: "h-12 w-12"
|
|
198
|
-
};
|
|
199
|
-
return /* @__PURE__ */ jsxs(
|
|
200
|
-
"svg",
|
|
201
|
-
{
|
|
202
|
-
className: clsx("animate-spin text-[var(--color-primary)]", sizes[size], className),
|
|
203
|
-
fill: "none",
|
|
204
|
-
viewBox: "0 0 24 24",
|
|
205
|
-
children: [
|
|
206
|
-
/* @__PURE__ */ jsx(
|
|
207
|
-
"circle",
|
|
208
|
-
{
|
|
209
|
-
className: "opacity-25",
|
|
210
|
-
cx: "12",
|
|
211
|
-
cy: "12",
|
|
212
|
-
r: "10",
|
|
213
|
-
stroke: "currentColor",
|
|
214
|
-
strokeWidth: "4"
|
|
215
|
-
}
|
|
216
|
-
),
|
|
217
|
-
/* @__PURE__ */ jsx(
|
|
218
|
-
"path",
|
|
219
|
-
{
|
|
220
|
-
className: "opacity-75",
|
|
221
|
-
fill: "currentColor",
|
|
222
|
-
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
|
|
223
|
-
}
|
|
224
|
-
)
|
|
225
|
-
]
|
|
226
|
-
}
|
|
227
|
-
);
|
|
228
|
-
}
|
|
229
|
-
function Avatar({ size = "md", fallback, src, alt, className, ...props }) {
|
|
230
|
-
const [error, setError] = React.useState(false);
|
|
231
|
-
const sizes = {
|
|
232
|
-
sm: "h-8 w-8 text-xs",
|
|
233
|
-
md: "h-10 w-10 text-sm",
|
|
234
|
-
lg: "h-16 w-16 text-lg"
|
|
235
|
-
};
|
|
236
|
-
if (error || !src) {
|
|
237
|
-
return /* @__PURE__ */ jsx(
|
|
238
|
-
"div",
|
|
239
|
-
{
|
|
240
|
-
className: clsx(
|
|
241
|
-
"flex items-center justify-center rounded-[var(--radius-full)] bg-[var(--color-primary)] text-white font-medium",
|
|
242
|
-
sizes[size],
|
|
243
|
-
className
|
|
244
|
-
),
|
|
245
|
-
children: fallback || alt?.charAt(0).toUpperCase() || "?"
|
|
246
|
-
}
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
return /* @__PURE__ */ jsx(
|
|
250
|
-
"img",
|
|
251
|
-
{
|
|
252
|
-
src,
|
|
253
|
-
alt,
|
|
254
|
-
onError: () => setError(true),
|
|
255
|
-
className: clsx("rounded-[var(--radius-full)] object-cover", sizes[size], className),
|
|
256
|
-
...props
|
|
257
|
-
}
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
export {
|
|
261
|
-
Avatar,
|
|
262
|
-
Badge,
|
|
263
|
-
Button,
|
|
264
|
-
Card,
|
|
265
|
-
Input,
|
|
266
|
-
Spinner,
|
|
267
|
-
ThemeProvider,
|
|
268
|
-
themes,
|
|
269
|
-
useTheme
|
|
270
|
-
};
|