Files
gridpilot.gg/apps/website/components/ui/Button.tsx
2025-12-02 19:44:18 +01:00

53 lines
1.6 KiB
TypeScript

import { ButtonHTMLAttributes, AnchorHTMLAttributes, ReactNode } from 'react';
type ButtonAsButton = ButtonHTMLAttributes<HTMLButtonElement> & {
as?: 'button';
href?: never;
};
type ButtonAsLink = AnchorHTMLAttributes<HTMLAnchorElement> & {
as: 'a';
href: string;
};
type ButtonProps = (ButtonAsButton | ButtonAsLink) & {
variant?: 'primary' | 'secondary';
children: ReactNode;
};
export default function Button({
variant = 'primary',
children,
className = '',
as = 'button',
...props
}: ButtonProps) {
const baseStyles = 'min-h-[44px] rounded-full px-6 py-3 text-sm font-semibold transition-all duration-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 hover:scale-[1.03] active:scale-95';
const variantStyles = {
primary: 'bg-primary-blue text-white shadow-[0_0_15px_rgba(25,140,255,0.4)] hover:shadow-[0_0_25px_rgba(25,140,255,0.6)] active:ring-2 active:ring-primary-blue focus-visible:outline-primary-blue',
secondary: 'bg-iron-gray text-white border border-charcoal-outline shadow-[0_0_10px_rgba(25,140,255,0.2)] hover:shadow-[0_0_20px_rgba(25,140,255,0.4)] hover:border-primary-blue focus-visible:outline-primary-blue'
};
const classes = `${baseStyles} ${variantStyles[variant]} ${className}`;
if (as === 'a') {
return (
<a
className={classes}
{...(props as AnchorHTMLAttributes<HTMLAnchorElement>)}
>
{children}
</a>
);
}
return (
<button
className={classes}
{...(props as ButtonHTMLAttributes<HTMLButtonElement>)}
>
{children}
</button>
);
}