46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
import type { ButtonHTMLAttributes, ReactNode } from "react";
|
|
|
|
type ButtonVariant = "primary" | "secondary" | "ghost";
|
|
type ButtonSize = "sm" | "md" | "lg";
|
|
|
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
children: ReactNode;
|
|
variant?: ButtonVariant;
|
|
size?: ButtonSize;
|
|
}
|
|
|
|
const baseClasses =
|
|
"inline-flex items-center justify-center font-medium rounded-[var(--radius-md)] transition-all duration-[var(--duration-normal)] ease-[var(--easing-default)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--color-primary)] disabled:pointer-events-none disabled:opacity-50";
|
|
|
|
const variantClasses: Record<ButtonVariant, string> = {
|
|
primary:
|
|
"bg-[var(--color-primary)] text-[color:var(--color-background)] hover:opacity-90",
|
|
secondary:
|
|
"bg-[var(--color-muted)] text-[color:var(--color-foreground)] border border-[color:var(--color-border)] hover:opacity-80",
|
|
ghost:
|
|
"bg-transparent text-[color:var(--color-foreground)] hover:bg-[var(--color-muted)]",
|
|
};
|
|
|
|
const sizeClasses: Record<ButtonSize, string> = {
|
|
sm: "px-[var(--spacing-sm)] py-[var(--spacing-xs)] text-[length:var(--font-size-sm)]",
|
|
md: "px-[var(--spacing-md)] py-[var(--spacing-sm)] text-[length:var(--font-size-base)]",
|
|
lg: "px-[var(--spacing-lg)] py-[var(--spacing-md)] text-[length:var(--font-size-lg)]",
|
|
};
|
|
|
|
export function Button({
|
|
children,
|
|
variant = "primary",
|
|
size = "md",
|
|
className = "",
|
|
...props
|
|
}: ButtonProps) {
|
|
return (
|
|
<button
|
|
className={`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${className}`.trim()}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</button>
|
|
);
|
|
}
|