NODEDC_DESIGN_GUIDELINE/docs/COMPONENTS.md

234 lines
24 KiB
Markdown
Raw Permalink 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.

# Канонические компоненты
Машинный список находится в `registry/components.json`. Ниже зафиксирован смысл компонентов и границы их использования.
## GlassSurface
Базовая непрозрачная поверхность для карточки, панели и большого окна. Варианты меняют плотность нейтральной поверхности, но не создают отдельный дизайн. Реальный glass-материал с blur и rim используется только у floating-слоёв: modal `Window` и portal-dropdown/select.
- `default` — обычная карточка/панель;
- `strong` — dropdown, modal и поверхность над сложным фоном;
- `soft` — вложенная или вторичная область.
Material rim допустим только как часть floating glass. Жёсткая цветная рамка, случайный browser outline или debug border не являются rim.
`GlassMaterialSurface` — отдельный переносимый контракт Engine Glass V4. Он централизует tint/opacity, blur, saturation, brightness, gradient rim и shadow. Его используют только modal `Window` и modeless draggable Inspector; обычные Launcher/SEO панели остаются непрозрачными. Сам `Window` всегда получает класс `nodedc-glass-material` и `data-material="glass-v4"`, поэтому sharing, confirmation и остальные modal-паттерны физически используют тот же surface, что Inspector и лабораторный preview. Настройки применяются через `applyGlassMaterial`, поэтому consumer не пересобирает CSS материала вручную.
## Button и IconButton
Button используется для всех текстовых действий. IconButton — для действия без текста.
- primary/accent — главное действие текущего контекста;
- secondary — обычное действие на glass surface;
- ghost — малозаметное действие без собственной подложки;
- danger — разрушительное действие, обычно в окне подтверждения.
Icon-only action по умолчанию круглый. Квадратная кнопка с маленьким радиусом допустима только как кнопка закрытия окна или плотный инструмент, где это зафиксировано контрактом.
## Field
FieldFrame объединяет label, control, hint и description. TextField/TextAreaField реализуют стандартные текстовые поля.
Приложение не должно вручную собирать label и input, если подходит Field. Ошибка и validation state будут расширением этого контракта, а не локальным классом приложения.
## Checker
Круглый бинарный контрол из нового Engine settings/agent inspector. Он использует checkbox semantics, но не копирует квадратный системный checkbox.
Внутри Checker допускается только короткий однострочный заголовок. Пояснение, hint или описание размещается отдельным текстовым блоком перед Checker; сам бинарный контрол не является контейнером для вторичной копии.
## RangeControl
Pill-range с заполнением акцентным цветом, встроенной подписью и значением. Домен определяет min/max/step и формат числа.
## ColorField
Engine/BIM-геометрия color field: круглый swatch и HEX-значение в pill control. Swatch открывает общий portal-picker: saturation/value plane, hue slider и быстрые цвета. Это устраняет зависимость от тёмной системной палитры браузера и делает выбор одинаковым в dark/light.
Значение контролируемое; приложение по-прежнему отвечает за допустимый формат, сохранение и доменную реакцию на цвет.
## Dropdown
Dropdown владеет floating-layer поведением:
- рендерится в `document.body`;
- позиционируется относительно viewport;
- переворачивается вверх при недостатке места;
- ограничивает размеры viewport;
- обновляется при resize и scroll;
- закрывается по outside pointer и Escape;
- после Escape возвращает фокус на реальную trigger-кнопку, не закрывая родительское окно;
- закрывает другой открытый dropdown.
Содержимое меню передаётся приложением. Selection, action menu и filter menu используют один engine.
Поверх Cesium/map imagery dropdown получает класс `nodedc-map-glass` (`MapGlassSurface`): это отдельный светлый полупрозрачный материал, совпадающий с Map Toolbar. Он не заменяет обычный theme-dependent floating surface вне карты.
## Select
Select добавляет к Dropdown контролируемое значение, options и необязательный поиск. У него две канонические формы:
- `integrated` — единая pill-поверхность Hub/Launcher: label слева, chevron строго у правого края;
- `split` — форма Engine с отдельной областью значения и отдельной кнопкой раскрытия `46 px`, между ними зазор `8 px`.
Native select не используется как видимый runtime UI. Меню рендерится через portal; у Engine-варианта меню имеет радиус `20 px`, а строки — `14 px` и высоту `42 px`.
Внутри `Inspector` форма `integrated` запрещена. Selection-поле собирается только через `InspectorSelectField`: видимая подпись находится сверху, а полноширинный control всегда использует `split`. Компонент намеренно не принимает `layout` и `variant`, поэтому consumer не может вернуть Inspector к Hub/Launcher pill-форме.
## Window
Window — единая механика открытия modal и правой panel:
- приложение контролирует `open`;
- библиотека управляет portal, focus entry/trap/restore, Escape, backdrop и scroll lock;
- `center` — modal;
- `end` — modeless inspector/settings/detail panel без затемнения, backdrop blur, backdrop close, focus trap и блокировки прокрутки страницы.
Содержание, сохранение и запросы принадлежат приложению.
Для modeless Inspector доступен `draggable`: окно двигается за header, не блокирует приложение и ограничивается viewport. Modal-окна не становятся draggable автоматически.
## WorkspaceWindow
`WorkspaceWindow` — modeless-окно внутри рабочей сцены приложения. Оно рендерится непосредственно в переданном workspace, не использует portal и не может перекрыть шапку, навигацию или соседние панели за пределами этого workspace.
Приложение контролирует `rect`, `maximized`, видимость, active-state и `zIndex`. Компонент владеет pointer/keyboard-механикой перемещения и изменения размера, кнопками maximize/restore и close, а также повторно ограничивает геометрию при изменении размеров workspace через `ResizeObserver`. Родительский bounds-контейнер должен быть позиционированным и обрезать содержимое (`position: relative; overflow: hidden`).
Окно предназначено для вспомогательных камер, инструментов и сопоставляемых представлений внутри сцены. Modal workflow, подтверждение и viewport-level Inspector по-прежнему используют `Window`.
## Toolbar
`Toolbar` — канонический dock из нового Engine с требованиями BIM Viewer. Он поддерживает позиции `left`, `right`, `bottom`, lens magnification и autohide. Контролируются фон, border, outline, минимальный/максимальный размер и количество иконок линзы.
Дефолты перенесены из Engine без переизобретения: `#111115`, `#111117`, `#1c1c1c`, `25 px`, `87 px`, `5`. Toolbar получает те же section actions, что и основная navigation, но не владеет route-state.
Компонент сам владеет всей механикой dock: base-размеры кнопок не меняют flex-layout, lens использует `transform: scale + shift`, движение сглаживается единым spring-циклом `requestAnimationFrame`, а autohide закрывает панель с задержкой и возвращает её через edge hotzone. Consumer не реализует hover-расчёты, таймеры или анимацию повторно. React использует `Toolbar`, а BIM/CMS и другие DOM-приложения подключают тот же контракт через `createToolbarController`; обе обёртки используют общие `normalizeToolbarSettings`, `calculateToolbarTargets` и `stepToolbarSpring` из `@nodedc/ui-core`.
## ConfirmationModal
ConfirmationModal оборачивает Window и защищает async-confirm от повторного запуска. До завершения операции закрытие можно заблокировать.
## ShareAccessModal
Workflow-sharing modal из нового Engine: заголовок ресурса, compact avatar stack, список участников, редактирование ролей, удаление доступа, email и роль нового участника. Компонент сохраняет Engine-геометрию `600 px` и controls `46 px`, но не импортирует ACL API. Consumer передаёт members, permissions и callbacks.
Владелец отмечается `immutable`; отсутствие права управления задаётся `canManage`. Backdrop по умолчанию не закрывает access-modal, чтобы пользователь не потерял введённое приглашение.
## ShareLinkModal
Read-only link/copy окно из BIM Viewer. React-компонент использует общий Window, а Vanilla DOM consumer использует `createShareLinkController` вместе с `createModalController`. URL формируется сервисом модели; дизайн-система отвечает только за presentation, copy-state и ошибки адаптера.
## SegmentedControl
Pill navigation для верхней панели и компактного переключения режимов. Active segment использует активную поверхность темы; это не обязательно основной accent приложения.
## AppHeader
Трёхосевая верхняя панель:
- слева фиксированная область логотипа и optional context;
- по центру workspace/navigation;
- справа actions/profile.
Компонент фиксирует положение логотипа, высоту и выравнивание, но не знает маршруты конкретного приложения. Launcher-пресет состоит из внешнего toolbar `68 px` и отдельной видимой строки `48 px`; логотип, центральный switcher и profile-group центрируются по строке `48 px`, а не по всей внешней высоте. Эта двухслойная геометрия закрыта внутри компонента и не переопределяется локальным `className/style`.
В Hub-форме центр состоит из круглого workspace trigger и segmented navigation. Справа используется единая profile-group поверхность с иконкой, подписью и круглым avatar. Эти элементы нельзя заменять случайными standalone-кнопками, сохраняя только приблизительную позицию.
В каноническом `ApplicationShell` шапка фиксирована. Её три оси не двигаются при открытии navigation/content и не зависят от ширины предметного контента.
## UserProfileMenu
Каноническая выпадашка профиля для правой группы `AppHeader`. Она использует
общий portal `Dropdown`, показывает identity cover с аватаром, именем и
подписью и принимает список application-owned действий.
Компонент владеет только геометрией, темизацией, закрытием по outside pointer и
Escape. Переход в профиль, открытие настроек, logout, permissions и продуктовые
правила остаются в приложении. Меню не должно содержать скрытый MCP или ACL
контракт.
## FeatureSettingsWindow
Большое модальное окно настроек по принятой механике нового Engine: identity
текущего модуля слева, сгруппированная навигация features и scrollable content
справа. Компонент переиспользует `Window`, поэтому не создаёт собственный
portal, backdrop или focus trap.
`FeatureSettingsWindow` хранит только controlled active section. Формы,
setup-команды, сохранение, API и права принадлежат приложению. Цвет и материал
берутся из активного Design Profile; отдельная Engine/Foundry тема внутри
компонента запрещена.
## ApplicationShell и ApplicationPanel
Общий шаблон приложения по механике Launcher/Hub: фиксированный `AppHeader`, центральный stage, левая navigation panel и отдельное правое content window.
- на главной виден только stage;
- открытая navigation сдвигает stage;
- content открывается справа от navigation;
- expand растягивает content до правого края и уводит stage за viewport;
- на мобильном navigation и content используют всю область под шапкой последовательно;
- нижняя service rail не входит в шаблон — это элемент витрины Launcher.
`useApplicationWorkspace` является каноническим контроллером этих состояний для React. Приложение не должно заново связывать набор локальных boolean-state для navigation/content/expand. DOM-проекты используют идентичный `createApplicationWorkspaceController`.
Постоянные действия всего рабочего окна передаются через `ApplicationPanel.utilityActions` и всегда находятся в правой части шапки перед expand/close. Сохранение общего layout или настроек приложения — одно такое действие для всего окна; оно не дублируется внутри отдельных карточек и секций.
Точные состояния и размеры зафиксированы в `docs/APPLICATION_TEMPLATE.md`.
## MediaSourceField
Общий компонент Launcher/CMS для медиа-поля: file control, имя файла, URL input, переключатель `HD / URL`, круглое превью, path/hint/error. Один контракт применяется и для stage-видео, и для изображений/логотипов; тип файла, подписи и preview задаёт consumer. Публичный API контролируемый.
Компонент владеет геометрией, доступностью и выбором источника. Приложение владеет file picker/media library, загрузкой в storage, валидацией, разрешениями и сохраняемым URL. Поэтому один и тот же компонент подключается к разным backend без fork. В каталоге видео и знак шапки сохраняются одной кнопкой вместе с темой и настройками layout. Для Vanilla DOM используется `createMediaSourceController`.
## SettingsCard и Switch
`SettingsCard` фиксирует нейтральную структуру админской группы: eyebrow/title/description/actions/body. `Switch` покрывает компактное включение/видимость внутри таких групп. Данные секции, сохранение и права остаются в consumer.
## AdminNavigationPanel
Левая выезжающая панель Hub/Launcher. Библиотека владеет оболочкой `352 px`, радиусом `21.6 px`, внутренними отступами, full-bleed context/navigation pills, круглыми icon surfaces и анимацией появления. Приложение передаёт workspace/company, маршруты, active id и footer identity.
На desktop открытая панель занимает отдельную колонку с Launcher page gap `20 px` до content/stage, а не перекрывает их затемнённым overlay.
`AdminNavigationPanel` поддерживает сортируемые route-items через общий Drag & Drop contract. Приложение передаёт новый порядок id, а панель использует каноническую шеститочечную ручку Engine. Порядок не хранится отдельно внутри navigation-компонента.
## Drag & Drop
`DragHandle`, `DragDropRoot`, `DraggableItem`, `DropZone`, `SortableScope`, `SortableItem` и `SortableList` образуют общий React-контракт переноса и сортировки. Он перенесён из рабочего Engine-паттерна: drag начинается только за шесть точек и только после движения на `6 px`, поэтому обычный клик по строке не конфликтует с навигацией.
Sortable-строки ограничены вертикальной осью: горизонтальное движение указателя не сдвигает navigation или composition layout. `DragDropRoot` возвращает реальные active/over rectangles, поэтому consumer может принять перенос только после достаточного перекрытия destination. Module Foundry использует порог `20%` ширины переносимой строки: короткое движение, движение влево или касание границы не создаёт page instance.
В Module Foundry исходная строка Page Template остаётся в Page Library после переноса. Каждый подтверждённый drop создаёт новый page instance с уникальным id; состав приложения и левая навигация читают один массив страниц и потому всегда перестраиваются синхронно. Удаление instance выполняется стандартным `ConfirmationModal`, а не мгновенным действием крестика.
## Icon
`Icon` предоставляет только подтверждённый общий subset иконок. Каноническое имя описывает смысл (`close`, `expand`, `refresh`), а не конкретный путь SVG. Default glyph — `16 px`, stroke — `1.6`; размер не уменьшается дополнительным CSS-scale. В profile-group шапки допустим подтверждённый Launcher-размер `20 px`. Размеры surface/hit target при этом остаются независимыми и не уменьшаются.
Поверхность, круглая форма, hit target, active и disabled состояния принадлежат `IconButton`, `Button` или navigation item. Полный список находится в `registry/icons.json` и `docs/ICONS.md`.
## StatusBadge
Статус использует semantic tone: neutral, success, warning, danger или accent. Бизнес-статус приложения маппится на tone в самом приложении.
## ToastStack
`ToastCard` и `ToastStack` фиксируют Tasker-derived bottom-right уведомления для `success`, `error`, `warning`, `info` и `loading`. Приложение владеет текстом и состоянием операции; стек владеет portal, геометрией, aria-live и таймерами. Loading не закрывается автоматически и обновляется тем же id после завершения операции. Toast не используется вместо modal confirmation.
## Environment Controls: Inspector и ControlRow
Единая accordion-панель для settings и definition controls. Источник — только новый Environment Settings и NDC Agent Inspector.
Inspector владеет:
- заголовками разделов;
- открытием/закрытием секций;
- active state;
- вертикальным ритмом;
- раскладкой label/control.
Для Engine Environment Settings desktop-контракт точный: окно `390 px`, рабочая колонка `330 px`, строка `154 + 14 + 162 px`, высота контрола `46 px`, section header `50 px` с радиусом `12 px`. Accent-filled section headers и полноширинные range/checker/select сохраняют геометрию исходника.
Engine продолжает владеть определениями полей, типами нод и сохранением значений. В живом catalog эти collapsible sections находятся в `Guideline → Контролы`; отдельной product-вкладки Inspector нет.