65 lines · 2.0 KB
import { forwardRef } from "react";
import { Button as KumoButton, buttonVariants } from "@cloudflare/kumo/components/button";
import { cn } from "~/utils/cn";

type Variant = "primary" | "secondary" | "danger" | "ghost";
type Size = "sm" | "md";
type KumoVariantProps = NonNullable<Parameters<typeof buttonVariants>[0]>;

const VARIANTS: Record<Variant, KumoVariantProps["variant"]> = {
  primary: "primary",
  secondary: "secondary",
  danger: "secondary-destructive",
  ghost: "ghost",
};

const SIZES: Record<Size, KumoVariantProps["size"]> = {
  sm: "sm",
  md: "base",
};

const ICON_SPACING: Record<Size, string> = {
  sm: "gap-1.5 [&_svg]:size-3.5 [&_svg]:shrink-0",
  md: "gap-2 [&_svg]:size-4 [&_svg]:shrink-0",
};

/** Kumo's Button sets primary emphasis colors inline; class-only buttons (links) get them from a utility. */
const EMPHASIS: Partial<Record<Variant, string>> = {
  primary: "button-emphasis-primary",
};

/** Button styling for non-button elements (router links, anchors, labels). */
export function buttonClass(variant: Variant = "secondary", size: Size = "md", className?: string): string {
  return cn(
    buttonVariants({ variant: VARIANTS[variant], size: SIZES[size] }),
    "inline-flex justify-center whitespace-nowrap no-underline",
    ICON_SPACING[size],
    EMPHASIS[variant],
    className,
  );
}