NODEDC_DESIGN_GUIDELINE/docs/COMPONENTS.md

20 KiB
Raw Blame History

Канонические компоненты

Машинный список находится в 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.

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 автоматически.

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 и не зависят от ширины предметного контента.

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 в самом приложении.

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 нет.