@reformer/renderer-json
Форма целиком как JSON: операторы $model/$component/$dataSource + реестр компонентов.
@reformer/renderer-json описывает всю форму декларативной JSON-схемой (JsonFormSchema, M1). Привязки к модели, компонентам и источникам данных кодируются строками-операторами ($model(...), $component(...), $dataSource(...)), поэтому схема — чистый JSON: её можно положить в .json, принять строкой с сервера/CMS и отрисовать в разных UI-китах через реестр — без per-field React-кода.
Пакет строится поверх @reformer/renderer-react: JSON-схема конвертируется в RenderNode-дерево и рендерится тем же движком. Ключевая идея M1: модель (FormModel) — источник данных, JSON-схема — layout. Модель передаётся через провайдер, листья схемы (value: '$model(path)') биндятся к её сигналам.
Установка
npm install @reformer/renderer-json @reformer/core @reformer/renderer-react
@reformer/ui-kit — опциональный peer: используйте его (или свои компоненты) для наполнения реестра.
Быстрый пример
Схема — чистые данные, операторы-строки, никаких React-импортов:
{
"version": "1.0",
"root": {
"component": "$component(Box)",
"children": [
{
"value": "$model(email)",
"component": "$component(Input)",
"componentProps": { "label": "Email" }
}
]
}
}
Рендеринг: реестр (defineRegistry) сопоставляет имена из схемы React-компонентам, модель отдаётся через JsonRendererProvider:
import { useMemo } from 'react';
import { createModel } from '@reformer/core';
import { Input, Box, FormField } from '@reformer/ui-kit';
import {
JsonFormRenderer,
JsonRendererProvider,
defineRegistry,
FIELD_WRAPPER,
type JsonFormSchema,
} from '@reformer/renderer-json';
type MyForm = { email: string };
export function MyFormPage() {
// M1: модель — источник данных; листья схемы биндятся к её сигналам.
const model = useMemo(() => createModel<MyForm>({ email: '' }), []);
const registry = useMemo(
() =>
defineRegistry((reg) => {
reg.component('Input', Input);
reg.component('Box', Box);
reg.component(FIELD_WRAPPER, FormField); // системная обёртка полей
}),
[]
);
// Модель передаётся через провайдер (settings.model), не как проп рендерера.
return (
<JsonRendererProvider settings={{ registry, model }}>
<JsonFormRenderer<MyForm> schema={schema} validate={import.meta.env.DEV} />
</JsonRendererProvider>
);
}
JsonFormRenderer принимает только { schema, renderBehavior?, onSchemaReady?, validate? }. FormModel обязательна и подаётся через JsonRendererProvider settings (model) — без неё рендерер бросит settings.model is required (M1).
Что внутри
- JsonFormRenderer — главный компонент-рендерер; получает JSON-схему пропом, модель и реестр — из контекста провайдера.
JsonRendererProviderзадаёт{ registry, model }, аuseJsonRendererSettingsчитает текущие настройки. - Операторы — строки
$model(path)(привязка листа к сигналу модели),$component(Name)(компонент из реестра),$dataSource(Name)(значение-источник). Разбираются черезparseOperator/isModelOp/isComponentOp/isDataSourceOp; голые строки идут как есть. - Реестр —
defineRegistryстроит карту имён на компоненты и dataSource-значения.FIELD_WRAPPER('$fieldWrapper') — зарезервированный ключ для компонента-обёртки полей (label, error, hint), обычноFormFieldиз@reformer/ui-kit. - Валидация схемы — мета-схема form-DSL (
formSchemaMetaSchema,buildFormSchemaMetaSchema,getComponentNames,getDataSourceNames, ajv-free). ПолныйvalidateFormSchemaживёт в отдельной точке входа@reformer/renderer-json/validate(тянет ajv, не попадает в render-бандл);JsonFormRendererгрузит её динамически приvalidate={true}, ошибки рисуетSchemaErrorPanel.
Для низкоуровневого доступа доступны convertJsonToM1Tree (JSON → RenderNode-дерево для createForm({ model, schema })) и createRenderSchemaFromJsonM1 (JSON → RenderSchemaFn), а также type guards isFieldNode / isArrayNode / isContainerNode.