Files
NODEDC_DESIGN_GUIDELINE/docs/WINDOWS_AND_LAYERS.md

8.6 KiB
Raw Permalink Blame History

Окна, 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. trigger, полностью ушедший за viewport, закрывает surface;
  8. outside pointer и Escape закрывают surface;
  9. после Escape фокус возвращается на trigger;
  10. открытие другого 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.

ApplicationSidePanel: отдельная push-колонка

Когда settings/detail принадлежат всему Application и должны физически уменьшать рабочую область, используется ApplicationSidePanel внутри ApplicationShell.endPanel. На desktop панель имеет ту же ширину, surface, радиус и тень, что AdminNavigationPanel, входит справа налево и сдвигает content/stage на panel width + page gap. Она не является Window, не получает backdrop и не входит в stack bounded-окон сцены.

Открытие панели контролирует action в header владельца, закрытие — тот же action или обязательный close action самой панели. Клик по рабочей области не закрывает её неявно. На mobile отдельная колонка становится полноширинным верхним panel-layer, потому что сохранять две узкие колонки там невозможно.

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.

Если Inspector принадлежит конкретной bounded-сцене и должен конкурировать по z-order с её карточками и инструментами, он является содержимым WorkspaceWindow, а не application-level side panel. Текущий Map Page разделяет уровни явно: активный сектор, окна bindings и карточка объекта входят в один bounded stack; настройки карты живут в ApplicationSidePanel; короткие настройки слоёв открываются из нижнего toolbar через Dropdown в том же map-glass дизайне, что Objects.

Управление состоянием

Библиотека не создаёт глобальный store окон. Приложение владеет тем, какое окно открыто и какие данные в нём загружены. Библиотека владеет одинаковым поведением самого слоя.

Stack workspace-окон остаётся контролируемым приложением: оно передаёт active-state и zIndex, а компонент отвечает только за одинаковую геометрию и взаимодействие. Глобальный stack viewport-level modeless-окон остаётся отдельным будущим контрактом.