98 lines
2.4 KiB
TypeScript
98 lines
2.4 KiB
TypeScript
import * as React from "react";
|
|
import {
|
|
Button as KumoButton,
|
|
LinkButton as KumoLinkButton,
|
|
type ButtonProps as KumoButtonProps,
|
|
type LinkButtonProps as KumoLinkButtonProps,
|
|
} from "@cloudflare/kumo/components/button";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type ButtonVariant = "default" | "secondary" | "outline" | "ghost" | "destructive";
|
|
type ButtonSize = "default" | "sm" | "lg" | "icon";
|
|
|
|
const variantMap: Record<ButtonVariant, KumoButtonProps["variant"]> = {
|
|
default: "primary",
|
|
secondary: "secondary",
|
|
outline: "outline",
|
|
ghost: "ghost",
|
|
destructive: "destructive",
|
|
};
|
|
|
|
const sizeMap: Record<ButtonSize, KumoButtonProps["size"]> = {
|
|
default: "base",
|
|
sm: "sm",
|
|
lg: "lg",
|
|
icon: "base",
|
|
};
|
|
|
|
type BaseButtonProps = Omit<KumoButtonProps, "variant" | "size" | "shape"> & {
|
|
variant?: ButtonVariant;
|
|
};
|
|
|
|
type TextButtonProps = BaseButtonProps & {
|
|
size?: Exclude<ButtonSize, "icon">;
|
|
};
|
|
|
|
type IconButtonProps = BaseButtonProps & {
|
|
"aria-label": string;
|
|
size: "icon";
|
|
};
|
|
|
|
export type ButtonProps = TextButtonProps | IconButtonProps;
|
|
|
|
export type LinkButtonProps = Omit<KumoLinkButtonProps, "variant" | "size"> & {
|
|
variant?: ButtonVariant;
|
|
size?: Exclude<ButtonSize, "icon">;
|
|
};
|
|
|
|
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
|
{ className, variant = "default", size = "default", ...props },
|
|
ref,
|
|
): React.ReactElement {
|
|
if (size === "icon") {
|
|
const iconAriaLabel = props["aria-label"];
|
|
|
|
if (!iconAriaLabel) {
|
|
throw new Error("Icon buttons require an aria-label.");
|
|
}
|
|
|
|
return (
|
|
<KumoButton
|
|
{...props}
|
|
ref={ref}
|
|
aria-label={iconAriaLabel}
|
|
className={cn("teatea-button", `teatea-button-${variant}`, className)}
|
|
shape="square"
|
|
size={sizeMap[size]}
|
|
variant={variantMap[variant]}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<KumoButton
|
|
ref={ref}
|
|
className={cn("teatea-button", `teatea-button-${variant}`, className)}
|
|
size={sizeMap[size]}
|
|
variant={variantMap[variant]}
|
|
{...props}
|
|
/>
|
|
);
|
|
});
|
|
|
|
export const LinkButton = React.forwardRef<HTMLAnchorElement, LinkButtonProps>(function LinkButton(
|
|
{ className, variant = "default", size = "default", ...props },
|
|
ref,
|
|
): React.ReactElement {
|
|
return (
|
|
<KumoLinkButton
|
|
ref={ref}
|
|
className={cn("teatea-button", `teatea-button-${variant}`, className)}
|
|
size={sizeMap[size]}
|
|
variant={variantMap[variant]}
|
|
{...props}
|
|
/>
|
|
);
|
|
});
|