All files / src/components Button.tsx

100% Statements 30/30
100% Branches 1/1
100% Functions 1/1
100% Lines 30/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 431x               1x 107x 107x 107x 107x 107x 107x 107x 107x   107x 107x 107x 107x 107x 107x 107x 107x   107x 107x 107x 107x 107x   107x 107x 107x 107x   107x 107x   107x  
import type { ButtonHTMLAttributes, ReactNode } from 'react';
 
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
  size?: 'sm' | 'md' | 'lg';
  children: ReactNode;
}
 
export function Button({
  variant = 'primary',
  size = 'md',
  className = '',
  children,
  ...props
}: ButtonProps) {
  const baseStyles =
    'inline-flex items-center justify-center font-medium rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-bambu-dark disabled:opacity-50 disabled:cursor-not-allowed';
 
  const variants = {
    primary: 'bg-bambu-green hover:bg-bambu-green-light text-white focus:ring-bambu-green',
    secondary:
      'bg-bambu-dark-tertiary hover:bg-bambu-gray-dark text-white focus:ring-bambu-gray',
    danger: 'bg-red-600 hover:bg-red-700 text-white focus:ring-red-500',
    ghost:
      'bg-transparent hover:bg-bambu-dark-tertiary text-bambu-gray-light hover:text-white',
  };
 
  const sizes = {
    sm: 'px-3 py-1.5 text-sm gap-1.5 min-h-[44px] md:min-h-0',
    md: 'px-4 py-2 text-sm gap-2 min-h-[44px] md:min-h-0',
    lg: 'px-6 py-3 text-base gap-2 min-h-[48px] md:min-h-0',
  };
 
  return (
    <button
      className={`${baseStyles} ${variants[variant]} ${sizes[size]} ${className}`}
      {...props}
    >
      {children}
    </button>
  );
}