NODEDC_DESIGN_GUIDELINE/docs/WINDOWS_AND_LAYERS.md

95 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Окна, dropdown и слои
## Зачем отдельный контракт
В NODE.DC повторяется одна механика: пользователь нажимает trigger, открывается окно или floating surface, взаимодействует и закрывает его. Если каждое приложение реализует outside click, Escape, portal и z-index отдельно, одинаковые окна начинают вести себя по-разному.
## Layer scale
- base: `0`;
- panel: `100`;
- header: `400`;
- overlay/window: `800`;
- dropdown/popover: `900`;
- toast: `950`.
Произвольные значения вроде `30030` допускаются только во временном legacy adapter. Новый код использует scale.
## Dropdown/popover
Обязательное поведение:
1. trigger сообщает `aria-expanded`;
2. surface переносится в body;
3. координаты рассчитываются как fixed;
4. горизонтальная позиция ограничивается viewport;
5. при недостатке места surface меняет bottom/top placement;
6. scroll/resize пересчитывают позицию;
7. outside pointer и Escape закрывают surface;
8. после Escape фокус возвращается на trigger;
9. открытие другого dropdown закрывает предыдущий.
Inline absolute dropdown внутри card/sidebar/sticky container является дефектом.
## Modal window
Обязательное поведение:
1. window рендерится в body;
2. при открытии запоминается текущий focus;
3. focus переносится на первый интерактивный элемент или dialog;
4. Tab не выходит за пределы dialog;
5. Escape закрывает окно, если операция не блокирует закрытие;
6. backdrop закрывает окно только при клике именно на backdrop;
7. body scroll блокируется;
8. после закрытия focus возвращается на предыдущий trigger.
## Карта modal-паттернов
| Тип | Источник | Каноническая реализация |
| --- | --- | --- |
| Form/create/save | Launcher, CMS, BIM | `Window` + Field/Select + footer actions |
| Destructive confirmation | Launcher, Engine, BIM | `ConfirmationModal` |
| Workflow access sharing | новый Engine | `ShareAccessModal` |
| Resource link sharing | BIM Viewer | `ShareLinkModal` / `createShareLinkController` |
| Context actions | BIM measurement/object | `Window size="sm"` + application-owned actions |
| Expandable detail | BIM comment workspace | `Window` или `ApplicationPanel`, domain content остаётся в BIM |
| Large data/history | BIM version history | `Window size="lg"`, data table остаётся domain composition |
Новый тип появляется только если отличается поведением слоя или имеет устойчивую независимую anatomy. Разная таблица, форма или текст внутри Window не создают новую modal-систему.
## Side window / inspector
Side window использует ту же механику, но placement `end` и ограниченную ширину. Это канон для:
- настроек окружения;
- инспектора агентной ноды;
- будущих detail/settings panels;
- CMS/SEO side editors, если они не требуют отдельного полноэкранного workflow.
По умолчанию это modeless-слой: он не затемняет страницу, не перехватывает клики по основной области, не закрывается по backdrop, не блокирует body scroll и не удерживает Tab внутри панели. Escape и кнопка закрытия остаются доступны. Если конкретный workflow должен быть modal, это задаётся явно, а не получается случайно из placement.
## Workspace window
`WorkspaceWindow` отличается от modal и side inspector границей слоя: это inline modeless-окно, ограниченное конкретной рабочей сценой приложения.
Обязательное поведение:
1. окно рендерится внутри bounds-контейнера без portal;
2. приложение контролирует rectangle, maximized-state, visibility, active-state и z-order;
3. drag доступен за header мышью, touch/pen pointer и стрелками клавиатуры;
4. resize выполняется нижней правой ручкой pointer-ом или стрелками клавиатуры;
5. move и resize всегда ограничены текущими размерами workspace;
6. `ResizeObserver` повторно ограничивает rectangle после изменения layout;
7. maximize заполняет только workspace, а restore возвращает сохранённый приложением rectangle;
8. close сообщает intent приложению и не создаёт внутренний store;
9. родительский bounds-контейнер использует `position: relative` и `overflow: hidden`.
Workspace window используется для вспомогательных камер, инструментов и сопоставляемых представлений внутри stage. Оно не заменяет modal `Window`, viewport-level Inspector или `ApplicationPanel`.
## Управление состоянием
Библиотека не создаёт глобальный store окон. Приложение владеет тем, какое окно открыто и какие данные в нём загружены. Библиотека владеет одинаковым поведением самого слоя.
Stack workspace-окон остаётся контролируемым приложением: оно передаёт active-state и `zIndex`, а компонент отвечает только за одинаковую геометрию и взаимодействие. Глобальный stack viewport-level modeless-окон остаётся отдельным будущим контрактом.