Files
flyer-crawler.projectium.com/src/components/Button.tsx
Torben Sorensen 4e5d709973
Some checks failed
Deploy to Test Environment / deploy-to-test (push) Failing after 12s
more fixin logging, UI update #1, source maps fix
2026-01-21 03:27:44 -08:00

82 lines
2.6 KiB
TypeScript

import React from 'react';
import { LoadingSpinner } from './LoadingSpinner';
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
size?: 'sm' | 'md' | 'lg';
isLoading?: boolean;
leftIcon?: React.ReactNode;
rightIcon?: React.ReactNode;
fullWidth?: boolean;
}
export const Button: React.FC<ButtonProps> = ({
variant = 'primary',
size = 'md',
isLoading = false,
leftIcon,
rightIcon,
fullWidth = false,
className = '',
children,
disabled,
...props
}) => {
const baseClasses =
'inline-flex items-center justify-center font-bold rounded-lg transition-colors duration-300 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed';
const variantClasses = {
primary:
'bg-brand-secondary hover:bg-brand-dark text-white focus:ring-brand-primary disabled:bg-gray-400 disabled:hover:bg-gray-400',
secondary:
'bg-gray-200 hover:bg-gray-300 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-200 focus:ring-gray-400 disabled:bg-gray-100 disabled:hover:bg-gray-100 dark:disabled:bg-gray-800 dark:disabled:hover:bg-gray-800 disabled:text-gray-400',
danger:
'bg-red-100 hover:bg-red-200 dark:bg-red-900/50 dark:hover:bg-red-900/70 text-red-700 dark:text-red-300 focus:ring-red-500 disabled:bg-red-50 disabled:hover:bg-red-50 dark:disabled:bg-red-900/20 dark:disabled:hover:bg-red-900/20 disabled:text-red-300',
ghost:
'bg-transparent hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-200 focus:ring-gray-400 disabled:text-gray-400 disabled:hover:bg-transparent',
};
const sizeClasses = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg',
};
const widthClass = fullWidth ? 'w-full' : '';
const iconSizeClasses = {
sm: 'w-4 h-4',
md: 'w-5 h-5',
lg: 'w-6 h-6',
};
const isDisabled = disabled || isLoading;
return (
<button
className={`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${widthClass} ${className}`}
disabled={isDisabled}
{...props}
>
{isLoading ? (
<>
<span className={`${iconSizeClasses[size]} mr-2`}>
<LoadingSpinner />
</span>
{children}
</>
) : (
<>
{leftIcon && (
<span className={`${iconSizeClasses[size]} mr-2 flex-shrink-0`}>{leftIcon}</span>
)}
{children}
{rightIcon && (
<span className={`${iconSizeClasses[size]} ml-2 flex-shrink-0`}>{rightIcon}</span>
)}
</>
)}
</button>
);
};