All files / react-classic/src/components Toggle.tsx

100% Statements 58/58
100% Branches 17/17
100% Functions 3/3
100% Lines 58/58

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 721x 1x       1x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x   12x 12x 12x   2x 2x 1x 1x 2x   1x 12x   12x 5x 5x   5x 2x 1x 1x 1x 1x 5x 3x 1x 3x 2x 2x 3x   5x 5x 5x   12x 12x 12x 12x 12x 12x 12x 12x   12x 12x   12x   1x 2x 2x  
import { debugRender, useValueIs } from '../index.js';
import { type HTMLAttributes, type MouseEventHandler, useMemo, useRef } from 'react';
import type { WritableKeys } from '@anchorlib/core';
import type { ToggleProps } from './Types.js';
 
export function Toggle<T, K extends WritableKeys<T>>({
  bind,
  name,
  value,
  children,
  inherits,
  onChange,
  onClick,
  ref,
  ...props
}: ToggleProps<T, K>) {
  const selfRef = useRef<HTMLButtonElement>(null);
  debugRender(ref ?? selfRef);
 
  const checked = useValueIs(bind as never, name, value ?? true);
  const partial = useMemo(() => {
    if (!Array.isArray(inherits) || !inherits.length) return false;
 
    for (const ref of inherits) {
      if (ref?.[name] === (value ?? true)) {
        return true;
      }
    }
 
    return false;
  }, [bind, name, value]);
 
  const handleToggle: MouseEventHandler<HTMLButtonElement> = (e) => {
    e.stopPropagation();
    e.preventDefault();
 
    if (checked) {
      if (value) {
        delete bind[name];
      } else {
        bind[name] = false as never;
      }
    } else {
      if (value) {
        bind[name] = value as never;
      } else {
        bind[name] = true as never;
      }
    }
 
    onClick?.(e);
    onChange?.(bind[name]);
  };
 
  return (
    <button
      ref={ref ?? selfRef}
      disabled={!bind}
      data-checked={checked}
      data-partial={partial}
      onClick={handleToggle}
      {...props}
    >
      {children}
    </button>
  );
}
 
export function ToggleGroup({ children, className }: HTMLAttributes<HTMLDivElement>) {
  return <div className={`ark-toggle-group ${className}`}>{children}</div>;
}