mirror of
https://github.com/arthur-pbty/flint.git
synced 2026-08-02 04:37:57 +02:00
76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
import type { ButtonHTMLAttributes } from "react";
|
|
|
|
import { cn } from "./cn";
|
|
|
|
type ButtonVariant = "primary" | "secondary" | "ghost" | "danger";
|
|
type ButtonSize = "sm" | "md" | "lg";
|
|
|
|
const baseStyles =
|
|
"inline-flex items-center justify-center gap-2 rounded-xl border font-semibold transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--primary)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--bg)] disabled:cursor-not-allowed disabled:opacity-50";
|
|
|
|
const variantStyles: Record<ButtonVariant, string> = {
|
|
primary:
|
|
"border-transparent bg-[var(--primary)] text-white hover:bg-[var(--primary-hover)]",
|
|
secondary:
|
|
"border-[var(--border-subtle)] bg-[var(--surface-subtle)] text-[var(--foreground)] hover:bg-[var(--surface-strong)]",
|
|
ghost:
|
|
"border-transparent bg-transparent text-[var(--foreground-muted)] hover:bg-[var(--surface-subtle)] hover:text-[var(--foreground)]",
|
|
danger:
|
|
"border-transparent bg-[var(--danger)] text-white hover:brightness-95",
|
|
};
|
|
|
|
const sizeStyles: Record<ButtonSize, string> = {
|
|
sm: "h-9 px-3 text-xs",
|
|
md: "h-10 px-4 text-sm",
|
|
lg: "h-11 px-5 text-sm",
|
|
};
|
|
|
|
type ButtonClassNameOptions = {
|
|
variant?: ButtonVariant;
|
|
size?: ButtonSize;
|
|
fullWidth?: boolean;
|
|
className?: string;
|
|
};
|
|
|
|
export function buttonClassName({
|
|
variant = "primary",
|
|
size = "md",
|
|
fullWidth = false,
|
|
className,
|
|
}: ButtonClassNameOptions = {}) {
|
|
return cn(
|
|
baseStyles,
|
|
variantStyles[variant],
|
|
sizeStyles[size],
|
|
fullWidth ? "w-full" : "",
|
|
className,
|
|
);
|
|
}
|
|
|
|
export type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
variant?: ButtonVariant;
|
|
size?: ButtonSize;
|
|
fullWidth?: boolean;
|
|
};
|
|
|
|
export function Button({
|
|
className,
|
|
variant,
|
|
size,
|
|
fullWidth,
|
|
type = "button",
|
|
...props
|
|
}: ButtonProps) {
|
|
return (
|
|
<button
|
|
className={buttonClassName({
|
|
variant: variant ?? "primary",
|
|
size: size ?? "md",
|
|
fullWidth: fullWidth ?? false,
|
|
className: className ?? "",
|
|
})}
|
|
type={type}
|
|
{...props}
|
|
/>
|
|
);
|
|
} |