the-tip-top-frontend/components/Button.tsx
soufiane 81a3e0bfae feat: update color palette to WCAG AA compliant green theme
- Update primary colors to forest green (#0B6029)
- Update all page titles to use primary-300/500 colors
- Update components (Header, Footer, Button, etc.)
- Fix email to thetiptopgr3@gmail.com
- Adjust hero section spacing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 11:18:19 +01:00

91 lines
2.6 KiB
TypeScript

import { ButtonHTMLAttributes, forwardRef } from "react";
import { cn } from "@/utils/helpers";
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: "primary" | "secondary" | "outline" | "danger" | "success";
size?: "sm" | "md" | "lg";
isLoading?: boolean;
fullWidth?: boolean;
}
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
(
{
children,
className,
variant = "primary",
size = "md",
isLoading = false,
fullWidth = false,
disabled,
...props
},
ref
) => {
const baseStyles =
"inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed";
const variants = {
primary:
"bg-primary-500 text-white hover:bg-primary-600 focus:ring-primary-500 shadow-md hover:shadow-lg",
secondary:
"bg-white text-gray-700 hover:bg-primary-500 hover:text-white focus:ring-primary-500 border border-gray-300 shadow-sm",
outline:
"border-2 border-primary-500 text-primary-500 hover:bg-primary-500 hover:text-white focus:ring-primary-500 shadow-sm",
danger:
"bg-red-600 text-white hover:bg-red-700 focus:ring-red-500 shadow-md",
success:
"bg-primary-600 text-white hover:bg-primary-700 focus:ring-primary-600 shadow-md hover:shadow-lg",
};
const sizes = {
sm: "px-3 py-1.5 text-sm",
md: "px-4 py-2 text-base",
lg: "px-6 py-3 text-lg",
};
return (
<button
ref={ref}
disabled={disabled || isLoading}
className={cn(
baseStyles,
variants[variant],
sizes[size],
fullWidth && "w-full",
className
)}
{...props}
>
{isLoading && (
<svg
className="animate-spin -ml-1 mr-2 h-4 w-4"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
/>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
)}
{children}
</button>
);
}
);
Button.displayName = "Button";
export default Button;