Skip to content

Формы

@virentia/forms - модельный слой для форм. Это не библиотека компонентов и не набор интерфейсных хелперов. Форма описывается как поля, валидаторы, ошибки, динамические секции и правила навигации; интерфейс, тесты, SSR и фоновые сценарии используют одну и ту же модель через скоуп Virentia.

Используйте пакет, когда поведение формы является частью продуктовой логики: серверные ошибки не должны затираться локальной валидацией, шаг должен валидироваться перед переходом, строка списка имеет собственные поля или доменное поле ввода должно быть переиспользуемым.

Установка

sh
pnpm add @virentia/forms @virentia/core

Дополнительные пакеты:

sh
pnpm add @virentia/forms-react @virentia/react react
pnpm add @virentia/forms-zod zod

Как устроен раздел

Документация форм разложена по ментальным паттернам. Каждая страница объясняет, зачем существует паттерн, когда его брать, как выглядит API и какие кейсы обычно встречаются первыми.

ПаттернКогда нужен
Модель поляОдному значению нужен жизненный цикл: заполнение, сброс, валидация, фокус, метаданные.
Модель формыНесколько полей должны стать одним объектом значений и ошибок.
Жизненный цикл валидацииПравила запускаются как функции, эффекты, схемы или валидаторы с зависимостями от сторов.
Каналы ошибокСерверные ошибки и локальная валидация должны сосуществовать.
Кастомные поляНесколько внутренних полей должны дать одно доменное значение.
Типы полейФабрика поля должна нести переиспользуемое доменное поведение.
Shape-поляУ объекта появляются динамические ключи.
Array-поляВ форме есть упорядоченные повторяемые элементы.
Визард-формыНавигация зависит от валидации форм шагов.
React-интеграцияКомпоненты читают модели и вызывают обработчики в нужном скоупе.
Адаптеры схемZod нужны как валидаторы, а не как рантайм формы.

Первая модель

Начните с полей и формы. Поля владеют значениями; форма читает их в общий объект значений и запускает правила между полями.

ts
import { scope, scoped } from "@virentia/core";
import { createField, createForm } from "@virentia/forms";

const signup = createForm({
  schema: {
    email: createField(""),
    password: createField(""),
    confirmPassword: createField(""),
  },
  validation(values) {
    return values.password === values.confirmPassword
      ? null
      : { confirmPassword: "Пароли не совпадают" };
  },
});

const appScope = scope();

await scoped(appScope, async () => {
  await signup.fill({
    values: {
      email: "ada@example.com",
      password: "supersecret",
      confirmPassword: "supersecret",
    },
  });

  await signup.submit();
});

Что это дает:

  • signup.values собирается из полей;
  • signup.errors повторяет форму схемы;
  • submit() валидирует и обновляет снимок (snapshot) только после успеха;
  • та же модель работает в React, тестах или другом скоупе.

Карта пакетов

ts
@virentia/forms        // основные модели и контракты
@virentia/forms-react  // хуки React
@virentia/forms-zod    // Zod-валидаторы

Полные сигнатуры находятся в API-справке.