hackdex-website/src/components/Button.tsx
2025-10-07 02:06:46 -10:00

56 lines
1.5 KiB
TypeScript

"use client";
import React from "react";
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
variant?: "primary" | "secondary" | "ghost";
size?: "sm" | "md" | "lg";
isLoading?: boolean;
};
const base =
"inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] disabled:opacity-60 disabled:cursor-not-allowed";
const variants: Record<string, string> = {
primary:
"bg-[var(--accent)] text-[var(--accent-foreground)] hover:bg-[var(--accent-700)]",
secondary:
"bg-white/10 text-foreground border border-white/10 hover:bg-white/15",
ghost: "bg-transparent text-foreground hover:bg-white/5",
};
const sizes: Record<string, string> = {
sm: "h-9 px-3 text-sm",
md: "h-11 px-4 text-sm",
lg: "h-12 px-5 text-base",
};
export default function Button({
className,
variant = "primary",
size = "md",
isLoading,
children,
...props
}: ButtonProps) {
return (
<button
className={`${base} ${variants[variant]} ${sizes[size]} ${className ?? ""}`}
{...props}
>
{isLoading ? (
<span className="relative">
<span className="opacity-0">{children}</span>
<span className="absolute inset-0 flex items-center justify-center">
<span className="h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white" />
</span>
</span>
) : (
children
)}
</button>
);
}