Изучите точные значения отступов, скруглений и типографики Horizon Workspace на примере полного локального сценария проверки запросов с сохранением черновика, проверкой данных, фильтрами статусов и восстановлением.
Руководство OpenDesign6 глав19 справочных записейАвторское руководство по приложению
01
Предварительный просмотр интерфейса дизайн-системы ServiceNow Horizon
Сохраняйте черновики при переходе между записями, отмечайте запросы как проверенные и восстанавливайте состояние после фильтрации или повторного открытия.
Оригинальная реализация HTML/CSS/JavaScript с локальными шрифтами Cabin и Lato; подключения к платформе ServiceNow нет. · Справочник по реализации
02
Справочник по дизайн-системе ServiceNow Horizon
Опубликованные рекомендации Horizon Workspace по интервалам, радиусам скругления и типографике. Исходные цвета приложения намеренно не включены в эту официальную справочную таблицу.
Опубликованные рекомендации по дизайну. Малые значения подходят для компактных меток, средние — для вложенных элементов управления, большие — для контейнеров.
now-global-border-radius--md
6px
Опубликованные рекомендации по дизайну. Малые значения подходят для компактных меток, средние — для вложенных элементов управления, большие — для контейнеров.
now-global-border-radius--lg
8px
Опубликованные рекомендации по дизайну. Малые значения подходят для компактных меток, средние — для вложенных элементов управления, большие — для контейнеров.
Область применения и реализации Workspace дизайн-системы ServiceNow Horizon
Начните с фреймворка приложения
Horizon поддерживает несколько фреймворков приложений ServiceNow. Эта страница посвящена Workspace: очередь и выбранная запись отображаются рядом, чтобы проверяющий мог просматривать локальные задачи, не теряя контекста. Service Portal, Native Mobile и Core UI здесь не представлены как взаимозаменяемые оболочки. Интерактивное исследование — это оригинальное приложение HTML, а не встроенный экземпляр ServiceNow.
Отделяйте подтверждённые основы от оригинальных решений
В справочнике приведены точные опубликованные названия интервалов, значения радиусов и роли типографики. Зелёный цвет действий, нейтральные поверхности и синий цвет фокуса в исследовании — оригинальные значения OpenDesign с префиксом приложения. Они не выдаются за официальный экспорт токенов Horizon. Для запуска полного примера не требуется установка вымышленного пакета ServiceNow или платформа API.
Интервалы, радиусы и типографика Workspace дизайн-системы ServiceNow Horizon
Используйте фактическую шкалу интервалов
Документированная шкала состоит из значений 2, 4, 8, 12, 16, 24, 32 и 40px. В исследовании она задаёт расстояние между очередью и записью, внутренние отступы записи и меньшие интервалы между метаданными. Эти значения отвечают за разные связи группировки, даже если один и тот же шаг используется несколько раз. Единообразные отступы на всём экране разрушили бы эту иерархию.
Разделяйте роли заголовков и основного текста
Для заголовков используется Cabin, а для основного текста — Lato, как и предусмотрено опубликованными ролями шрифтовых семейств. В исследовании заголовок страницы имеет размер 32px на широких экранах, а заголовок записи — 24px. В справочнике указаны радиусы 2, 6 и 8px, а не предполагаемая стандартная последовательность 4/8/12. Скруглённые метки статуса не передают его только формой или цветом: в них также указаны слова «Открыт» или «Проверен».
Очередь, выбранная запись и фильтрация в дизайн-системе ServiceNow Horizon
Поддерживайте одну выбранную запись
Для каждого действия в очереди указаны запрос по практике, владелец и статус. При выборе действия рядом отображаются подробности, а фокус перемещается на новый заголовок. Для выбранного действия задаётся aria-current и видимая рамка. Это оригинальный шаблон списка с подробностями, а не нативный компонент Horizon API; вся логика его состояний доступна для проверки.
Восстанавливайте состояние, если фильтр скрывает выбранную запись
Фильтр по статусу сокращает список отображаемых записей. Если выбранный запрос больше не соответствует фильтру, приложение выбирает первый доступный подходящий запрос. Если таких записей нет, показывается сообщение о пустом списке и действие «Показать все запросы». Для расчёта количества в знаменателе используется полная коллекция из трёх записей. Фильтрация не удаляет записи и не меняет их статус без уведомления.
Оставляйте выбранную запись в текущем отфильтрованном списке.
Показывайте понятное пустое состояние, если список не содержит записей.
Восстанавливайте список с помощью действия «Показать все запросы», не удаляя данные.
Черновики заметок и проверка запросов в дизайн-системе ServiceNow Horizon
Связывайте черновики с соответствующими записями
При вводе текста проверяющим текстовое поле обновляет черновик в соответствующей записи. Черновик сохраняется при переходе к другому запросу и возвращении. Пустая заметка или заметка только из пробелов не позволяет отметить запрос как проверенный: появляется встроенное сообщение об ошибке, устанавливается aria-invalid, а фокус возвращается в текстовое поле. В модели данных сохранённая заметка и текущий черновик представлены явно.
Обеспечьте наблюдаемость локального изменения состояния
Повторное открытие и доступная обратная связь в дизайн-системе ServiceNow Horizon
Сохраняйте полезные данные при повторном открытии
Действие «Повторно открыть запрос» возвращает проверенную запись в статус «Открыт», сохраняя её заметку. При фильтре, показывающем только проверенные записи, список может опустеть; действие восстановления вернёт полную очередь. Такой сценарий позволяет проверить взаимосвязь состояния записи, фильтрации и выбранных подробностей — это информативнее, чем тестирование каждой кнопки по отдельности.
Сочетайте текст, фокус и сообщения о статусе
Цвет статуса сопровождается текстовой меткой. При проверке фокус перемещается к полю, требующему внимания; при переходе между записями — к заголовку; локальные обновления объявляются через область статуса. Исследование не отменяет необходимости тестирования Workspace с ассистивными технологиями в производственной среде. Оно предоставляет полноценный локальный сценарий для ознакомления и начала таких проверок.
Полный локальный исходный код и проверки дизайн-системы ServiceNow Horizon
Установите общедоступные зависимости шрифтов
Предоставленная точка входа подключает общедоступные пакеты шрифтов Cabin и Lato, а также оригинальную таблицу стилей композиции. Оболочка HTML предоставляет корневой элемент. В этом примере нет среды выполнения ServiceNow, учётных данных или конечной точки. Фактическую интеграцию с платформой следует начинать с ресурсов Horizon для Workspace и разработчиков, а не считать локальный массив записей контрактом API ServiceNow.
Установите общедоступные зависимости шрифтов в обычном приложении.
Сохраните полный код точки входа, таблицу стилей и корневую оболочку HTML.
Перед сохранением проверки проверьте, сохраняются ли черновики.
Проверьте фильтрацию по статусу вместе с повторным открытием и восстановлением пустого состояния.
Проверьте связанный сценарий целиком
Отправьте пустую заметку, введите черновик, откройте другой запрос и вернитесь, чтобы убедиться, что заметка сохранилась. Отметьте запись как проверенную, отфильтруйте список по статусу «Проверен» и повторно откройте её. Проверьте восстановление пустого состояния и сохранность заметки. На узких экранах очередь располагается над подробностями, при этом ни одно действие не исчезает. Одновременно с этими изменениями состояния проверяются загрузка шрифтов, ошибки JavaScript и горизонтальная прокрутка.
Все записи, черновики, фильтры, проверки и восстановление состояния.
javascript
import '@fontsource/cabin/latin-600.css';
import '@fontsource/lato/latin-400.css';
import '@fontsource/lato/latin-700.css';
import './horizon.css';
const records=[{id:'REQ-104',title:'Review the workshop outline',owner:'Design team',priority:'Normal',detail:'Compare the proposed agenda with the decision the team needs to make. Capture one question that should be resolved before the workshop.'},{id:'REQ-105',title:'Check the shared resource list',owner:'Content team',priority:'High',detail:'Review the resource titles for clear action language and confirm that each summary explains when the resource is useful.'},{id:'REQ-106',title:'Prepare the research readout',owner:'Research team',priority:'Normal',detail:'Group the observations by theme. Keep direct observations separate from the team’s interpretation and include the questions still open.'}].map(x=>({...x,status:'Open',note:''}));let selected=records[0].id;
document.querySelector('#root').innerHTML=`<main><header><p class="eyebrow">OpenDesign · Workflow study</p><h1>Team review workspace</h1><p>Review three original practice requests. Update a local record while keeping the queue and details in context.</p></header><div class="toolbar"><label>Status <select id="filter"><option>All</option><option>Open</option><option>Reviewed</option></select></label><p id="queue-count" role="status"></p></div><div class="workspace"><nav aria-label="Practice request queue"><div id="queue"></div><p id="empty" hidden>No requests match this status.</p><button id="clear" hidden>Show all requests</button></nav><section id="detail" aria-labelledby="record-title"></section></div><p id="feedback" role="status"></p><footer><strong>Original application, documented foundations.</strong> Cabin headings, Lato body text, the published 2–40px spacing scale and 2/6/8px radius references inform this study. The colors and application behavior are original OpenDesign choices. This is not the ServiceNow platform or a connected Workspace.</footer></main>`;
function renderQueue(){let filter=document.querySelector('#filter').value,visible=records.filter(x=>filter==='All'||x.status===filter);if(!visible.some(x=>x.id===selected))selected=visible[0]?.id;const queue=document.querySelector('#queue');queue.replaceChildren(...visible.map(r=>{let b=document.createElement('button');b.className='queue-item';b.dataset.id=r.id;b.setAttribute('aria-current',String(r.id===selected));b.innerHTML=`<span class="record-id">${r.id}</span><strong>${r.title}</strong><span>${r.owner}</span><span class="status ${r.status.toLowerCase()}">${r.status}</span>`;b.onclick=()=>{selected=r.id;renderQueue();renderDetail();document.querySelector('#record-title')?.focus()};return b}));document.querySelector('#queue-count').textContent=`${visible.length} of ${records.length} requests`;document.querySelector('#empty').hidden=visible.length>0;document.querySelector('#clear').hidden=visible.length>0;}
function renderDetail(){const r=records.find(x=>x.id===selected),panel=document.querySelector('#detail');if(!r){panel.innerHTML='<h2 id="record-title">Choose another status</h2><p>All local requests are still available through the status filter.</p>';return}panel.innerHTML=`<p class="eyebrow">${r.id} · ${r.owner}</p><h2 id="record-title" tabindex="-1">${r.title}</h2><p>${r.detail}</p><dl><div><dt>Priority</dt><dd>${r.priority}</dd></div><div><dt>Status</dt><dd>${r.status}</dd></div></dl><form id="review"><label for="note">Review note</label><p class="hint" id="hint">Write one useful observation. This note remains in the page.</p><textarea id="note" rows="4" aria-describedby="hint error"></textarea><p id="error" class="error" hidden>Enter a review note before marking this request reviewed.</p><div class="actions"><button type="submit" class="primary">${r.status==='Open'?'Mark reviewed':'Update review'}</button><button type="button" id="reopen" ${r.status==='Open'?'hidden':''}>Reopen request</button></div></form>`;const note=panel.querySelector('#note');note.value=r.draft??r.note;note.oninput=()=>{r.draft=note.value;document.querySelector('#error').hidden=true;note.removeAttribute('aria-invalid');document.querySelector('#feedback').textContent=''};panel.querySelector('#review').onsubmit=e=>{e.preventDefault();if(!note.value.trim()){document.querySelector('#error').hidden=false;note.setAttribute('aria-invalid','true');note.focus();return}r.note=note.value.trim();r.draft=r.note;r.status='Reviewed';renderQueue();renderDetail();document.querySelector('#feedback').textContent=r.id+' reviewed locally. No record was sent to ServiceNow.';document.querySelector('#record-title')?.focus();};panel.querySelector('#reopen').onclick=()=>{r.status='Open';renderQueue();renderDetail();document.querySelector('#feedback').textContent=r.id+' reopened. The saved review note is retained.';document.querySelector('#record-title')?.focus();};}
document.querySelector('#filter').onchange=()=>{renderQueue();renderDetail();document.querySelector('#feedback').textContent=''};document.querySelector('#clear').onclick=()=>{document.querySelector('#filter').value='All';renderQueue();renderDetail();document.querySelector('#filter').focus()};renderQueue();renderDetail();
Это запускает только исходное исследование. Для нативной реализации в ServiceNow требуется соответствующая среда разработки платформы.
sh
npm create vite@latest horizon-study -- --template vanilla
cd horizon-study
npm install
npm install @fontsource/[email protected] @fontsource/[email protected]
# Save index.html at root; main.js and horizon.css in src.
npm run dev
Запрос для вашего проекта
Промпт для AI-агента
Создайте полноценное исходное исследование проверки запросов, используя проверенные значения типографики, интервалов и скруглений Horizon Workspace. Для исходных цветов используйте префикс app. Сохраняйте черновики для каждой записи, проверяйте данные перед проверкой, пересчитывайте отфильтрованный выбор после изменения статуса, сохраняйте заметки при повторном открытии и предусмотрите восстановление после пустого результата. Не заявляйте о подключении к работающему экземпляру ServiceNow.
05
Источники и область применения дизайн-системы ServiceNow Horizon
Самостоятельный учебный пример OpenDesign HTML/CSS, созданный с опорой на основы Horizon Workspace. В нём используются документированные значения типографики Cabin/Lato и интервалов/скруглений, а также оригинальные цвета и логика рабочего процесса. Это не экземпляр ServiceNow и не среда выполнения Workspace.