Files
maqt-desktop/src/components/ui/Button.tsx

56 lines
1.6 KiB
TypeScript

import React from 'react';
type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';
type ButtonSize = 'sm' | 'md' | 'lg';
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: ButtonVariant;
size?: ButtonSize;
loading?: boolean;
}
const variantStyles: Record<ButtonVariant, string> = {
primary:
'bg-[#ff4500] text-[#111] border-[#ff4500] hover:bg-[#111] hover:text-[#ff4500]',
secondary:
'bg-transparent text-[#e0e0e0] border-[#555] hover:bg-[#e0e0e0] hover:text-[#111]',
ghost:
'bg-transparent text-[#888] border-[#333] hover:border-[#e0e0e0] hover:text-[#e0e0e0]',
danger:
'bg-transparent text-[#cc3300] border-[#cc3300] hover:bg-[#cc3300] hover:text-[#111]',
};
const sizeStyles: Record<ButtonSize, string> = {
sm: 'px-4 py-2 text-[15px]',
md: 'px-6 py-3 text-[34px]',
lg: 'px-8 py-4 text-[15px]',
};
export default function Button({
variant = 'primary',
size = 'md',
loading,
disabled,
className = '',
children,
...props
}: ButtonProps) {
return (
<button
disabled={disabled || loading}
className={`inline-flex items-center justify-center gap-2 font-semibold tracking-[0.08em] uppercase
border transition-colors duration-75
${variantStyles[variant]}
${sizeStyles[size]}
${disabled ? 'opacity-40 cursor-not-allowed' : 'cursor-pointer'}
${className}`}
{...props}
>
{loading && (
<span className="w-3 h-3 border border-current border-t-transparent animate-spin" />
)}
{!loading && children}
</button>
);
}