diff --git a/src/components/ui/Button.tsx b/src/components/ui/Button.tsx index e56214e..a6a1c4e 100644 --- a/src/components/ui/Button.tsx +++ b/src/components/ui/Button.tsx @@ -12,56 +12,42 @@ export function Button({ size = 'md', loading = false, disabled, + className, style, ...props }: ButtonProps) { - const baseStyle: React.CSSProperties = { - fontFamily: 'var(--font-mono)', - fontSize: - size === 'sm' ? 'var(--text-xs)' : size === 'lg' ? 'var(--text-lg)' : 'var(--text-sm)', - padding: size === 'sm' ? '4px 10px' : size === 'lg' ? '10px 24px' : '7px 16px', - border: '1px solid var(--border)', - borderRadius: '6px', - cursor: disabled || loading ? 'not-allowed' : 'pointer', - transition: 'all 0.15s ease', - letterSpacing: '-0.01em', - display: 'inline-flex', - alignItems: 'center', - gap: '6px', - opacity: disabled || loading ? 0.5 : 1, - ...getVariantStyle(variant), - ...style, + const baseClasses = + 'inline-flex items-center gap-1.5 rounded-[6px] border font-[var(--font-mono)] tracking-[-0.01em] transition-all duration-150 ease-in-out'; + const sizeClasses: Record, string> = { + sm: 'text-[var(--text-xs)] px-[10px] py-[4px]', + md: 'text-[var(--text-sm)] px-[16px] py-[7px]', + lg: 'text-[var(--text-lg)] px-[24px] py-[10px]', }; + const variantClasses: Record, string> = { + primary: 'bg-[var(--bg-tertiary)] text-[var(--text)] border-[var(--border)]', + ghost: 'bg-transparent text-[var(--text-muted)] border-transparent', + danger: 'bg-[color-mix(in_srgb,var(--status-error),transparent_90%)] text-[var(--status-error)] border-[color-mix(in_srgb,var(--status-error),transparent_80%)]', + }; + const stateClasses = disabled || loading ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'; + const combinedClassName = [ + baseClasses, + sizeClasses[size], + variantClasses[variant], + stateClasses, + className, + ] + .filter(Boolean) + .join(' '); return ( - ); } - -function getVariantStyle(variant: string): React.CSSProperties { - switch (variant) { - case 'primary': - return { - background: 'var(--bg-tertiary)', - color: 'var(--text)', - borderColor: 'var(--border)', - }; - case 'ghost': - return { - background: 'transparent', - color: 'var(--text-muted)', - borderColor: 'transparent', - }; - case 'danger': - return { - background: 'rgba(248, 81, 73, 0.1)', - color: 'var(--status-error)', - borderColor: 'rgba(248, 81, 73, 0.2)', - }; - default: - return {}; - } -}