UNPKG

@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
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