Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
dae4b28
feat: add @kaspersky/ui-normalization tooling
vostrik Mar 24, 2026
a1b462f
feat: add init norma spec
vostrik Mar 24, 2026
84eb090
fet: store selected dirs
vostrik Mar 24, 2026
4fa8219
feat: store opend form in url
vostrik Mar 24, 2026
a3a5117
feat: add norma roadmap
vostrik Mar 24, 2026
00e01c6
feat: add final target for plan
vostrik Mar 24, 2026
c245f76
feat: add plan for button
vostrik Mar 24, 2026
a9b23fa
feat: add configHook in js
vostrik Mar 24, 2026
294859d
chore: remove ControlType from configHook arguments
vostrik Mar 24, 2026
690136f
feat: add fully TypeScript support to configHook
vostrik Mar 24, 2026
14968e9
feat: actualize plan about config handlers and ts
vostrik Mar 24, 2026
d2cb115
feat: plan dynamic imports for configs
vostrik Mar 24, 2026
3790007
docs: move HLE to tooling.md and strip roadmap
vostrik Mar 24, 2026
b3578b0
feat: add text implementation
vostrik Mar 24, 2026
9d4ff45
chore: add 6 point to roadmap
vostrik Mar 24, 2026
939b7e5
feat: add grid implementation
vostrik Mar 24, 2026
3432d06
feat: add table implementation
vostrik Mar 24, 2026
b2ad7d4
docs: add more table configuration examples
vostrik Mar 24, 2026
de18de2
docs: mark roadmap p1 as done
vostrik Mar 24, 2026
1105582
feat: change tools layout to increase content vh
vostrik Mar 24, 2026
a22f798
docs: add p8 roadmap
vostrik Mar 24, 2026
5c35627
docs: update p3 roadmap — formRenderer dod
vostrik Mar 24, 2026
b0ef0f3
feat: use ts for form dsl
vostrik Mar 25, 2026
172ffb2
docs: split p2 roadmap into 2 points and make the first as done
vostrik Mar 25, 2026
64e6b08
docs: move hle from roadmap to tooling doc
vostrik Mar 25, 2026
f19cc62
feat: support dynamic imports
vostrik Mar 25, 2026
6c605d4
docs: add features layer
vostrik Mar 25, 2026
ffe0286
feat: 3.1 one render tool
vostrik Mar 25, 2026
4bcc884
feat: 3.2 manage cols from hook
vostrik Mar 25, 2026
86b1820
feat: 3.3.1 wysiwyg settings
vostrik Mar 25, 2026
b15dffc
feat: 3.3.3 add DnD
vostrik Mar 25, 2026
318d32d
feat: add 3.4 split-screen feature
vostrik Mar 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions docs/normalization/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Документация: UI Normalization

Spec-driven описание **config-driven** форм (редактор **normalization-tool**, просмотр **transpile-viewer**, общий DSL).

---

## Итоговый вид документации (три слоя)

```mermaid
flowchart TB
subgraph layer1 [1. Обзор решения]
T[tooling.md]
end
subgraph layer2 [2. Фичи]
F[features/README.md]
F1[feat-*.md]
end
subgraph layer3 [3. Требования по эпикам]
P[plans/plan-*.md]
end
subgraph meta [Мета]
R[roadmap.md]
end
R --> T
R --> F
R --> P
T --> F
F --> F1
P --> F1
```

| Слой | Документ | Назначение |
|------|----------|------------|
| **1** | **[tooling.md](./tooling.md)** | Краткое **описание решения** (что строим, зачем, как устроено в целом) и **таблица ссылок** на фичи. В конце файла — **прежние ссылки на разделы** (`#…`) для совместимости. |
| **2** | **[features/README.md](./features/README.md)** | **Дерево вложенных фич** и ссылки на файлы **`feat-*.md`**: контракты, ограничения, связь с кодом. |
| **3** | **[plans/](./plans/)** | **Требования** закрытых и текущих эпиков: таблица *`id` · фича · описание*; трассировка к роадмапу и к файлам из **`features/`**. |
| **Мета** | **[roadmap.md](./roadmap.md)** | Этапы **п.1–9**, статусы, указатели на слои 1–3. |

**Точка входа для чтения:** [tooling.md](./tooling.md) → при необходимости углубления — конкретный **`features/feat-…`** → для приёмки эпика — **`plans/plan-…`**.

**П.9 роадмапа** закрепляет поддержание этой структуры при эволюции кода.

---

## Быстрый указатель

| Тема | Куда |
|------|------|
| Два приложения, паритет, границы продукта | [feat-product-and-parity.md](./features/feat-product-and-parity.md) |
| `FormData`, дерево контролов | [feat-dsl-root-model.md](./features/feat-dsl-root-model.md) |
| `configHook` | [feat-config-hook.md](./features/feat-config-hook.md) |
| Sucrase, чанки, `loadFormDslBrowserRuntime` | [feat-lazy-dsl-runtime.md](./features/feat-lazy-dsl-runtime.md) |
| FSA, IndexedDB, `?form=` | [feat-workspace-browser.md](./features/feat-workspace-browser.md) |
| Button / Text / Grid / Table / DSL п.2 | [plans/](./plans/) |
47 changes: 47 additions & 0 deletions docs/normalization/features/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Каталог фич: UI Normalization

Иерархия **возможностей** (feature tree) туллинга. Каждая фича — отдельный файл: контракт, ограничения, связь с кодом. Сводный обзор решения и навигация — **[tooling.md](../tooling.md)**.

---

## Дерево (вложенность)

```
Решение: config-driven формы + Hexa UI
├── Продукт и поставка
│ └── [Продукт, паритет, два приложения](./feat-product-and-parity.md)
├── DSL и исполнение
│ ├── [Корневая модель FormData](./feat-dsl-root-model.md)
│ ├── [Принцип «одна настройка — один способ»](./feat-dsl-one-setting.md)
│ ├── [Контракт configHook](./feat-config-hook.md)
│ ├── [Ленивый рантайм: parseFormTs, Sucrase, чанки](./feat-lazy-dsl-runtime.md)
│ └── [Типизация автором и импорты потребителя](./feat-typing-and-imports.md)
├── Рабочее пространство (браузер)
│ └── [FSA, IndexedDB, URL form, сценарии, среда](./feat-workspace-browser.md)
├── Целевое состояние (роадмап)
│ ├── [Архитектурные решения и направления](./feat-architecture-directions.md)
│ └── [Превью в редакторе — единый рендер-движок](./feat-editor-preview-target.md)
└── Репозиторий
└── [Пакеты и shared-модули](./feat-repo-layout.md)
```

---

## Связь с другими документами

| Документ | Роль |
|----------|------|
| [tooling.md](../tooling.md) | Краткое **описание решения** + таблица ссылок на фичи |
| [roadmap.md](../roadmap.md) | Этапы п.1–9, статусы |
| [plans/](../plans/) | **Требования** по эпикам (фича → описание), трассировка к роадмапу |

---

## Именование фич в требованиях (plans)

В планах используются стабильные идентификаторы вида **`domain.short-name`** (например **`config-hook.button`**) для ссылок из обсуждений и PR.
29 changes: 29 additions & 0 deletions docs/normalization/features/feat-architecture-directions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Фича: архитектурные решения и долгосрочные направления

**Родитель:** целевое состояние (роадмап п.5–8 и часть п.7).

---

## Описание

Зафиксированные и целевые решения, которые задают рамку эволюции кода и продуктов, без пошаговой инструкции внедрения.

---

## Требования / направления

- **`arch.dsl.shared-module`:** один общий модуль DSL в дереве репозитория; **отдельный publishable npm-пакет** под DSL **не вводится**; **двух расходящихся копий** полного DSL **нет**.
- **`arch.forms.ts-only`:** артефакты форм в каталоге — **только `.ts`**.
- **`arch.code.genericity`:** контролы обрабатываются общими механизмами; частное — в дескрипторах и типах, не копипаста веток в рендерерах.
- **`arch.products.storybook`:** tool — целевой сценарий аддона **Storybook**; viewer — общий движок рендера для Storybook и прод.
- **`arch.shell.hexa`:** оболочки инструментов на **Hexa UI**; целевое **dogfooding** — UI инструментов из DSL + общего рендерера (оговорки для холста/DnD — при проектировании).
- **`arch.rename`:** целевые имена пакетов **`kant-editor`** / **`kant-renderer`**.
- **`arch.compat.json-ui-builder`:** обратная совместимость **`form-dsl`** и артефактов с **JSON UI Builder** (или явный мост версий).
- **`arch.viewer.adapters`:** viewer на адаптерах и **Auto UI** без монолитного маппинга всех типов; **Auto UI** — миграция на **React** end-to-end.

---

## Ссылки

- [roadmap.md](../roadmap.md) п.5–8, п.7
- Детализация превью в редакторе: [feat-editor-preview-target.md](./feat-editor-preview-target.md)
41 changes: 41 additions & 0 deletions docs/normalization/features/feat-config-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Фича: контракт configHook

**Родитель:** DSL и исполнение. Зависит от [feat-dsl-one-setting](./feat-dsl-one-setting.md). Загрузка модулей — [feat-lazy-dsl-runtime](./feat-lazy-dsl-runtime.md).

---

## Описание

В динамическом режиме пропсы экземпляра компонента ДС задаёт **один** TS-модуль (**`configHook`**). Колбэки (`onClick`, `onChange`, …) объявляются **внутри** возвращаемого объекта пропсов.

---

## Требования

- **`config-hook.api.input`:** единственный аргумент — **`FormSlice`** (`state` + `config.elements`); тип контрола задаётся самим модулем (один файл — один вид).
- **`config-hook.api.output`:** полный объект пропсов экземпляра компонента ДС **или `null`**; **`null`** — не монтировать компонент; отдельных полей `visible` в DSL для этого нет.
- **`config-hook.react`:** модуль исполняется как React-хук; пересчёт через React и стейт, без декларативного списка зависимостей в DSL.
- **`config-hook.context.layers`:** в колбэках автор разводит контекст **формы/инструмента** и контекст **Hexa** (события, пропсы экземпляра).
- **`config-hook.file.ts-only`:** путь в DSL и в пикере — только **`.ts`**; перед исполнением в браузере — транспиляция (см. ленивый рантайм).

### Примеры возврата (Hexa UI)

- Кнопка: **`ButtonProps | null`**
- Текст: **`TextProps | null`**
- Сетка / таблица: см. планы [plan-grid](../plans/plan-grid.md), [plan-table](../plans/plan-table.md)

### Артефакты формы

| Артефакт | Расширение | Загрузка |
|----------|------------|----------|
| **`configHook`** | **`.ts`** | [feat-lazy-dsl-runtime](./feat-lazy-dsl-runtime.md) → транспиляция → blob → `import()` |
| В **`.ts`** формы | — | путь к хуку сериализуется как **`() => import('./…')`** |

Пути **`handlers`** на форме/контроле в UI могут указывать **`.js`** или **`.ts`**; для новых артефактов приоритет **TS** ([tooling — обзор](../tooling.md)).

---

## Ссылки

- Пример стиля: `packages/kaspersky-ui-normalization-tool/jsons/handlers/*.config-hook.ts`
- Код: `loadConfigHookDefaultExport` в tool и viewer
22 changes: 22 additions & 0 deletions docs/normalization/features/feat-dsl-one-setting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Фича: одна настройка — один способ

**Родитель:** DSL и исполнение.

---

## Описание

У каждого **пропа** экземпляра компонента ДС в форме ровно **один** источник значения: либо статическое поле в DSL (инспектор), либо динамика целиком через **`configHook`**. Смешивание для одного пропа запрещено.

---

## Требования

- **`dsl.setting.single-source`:** параметр либо **статический** (хранится в DSL и задаётся в панели свойств), либо **динамический** (только из модуля **`configHook`**; отдельного поля DSL для этого пропа нет).
- **`dsl.setting.no-merge`:** нет объединения статики и динамики и нет «динамика перекрывает статику» для одного и того же пропа.

---

## Ссылки

- Контракт динамики: [feat-config-hook.md](./feat-config-hook.md)
26 changes: 26 additions & 0 deletions docs/normalization/features/feat-dsl-root-model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Фича: корневая модель DSL (FormData)

**Родитель:** DSL и исполнение.

---

## Описание

Форма в рантайме — объект **`FormData`**: идентификаторы, опционально схема полей и обработчики уровня формы, дерево контролов. Источник в репозитории — **`shared/types/form.ts`** и нормализация в **`shared/normalization-form-dsl/form-dsl-core.ts`**.

---

## Требования

- **`dsl.root.fields`:** корень содержит **`name`**, **`id`**.
- **`dsl.root.schema`:** опционально — описание полей данных формы.
- **`dsl.root.handlers`:** опционально — события уровня формы → пути к файлам-скриптам.
- **`dsl.root.elements`:** дерево контролов: семантический **`type`**, **`id`**, привязки к данным, валидация, условия видимости/доступности, обработчики на контроле.
- **`dsl.mapping.semantics-to-hexa`:** маппинг «семантика контрола → компонент ДС» живёт в **реестрах / рендерерах** приложений, не как отдельный дублирующий метатип в DSL.

---

## Ссылки

- Типы: `shared/types/form.ts`
- Логика контролов: `shared/normalization-form-dsl/form-dsl-core.ts`, entry `form-dsl.ts`
59 changes: 59 additions & 0 deletions docs/normalization/features/feat-editor-preview-target.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Фича: превью в редакторе — единый рендер-движок

**Родитель:** решение config-driven. Роадмап **п.3.1** ✅ ([якорь](../roadmap.md#normalization-roadmap-p31)); структура Grid/Table — **п.3.2** ✅ ([якорь](../roadmap.md#normalization-roadmap-p32)); WYSIWYG-canvas — **п.3.3** ✅ ([якорь](../roadmap.md#normalization-roadmap-p33)).

---

## Описание

Режим визуализации в **normalization-tool** использует **тот же** `FormRenderer`, что и **transpile-viewer**. Два режима tool: **editor** (холст, DnD, свойства) и **viewer** (превью через `FormRenderer`). Визуализация в превью идентична внешнему потребителю — один рендер-движок, один контур модулей.

---

## Реализация

| Артефакт | Назначение |
|----------|-----------|
| `vite.config.ts` → `@viewer` | Алиас на `transpile-viewer/src`; `resolve.dedupe` для react/hexa — один экземпляр зависимостей |
| `src/viewer-form-renderer.d.ts` | Ambient-модуль `@viewer/components/FormRenderer` — типы для `tsc` без компиляции исходника viewer |
| `src/components/ToolbarStaticPreview.tsx` | Шим: реэкспорт `ToolbarStaticPreview` из дескриптора тулбара для импорта `@/components/ToolbarStaticPreview` из `FormRenderer` |
| `App.tsx` → `<FormRenderer>` | В `previewMode` — `FormRenderer` с `elements`, `formDirectoryHandle`, `formKey` |

Все `@/` внутри `FormRenderer` при сборке tool резолвятся в `tool/src/` — утилиты (`loadConfigHookModule`, `tableControlHexa`, `defaultGridHexaProps`), типы (`form-dsl`), компоненты. Viewer-исходник **не** входит в `tsconfig` tool (нет дублирования типов React/Hexa).

---

## Требования

| ID | Описание | Статус |
|----|----------|--------|
| `editor.preview.embed-viewer` | В превью — `FormRenderer` из viewer, без дублирования кода | ✅ |
| `editor.preview.same-import-graph` | Один контур `@/`-импортов, те же `configHook` и утилиты | ✅ |
| `editor.preview.ts-isolation` | Ambient `.d.ts` вместо `tsconfig`-включения viewer | ✅ |
| `editor.preview.toolbar-shim` | Шим `ToolbarStaticPreview` для `FormRenderer` | ✅ |
| `editor.preview.vite-dedupe` | `resolve.dedupe` react/hexa — единый экземпляр | ✅ |
| `editor.preview.scenario-hook` | Опциональный модуль моков/патча `state` для превью (черновик) | ⏳ |
| `editor.preview.grid-hook-cols` | `configHook` может вернуть `cols` для Grid; renderer — pad/truncate children | ✅ (п.3.2) |
| `editor.preview.table-hook-dims` | `configHook` может вернуть `dslCols`/`dslRows` для Table; rebuild matrix | ✅ (п.3.2) |
| `editor.preview.table-toolbar` | `toolbar` из хука — нативный Hexa; при отсутствии — статический превью DSL | ✅ (п.3.2) |
| `editor.wysiwyg.data-control-id` | Каждый контрол в `FormRenderer` обёрнут в `div[data-control-id]` — DOM-якорь для overlay | ✅ (п.3.3) |
| `editor.wysiwyg.overlay-selection` | `WysiwygCanvas`: transparent overlay, `elementFromPoint` → click-to-select, highlight с `ResizeObserver` | ✅ (п.3.3) |
| `editor.wysiwyg.props-panel` | Панель свойств видна в WYSIWYG-режиме; редактирование свойств через панель, undo/redo | ✅ (п.3.3) |
| `editor.wysiwyg.dnd` | DnD в WYSIWYG-режиме: шестерёнка = drag source, drop zones overlay, root reorder/insert, palette drop, grid/table cell move/insert | ✅ (п.3.3 it.2) |
| `editor.wysiwyg.dnd-utils` | `src/utils/dnd.ts`: shared DATA_ID_KEY/DATA_TYPE_KEY, getDropTypeAndOptions, tree mutation helpers; FormCanvas переходит на импорты из utils | ✅ (п.3.3 it.2) |
| `editor.wysiwyg.palette-both-modes` | Палитра компонентов видна в обоих режимах (Editor и WYSIWYG) | ✅ (п.3.3 it.2) |

---

## Решённые вопросы (п.3.2 ✅)

- ~~Синхронизация **`rows`/`cols`** у Grid/Table~~ → хук возвращает нужные размерности, renderer делает pad/truncate.
- ~~Единый контракт **тулбара**~~ → `toolbar` из хука заменяет DSL-превью; `rowSelection` — пропс Hexa Table, проходит через хук.
- **`editor.preview.scenario-hook`** — остаётся открытым, не привязан к п.3.2.

---

## Ссылки

- [plan-editor-preview.md](../plans/plan-editor-preview.md)
- [roadmap §3.1](../roadmap.md#normalization-roadmap-p31), [§3.2](../roadmap.md#normalization-roadmap-p32), [§3.3](../roadmap.md#normalization-roadmap-p33)
Loading