rage-framework-example/apps/browser/src/components/ui/Button.tsx
2025-03-28 17:03:23 +02:00

63 lines
2.0 KiB
TypeScript

import React from 'react'
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
isLoading?: boolean
}
const Button: React.FC<ButtonProps> = ({
children,
className,
isLoading = false,
disabled,
...props
}) => {
const baseClasses =
'w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white focus:outline-none focus:ring-2 focus:ring-offset-2'
const activeClasses = 'bg-sky-600 hover:bg-sky-700 focus:ring-sky-500'
const loadingClasses = 'bg-sky-400 cursor-not-allowed'
const disabledClasses = 'bg-gray-400 cursor-not-allowed'
const getButtonClasses = () => {
if (isLoading)
return `${baseClasses} ${loadingClasses} ${className || ''}`
if (disabled)
return `${baseClasses} ${disabledClasses} ${className || ''}`
return `${baseClasses} ${activeClasses} ${className || ''}`
}
return (
<button
className={getButtonClasses()}
disabled={disabled || isLoading}
{...props}
>
{isLoading ? (
<svg
className="animate-spin -ml-1 mr-3 h-5 w-5 text-white"
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.938l3-2.647z"
></path>
</svg>
) : (
children
)}
</button>
)
}
export default Button