|
|
|
@@ -0,0 +1,140 @@
|
|
|
|
|
---
|
|
|
|
|
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<"a"> {
|
|
|
|
|
variant?: Variant;
|
|
|
|
|
color?: Color;
|
|
|
|
|
size?: Size;
|
|
|
|
|
pill?: boolean;
|
|
|
|
|
icon?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
variant = "solid",
|
|
|
|
|
color = "primary",
|
|
|
|
|
size = "md",
|
|
|
|
|
pill = false,
|
|
|
|
|
icon = "",
|
|
|
|
|
class: className,
|
|
|
|
|
href = "#",
|
|
|
|
|
...rest
|
|
|
|
|
}: Props = Astro.props;
|
|
|
|
|
|
|
|
|
|
const base =
|
|
|
|
|
"wr:inline-flex wr:items-center wr:justify-center wr:gap-2 wr:font-medium wr:transition-colors " +
|
|
|
|
|
"wr:focus-visible:outline-none wr:focus-visible:ring-2 wr:focus-visible:ring-offset-2 " +
|
|
|
|
|
"wr:disabled:opacity-50 wr:disabled:pointer-events-none";
|
|
|
|
|
|
|
|
|
|
const sizeClass: Record<Size, string> = {
|
|
|
|
|
sm: "wr:h-8 wr:px-3 wr:text-sm",
|
|
|
|
|
md: "wr:h-10 wr:px-4 wr:text-sm",
|
|
|
|
|
lg: "wr:h-11 wr:px-5 wr:text-base",
|
|
|
|
|
icon: "wr:h-10 wr:w-10 wr:p-0",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const radius = pill ? "wr:rounded-full" : "wr:rounded-md";
|
|
|
|
|
|
|
|
|
|
const styles: Record<Color, Record<Variant, string>> = {
|
|
|
|
|
primary: {
|
|
|
|
|
solid: "wr:bg-primary wr:text-primary-foreground wr:hover:bg-primary/90 wr:border wr:border-transparent wr:focus-visible:ring-primary/40",
|
|
|
|
|
outline:
|
|
|
|
|
"wr:border wr:border-primary wr:text-primary wr:hover:bg-primary/10 wr:focus-visible:ring-primary/40",
|
|
|
|
|
ghost: "wr:text-primary wr:hover:bg-primary/10 wr:border wr:border-transparent wr:focus-visible:ring-primary/30",
|
|
|
|
|
soft: "wr:bg-primary/15 wr:text-primary wr:hover:bg-primary/20 wr:border wr:border-transparent wr:focus-visible:ring-primary/30",
|
|
|
|
|
link: "wr:text-primary wr:underline wr:underline-offset-4 wr:p-0 wr:h-auto wr:border-0 wr:focus-visible:ring-primary/40",
|
|
|
|
|
},
|
|
|
|
|
secondary: {
|
|
|
|
|
solid: "wr:bg-secondary wr:text-secondary-foreground wr:hover:bg-secondary/90 wr:border wr:border-transparent wr:focus-visible:ring-secondary/40",
|
|
|
|
|
outline:
|
|
|
|
|
"wr:border wr:border-secondary wr:text-secondary wr:hover:bg-secondary/10 wr:focus-visible:ring-secondary/40",
|
|
|
|
|
ghost: "wr:text-secondary wr:hover:bg-secondary/10 wr:border wr:border-transparent wr:focus-visible:ring-secondary/30",
|
|
|
|
|
soft: "wr:bg-secondary/15 wr:text-secondary wr:hover:bg-secondary/20 wr:border wr:border-transparent wr:focus-visible:ring-secondary/30",
|
|
|
|
|
link: "wr:text-secondary wr:underline wr:underline-offset-4 wr:p-0 wr:h-auto wr:border-0 wr:focus-visible:ring-secondary/40",
|
|
|
|
|
},
|
|
|
|
|
tertiary: {
|
|
|
|
|
solid: "wr:bg-tertiary wr:text-tertiary-foreground wr:hover:bg-tertiary/90 wr:border wr:border-transparent wr:focus-visible:ring-tertiary/40",
|
|
|
|
|
outline:
|
|
|
|
|
"wr:border wr:border-tertiary wr:text-tertiary wr:hover:bg-tertiary/10 wr:focus-visible:ring-tertiary/40",
|
|
|
|
|
ghost: "wr:text-tertiary wr:hover:bg-tertiary/10 wr:border wr:border-transparent wr:focus-visible:ring-tertiary/30",
|
|
|
|
|
soft: "wr:bg-tertiary/15 wr:text-tertiary wr:hover:bg-tertiary/20 wr:border wr:border-transparent wr:focus-visible:ring-tertiary/30",
|
|
|
|
|
link: "wr:text-tertiary wr:underline wr:underline-offset-4 wr:p-0 wr:h-auto wr:border-0 wr:focus-visible:ring-tertiary/40",
|
|
|
|
|
},
|
|
|
|
|
accent: {
|
|
|
|
|
solid: "wr:bg-accent wr:text-accent-foreground wr:hover:bg-accent/90 wr:border wr:border-transparent wr:focus-visible:ring-accent/40",
|
|
|
|
|
outline:
|
|
|
|
|
"wr:border wr:border-accent wr:text-accent wr:hover:bg-accent/10 wr:focus-visible:ring-accent/40",
|
|
|
|
|
ghost: "wr:text-accent wr:hover:bg-accent/10 wr:border wr:border-transparent wr:focus-visible:ring-accent/30",
|
|
|
|
|
soft: "wr:bg-accent/15 wr:text-accent wr:hover:bg-accent/20 wr:border wr:border-transparent wr:focus-visible:ring-accent/30",
|
|
|
|
|
link: "wr:text-accent wr:underline wr:underline-offset-4 wr:p-0 wr:h-auto wr:border-0 wr:focus-visible:ring-accent/40",
|
|
|
|
|
},
|
|
|
|
|
info: {
|
|
|
|
|
solid: "wr:bg-info wr:text-info-foreground wr:hover:bg-info/90 wr:border wr:border-transparent wr:focus-visible:ring-info/40",
|
|
|
|
|
outline:
|
|
|
|
|
"wr:border wr:border-info wr:text-info wr:hover:bg-info/10 wr:focus-visible:ring-info/40",
|
|
|
|
|
ghost: "wr:text-info wr:hover:bg-info/10 wr:border wr:border-transparent wr:focus-visible:ring-info/30",
|
|
|
|
|
soft: "wr:bg-info/15 wr:text-info wr:hover:bg-info/20 wr:border wr:border-transparent wr:focus-visible:ring-info/30",
|
|
|
|
|
link: "wr:text-info wr:underline wr:underline-offset-4 wr:p-0 wr:h-auto wr:border-0 wr:focus-visible:ring-info/40",
|
|
|
|
|
},
|
|
|
|
|
success: {
|
|
|
|
|
solid: "wr:bg-success wr:text-success-foreground wr:hover:bg-success/90 wr:border wr:border-transparent wr:focus-visible:ring-success/40",
|
|
|
|
|
outline:
|
|
|
|
|
"wr:border wr:border-success wr:text-success wr:hover:bg-success/10 wr:focus-visible:ring-success/40",
|
|
|
|
|
ghost: "wr:text-success wr:hover:bg-success/10 wr:border wr:border-transparent wr:focus-visible:ring-success/30",
|
|
|
|
|
soft: "wr:bg-success/15 wr:text-success wr:hover:bg-success/20 wr:border wr:border-transparent wr:focus-visible:ring-success/30",
|
|
|
|
|
link: "wr:text-success wr:underline wr:underline-offset-4 wr:p-0 wr:h-auto wr:border-0 wr:focus-visible:ring-success/40",
|
|
|
|
|
},
|
|
|
|
|
warning: {
|
|
|
|
|
solid: "wr:bg-warning wr:text-warning-foreground wr:hover:bg-warning/90 wr:border wr:border-transparent wr:focus-visible:ring-warning/40",
|
|
|
|
|
outline:
|
|
|
|
|
"wr:border wr:border-warning wr:text-warning wr:hover:bg-warning/10 wr:focus-visible:ring-warning/40",
|
|
|
|
|
ghost: "wr:text-warning wr:hover:bg-warning/10 wr:border wr:border-transparent wr:focus-visible:ring-warning/30",
|
|
|
|
|
soft: "wr:bg-warning/14 wr:text-warning wr:hover:bg-warning/20 wr:border wr:border-transparent wr:focus-visible:ring-warning/30",
|
|
|
|
|
link: "wr:text-warning wr:underline wr:underline-offset-4 wr:p-0 wr:h-auto wr:border-0 wr:focus-visible:ring-warning/40",
|
|
|
|
|
},
|
|
|
|
|
danger: {
|
|
|
|
|
solid: "wr:bg-danger wr:text-danger-foreground wr:hover:bg-danger/90 wr:border wr:border-transparent wr:focus-visible:ring-danger/40",
|
|
|
|
|
outline:
|
|
|
|
|
"wr:border wr:border-danger wr:text-danger wr:hover:bg-danger/10 wr:focus-visible:ring-danger/40",
|
|
|
|
|
ghost: "wr:text-danger wr:hover:bg-danger/10 wr:border wr:border-transparent wr:focus-visible:ring-danger/30",
|
|
|
|
|
soft: "wr:bg-danger/15 wr:text-danger wr:hover:bg-danger/20 wr:border wr:border-transparent wr:focus-visible:ring-danger/30",
|
|
|
|
|
link: "wr:text-danger wr:underline wr:underline-offset-4 wr:p-0 wr:h-auto wr:border-0 wr:focus-visible:ring-danger/40",
|
|
|
|
|
},
|
|
|
|
|
neutral: {
|
|
|
|
|
solid: "wr:bg-neutral wr:text-neutral-foreground wr:hover:bg-neutral/90 wr:border wr:border-transparent wr:focus-visible:ring-neutral/40",
|
|
|
|
|
outline:
|
|
|
|
|
"wr:border wr:border-neutral wr:text-neutral wr:hover:bg-neutral/10 wr:focus-visible:ring-neutral/40",
|
|
|
|
|
ghost: "wr:text-neutral wr:hover:bg-neutral/10 wr:border wr:border-transparent wr:focus-visible:ring-neutral/30",
|
|
|
|
|
soft: "wr:bg-neutral/15 wr:text-neutral wr:hover:bg-neutral/20 wr:border wr:border-transparent wr:focus-visible:ring-neutral/30",
|
|
|
|
|
link: "wr:text-neutral wr:underline wr:underline-offset-4 wr:p-0 wr:h-auto wr:border-0 wr:focus-visible:ring-neutral/40",
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const variantColor = styles[color][variant];
|
|
|
|
|
const sizeKls = variant === "link" ? "" : sizeClass[size];
|
|
|
|
|
const iconSize =
|
|
|
|
|
size === "sm" ? "wr:size-4" : size === "lg" ? "wr:size-5" : "wr:size-5";
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
<a
|
|
|
|
|
href={href}
|
|
|
|
|
class={cn(base, radius, sizeKls, variantColor, className)}
|
|
|
|
|
{...rest}
|
|
|
|
|
>
|
|
|
|
|
{icon && <Icon name={icon} class={cn(iconSize, "wr:shrink-0")} />}
|
|
|
|
|
<slot />
|
|
|
|
|
</a>
|