All files / packages/ui/src/components/Form FormSwitch.tsx

100% Statements 11/11
100% Branches 4/4
100% Functions 4/4
100% Lines 11/11

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                                                              2x           9x 9x   2x 2x         9x                   2x       2x             6x           9x                   2x  
import { memo, ReactElement, useCallback } from "react";
import {
  Control,
  Controller,
  ControllerFieldState,
  ControllerRenderProps,
  FieldValues,
  Path,
} from "react-hook-form";
 
import { CustomSwitchProps, Switch } from "../Switch";
 
interface FormSwitchProps<T extends FieldValues> extends Omit<
  CustomSwitchProps,
  "value" | "onValueChange" | "errorMessage"
> {
  control: Control<T>;
  name: Path<T>;
  rules?: object;
  errorMessage?: string; // Add this back if needed, but it's in rest anyway.
  onValueChange?: (value: boolean) => void;
}
 
interface SwitchControllerProps<T extends FieldValues> {
  field: ControllerRenderProps<T, Path<T>>;
  fieldState: ControllerFieldState;
  props: Omit<CustomSwitchProps, "value" | "onValueChange">;
  errorMessage?: string;
  onPropsValueChange?: (value: boolean) => void;
}
 
const SwitchControllerInstance = <T extends FieldValues>({
  field: { onChange, value },
  fieldState: { error },
  props,
  onPropsValueChange,
}: SwitchControllerProps<T>) => {
  const { errorMessage, ...rest } = props;
  const handleChange = useCallback(
    (val: boolean) => {
      onChange(val);
      onPropsValueChange?.(val);
    },
    [onChange, onPropsValueChange],
  );
 
  return (
    <Switch
      {...rest}
      value={(value as boolean) ?? false}
      onValueChange={handleChange}
      errorMessage={error?.message || errorMessage}
    />
  );
};
 
const SwitchController = memo(
  SwitchControllerInstance,
) as typeof SwitchControllerInstance;
 
export const FormSwitch = <T extends FieldValues>({
  control,
  name,
  rules,
  onValueChange: propsOnValueChange,
  ...props
}: FormSwitchProps<T>): ReactElement => {
  return (
    <Controller
      control={control}
      name={name}
      rules={rules}
      render={(renderProps) => (
        <SwitchController
          {...renderProps}
          props={props}
          onPropsValueChange={propsOnValueChange}
        />
      )}
    />
  );
};
 
FormSwitch.displayName = "FormSwitch";