All files / src/components toggle-switch.tsx

100% Statements 7/7
86.66% Branches 13/15
100% Functions 2/2
100% Lines 7/7

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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92                                        8x                           10x   10x   10x 1x 1x       10x                                                                                              
import { type FC } from 'react';
import cn from 'classnames';
 
import Chip from './chip';
 
import '../styles/components/toggle-switch.scss';
 
type Props = {
  header: string;
  statusOff: string;
  statusLoading: string;
  statusOn: string;
  icon: React.ReactNode;
  checked: boolean;
  isLoading?: boolean;
  onChange: (checked: boolean) => void;
  ariaLabel?: string;
  className?: string;
} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'>;
 
const ToggleSwitch: FC<Props> = ({
  header,
  statusOff,
  statusLoading,
  statusOn,
  icon,
  checked,
  isLoading = false,
  onChange,
  ariaLabel = 'Toggle',
  disabled = false,
  className = '',
  ...rest
}) => {
  const isOn = checked && !isLoading;
  const status =
    (isLoading && statusLoading) || (checked && statusOn) || statusOff;
 
  const handleToggle = () => {
    Eif (!disabled) {
      onChange(!checked);
    }
  };
 
  return (
    <button
      type="button"
      className={cn(
        'toggle',
        {
          'toggle--on': isOn,
          'toggle--loading': isLoading,
          'toggle--disabled': disabled,
        },
        className
      )}
      role="switch"
      aria-checked={checked}
      aria-label={ariaLabel}
      disabled={disabled}
      onClick={handleToggle}
      {...rest}
    >
      <div className="toggle__content">
        <div className="toggle__icon">{icon}</div>
        <div className="toggle__text">
          <div className="toggle__header">
            {header}
            {isOn && (
              <Chip
                compact
                className="toggle__header__chip"
                tabIndex={-1}
                aria-hidden="true"
                asSpan
              >
                ON
              </Chip>
            )}
          </div>
          <div className="toggle__status">{status}</div>
        </div>
        <div className="toggle__switch" aria-hidden="true">
          <span className="slider" />
        </div>
      </div>
    </button>
  );
};
 
export default ToggleSwitch;