Files
pasargad/src/components/Button.tsx
T

79 lines
2.4 KiB
TypeScript
Raw Normal View History

2025-05-31 14:46:26 +03:30
import React, { ButtonHTMLAttributes, ReactNode } from 'react';
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
children?: ReactNode; // Make children optional for icon-only buttons
loading?: boolean;
disabled?: boolean;
endIcon?: ReactNode;
size?: 'small' | 'medium' | 'large'; // Add size prop
iconOnly?: boolean; // Add iconOnly prop
}
const Button: React.FC<ButtonProps> = ({
children,
loading = false,
disabled = false,
endIcon,
size = 'medium', // Default size to medium
iconOnly = false, // Default iconOnly to false
className,
...props
}) => {
const baseStyles =
'inline-flex items-center justify-center border border-transparent font-medium rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 ';
const enabledStyles =
'text-white bg-primary-light hover:bg-indigo-700 active:bg-indigo-800 focus:ring-indigo-500';
const disabledStyles = 'text-gray-400 bg-gray-200 cursor-not-allowed';
const loadingStyles = 'text-gray-400 bg-gray-200 cursor-wait';
const sizeStyles = {
small: iconOnly ? 'p-2 text-sm' : 'px-3 py-1.5 text-sm',
medium: iconOnly ? 'p-2.5 text-base' : 'px-4 py-2 text-base',
large: iconOnly ? 'p-3 text-lg' : 'px-6 py-3 text-lg',
};
const currentStyles = disabled
? disabledStyles
: loading
? loadingStyles
: enabledStyles;
return (
<button
className={`${baseStyles} ${sizeStyles[size]} ${currentStyles} ${className || 'bg-gray-500 '}`}
disabled={disabled || loading}
{...props}
>
{loading ? (
<svg
className="animate-spin -ml-1 mr-3 h-5 w-5 text-primary"
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"
></circle>
<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.938l2-2.647z"
></path>
</svg>
) : null}
{children && !iconOnly ? children : null}
{endIcon && !loading && !iconOnly ? (
<span className="ml-2">{endIcon}</span>
) : null}
{iconOnly && endIcon && !loading ? endIcon : null}
</button>
);
};
export default Button;