@switch-to-eu/layout-ui
Version:
Modular UI design system for privacy-focused tools - React components with Tailwind CSS and theme customization
753 lines (747 loc) • 30 kB
JavaScript
import * as React10 from 'react';
import { Slot } from '@radix-ui/react-slot';
import { cva } from 'class-variance-authority';
import { clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
import * as LabelPrimitive from '@radix-ui/react-label';
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
import { Check, Loader2, ChevronDown, ChevronUp, X } from 'lucide-react';
import * as SelectPrimitive from '@radix-ui/react-select';
import * as DialogPrimitive from '@radix-ui/react-dialog';
function cn(...inputs) {
return twMerge(clsx(inputs));
}
// src/components/ui/Button.tsx
var buttonVariants = cva(
"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default: "gradient-purple-blue text-white shadow-xs hover:shadow-lg transition-all",
// Solid color variants
primary: "bg-primary text-white shadow-xs hover:opacity-90 focus-visible:ring-primary/20",
secondary: "bg-secondary text-white shadow-xs hover:opacity-90 focus-visible:ring-secondary/20",
tertiary: "bg-tertiary text-white shadow-xs hover:opacity-90 focus-visible:ring-tertiary/20",
quaternary: "bg-quaternary text-white shadow-xs hover:opacity-90 focus-visible:ring-quaternary/20",
// Gradient variants
"gradient-primary": "gradient-primary text-white shadow-xs hover:opacity-90 hover:shadow-lg transition-all",
"gradient-secondary": "gradient-secondary text-white shadow-xs hover:opacity-90 hover:shadow-lg transition-all",
"gradient-tertiary": "gradient-tertiary text-white shadow-xs hover:opacity-90 hover:shadow-lg transition-all",
"gradient-quaternary": "gradient-quaternary text-white shadow-xs hover:opacity-90 hover:shadow-lg transition-all",
// Status variants - solid
success: "bg-success text-white shadow-xs hover:opacity-90 focus-visible:ring-success/20",
warning: "bg-warning text-white shadow-xs hover:opacity-90 focus-visible:ring-warning/20",
destructive: "bg-destructive text-white shadow-xs hover:opacity-90 focus-visible:ring-destructive/20",
// Utility variants
neutral: "border border-primary bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
ghost: "shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
link: "underline-offset-4 hover:underline"
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
icon: "size-9"
}
},
defaultVariants: {
variant: "gradient-primary",
size: "default"
}
}
);
var Button = React10.forwardRef(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return /* @__PURE__ */ React10.createElement(
Comp,
{
className: cn(buttonVariants({ variant, size, className })),
ref,
...props
}
);
}
);
Button.displayName = "Button";
var Card = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
"data-slot": "card",
className: cn(
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border-primary border py-6 shadow-sm shadow-card",
className
),
...props
}
));
Card.displayName = "Card";
var CardHeader = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
"data-slot": "card-header",
className: cn(
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
className
),
...props
}
));
CardHeader.displayName = "CardHeader";
var CardTitle = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
"data-slot": "card-title",
className: cn("leading-none font-semibold", className),
...props
}
));
CardTitle.displayName = "CardTitle";
var CardDescription = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
"data-slot": "card-description",
className: cn("text-muted-foreground text-sm", className),
...props
}
));
CardDescription.displayName = "CardDescription";
var CardAction = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
"data-slot": "card-action",
className: cn(
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
className
),
...props
}
));
CardAction.displayName = "CardAction";
var CardContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
"data-slot": "card-content",
className: cn("px-6", className),
...props
}
));
CardContent.displayName = "CardContent";
var CardFooter = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
"data-slot": "card-footer",
className: cn("flex items-center px-6 [.border-t]:pt-6", className),
...props
}
));
CardFooter.displayName = "CardFooter";
var Input = React10.forwardRef(
({ className, type, ...props }, ref) => {
return /* @__PURE__ */ React10.createElement(
"input",
{
type,
"data-slot": "input",
className: cn(
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"focus-visible:border-purple-400 focus-visible:ring-purple-100 focus-visible:ring-1",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
className
),
ref,
...props
}
);
}
);
Input.displayName = "Input";
var Textarea = React10.forwardRef(
({ className, ...props }, ref) => {
return /* @__PURE__ */ React10.createElement(
"textarea",
{
className: cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background 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",
className
),
ref,
...props
}
);
}
);
Textarea.displayName = "Textarea";
var labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
);
var Label = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
LabelPrimitive.Root,
{
ref,
className: cn(labelVariants(), className),
...props
}
));
Label.displayName = LabelPrimitive.Root.displayName;
function Skeleton({
className,
...props
}) {
return /* @__PURE__ */ React10.createElement(
"div",
{
className: cn("animate-pulse rounded-md bg-muted", className),
...props
}
);
}
var alertVariants = cva(
"relative w-full p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground overflow-hidden shadow-card",
{
variants: {
variant: {
default: "bg-background text-foreground border-t border-b border-primary sm:rounded-lg sm:border-l sm:border-r",
destructive: "gradient-bg-destructive border-t border-b border-primary sm:rounded-lg sm:border-l sm:border-r text-gray-900 [&>svg]:text-warning",
primary: "gradient-bg-primary border-t border-b border-primary sm:rounded-lg sm:border-l sm:border-r text-gray-900",
secondary: "gradient-bg-secondary border-t border-b border-primary sm:rounded-lg sm:border-l sm:border-r text-gray-900",
tertiary: "gradient-bg-tertiary border-t border-b border-primary sm:rounded-lg sm:border-l sm:border-r text-gray-900",
quaternary: "gradient-bg-quaternary border-t border-b border-primary sm:rounded-lg sm:border-l sm:border-r text-gray-900",
neutral: "bg-gray-50 border-t border-b border-primary sm:rounded-lg sm:border-l sm:border-r text-gray-900"
}
},
defaultVariants: {
variant: "default"
}
}
);
var Alert = React10.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
role: "alert",
className: cn(alertVariants({ variant }), className),
...props
}
));
Alert.displayName = "Alert";
var AlertTitle = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"h5",
{
ref,
className: cn("mb-1 font-medium leading-none tracking-tight", className),
...props
}
));
AlertTitle.displayName = "AlertTitle";
var AlertDescription = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
className: cn("text-sm [&_p]:leading-relaxed", className),
...props
}
));
AlertDescription.displayName = "AlertDescription";
var Checkbox = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
CheckboxPrimitive.Root,
{
ref,
className: cn(
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
className
),
...props
},
/* @__PURE__ */ React10.createElement(
CheckboxPrimitive.Indicator,
{
className: cn("flex items-center justify-center text-current")
},
/* @__PURE__ */ React10.createElement(Check, { className: "h-4 w-4" })
)
));
Checkbox.displayName = CheckboxPrimitive.Root.displayName;
var LoadingButton = React10.forwardRef(
({ loading = false, loadingText, children, disabled, ...props }, ref) => {
return /* @__PURE__ */ React10.createElement(
Button,
{
ref,
disabled: disabled ?? loading,
...props
},
loading ? /* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), loadingText ?? "Loading...") : children
);
}
);
LoadingButton.displayName = "LoadingButton";
var Select = SelectPrimitive.Root;
var SelectGroup = SelectPrimitive.Group;
var SelectValue = SelectPrimitive.Value;
var SelectTrigger = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ React10.createElement(
SelectPrimitive.Trigger,
{
ref,
className: cn(
"flex h-10 w-full items-center justify-between rounded-md border border-primary bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
className
),
...props
},
children,
/* @__PURE__ */ React10.createElement(SelectPrimitive.Icon, { asChild: true }, /* @__PURE__ */ React10.createElement(ChevronDown, { className: "h-4 w-4 opacity-50" }))
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
var SelectScrollUpButton = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
SelectPrimitive.ScrollUpButton,
{
ref,
className: cn(
"flex cursor-default items-center justify-center py-1",
className
),
...props
},
/* @__PURE__ */ React10.createElement(ChevronUp, { className: "h-4 w-4" })
));
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
var SelectScrollDownButton = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
SelectPrimitive.ScrollDownButton,
{
ref,
className: cn(
"flex cursor-default items-center justify-center py-1",
className
),
...props
},
/* @__PURE__ */ React10.createElement(ChevronDown, { className: "h-4 w-4" })
));
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
var SelectContent = React10.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ React10.createElement(SelectPrimitive.Portal, null, /* @__PURE__ */ React10.createElement(
SelectPrimitive.Content,
{
ref,
className: cn(
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border-primary bg-background text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
className
),
position,
...props
},
/* @__PURE__ */ React10.createElement(SelectScrollUpButton, null),
/* @__PURE__ */ React10.createElement(
SelectPrimitive.Viewport,
{
className: cn(
"p-1",
position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
)
},
children
),
/* @__PURE__ */ React10.createElement(SelectScrollDownButton, null)
)));
SelectContent.displayName = SelectPrimitive.Content.displayName;
var SelectLabel = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
SelectPrimitive.Label,
{
ref,
className: cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className),
...props
}
));
SelectLabel.displayName = SelectPrimitive.Label.displayName;
var SelectItem = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ React10.createElement(
SelectPrimitive.Item,
{
ref,
className: cn(
"relative flex w-full cursor-default bg-background border-primary select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className
),
...props
},
/* @__PURE__ */ React10.createElement("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center" }, /* @__PURE__ */ React10.createElement(SelectPrimitive.ItemIndicator, null, /* @__PURE__ */ React10.createElement(Check, { className: "h-4 w-4" }))),
/* @__PURE__ */ React10.createElement(SelectPrimitive.ItemText, null, children)
));
SelectItem.displayName = SelectPrimitive.Item.displayName;
var SelectSeparator = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
SelectPrimitive.Separator,
{
ref,
className: cn("-mx-1 my-1 h-px bg-muted", className),
...props
}
));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
var Dialog = DialogPrimitive.Root;
var DialogTrigger = DialogPrimitive.Trigger;
var DialogPortal = DialogPrimitive.Portal;
var DialogClose = DialogPrimitive.Close;
var DialogOverlay = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
DialogPrimitive.Overlay,
{
ref,
className: cn(
"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
),
...props
}
));
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
var DialogContent = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ React10.createElement(DialogPortal, null, /* @__PURE__ */ React10.createElement(DialogOverlay, null), /* @__PURE__ */ React10.createElement(
DialogPrimitive.Content,
{
ref,
className: cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg border-primary 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",
className
),
...props
},
children,
/* @__PURE__ */ React10.createElement(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" }, /* @__PURE__ */ React10.createElement(X, { className: "h-4 w-4" }), /* @__PURE__ */ React10.createElement("span", { className: "sr-only" }, "Close"))
)));
DialogContent.displayName = DialogPrimitive.Content.displayName;
var DialogHeader = ({
className,
...props
}) => /* @__PURE__ */ React10.createElement(
"div",
{
className: cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
className
),
...props
}
);
DialogHeader.displayName = "DialogHeader";
var DialogFooter = ({
className,
...props
}) => /* @__PURE__ */ React10.createElement(
"div",
{
className: cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
),
...props
}
);
DialogFooter.displayName = "DialogFooter";
var DialogTitle = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
DialogPrimitive.Title,
{
ref,
className: cn(
"text-lg font-semibold leading-none tracking-tight",
className
),
...props
}
));
DialogTitle.displayName = DialogPrimitive.Title.displayName;
var DialogDescription = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React10.createElement(
DialogPrimitive.Description,
{
ref,
className: cn("text-sm text-muted-foreground", className),
...props
}
));
DialogDescription.displayName = DialogPrimitive.Description.displayName;
var SectionCard = React10.forwardRef(
({ children, className }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
className: cn(
"overflow-hidden shadow-card",
// Mobile: only top/bottom borders, no left/right
"border-t border-b border-primary",
// Desktop: rounded corners and full border
"sm:rounded-lg sm:border-l sm:border-r",
className
)
},
children
)
);
SectionCard.displayName = "SectionCard";
var SectionHeader = React10.forwardRef(
({ children, icon, title, description, className, variant = "primary" }, ref) => {
const variantStyles = {
primary: "gradient-bg-primary border-b",
secondary: "gradient-bg-secondary border-b",
tertiary: "gradient-bg-tertiary border-b",
quaternary: "gradient-bg-quaternary border-b",
neutral: "bg-gray-50 border-b"
};
const iconColors = {
primary: "text-brand-primary",
secondary: "text-warning",
tertiary: "text-success",
quaternary: "text-warning",
neutral: "text-gray-600"
};
return /* @__PURE__ */ React10.createElement(
"div",
{
ref,
className: cn(
"border-gray-200 px-6 py-4",
variantStyles[variant],
className
)
},
/* @__PURE__ */ React10.createElement("div", { className: "flex items-center gap-2" }, icon && /* @__PURE__ */ React10.createElement("span", { className: iconColors[variant] }, icon), /* @__PURE__ */ React10.createElement("h2", { className: "text-lg font-semibold text-gray-900" }, title)),
description && /* @__PURE__ */ React10.createElement("p", { className: "mt-1 text-sm text-gray-600" }, description),
children
);
}
);
SectionHeader.displayName = "SectionHeader";
var SectionContent = React10.forwardRef(
({ children, className }, ref) => /* @__PURE__ */ React10.createElement("div", { ref, className: cn("p-6 bg-white", className) }, children)
);
SectionContent.displayName = "SectionContent";
var Header = React10.forwardRef(
({ children, className, sticky = true }, ref) => /* @__PURE__ */ React10.createElement(
"header",
{
ref,
className: cn(
"max-w bg-background/95 supports-[backdrop-filter]:bg-background/60 backdrop-blur border-b border-primary",
sticky && "sticky top-0 z-50",
className
)
},
children
)
);
Header.displayName = "Header";
var HeaderContent = React10.forwardRef(
({ children, className }, ref) => /* @__PURE__ */ React10.createElement(
"div",
{
ref,
className: cn(
"container mx-auto flex items-center justify-between py-3 sm:py-4",
className
)
},
children
)
);
HeaderContent.displayName = "HeaderContent";
var HeaderBrand = React10.forwardRef(
({ children, href, className, onClick, icon }, ref) => {
const brandContent = /* @__PURE__ */ React10.createElement(
"div",
{
ref,
className: cn(
"flex text-primary cursor-pointer items-center gap-2 text-lg font-black transition-opacity hover:opacity-80 sm:text-xl",
className
),
onClick
},
icon && /* @__PURE__ */ React10.createElement("div", { className: "relative text-primary h-3 w-3 flexitems-center justify-center rounded-sm bg-purple-600" }, /* @__PURE__ */ React10.createElement("div", { className: "h-3 w-3 text-primary" }, icon)),
/* @__PURE__ */ React10.createElement("span", { className: "font-black tracking-wide uppercase" }, children)
);
if (href) {
return /* @__PURE__ */ React10.createElement("a", { href, className: "no-underline" }, brandContent);
}
return brandContent;
}
);
HeaderBrand.displayName = "HeaderBrand";
var HeaderNav = React10.forwardRef(
({ children, className, align = "right" }, ref) => /* @__PURE__ */ React10.createElement(
"nav",
{
ref,
className: cn(
"flex items-center gap-2",
align === "left" && "justify-start",
align === "center" && "justify-center",
align === "right" && "justify-end",
className
)
},
children
)
);
HeaderNav.displayName = "HeaderNav";
// src/components/form/FormUtils.tsx
function isFieldRequired(schema, fieldName) {
try {
const shape = schema.shape;
const fieldSchema = shape[fieldName];
if (!fieldSchema) return false;
const result = fieldSchema.safeParse(void 0);
return !result.success;
} catch {
return false;
}
}
// src/components/form/FormInput.tsx
var FormInput = ({
label,
name,
register,
error,
description,
className,
id,
valueAsNumber,
schema,
...props
}) => {
const inputId = id ?? name ?? label.toLowerCase().replace(/\s+/g, "-");
const isRequired = schema ? isFieldRequired(schema, String(name)) : false;
return /* @__PURE__ */ React10.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React10.createElement(Label, { htmlFor: inputId, className: "text-sm font-medium" }, label, isRequired && /* @__PURE__ */ React10.createElement("span", { className: "text-destructive ml-1" }, "*"), !isRequired && /* @__PURE__ */ React10.createElement("span", { className: "text-muted-foreground ml-1" }, "(Optional)")), description && /* @__PURE__ */ React10.createElement("p", { className: "text-sm text-muted-foreground" }, description), /* @__PURE__ */ React10.createElement(
Input,
{
id: inputId,
className: cn(
error && "border-destructive focus-visible:ring-destructive",
className
),
...register(name, { valueAsNumber }),
...props
}
), error && /* @__PURE__ */ React10.createElement("p", { className: "text-sm text-destructive" }, error.message));
};
FormInput.displayName = "FormInput";
var FormTextarea = ({
label,
name,
register,
error,
description,
className,
id,
rows = 4,
schema,
...props
}) => {
const inputId = id ?? name ?? label.toLowerCase().replace(/\s+/g, "-");
const isRequired = schema ? isFieldRequired(schema, String(name)) : false;
return /* @__PURE__ */ React10.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React10.createElement(Label, { htmlFor: inputId, className: "text-sm font-medium" }, label, isRequired && /* @__PURE__ */ React10.createElement("span", { className: "text-destructive ml-1" }, "*"), !isRequired && /* @__PURE__ */ React10.createElement("span", { className: "text-muted-foreground ml-1" }, "(Optional)")), description && /* @__PURE__ */ React10.createElement("p", { className: "text-sm text-muted-foreground" }, description), /* @__PURE__ */ React10.createElement(
Textarea,
{
id: inputId,
rows,
className: cn(
error && "border-destructive focus-visible:ring-destructive",
className
),
...register(name),
...props
}
), error && /* @__PURE__ */ React10.createElement("p", { className: "text-sm text-destructive" }, error.message));
};
FormTextarea.displayName = "FormTextarea";
// src/lib/theme.ts
var baseLightTheme = {
primary: "222.2 47.4% 11.2%",
"primary-foreground": "210 40% 98%",
secondary: "210 40% 96%",
"secondary-foreground": "222.2 84% 4.9%",
accent: "210 40% 96%",
"accent-foreground": "222.2 84% 4.9%",
background: "0 0% 100%",
foreground: "222.2 84% 4.9%",
card: "0 0% 100%",
"card-foreground": "222.2 84% 4.9%",
popover: "0 0% 100%",
"popover-foreground": "222.2 84% 4.9%",
muted: "210 40% 96%",
"muted-foreground": "215.4 16.3% 46.9%",
destructive: "0 84.2% 60.2%",
"destructive-foreground": "210 40% 98%",
border: "214.3 31.8% 91.4%",
input: "214.3 31.8% 91.4%",
ring: "222.2 84% 4.9%",
radius: "0.5rem"
};
var baseDarkTheme = {
primary: "210 40% 98%",
"primary-foreground": "222.2 47.4% 11.2%",
secondary: "217.2 32.6% 17.5%",
"secondary-foreground": "210 40% 98%",
accent: "217.2 32.6% 17.5%",
"accent-foreground": "210 40% 98%",
background: "222.2 84% 4.9%",
foreground: "210 40% 98%",
card: "222.2 84% 4.9%",
"card-foreground": "210 40% 98%",
popover: "222.2 84% 4.9%",
"popover-foreground": "210 40% 98%",
muted: "217.2 32.6% 17.5%",
"muted-foreground": "215 20.2% 65.1%",
destructive: "0 62.8% 30.6%",
"destructive-foreground": "210 40% 98%",
border: "217.2 32.6% 17.5%",
input: "217.2 32.6% 17.5%",
ring: "212.7 26.8% 83.9%",
radius: "0.5rem"
};
function applyTheme(theme) {
if (typeof document === "undefined") {
return;
}
const root = document.documentElement;
Object.entries(theme).forEach(([key, value]) => {
if (value) {
root.style.setProperty(`--${key}`, value);
}
});
}
function getSystemColorMode() {
if (typeof window === "undefined") {
return "light";
}
const stored = localStorage.getItem("color-mode");
if (stored && ["light", "dark", "system"].includes(stored)) {
return stored;
}
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
return "dark";
}
return "light";
}
function setColorMode(mode) {
if (typeof document === "undefined") {
return;
}
localStorage.setItem("color-mode", mode);
const isDark = mode === "dark" || mode === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches;
document.documentElement.classList.toggle("dark", isDark);
}
function applyBaseTheme(colorMode = "light") {
const isDark = colorMode === "dark" || colorMode === "system" && typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
const theme = isDark ? baseDarkTheme : baseLightTheme;
applyTheme(theme);
setColorMode(colorMode);
}
function getCSSVariableName(property) {
return `--${property}`;
}
export { Alert, AlertDescription, AlertTitle, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, FormInput, FormTextarea, Header, HeaderBrand, HeaderContent, HeaderNav, Input, Label, LoadingButton, SectionCard, SectionContent, SectionHeader, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Skeleton, Textarea, applyBaseTheme, applyTheme, baseDarkTheme, baseLightTheme, buttonVariants, cn, getCSSVariableName, getSystemColorMode, isFieldRequired, setColorMode };
//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map