0.0.22-beta • Published 9 months ago

recalculate-form v0.0.22-beta

Weekly downloads
-
License
ISC
Repository
github
Last release
9 months ago

recalculate-form

 Версия npm

Установка

npm i recalculate-form

Or

yarn add recalculate-form

API

Form<T, M> - основной класс для создания экземпляра формы

Типизация:

  • T - значения формы;
  • M - типы мутаций (расширяет базовые: native | change)

Данные:

  • data - объект с реактивными данными формы;

Методы:

  • getValues(): T - метод для получения значений формы;

  • getValues<T>(...paths: string[]): T - метод для получения конкретных значений формы;

  • setErrors(errors: Errors): void - метод для установки ошибок формы;

  • resetError(...paths: string[]): void - метод для сброса ошибок формы(при вызове без параметров сносит все ошибки);

  • reset(): void - метод полной очистки формы;

  • commit(changes: Commit<ChangeMode<M>): boolean[] - метод для внесения изменений в поля формы;

  • handleSubmit(onSubmit: OnSubmit<T>): (event?: FormEvent) => void - метод для подключения html формы;

useForm<T, M>(options: FormConstructorParams<T>) - хук для создания локального экземпляра формы;

Типизация:

  • T - значения формы;
  • M - типы мутаций (расширяет базовые: native | change)

useField<T, V, M>(name: string, form?: FormConstructor<V, M>): UseFieldResult<T> - хук для подключения html полей к форме;

Типизация:

  • T - значение поля;
  • V - значения формы;
  • M - типы мутаций (расширяет базовые: native | change)

Возвращаемое значение:

  • input: object - значения для нативного html инпута (value, onChange с типом мутации native, name);

  • fieldState: object - значение дополнительных состояний формы (isTouched, error);

  • change(value: T) - функция для мутирования значения поля (тип мутации change);

useWatch<R, V, M>(paths?: string[], form?: FormConstructor<V, M>): UseFieldResult<T> - хук подписки на отслеживание изменения полей переданных в параметре paths;

Типизация:

  • V - значения формы;
  • R - возвращаемое значение;
  • M - типы мутаций (расширяет базовые: native | change)

useFormState<T, M>(form?: FormConstructor<V, M>): UseFieldResult<T> - хук подписки на отслеживание изменения состояний формы;

Типизация:

  • T - значения формы;
  • M - типы мутаций (расширяет базовые: native | change);

Возвращаемое значение:

  • touchedFields: Record<string, boolean> - пути к измененным значеним полей ввода;

  • isSubmitted: boolean - указывает на то был ли совершен вызов метода onSubmit;

  • isSubmitting: boolean - состояние выполнения метода onSubmit;

useErrors<T, M>(form?: FormConstructor<V, M>): Errors - хук подписки на отслеживание изменения ошибок формы;

Типизация:

  • T - значения формы;
  • M - типы мутаций (расширяет базовые: native | change);

Возвращаемое значение:

  • errors: Record<string, string | null> - объект с ошибками формы;

useValidate<T, D, M>(validator: ValidateCallback<T, D>, deps?: D, form?: FormConstructor<V, M>): Errors - хук для валидации формы. Вызов метода validator производится в момент изменения значений формы;

Типизация:

  • T - значения формы;
  • D - внешние зависимости для валидации;
  • M - типы мутаций (расширяет базовые: native | change);

  • validator: ValidateCallback<T, D> - метод для валидации. Принимает аргементами значения формы, ошибки и внешние зависимости;

Возвращаемые значени:

  • null - сброс всех значений;
  • {} - нет действий (оставить все ошибки как было до вызова валидатора)
  • { field: null } - сбросить отдельное поле field

useRecalculate<T, E, M>(schema: RecalculateOptions<T, E, M>, form?: FormConstructor<V, M>): JoinRecalculateResult<E> - хук для подключения декораторов перерасчета значений;

Типизация:

  • T - значения формы;
  • E - значения внешних значений влияющих на расчеты;
  • M - типы мутаций (расширяет базовые: native | change);

Возвращаемое значение:

  • callExternal(field: keyof E, value: unknown): void - функция для вызова мутации внешних зависимостей;

  • callRecalculate(field: string, value?: unknown): void - функция для вызова перерасчетов формы (иммитирует изменение значения из поля ввода). Вызывает декораторы с типом мутации указанным для отслеживания;

  • dispose: VoidFunction - метод для очищеня дначений и отключения отслеживания значений;

useCommit<T, M>(form?: FormConstructor<T, M>): CommitFunction - хук для получения функции мутации значений формы.

FormProvider<T, M> - react компонент провайдера формы;

Примеры

Бызовая форма логина

import React, { useState } from "react";
import {
  useForm,
  useField,
  FormProvider,
  useValidate,
  useError,
  useWatch,
} from "recalculate-form";

interface InputProps {
  name: string;
  type: "text" | "password";
  label: string;
}

function Input({ name, type, label }: InputProps) {
  const {
    input,
    fieldState: { error, isTouched },
  } = useField<string>(name);

  return (
    <label>
      <span>{label} </span>
      <input {...input} type={type} />
      {error && isTouched && <div style={{ color: "tomato" }}>{error}</div>}
    </label>
  );
}

function App() {
  const [show, setShow] = useState(false);
  const form = useForm({
    defaultValues: { password: "", username: "" },
  });

  const { errors, resetErrors, setErrors } = useError(form);

  useValidate(
    ({ password, username }, err, showErrors) => {
      if (!showErrors) {
        return null;
      }

      const errors: any = {};

      errors.password = password.length ? null : "Error";
      errors.username = username.length ? null : "Error";

      return errors;
    },
    [show],
    form
  );

  return (
    <FormProvider form={form}>
      <form onSubmit={form.handleSubmit((values) => console.log(values))}>
        <h1>Login</h1>
        <div>
          <Input name="username" type="text" label="Username" />
        </div>
        <div>
          <Input name="password" type="password" label="password" />
        </div>

        <button type="submit">Login</button>
      </form>

      <button onClick={() => setErrors({ loading: "random text" })}>
        set errors
      </button>
      <button onClick={() => setErrors({ loading: null })}>
        reset random errors
      </button>
      <button onClick={() => resetErrors()}>reset errors</button>

      <button onClick={() => set(true)} disabled={c}>
        on
      </button>
      <button onClick={() => set(false)} disabled={!c}>
        off
      </button>
    </FormProvider>
  );
}

Бызовая форма с перерасчетом значений

import { useForm, useField, useRecalculate } from "recalculate-form";

interface InputProps {
  name: string;
  type: "text" | "number";
  label: string;
}

function Input({ name, type, label }: InputProps) {
  const {
    input,
    fieldState: { error },
  } = useField<string>(name);

  return (
    <label>
      <span>{label} </span>
      <input {...input} type={type} />
      {error && <div style={{ color: "tomato" }}>{error}</div>}
    </label>
  );
}

function App() {
  const form = useForm({
    defaultValues: { first: 0, second: 0 },
  });

  useRecalculate(
    {
      fields: [
        {
          path: "first",
          handler(current) {
            return {
              second: Number(current) + 10,
            };
          },
        },
        {
          path: "second",
          handler(current) {
            return {
              first: Number(current) * 10,
            };
          },
        },
      ],
    },
    form
  );

  return (
    <FormProvider form={form}>
      <form onSubmit={form.handleSubmit((values) => console.log(values))}>
        <h1>Recalculate</h1>
        <div>
          <Input name="first" type="number" label="First" />
        </div>
        <div>
          <Input name="second" type="number" label="Second" />
        </div>

        <button type="submit">Submit</button>
      </form>
    </FormProvider>
  );
}

Форма с перерасчетом значений и внешней зависимостью

import { useEffect, useState } from "react";
import {
  useForm,
  useField,
  FormProvider,
  useRecalculate,
} from "recalculate-form";

interface InputProps {
  name: string;
  type: "text" | "number";
  label: string;
}

function Input({ name, type, label }: InputProps) {
  const {
    input,
    fieldState: { error },
  } = useField<string>(name);

  return (
    <label>
      <span>{label} </span>
      <input {...input} type={type} />
      {error && <div style={{ color: "tomato" }}>{error}</div>}
    </label>
  );
}

function App() {
  const [mul, setMul] = useState(10);
  const form = useForm({
    defaultValues: { first: 0, second: 0 },
  });

  const recalculate = useRecalculate(
    {
      defaultExternal: { multiple: mul },
      fields: [
        {
          path: "first",
          handler(current, prev, { external }) {
            return {
              second: Number(current) * external.multiple,
            };
          },
        },
        {
          path: "second",
          handler(current, prev, { external }) {
            return {
              first: Number(current) * external.multiple,
            };
          },
        },
        {
          path: "multiple",
          handler(current, prev, { lastCalledPath, values }) {
            const field = lastCalledPath === "first" ? "second" : "first";

            return {
              [field]:
                values[lastCalledPath as keyof typeof values] * Number(current),
            };
          },
        },
      ],
    },
    form
  );

  useEffect(() => {
    recalculate.callExternal("multiple", mul);
  }, [mul]);

  return (
    <FormProvider form={form}>
      <form onSubmit={form.handleSubmit((values) => console.log(values))}>
        <h1>Recalculate external</h1>
        <div>
          <Input name="first" type="number" label="First" />
        </div>
        <div>
          <Input name="second" type="number" label="Second" />
        </div>

        <button type="submit">Submit</button>
      </form>

      <button onClick={() => setMul((prev) => prev + 1)}>{mul}</button>
    </FormProvider>
  );
}
0.0.18-beta

9 months ago

0.0.21-beta

9 months ago

0.0.22-beta

9 months ago

0.0.17-beta

9 months ago

0.0.19-beta

9 months ago

0.0.20-beta

9 months ago

0.0.16-beta

9 months ago

0.0.15-beta

12 months ago

0.0.14-beta

1 year ago

0.0.13-beta

1 year ago

0.0.12-beta

1 year ago

0.0.11-beta

1 year ago

0.0.10-beta

1 year ago

0.0.9-beta

1 year ago

0.0.8-beta

1 year ago

0.0.7-beta

1 year ago

0.0.6-beta

1 year ago

0.0.5-beta

1 year ago

0.0.4-beta

1 year ago

0.0.3-beta

1 year ago

0.0.2-beta

1 year ago

0.0.1-beta

1 year ago