48 KiB
Канонические компоненты
Машинный список находится в registry/components.json. Ниже зафиксирован смысл компонентов и границы их использования.
GlassSurface
Базовая непрозрачная поверхность для карточки, панели и большого окна. Варианты меняют плотность нейтральной поверхности, но не создают отдельный дизайн. Реальный glass-материал с blur и rim используется только у floating-слоёв: modal Window и portal-dropdown/select.
default— обычная карточка/панель;strong— dropdown, modal и поверхность над сложным фоном;soft— вложенная или вторичная область.
radius="pill" задаёт каноническую капсульную геометрию через --nodedc-radius-circle. Она предназначена, в частности, для компактных вертикальных и горизонтальных реек из круглых действий: верхняя и нижняя части поверхности повторяют круг кнопок без прямых торцевых пролётов. Consumer не воспроизводит этот радиус локальным CSS.
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 по умолчанию круглый. Квадратная кнопка с маленьким радиусом допустима только как кнопка закрытия окна или плотный инструмент, где это зафиксировано контрактом.
size="dense" — каноническая плотность для текстовых layer/mode-действий внутри визуализатора. Она уменьшает площадь и подпись контрола, но не меняет hover, active, disabled и focus-состояния. В шапках приложения и обычных формах эта плотность не используется.
Переключаемый IconButton передаёт контролируемое состояние через aria-pressed. Активная поверхность и контраст принадлежат дизайн-системе; размер круга и glyph при переключении не меняются.
loading в Button и IconButton помещает индикатор по центру нажатой кнопки, сохраняет её размеры и accessible name, выставляет aria-busy и блокирует повторное нажатие. Подробный контракт — состояния загрузки.
LoadingRegion
LoadingRegion loading={pending} label="Получаем данные" центрирует ожидание внутри области содержимого, сохраняя её детей смонтированными. Приложение резервирует размер визуализатора и снимает loading после первого пригодного содержимого, ошибки или timeout. Командный spinner принадлежит кнопке и сюда не дублируется.
ActivityIndicator
ActivityIndicator — общий индикатор неопределённого по длительности процесса. default используется внутри LoadingRegion или явного inline-статуса, compact — внутри Button.loading/IconButton.loading либо фиксированного слота строки ресурса. Владелец операции по-прежнему задаёт видимый текст pending-состояния и aria-busy; индикатор не хранит таймер и не определяет завершение операции.
Без label индикатор декоративный и скрыт от accessibility tree. label включает role="status" только когда сам индикатор должен объявить процесс. При prefers-reduced-motion: reduce кольцо остаётся видимым, но не вращается.
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
Вертикальная шкала занимает 0.4 × --nodedc-control-height по ширине (18.4 px при базовой высоте 46 px): на 20% тоньше первоначального варианта 11.09.2026. Высота, диапазон и управление сохраняются.
Pill-range с заполнением акцентным цветом, встроенной подписью и значением. Домен определяет min/max/step и формат числа. min/max задают только рабочий диапазон перетаскивания; ручной ввод по умолчанию принимает любое конечное число и не меняет геометрию ползунка. Опциональный exactValueBounds независимо задаёт жёсткие границы ручного ввода: например, { min: 0 } сохраняет неотрицательное значение, но не ограничивает верхнюю границу ползунком.
Drag всегда принадлежит невидимому native range и продолжается под областью значения. Над числом постоянно смонтирован один прозрачный native text input: фокус включает редактирование без замены DOM-узла и без pointer-state mutation, браузер ставит каретку в фактическое место клика, а drag/keyboard-selection и замена выделенного текста остаются полностью нативными. Поле не получает собственной подложки, select-all или второго focus-ring. Цвет текста и каретки автоматически выбирается между theme text и on-accent по фактической границе заливки под областью значения, поэтому светлая заливка получает тёмный контраст без application-local цвета. Enter/blur применяют значение с exact-bound/step-нормализацией, Escape отменяет ввод; события редактора не всплывают в оконные shortcuts. Оконный focus-manager выполняет начальный autofocus только при открытии и не отбирает фокус при последующих ререндерах.
RangeControl orientation="vertical" — утверждённый владельцем 11.09.2026 вертикальный вариант для высоты среза. Максимум расположен сверху, заливка растёт снизу, стрелки вверх/вниз меняют значение. Подпись, числовое значение, контраст и focus принадлежат тому же компоненту. Узкий вертикальный вариант использует drag/клавиатуру без inline-редактора; точные границы задаёт домен.
Последнее уточнение владельца от 19.09.2026 заменяет промежуточный вариант с границами внутри: верхняя и нижняя границы вынесены с внутренней стороны сцены, читаются горизонтально и сохраняют цвет theme text, не меняясь от заливки. formatLimit форматирует их отдельно от текущего значения, без единицы измерения по умолчанию. По умолчанию это правая сторона; limitSide="left" зеркалит только внешние границы для шкалы, закреплённой справа от сцены. В центре неподвижно расположена строка «подпись · значение»; единица остаётся в formatValue. Внутренний и наружный шрифт уменьшены на 10% относительно токенов sm/xs. Два совпадающих центральных текстовых слоя и маска формы заливки меняют контраст ровно по её границе, в том числе посередине символа.
Уточнение от 20.09.2026: вертикальная шкала не получает border, outline или тень по периметру ни в одном состоянии. Native range может сохранять :focus-visible и после pointer-ввода, поэтому этот селектор больше не рисует контур. Доступный фокус обозначается подчёркиванием центральной подписи в обоих контрастных слоях; стрелки и Home/End продолжают работать нативно.
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;
- сохраняет border-box геометрию при собственной прокрутке и не накапливает padding в измеренной ширине;
- удерживает wheel/trackpad overscroll внутри меню, не прокручивая лежащую под portal поверхность;
- закрывается, когда trigger полностью уходит за границы viewport;
- закрывается по 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;inline— компактный toolbar-trigger: только текущее значение без постоянной подложки и chevron; всё значение открывает обычное portal-меню.
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-форме.
SelectOption.action добавляет независимое действие справа от строки (label, icon, disabled, onAction), например корзину. Это соседний канонический IconButton, не вложенная кнопка. Действие закрывает меню, не выбирает строку и не вызывает onChange; подтверждение и запрос принадлежат приложению. Меню с действиями использует dialog-семантику и отдельные доступные кнопки выбора/действия; обычный Select сохраняет listbox. Состояние option.disabled не блокирует независимое действие — для него предусмотрен action.disabled.
Действие строки повторяет принятый образец каталога сессий Mission Core: прозрачная колонка нажатия 2.35rem, иконка 15 px, приглушённый цвет, без круглой подложки, скругления или тени. Опциональный tone="danger" меняет цвет при наведении и клавиатурном фокусе, но не окрашивает корзину постоянно. Доступный focus-индикатор общего IconButton сохраняется.
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 закрывается независимо от результата автосохранения. Приложение сначала закрывает controlled Window, затем завершает сохранение асинхронно; сбой сообщает через компактный ToastStack с tone error, сохраняя draft текущего просмотра. Нельзя удерживать окно открытым, выводить внутри него browser-default p/heading или увеличивать текст ошибки до title-размера.
Для modeless Inspector доступен draggable: окно двигается за header, не блокирует приложение и ограничивается viewport. Modal-окна не становятся draggable автоматически.
WorkspaceWindow
WorkspaceWindow — modeless-окно внутри рабочей сцены приложения. Оно рендерится непосредственно в переданном workspace, не использует portal и не может перекрыть шапку, навигацию или соседние панели за пределами этого workspace.
На Map Page WorkspaceWindow используется для facet-групп, активного сектора
и provider-neutral карточки выбранного subject. Настройки карты являются
application-level панелью ApplicationSidePanel, а слои открываются через
канонический toolbar Dropdown; они не участвуют в bounded z-index stack.
Chevron внутри facet-строки
владеет только раскрытием дерева subjects; тело строки сохраняет действие
фильтра. Смена совместимого subject не пересоздаёт карточку и не сбрасывает
активную вкладку. Joined data-product aspects не создают отдельные окна или
слои, а наполняют декларативные секции существующей карточки.
Справочные точки транспорта используют тот же renderer adapter, но отдельный
slot reference-points. Их три presentation profiles (Метро, Вокзалы,
Станции РЖД) являются живыми каноническими Inspector sections: приложение
может менять высоту, размер, label и LOD, не создавая provider-specific UI.
Центральный Map Toolbar содержит Objects, Layers и template-owned универсальный поиск. Слои используют тот же map-glass dropdown и геометрию, что Objects, вместо отдельного плавающего окна. В закрытом состоянии toolbar содержит четыре круглых действия; при открытии поиска общий pill симметрично расширяется, действия остаются слева, а справа появляется search-field и список результатов. Индекс строится по domain subjects, presentation label fields и разрешённым Data Product projections. Компонент не принимает provider payload и использует renderer entity id только как внутренний адрес camera adapter. Локальные совпадения появляются сразу; явный Enter при отсутствии совпадения разрешает один точный reference-name lookup через Map Gateway, после которого камера сохраняет композицию и переносится к контрактным координатам результата.
Приложение контролирует rect, maximized, видимость, active-state и zIndex. Компонент владеет pointer/keyboard-механикой перемещения и изменения размера, кнопками maximize/restore и close, а также повторно ограничивает геометрию при изменении размеров workspace через ResizeObserver. Опциональный autoHeight подгоняет высоту под живое содержимое и сжимает её обратно, не выходя за нижнюю границу workspace. Родительский 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 от повторного запуска. До завершения операции закрытие можно заблокировать.
SplitPane
SplitPane — контролируемая раскладка двух синхронных представлений с общей регулируемой границей. Приложение передаёт содержимое обеих панелей, процент primary-панели и callback изменения; дизайн-система владеет pointer capture, ограничениями размеров, focus-state и доступностью role="separator".
Локальные toolbar и overlay каждого viewport являются содержимым соответствующей панели. Их нельзя позиционировать от общего workspace или вычислять по cursor/event-эвристике вложенного renderer. Если renderer хранит свою раскладку, приложение передаёт ему тот же controlled процент из SplitPane, чтобы renderer и локальный UI использовали одну геометрию.
Вертикальная граница меняется мышью или клавишами ←/→, горизонтальная — ↑/↓; Home/End переходят к разрешённым границам, а Shift ускоряет клавиатурный шаг. Доля сохраняется при resize контейнера. Минимальные проценты обеих панелей применяются одинаково к pointer и keyboard interaction.
Разделитель является структурной границей между двумя рабочими представлениями и не создаёт декоративную рамку вокруг контента. При resizable={false} панели сохраняют ту же стабильную DOM-композицию, а separator полностью отсутствует в визуальном слое и accessibility tree; это позволяет приложению сворачивать одну из панелей без remount тяжёлого renderer.
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 приложения.
size="dense" применяется только в насыщенной панели слоёв или режимов непосредственно над viewer. Шапка приложения сохраняет default-геометрию; consumer не воспроизводит dense-отступы или шрифт локальным CSS.
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 или настроек приложения — одно такое действие для всего окна; оно не дублируется внутри отдельных карточек и секций.
Переключение режима выбранного объекта может передать pressed в utility action: состояние получает aria-pressed и общую активную поверхность. Например, info открывает обзор текущей сохранённой сессии Mission Core.
Если заголовок и действия не помещаются в одну строку, шапка переносит действия на следующую строку с выравниванием вправо. Кнопки не обрезаются, заголовок сохраняет читаемую ширину. Состав действий одинаков в обычном и развёрнутом окне.
Точные состояния и размеры зафиксированы в 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.
Бегунок включённого Switch использует --nodedc-on-accent-rgb, поэтому
сохраняет контраст с белым, цветным и тёмным акцентом. Выключенный track
наследует тон темы от text-primary. Длина track не сжимается при переносе
подписи; положение бегунка остаётся дополнительным признаком состояния.
Для компактных сообщений о результате и пустых состояний SettingsCard align="center"
центрирует содержимое по горизонтали и вертикали. Пустой body не создаёт
асимметричный нижний отступ. Обычные группы настроек сохраняют align="start";
вариант не задаёт высоту и не меняет токены темы.
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-компонента.
ApplicationSidePanel
ApplicationSidePanel — правая application-level пара к AdminNavigationPanel.
Она использует ту же ширину 332–352 px, радиус, theme-aware surface, тень и
круглые действия, но появляется справа налево. ApplicationShell размещает её
в отдельной end-колонке и на desktop уменьшает доступную ширину раскрытого
content/stage на ширину панели плюс канонический gap 20 px; overlay карты не
создаётся.
Панель контролируется приложением. Она открывается и закрывается явным action
в header ApplicationPanel; Close всегда закрывает её, а взаимодействие с
картой не меняет состояние панели. Внутри настроек используется Inspector variant="panel": accordion сохраняет свой layout-state, а его заголовки
получают pill/icon geometry и цвета левой панели из theme tokens.
Этот формат предназначен для настроек и detail-контента уровня Application.
Инструменты, сектор, facet-окна и карточки, ограниченные самой сценой, остаются
WorkspaceWindow. Floating dropdown для короткого списка слоёв не заменяется
полноразмерной side panel.
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 в самом приложении.
pulse добавляет пульсацию только лампы, не текста и не фона. Подходит для потери подтверждения или другого состояния, требующего внимания. При prefers-reduced-motion: reduce лампа остаётся постоянной. Текст статуса обязателен рядом с отдельным индикатором или в самом badge.
ToastStack
ToastCard и ToastStack фиксируют Tasker-derived bottom-right уведомления для success, error, warning, info и loading. Приложение владеет текстом и состоянием операции; стек владеет portal, геометрией, aria-live и таймерами. Обычный terminal toast по умолчанию живёт 10 000 ms; каждый стабильный id получает собственный таймер, поэтому добавление соседнего уведомления не продлевает уже показанное. Loading не закрывается автоматически и обновляется тем же id после завершения операции; после перехода в terminal tone для него запускается обычный независимый таймер. Toast не используется вместо modal confirmation.
Environment Controls: Inspector и ControlRow
Единая accordion-панель для settings и definition controls. Источник — только новый Environment Settings и NDC Agent Inspector.
Inspector владеет:
- заголовками разделов;
- открытием/закрытием секций;
- active state;
- вертикальным ритмом;
- раскладкой label/control.
В uncontrolled-режиме начальные секции задаёт defaultOpen. Для layout-aware
приложений Inspector поддерживает controlled-пару
openSections/onOpenSectionsChange: она позволяет общей кнопке Save сохранять
точную конфигурацию раскрытых секций и восстанавливать её без remount-default.
Для 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 нет.
ResourceRow и ResourceList
Общие компактные строки ресурсов, выделенные из Mission Core AI Inference. Контракт, состояния и происхождение: RESOURCE_ROW.md.
Светлый одноцветный знак шапки явно помечается AppHeader.brandMonochrome и
HeaderWorkspace.monochrome: общая тема обеспечивает контраст на светлом фоне.
По умолчанию флаг выключен; цветные изображения и аватары не меняются.
ProgressBar
Линейная полоса выполнения: label, измеренная доля value 0…1 или
неопределённая продолжительность без value, доступный valueText.
В ResourceRow передаётся через progress и заменяет статус между
наименованием и кнопками. Процент принадлежит приложению, анимация его не выдумывает.
См. контракт.
StatusBadge variant="indicator" отображает только одну лампу состояния.
Передавайте aria-label и title; дополнительный текст и значки скрываются.
EnvironmentSettingsWindow и EnvironmentMediaPlaylistEditor
Единый редактор окружения перенесён из принятой композиции Mission Core. Принимает страницы, quick-action варианты, документ, состояние, upload/save adapters и название продукта. Использует тот же FeatureSettingsWindow, поля, переключатели, медиаконтент и перестановку; новое приложение передаёт данные, а не копирует форму. Для бортового приложения передаётся только home. Контракты и пример: ENVIRONMENT_SETTINGS.md.
LandingStage и EnvironmentBackgroundMedia
Общая главная: надзаголовок, заголовок, описание, быстрые действия, фон и необязательные status/footer slots. Изображения меняются по таймеру, видео — после завершения; ошибочные источники пропускаются. Пустой фон однотонный, без декоративного круга. Состояние страниц и хранение принадлежат приложению.
Для primary Button tone="neutral" фиксирует белый enabled и серый disabled, независимо от темы и акцента; keyboard focus остаётся видимым. MediaSourceField принимает disabled и блокирует все операции выбора источника, пока родитель сохраняет документ или загружает файл.