@danchin/direct-component
v0.1.0
Published
JSON-driven React UI compiler
Maintainers
Readme
direct-component
direct-component — экспериментальный JSON-driven React-компилятор UI. Он принимает декларативное описание дерева компонентов, подставляет параметры и состояние через шаблоны, валидирует структуру и рендерит готовый React-интерфейс.
Проект содержит библиотечный код в src/direct-component/ и showcase-приложение на Vite в src/App.tsx с примерами из src/examples/.
Быстрый старт
npm ci
npm run devОсновные команды:
npm run dev— запустить Vite dev server.npm run build— проверить TypeScript и собрать проект.npm run lint— запустить ESLint.npm run preview— открыть собранную версию локально.
Использование Compiler
Базовый сценарий — передать плоский список узлов, связи и внешние параметры:
import { Compiler } from "@danchin/direct-component";
import "@danchin/direct-component/styles.css";
import nodes from "./nodes.json";
import hierarchy from "./hierarchy.json";
import params from "./params.json";
export function Screen() {
return <Compiler nodes={nodes} hierarchy={hierarchy} params={params} />;
}Альтернатива — передать уже собранное дерево через spec:
<Compiler
spec={{
type: "vbox",
children: [{ type: "title", text: "Hello" }],
}}
/>Формат JSON
Для экранов в плоском формате используются три файла:
nodes.json— массив узлов с уникальнымidиtype; остальные поля становятся props компонента.hierarchy.json— массив связей[parentId, childId]; порядок связей задает порядок детей.params.json— внешние данные для шаблонов.
Пример:
[
{ "id": "root", "type": "margin", "top": 16 },
{ "id": "main", "type": "vbox", "gap": 12 },
{ "id": "title", "type": "title", "text": "Профиль {{ userName }}" }
][
["root", "main"],
["main", "title"]
]Компилятор проверяет, что у каждого узла есть уникальный id, все связи указывают на существующие узлы, в дереве есть ровно один корень и нет циклов.
Шаблоны, состояние и handlers
Шаблоны пишутся в строках через {{ ... }}. Значения по умолчанию берутся из params, а внутреннее состояние доступно через var:.
{
"id": "label",
"type": "label",
"text": "Имя: {{ userName | var:name | def:\"Гость\" }}"
}Поддерживаются pipe-фильтры для текста, чисел, дат, массивов, объектов и логики. Свои фильтры можно добавить через registerFilter.
Внешние обработчики передаются через handlers. Внешнее React-состояние можно связать через states, где ключ превращается в параметр и handler-сеттер:
<Compiler
nodes={nodes}
hierarchy={hierarchy}
params={{ title: "Анкета" }}
handlers={{ onReset: () => setName("Гость") }}
states={{ name: [name, setName] }}
/>Внутренние defaults объявляются узлом state, а изменение внутренних vars выполняется через stateBind.
Типы узлов
Доступные группы узлов:
- layout:
margin,panel,card,hbox,vbox,grid,scroll,tabs,group,fieldset,formRow. - display:
label,text,title,hint,badge,status,iconText,progress,image. - input/action:
button,input,textarea,select,checkbox,radioGroup,switch,slider,dateInput,numberInput,stateBind. - flow/data:
branch,repeat,switchCase,case,fallback,state,computed,debugVars,debugParams.
Общие поля: class, style, visible, disabled, expandH, expandV, expandHWeight, expandVWeight.
Темы
Compiler принимает theme как имя пресета (default, compact, soft) или объект overrides:
<Compiler
nodes={nodes}
hierarchy={hierarchy}
theme={{
button: { className: "primary-button" },
"button:hover": { className: "primary-button-hover" },
}}
/>Базовые стили находятся в src/direct-component/styles/direct-component.css.
Структура проекта
src/direct-component/— библиотека: компилятор, registry, компоненты, шаблоны, фильтры, тема и валидация.src/examples/— JSON-примеры для showcase.src/App.tsx— демо-приложение с переключением примеров и тем.src/controls/иsrc/template/— ранняя/параллельная реализация, не основная публичная точка входа..cursor/rules/— контекст и правила для Cursor Agent.
Публичный API экспортируется из src/direct-component/index.ts.
