Дизайн корпоративных продуктов · Новый ресурс

Дизайн-система Nord.

Изучите токены темы Therapy в Nord и контракты веб-компонентов на примере черновика запроса на бронирование комнаты: реальные цветовые роли, адаптивные размеры полей, явная проверка данных и локально подготовленные результаты.

Руководство OpenDesign8 глав38 справочных записейАвторское руководство по приложению
01

Предварительный просмотр интерфейса дизайн-система Nord

Выберите одну из пяти вместимостей помещения, проверьте заголовок и подготовьте локальную сводку запроса.

Черновик запроса на помещениеОткрыть полный пример
Автономная интерпретация токенов Nord Therapy HTML/CSS; интеграция с нативными веб-компонентами показана отдельно. · Справочник по реализации
02

Справочник по дизайну дизайн-система Nord

Токены Nord 9.0.4 и актуальная документация компонентов. Приведённые ниже значения описывают тему Therapy по умолчанию, а не все бренды Nordhealth. Общедоступная документация не даёт разрешения использовать Nord за пределами предусмотренной области применения Nordhealth.

Роли темы Therapy

Источник
Название / правилоЗначение / конфигурацияПрименение
--n-color-accent#3559c7 Основное действие.
--n-color-text#0c1a3d Основной текст.
--n-color-text-weak#36434a Вспомогательный текст.
--n-color-background#fafbfb Страница.
--n-color-surface#ffffff Панель.
--n-color-border#d8dee4 Разделитель.
--n-color-border-strong#bcc5cc Граница элемента управления.
--n-color-text-error#d24023 Сообщение об ошибке.

Интервалы

Источник
Название / правилоЗначение / конфигурацияПрименение
--n-space-xs4pxМинимальный.
--n-space-s8pxСвязанный.
--n-space-m16pxГруппа.
--n-space-l24pxРаздел.
--n-space-xl36pxКрупный.
--n-space-xxl72pxОсновной.

Типографика и форма

Источник
Название / правилоЗначение / конфигурацияПрименение
--n-font-size-m0.875remОсновной текст.
--n-font-size-l1remКрупный текст.
--n-font-size-xl1.25remЗаголовок раздела.
--n-font-size-xxl1.5remЗаголовок.
--n-line-height1.5Множитель основного текста.
--n-line-height-form20pxЛиния элемента управления.
--n-font-weight-heading600Заголовок.
--n-border-radius-s3pxЭлемент управления.
--n-border-radius5pxПоверхность.

Условия использования Input

Источник
Название / правилоЗначение / конфигурацияПрименение
label / hint / errorBuilt-in field textОтдельный элемент ввода имеет собственную метку.
expandBoolean, default falseЗанимает всю ширину родительского элемента.
sizes / m / lСредний размер по умолчанию.
readonly versus disabledSubmitted versus excludedЭлемент только для чтения остаётся доступным для фокуса.
--n-input-inline-size240pxПо умолчанию ширина фиксированная; для адаптивных форм предпочтителен expand.

Условия использования Select

Источник
Название / правилоЗначение / конфигурацияПрименение
Default slotNative option elementsНе создавайте nord-option.
valueStringВыбор с управлением извне.
requiredBooleanИспользуйте novalidate и ошибки приложения.
changeUser selection eventЧитайте значение из component.value.
focus()Component methodПеред вызовом дождитесь определения компонента.

Условия использования Button

Источник
Название / правилоЗначение / конфигурацияПрименение
typesubmit by defaultДля действий, не отправляющих форму, указывайте button.
variantdefault / primary / dashed / plain / dangerНе более одного основного действия в разделе.
hrefCreates anchor semanticsДля навигации.
sizes / m / lСредний размер по умолчанию.
loadingBusy presentationСопровождайте объявляемым статусом.
03

Дизайн-система Nord Полное руководство

Практическое руководство по выбору, применению и оценке этой системы для реального интерфейса.

DESIGN-nordhealth.md

Подробные рекомендации, отправная точка для реализации и ссылки на источники.

Скачать руководство

Дизайн-система Nord Nord — внутренняя продуктовая система с общедоступными справочными материалами

Учитывайте предусмотренную область применения

В документации Nord описана система, созданная для продуктов Nordhealth. Её общедоступные компоненты могут служить полезными примерами, однако это не означает, что бренд или названия компонентов можно произвольно использовать в коммерческих целях. Названия помещений и процесс оформления заявки в этом примере — оригинальные демонстрационные данные.

Из этого руководства OpenDesign

В таблице токенов по умолчанию представлены значения темы Therapy. Для ветеринарного или медицинского приложения следует выбрать предназначенную для него тему, а не считать, что синий акцент подходит для каждого продукта Nordhealth. Решение о теме принимайте на уровне приложения.

Прочитать вспомогательную спецификацию

Дизайн-система Nord Роли Therapy помогают сохранить сдержанный вид рабочей области

Разделяйте роли текста, границ и поверхностей

В примере для сведений о заявке используется основная роль текста, а для пояснений — менее акцентная. Белые панели расположены поверх почти белого фона страницы; более заметная граница обозначает редактируемые поля. Сообщение об ошибке отображается рядом с заголовком, содержащим ошибку, а не окрашивает весь интерфейс в красный цвет. В примере нет клинической информации и данных пациентов.

Прочитать вспомогательную спецификацию

Дизайн-система Nord Для компактного текста нужно достаточно места между строками

Используйте документированные размер шрифта и межстрочный интервал вместе

Токен сочетает размер основного текста 0.875rem с межстрочным интервалом 1.5, а для текста формы отдельно задана высота строки 20px. Это разные правила: применение значения для формы к длинным абзацам без необходимости их уплотняет. В работающем примере используется токен семейства шрифтов Nordhealth Sans; эта офлайн-интерпретация намеренно опирается на доступные системные шрифты и не предполагает, что лицензированный шрифт включён в комплект.

Прочитать вспомогательную спецификацию

Дизайн-система Nord Растягивайте элементы управления в пределах сетки приложения

Компонент не определяет точку перелома страницы

Для Input задана начальная переменная inline-size со значением 240px. Используйте expand, чтобы занять всю доступную ширину колонки поля. В нашем примере на настольных экранах список помещений расположен рядом с редактором, а на мобильных — над ним; точку перелома выбирает приложение, а не токен Nord. При выборе строки название помещения, вместимость и отметка доступности остаются видимыми.

В офлайн-интерпретации для выбора помещения используется нативная группа радиокнопок. В отдельном примере библиотеки представлен Select с пятью вариантами. Оба способа позволяют выбрать одно помещение, но демонстрируют разные варианты интерфейса и не представлены как одинаковые реализации компонентов во время выполнения.

Прочитать вспомогательную спецификацию

Дизайн-система Nord Выберите один способ задавать метки и сообщения об ошибках

Для этой формы достаточно отдельных полей

Input или Select могут самостоятельно отображать метку, подсказку и ошибку. При использовании новой композиции Field эти обязанности переходят к ней, поэтому дублирование обоих наборов приведёт к избыточным пояснениям. В этом примере используются отдельные компоненты, а при пустом после удаления пробелов заголовке задаётся одно короткое сообщение об ошибке.

Отключённые поля не отправляются вместе с формой, а поля только для чтения сохраняют значимое значение, доступное для фокуса и отправки. Не отключайте идентификатор помещения только ради запрета редактирования, если его всё ещё нужно передать вместе с заявкой.

  • Не скрывайте метку заголовка заявки.
  • Используйте подсказку, чтобы пояснить ожидаемое содержимое, а не вместо метки.
  • Свяжите сообщение о проверке с элементом управления, содержащим ошибку.

Прочитать вспомогательную спецификацию

Дизайн-система Nord Select содержит обычные элементы option

Читайте значение из компонента-оболочки

Слот по умолчанию принимает нативные элементы option. У каждого помещения есть стабильное значение и понятная видимая метка с указанием вместимости. Событие изменения сообщает приложению, что нужно пересчитать сводку на основе значения компонента-оболочки. В этой композиции нет пользовательского тега nord-option.

Nord рекомендует Select для большого набора вариантов, а радиокнопки — когда удобно сразу показать несколько вариантов. В примере пять помещений; оформление с радиокнопками в офлайн-версии позволяет легко сравнить их вместимость.

Прочитать вспомогательную спецификацию

Дизайн-система Nord Значения Button по умолчанию влияют на состав формы

Явно задавайте семантику действия, ссылки и загрузки

По умолчанию Nord Button использует type="submit". Поэтому для вторичного действия предварительного просмотра или сброса внутри формы нужно явно задать тип, если оно не должно отправлять форму. Если указать для компонента href, его семантика изменится на ссылку; используйте этот вариант для навигации вместо обработчика щелчка, имитирующего якорную ссылку.

Во время загрузки кнопка остаётся доступной для фокуса, но повторное нажатие предотвращается. Индикатор загрузки скрыт от вспомогательных технологий, поэтому приложение должно сообщать о ходе выполнения словами. Не заменяйте это состояние без разбора на disabled: недоступное действие и уже выполняемое действие требуют разного поведения фокуса и обратной связи.

Пример заявки на помещение синхронно формирует черновик, поэтому состояние загрузки ему не требуется. Основная кнопка проверяет заголовок и считывает выбранное помещение; при изменении любого из них устаревшее предложение черновика удаляется. В разделах о полях и Select выше описаны API Nord, отвечающие за эти элементы ввода.

Прочитать вспомогательную спецификацию

Дизайн-система Nord Перед вызовом методов компонента загрузите необходимые CSS

Загрузка для прототипа и сборка для продакшена различаются

В официальном кратком руководстве модуль компонентов используется вместе с фреймворком CSS. Последний предоставляет общие токены и базовые стили. Для приложения со сборкой установите @nordhealth/css и @nordhealth/components, один раз импортируйте CSS и импортируйте только нужные модули компонентов. Модули пакета регистрируют свои элементы как побочный эффект.

React 19 позволяет использовать эти пользовательские элементы напрямую. В актуальных рекомендациях обёртка @nordhealth/react помечена как устаревшая. При серверном рендеринге shadow DOM компонента не включается; для импортов в Next.js нужна граница клиентского кода. Не смешивайте эти ограничения интеграции с офлайн-примером HTML, взаимодействие с которым работает без библиотеки.

  1. Загрузите фреймворк CSS перед модулями компонентов.
  2. Перед вызовом focus при инициализации дождитесь выполнения customElements.whenDefined.
  3. Подключите обработчики проверки и локального состояния.
  4. Для продакшена собирайте зависимости, а не полагайтесь на множество запросов модулей с CDN.

Прочитать вспомогательную спецификацию

Дизайн-система Nord Примеры компонентов дизайн-системы

Полноценный автономный интерактивный пример

Сохраните весь документ как index.html и откройте его в браузере. Офлайн-интерпретация токенов Nord Therapy в HTML/CSS; интеграция с нативными веб-компонентами показана отдельно.

html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Nord room request interpretation</title><style>*{box-sizing:border-box}body{margin:0;background:#fafbfb;color:#0c1a3d;font:14px/1.5 system-ui,sans-serif}button,input{font:inherit}header{height:52px;background:white;border-bottom:1px solid #d8dee4;padding:0 24px;display:flex;align-items:center;justify-content:space-between}header small{color:#36434a}main{max-width:960px;margin:36px auto;padding:0 24px}h1{font-size:24px;line-height:1.2;margin:0 0 8px}h2{font-size:20px;line-height:1.2;margin:0 0 16px}p{margin:0 0 24px}.muted{color:#36434a}.layout{display:grid;grid-template-columns:310px 1fr;gap:24px}.panel{background:white;border:1px solid #d8dee4;border-radius:5px;padding:24px}fieldset{margin:0;padding:0;border:0;min-width:0}legend{font-weight:600;margin-bottom:16px}.room{display:flex;gap:12px;padding:12px;border:1px solid #d8dee4;border-radius:3px;margin-bottom:8px;cursor:pointer;align-items:center}.room:has(:checked){border-color:#3559c7;background:#f0f4ff}.room input{accent-color:#3559c7}.room span{flex:1}.room small{display:block;color:#36434a}.room b{font-size:12px;font-weight:500}.diagram{height:120px;background:#f6f8f8;display:grid;place-items:center;margin:-24px -24px 24px;border-radius:5px 5px 0 0;border-bottom:1px solid #d8dee4}.table{height:50px;border:2px solid #bcc5cc;border-radius:5px;background:#fff;position:relative;transition:width .2s ease}.chair{position:absolute;width:12px;height:10px;border:1px solid #bcc5cc;background:white;border-radius:3px;top:-16px}.chair.bottom{top:auto;bottom:-16px}label.field{display:block;font-weight:600;margin:16px 0 8px}#title{width:100%;border:1px solid #bcc5cc;border-radius:3px;height:36px;padding:7px 12px;color:inherit;background:white}#title[aria-invalid=true]{border-color:#d24023}.error{color:#d24023;min-height:20px;font-size:12px;margin:4px 0 12px}button{background:#3559c7;color:white;border:1px solid transparent;box-shadow:0 1px 3px #0c0c0c17;border-radius:3px;padding:7px 16px;cursor:pointer}button:focus-visible,input:focus-visible{outline:2px solid #3559c7;outline-offset:3px}.summary{margin-top:24px;background:#f0f4ff;border:1px solid #c6d4f9;padding:16px;border-radius:5px;overflow-wrap:anywhere}.summary:empty{display:none}.boundary{font-size:12px;color:#36434a;margin-top:24px}#selected{font-weight:600}.facts{display:flex;gap:24px;margin-bottom:24px}.facts strong{font-size:20px;display:block}.facts span{font-size:12px;color:#36434a}@media(max-width:650px){main{margin:24px auto;padding:0 16px}.layout{grid-template-columns:1fr;gap:16px}.panel{padding:16px}.diagram{margin:-16px -16px 16px}.room{padding:8px 12px}header{padding:0 16px}header small{display:none}}</style><header><strong>◈ Workplace</strong><small>Room request workspace</small></header><main><h1>A room for your next conversation</h1><p class="muted">Choose a room and prepare a request draft.</p><div class="layout"><section class="panel"><fieldset><legend>Choose a room</legend><div id="rooms"></div></fieldset></section><section class="panel"><div class="diagram" aria-hidden="true"><div class="table" id="table"></div></div><h2 id="selected">Birch</h2><div class="facts"><div><strong id="capacity">4</strong><span>Seats</span></div><div><strong>Draft</strong><span>Request status</span></div></div><form novalidate><label class="field" for="title">Request title</label><input id="title" type="text" aria-describedby="hint error" placeholder="e.g. Design review"><div id="error" class="error" role="alert"></div><p id="hint" class="muted">Use a non-sensitive meeting title. Availability is not checked in this example.</p><button type="submit">Prepare request</button></form><div class="summary" id="result" role="status"></div></section></div><p class="boundary">Independent HTML interpretation of Nord Therapy tokens. Nord is intended for Nordhealth products. This example creates a local draft only; it does not reserve a room.</p></main><script>const rooms=[['Birch',4],['Cedar',6],['Elm',8],['Maple',10],['Pine',12]],field=document.querySelector('#title'),result=document.querySelector('#result');let selected=0;document.querySelector('#rooms').innerHTML=rooms.map(([name,n],i)=>`<label class="room"><input type="radio" name="room" value="${i}" ${i===0?'checked':''}><span>${name}<small>Meeting room</small></span><b>${n} seats</b></label>`).join('');function update(){let [name,n]=rooms[selected];document.querySelector('#selected').textContent=name;document.querySelector('#capacity').textContent=n;let table=document.querySelector('#table');table.style.width=(n*12+44)+'px';table.innerHTML=Array.from({length:n},(_,i)=>`<i class="chair ${i>=n/2?'bottom':''}" style="left:${12+(i%(n/2))*24}px"></i>`).join('');result.textContent=''}document.querySelectorAll('[name=room]').forEach(input=>input.onchange=()=>{selected=Number(input.value);update()});document.querySelector('form').onsubmit=e=>{e.preventDefault();if(!field.value.trim()){document.querySelector('#error').textContent='Enter a request title.';field.setAttribute('aria-invalid','true');field.focus();return}result.textContent='Draft prepared: '+field.value.trim()+' · '+rooms[selected][0]+' · '+rooms[selected][1]+' seats. No room is reserved.'};field.oninput=()=>{field.removeAttribute('aria-invalid');document.querySelector('#error').textContent='';result.textContent=''};update();</script></html>

Справочник по коду

  • В этом примере варианты помещений представлены радиокнопками; в нативном примере Nord используется Select с обычными элементами option. Ни один вариант не бронирует настоящее помещение.

Форма заявки на помещение с меткой и явной проверкой

Отдельные nord-input и nord-select обеспечивают метки без необязательного семейства Field. При отправке считываются значения компонентов и свойство ошибки назначается полю ввода.

html
<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Room request draft</title>
<link rel="stylesheet" href="https://nordcdn.net/ds/css/5.2.4/nord.min.css">
<script type="module" src="https://nordcdn.net/ds/components/5.3.0/index.js"></script>
<style>main{max-width:560px;margin:auto;padding:var(--n-space-l)}form{display:grid;gap:var(--n-space-l)}</style>
<main><h1>Prepare a room request</h1><p>For an authorized Nordhealth product. Local demonstration only.</p>
<form novalidate>
<nord-input id="request" name="request" label="Request title" hint="Use a non-sensitive meeting title." required expand></nord-input>
<nord-select id="room" name="room" label="Room" value="Birch" expand>
<option value="Birch">Birch · 4 seats</option><option value="Cedar">Cedar · 6 seats</option>
<option value="Elm">Elm · 8 seats</option><option value="Maple">Maple · 10 seats</option><option value="Pine">Pine · 12 seats</option>
</nord-select>
<nord-button type="submit" variant="primary">Prepare request</nord-button>
</form><p id="result" role="status"></p></main>
<script type="module">
await Promise.all(['nord-input','nord-select','nord-button'].map(name=>customElements.whenDefined(name)));
const form=document.querySelector('form'), title=document.querySelector('#request'),room=document.querySelector('#room'),result=document.querySelector('#result');
form.addEventListener('submit',event=>{
 event.preventDefault();title.error=title.value.trim()?'':'Enter a request title.';
 if(title.error){title.focus();return;}
 result.textContent=`Draft: ${title.value.trim()} in ${room.value}. No room is reserved.`;
});
form.addEventListener('input',()=>{result.textContent='';title.error='';});
form.addEventListener('change',()=>{result.textContent='';});
</script></html>

Справочник по коду

  • Пять вариантов помещений делают Select удобным компактным способом выбора.
  • По умолчанию Button отправляет форму; в этом примере тип указан явно.
  • Перед использованием методов дожидаемся определения пользовательских элементов. Вызовов службы бронирования нет.
04

Дизайн-система Nord Настройка агента

Отправная точка для реализации

Полный прототип на общедоступном CDN для разрешённого использования Nordhealth. В текущей документации указаны CSS 5.2.4 и components 5.3.0. Для продакшена следует собирать npm-пакеты; приведённая ниже офлайн-интерпретация интерфейса не загружает эти удалённые пакеты.

html
<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Room request draft</title>
<link rel="stylesheet" href="https://nordcdn.net/ds/css/5.2.4/nord.min.css">
<script type="module" src="https://nordcdn.net/ds/components/5.3.0/index.js"></script>
<style>main{max-width:560px;margin:auto;padding:var(--n-space-l)}form{display:grid;gap:var(--n-space-l)}</style>
<main><h1>Prepare a room request</h1><p>For an authorized Nordhealth product. Local demonstration only.</p>
<form novalidate>
<nord-input id="request" name="request" label="Request title" hint="Use a non-sensitive meeting title." required expand></nord-input>
<nord-select id="room" name="room" label="Room" value="Birch" expand>
<option value="Birch">Birch · 4 seats</option><option value="Cedar">Cedar · 6 seats</option>
<option value="Elm">Elm · 8 seats</option><option value="Maple">Maple · 10 seats</option><option value="Pine">Pine · 12 seats</option>
</nord-select>
<nord-button type="submit" variant="primary">Prepare request</nord-button>
</form><p id="result" role="status"></p></main>
<script type="module">
await Promise.all(['nord-input','nord-select','nord-button'].map(name=>customElements.whenDefined(name)));
const form=document.querySelector('form'), title=document.querySelector('#request'),room=document.querySelector('#room'),result=document.querySelector('#result');
form.addEventListener('submit',event=>{
 event.preventDefault();title.error=title.value.trim()?'':'Enter a request title.';
 if(title.error){title.focus();return;}
 result.textContent=`Draft: ${title.value.trim()} in ${room.value}. No room is reserved.`;
});
form.addEventListener('input',()=>{result.textContent='';title.error='';});
form.addEventListener('change',()=>{result.textContent='';});
</script></html>

Запрос для вашего проекта

Промпт для AI-агента
Используйте семантические роли Nord Therapy и элементы управления с метками. Растягивайте поля в адаптивной раскладке приложения. Проверяйте заголовок заявки после удаления пробелов, сохраняйте выбор одного помещения и показывайте только локальный результат в виде черновика. Для реальной реализации Nordhealth соблюдайте документированные условия использования пакетов и тем.
05

Дизайн-система Nord Источники и область применения

Независимый справочник OpenDesign. Nord указывает, что система предназначена для продуктов Nordhealth. Эта оригинальная интерпретация HTML не бронирует помещение и не даёт прав на использование бренда или компонентов.