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

100% Statements 50/50
100% Branches 19/19
100% Functions 2/2
100% Lines 50/50

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 631x   1x       1x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x 16x   16x 16x   3x 3x 3x 3x 16x 16x   16x 16x 16x 16x 16x 16x 16x 6x 6x   6x 2x 2x 2x   6x 1x 6x 5x 5x   6x 1x 1x 6x   6x 6x 16x 16x   16x  
import { useMemo, useRef } from 'react';
import type { Bindable } from '../index.js';
import { debugRender, useValue } from '../index.js';
import type { WritableKeys } from '@anchorlib/core';
import type { InputProps } from './Types.js';
 
export function Input<T extends Bindable, K extends WritableKeys<T>>({
  ref,
  bind,
  name,
  pipe,
  value,
  inherits,
  onChange,
  placeholder,
  ...props
}: InputProps<T, K>) {
  const selfRef = useRef<HTMLInputElement>(null);
  debugRender(ref ?? selfRef);
 
  const inheritedPlaceholder: string | undefined = useMemo(() => {
    if (!Array.isArray(inherits) || !inherits.length) return undefined;
 
    for (const ref of inherits) {
      const refValue = ref?.[name as never];
      if (refValue !== undefined) return refValue as string;
    }
  }, [bind, name, value]);
  const current = (useValue(bind, name) ?? value ?? '') as string;
 
  return (
    <input
      ref={ref ?? selfRef}
      name={name as string}
      value={current}
      placeholder={inheritedPlaceholder ?? placeholder}
      onChange={(e) => {
        if (bind) {
          let value: string | number | undefined = e.target.value;
 
          if (props.type === 'number') {
            value = parseFloat(value);
            if (isNaN(value)) value = undefined;
          }
 
          if (typeof value === 'undefined') {
            delete bind[name];
          } else {
            bind[name] = value as T[K];
          }
 
          if (pipe) {
            pipe[name] = bind[name];
          }
        }
 
        onChange?.(e);
      }}
      {...props}
    />
  );
}