Files
teatea-pension/components/ui/button.tsx

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}
/>
);
});