--- import type { HTMLAttributes } from "astro/types"; import { cn } from "../utils/cn"; import { Icon } from "astro-icon/components"; type Variant = "solid" | "outline" | "ghost" | "soft" | "link"; type Color = | "primary" | "secondary" | "tertiary" | "accent" | "info" | "success" | "warning" | "danger" | "neutral"; type Size = "sm" | "md" | "lg" | "icon"; interface Props extends HTMLAttributes<"button"> { variant?: Variant; color?: Color; size?: Size; pill?: boolean; icon?: string; } const { variant = "solid", color = "primary", size = "md", pill = false, icon = "", class: className, ...rest }: Props = Astro.props; const base = "inline-flex items-center justify-center gap-2 font-medium transition-colors " + "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 " + "disabled:opacity-50 disabled:pointer-events-none"; const sizeClass: Record = { sm: "h-8 px-3 text-sm", md: "h-10 px-4 text-sm", lg: "h-11 px-5 text-base", icon: "h-10 w-10 p-0", }; const radius = pill ? "rounded-full" : "rounded-md"; const styles: Record> = { primary: { solid: "bg-primary text-primary-foreground hover:bg-primary/90 border border-transparent focus-visible:ring-primary/40", outline: "border border-primary text-primary hover:bg-primary/10 focus-visible:ring-primary/40", ghost: "text-primary hover:bg-primary/10 border border-transparent focus-visible:ring-primary/30", soft: "bg-primary/15 text-primary hover:bg-primary/20 border border-transparent focus-visible:ring-primary/30", link: "text-primary underline underline-offset-4 p-0 h-auto border-0 focus-visible:ring-primary/40", }, secondary: { solid: "bg-secondary text-secondary-foreground hover:bg-secondary/90 border border-transparent focus-visible:ring-secondary/40", outline: "border border-secondary text-secondary hover:bg-secondary/10 focus-visible:ring-secondary/40", ghost: "text-secondary hover:bg-secondary/10 border border-transparent focus-visible:ring-secondary/30", soft: "bg-secondary/15 text-secondary hover:bg-secondary/20 border border-transparent focus-visible:ring-secondary/30", link: "text-secondary underline underline-offset-4 p-0 h-auto border-0 focus-visible:ring-secondary/40", }, tertiary: { solid: "bg-tertiary text-tertiary-foreground hover:bg-tertiary/90 border border-transparent focus-visible:ring-tertiary/40", outline: "border border-tertiary text-tertiary hover:bg-tertiary/10 focus-visible:ring-tertiary/40", ghost: "text-tertiary hover:bg-tertiary/10 border border-transparent focus-visible:ring-tertiary/30", soft: "bg-tertiary/15 text-tertiary hover:bg-tertiary/20 border border-transparent focus-visible:ring-tertiary/30", link: "text-tertiary underline underline-offset-4 p-0 h-auto border-0 focus-visible:ring-tertiary/40", }, accent: { solid: "bg-accent text-accent-foreground hover:bg-accent/90 border border-transparent focus-visible:ring-accent/40", outline: "border border-accent text-accent hover:bg-accent/10 focus-visible:ring-accent/40", ghost: "text-accent hover:bg-accent/10 border border-transparent focus-visible:ring-accent/30", soft: "bg-accent/15 text-accent hover:bg-accent/20 border border-transparent focus-visible:ring-accent/30", link: "text-accent underline underline-offset-4 p-0 h-auto border-0 focus-visible:ring-accent/40", }, info: { solid: "bg-info text-info-foreground hover:bg-info/90 border border-transparent focus-visible:ring-info/40", outline: "border border-info text-info hover:bg-info/10 focus-visible:ring-info/40", ghost: "text-info hover:bg-info/10 border border-transparent focus-visible:ring-info/30", soft: "bg-info/15 text-info hover:bg-info/20 border border-transparent focus-visible:ring-info/30", link: "text-info underline underline-offset-4 p-0 h-auto border-0 focus-visible:ring-info/40", }, success: { solid: "bg-success text-success-foreground hover:bg-success/90 border border-transparent focus-visible:ring-success/40", outline: "border border-success text-success hover:bg-success/10 focus-visible:ring-success/40", ghost: "text-success hover:bg-success/10 border border-transparent focus-visible:ring-success/30", soft: "bg-success/15 text-success hover:bg-success/20 border border-transparent focus-visible:ring-success/30", link: "text-success underline underline-offset-4 p-0 h-auto border-0 focus-visible:ring-success/40", }, warning: { solid: "bg-warning text-warning-foreground hover:bg-warning/90 border border-transparent focus-visible:ring-warning/40", outline: "border border-warning text-warning hover:bg-warning/10 focus-visible:ring-warning/40", ghost: "text-warning hover:bg-warning/10 border border-transparent focus-visible:ring-warning/30", soft: "bg-warning/14 text-warning hover:bg-warning/20 border border-transparent focus-visible:ring-warning/30", link: "text-warning underline underline-offset-4 p-0 h-auto border-0 focus-visible:ring-warning/40", }, danger: { solid: "bg-danger text-danger-foreground hover:bg-danger/90 border border-transparent focus-visible:ring-danger/40", outline: "border border-danger text-danger hover:bg-danger/10 focus-visible:ring-danger/40", ghost: "text-danger hover:bg-danger/10 border border-transparent focus-visible:ring-danger/30", soft: "bg-danger/15 text-danger hover:bg-danger/20 border border-transparent focus-visible:ring-danger/30", link: "text-danger underline underline-offset-4 p-0 h-auto border-0 focus-visible:ring-danger/40", }, neutral: { solid: "bg-neutral text-neutral-foreground hover:bg-neutral/90 border border-transparent focus-visible:ring-neutral/40", outline: "border border-neutral text-neutral hover:bg-neutral/10 focus-visible:ring-neutral/40", ghost: "text-neutral hover:bg-neutral/10 border border-transparent focus-visible:ring-neutral/30", soft: "bg-neutral/15 text-neutral hover:bg-neutral/20 border border-transparent focus-visible:ring-neutral/30", link: "text-neutral underline underline-offset-4 p-0 h-auto border-0 focus-visible:ring-neutral/40", }, }; const variantColor = styles[color][variant]; const sizeKls = variant === "link" ? "" : sizeClass[size]; const iconSize = size === "sm" ? "size-4" : size === "lg" ? "size-5" : "size-5"; ---