diff --git a/src/components/Breadcrumb.astro b/src/components/Breadcrumb.astro new file mode 100644 index 0000000..a7d93ec --- /dev/null +++ b/src/components/Breadcrumb.astro @@ -0,0 +1,48 @@ +--- +import { Icon } from "astro-icon/components"; + +interface BreadcrumbItem { + name: string; + icon?: string; + url?: string; +} + +const { items, separator = "/" } = Astro.props as { + items: BreadcrumbItem[]; + separator?: string; +}; +--- + + diff --git a/src/components/Link.astro b/src/components/Link.astro new file mode 100644 index 0000000..96095f0 --- /dev/null +++ b/src/components/Link.astro @@ -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 = { + 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> = { + 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"; +--- + + + {icon && } + + diff --git a/src/layouts/ComponentLayout.astro b/src/layouts/ComponentLayout.astro index b8871f5..a86ced2 100644 --- a/src/layouts/ComponentLayout.astro +++ b/src/layouts/ComponentLayout.astro @@ -23,6 +23,12 @@ import Base from "./Base.astro";
  • Buttons
  • +
  • + Breadcrumb +
  • +
  • + Link +
  • Forms
  • diff --git a/src/pages/breadcrumb.astro b/src/pages/breadcrumb.astro new file mode 100644 index 0000000..8a523c0 --- /dev/null +++ b/src/pages/breadcrumb.astro @@ -0,0 +1,18 @@ +--- +import ComponentLayout from "../layouts/ComponentLayout.astro"; +import Breadcrumb from "../components/Breadcrumb.astro"; + +const breadcrumbItems = [ + { name: "Home", icon: "mdi:home", url: "/" }, + { name: "Products", url: "/products" }, + { name: "Electronics", url: "/products/electronics" }, + { name: "Cameras", icon: "mdi:camera-image" }, +]; +--- + + +
    + + +
    +
    diff --git a/src/pages/link.astro b/src/pages/link.astro new file mode 100644 index 0000000..1e63252 --- /dev/null +++ b/src/pages/link.astro @@ -0,0 +1,18 @@ +--- +import ComponentLayout from "../layouts/ComponentLayout.astro"; +import Link from "../components/Link.astro"; +--- + + +
    + + Submit + +
    +