Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | import { forwardRef } from "react";
import type { ButtonHTMLAttributes } from "react";
import { cn } from "@/utils/class-name";
const BUTTON_VARIANT_CLASSES = {
primary:
"bg-slate-900 text-white hover:bg-slate-800 disabled:bg-slate-400 disabled:text-white",
secondary:
"bg-slate-200 text-slate-900 hover:bg-slate-300 disabled:bg-slate-100 disabled:text-slate-400",
outline:
"border border-slate-300 bg-white text-slate-900 hover:bg-slate-50 disabled:border-slate-200 disabled:text-slate-400",
ghost:
"bg-transparent text-slate-900 hover:bg-slate-100 disabled:text-slate-400",
danger:
"bg-red-600 text-white hover:bg-red-500 disabled:bg-red-300 disabled:text-red-50",
} as const;
const BUTTON_SIZE_CLASSES = {
sm: "h-8 px-3 text-xs",
md: "h-10 px-4 text-sm",
lg: "h-11 px-5 text-sm",
} as const;
type ButtonVariant = keyof typeof BUTTON_VARIANT_CLASSES;
type ButtonSize = keyof typeof BUTTON_SIZE_CLASSES;
export type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
variant?: ButtonVariant;
size?: ButtonSize;
fullWidth?: boolean;
isLoading?: boolean;
};
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
(
{
variant = "primary",
size = "md",
fullWidth = false,
isLoading = false,
className,
disabled,
children,
...props
},
ref,
) => (
<button
ref={ref}
disabled={disabled || isLoading}
className={cn(
"inline-flex items-center justify-center rounded-lg font-medium transition disabled:cursor-not-allowed",
BUTTON_VARIANT_CLASSES[variant],
BUTTON_SIZE_CLASSES[size],
fullWidth && "w-full",
className,
)}
{...props}
>
{children}
</button>
),
);
Button.displayName = "Button";
|