Корпоративное ПО · Новый ресурс

Semi Design — дизайн-система.

Создайте пошаговую настройку рабочей среды с базовыми элементами Steps, рекомендованными Semi, управляемыми компонентами Input и Switch, реальными токенами темы и явным выбором пакета React 18 или React 19.

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

Предпросмотр интерфейса дизайн-системы Semi Design

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

Мастер настройки рабочего пространстваОткрыть полный пример
Офлайн-интерпретация HTML шкал темы Semi и поведения Steps/Input/Switch. Отдельный пример с нативным React. · Справочник по реализации
02

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

Официальная документация Semi и снимок SCSS темы по умолчанию. Имена $ — константы Sass, используемые на этапе компиляции; имена --semi-* — переменные CSS времени выполнения. Данные рабочего процесса приложения созданы специально для примера.

Отступы и размеры элементов управления

Источник
Название / правилоЗначение / конфигурацияПрименение
$height-control-small / default / large24 / 32 / 40pxОпубликованные высоты элементов управления.
$spacing-super-tight2pxМинимальный отступ.
$spacing-extra-tight4pxОчень маленький отступ.
$spacing-tight8pxМаленький отступ.
$spacing-base-tight12pxКомпактный отступ между группами.
$spacing-base16pxОтступ по умолчанию.
$spacing-base-loose20pxБолее свободная группировка.
$spacing-loose24pxРасстояние между разделами.
$spacing-extra-loose32pxБольшой промежуток.
$spacing-super-loose40pxСамый большой именованный отступ в этом наборе.

Сочетания параметров типографики

Источник
Название / правилоЗначение / конфигурацияПрименение
font-size-small mixin12 / 16pxРазмер взят из variables.scss, высота строки — из миксина.
font-size-regular mixin14 / 20pxОсновной текст.
font-size-header-6 mixin16 / 22pxНебольшой заголовок.
font-size-header-4 mixin20 / 28pxЗаголовок раздела.
font-size-header-3 mixin24 / 32pxВариант заголовка страницы.
font-size-header-1 mixin32 / 44pxСамый крупный именованный заголовок.

Соответствия ролей темы

Источник
Название / правилоЗначение / конфигурацияПрименение
--semi-color-primaryrgba(var(--semi-blue-5),1)В светлой палитре значение — rgb(0,100,250).
--semi-color-primary-hoverrgba(var(--semi-blue-6),1)В светлой палитре значение — rgb(0,98,214).
--semi-color-text-0rgba(var(--semi-grey-9),1)Светлый основной текст имеет значение rgb(28,31,35).
--semi-color-text-2Grey 9 at .62 opacity in light modeВторичный текст; в тёмной теме используется другая прозрачность.
--semi-color-fill-0Grey 8 at .05 opacity in light modeНенавязчивая заливка адаптируется к фону.
--semi-border-radius-small3pxРаспространённые элементы управления.
--semi-border-radius-medium6pxМеню и аналогичные поверхности.
--semi-border-radius-large12pxРоль для крупного контейнера.
--semi-border-radius-full9999pxОформление в виде капсулы.

Контракт Steps

Источник
Название / правилоЗначение / конфигурацияПрименение
type="basic"Recommended simple step barВ документации старый стиль по умолчанию помечен как устаревший.
currentZero-based numberНачинается с 0.
statuswait / process / finish / error / warningСтатус текущего шага.
type="nav"Non-interactive navigation appearanceНе заменяет кликабельный мастер.
onChange(index)Index includes initial offsetПриложение определяет, разрешена ли навигация.

Input и Switch

Источник
Название / правилоЗначение / конфигурацияПрименение
Input onChange(value,event)Первый аргумент — новое значение.
Input validateStatusdefault / error / warningТолько визуальное оформление; не проверяет бизнес-данные.
Input compositionBoolean, false by defaultЕсли параметр включён, откладывайте onChange до подтверждения ввода через IME.
Input aria-describedbyDescription IDСвяжите текст справки и ошибки с полем.

Варианты Switch и Button

Источник
Название / правилоЗначение / конфигурацияПрименение
Switch checkedControlled BooleanХраните настройку в состоянии родительского компонента.
Switch onChange(checked,event)Используйте логическое значение напрямую.
Switch aria-labelMeaningful state labelОпишите настройку, а не визуальное положение переключателя.
Switch size="small"No checkedText / uncheckedText treatmentРазмещайте длинные подписи вне переключателя.
03

Полное руководство по дизайн-системе Semi Design

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

DESIGN-semi-design.md

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

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

Дизайн-система Semi Design: выберите пакет для используемого мажорного выпуска React

Суффикс меняет способ интеграции

В актуальном кратком руководстве Semi пакет React 19 отделён от пакета, который используется в более ранних версиях React. В этом примере явно выбраны React 18 и @douyinfe/semi-ui. Для перехода на React 19 необходимо выбрать зависимость и импорты @douyinfe/semi-ui-19, как указано в документации.

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

Поддерживаемые сборщики загружают связанные CSS из компонентов JavaScript. Для изменений на этапе компиляции — например, пользовательского префикса, компиляции темы или слоёв CSS — нужны отдельные инструменты и настройки. Не следует на основании простого примера импорта утверждать, что любая настройка темы работает без конфигурации.

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

Дизайн-система Semi Design: именованные шкалы Sass задают конкретную плотность

Используйте опубликованные высоты элементов управления: 24, 32 и 40px

Три константы высоты элементов управления Semi — 24, 32 и 40px. Именованные отступы охватывают диапазон от 2 до 40px с неравномерным шагом. Для стандартного поля в мастере можно задать отступ 12px до пояснения и 24px до следующего раздела, не вводя новую шкалу отступов.

Это константы Sass, а не автоматически доступные переменные времени выполнения. В примере используются соответствующие им размеры на странице CSS. Это важно учитывать, если разработчик хочет менять оформление макета во время выполнения, а не пересобирать таблицу стилей.

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

Дизайн-система Semi Design: используйте реальные сочетания размера и высоты строки

Основной текст и заголовки имеют разный ритм

Обычный миксин сочетает шрифт размером 14px с высотой строки 20px, а малый — размер 12px с высотой строки 16px. Заголовок уровня 3 — 24/32, уровня 1 — 32/44. Для краткого названия мастера подойдёт первый вариант, а второй лучше оставить для более выраженной иерархии страницы.

В исходном списке шрифтов первым указан Inter, за ним следуют системные шрифты и шрифты для китайского, японского и корейского письма. В офлайн-предпросмотре используется доступный системный набор шрифтов — он не утверждает, что загружен конкретный шрифт. Формулируйте названия шагов кратко, чтобы они сохраняли смысл при переносе панели шагов на узком экране.

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

Дизайн-система Semi Design: роли темы и каналы палитры — разные понятия

Используйте готовые значения ролей в приложении CSS

Основная роль использует переменную канала палитры, обёрнутую в rgba. Переменная --semi-color-primary подходит для обычного свойства цвета; необработанный список каналов --semi-blue-5 сам по себе не является полным цветом CSS. В светлой и тёмной палитрах значения этих каналов различаются.

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

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

Дизайн-система Semi Design: Basic Steps показывает прогресс, а не даёт разрешение пропустить проверку

Правила переходов определяет приложение

Для простой панели шагов Semi рекомендует type="basic". Отсчёт current начинается с нуля, а текущему шагу можно назначить статус process, error или другой поддерживаемый статус. Более старое оформление по умолчанию в документации помечено как устаревшее.

В примере переход между шагами выполняется намеренно с помощью кнопок «Продолжить» и «Назад». Переход по нажатию на каждый шаг не вызывает setCurrent: иначе пользователь смог бы перейти к проверке с пустым именем. Описанное отдельно оформление nav не является интерактивным, и его не следует принимать за навигацию мастера.

  1. Проверьте имя, прежде чем переходить с первого шага.
  2. Сохраняйте выбранное значение настройки еженедельной рассылки при возврате к предыдущим шагам.
  3. Покажите все параметры на экране проверки.
  4. Подготовьте локальную конфигурацию, не утверждая, что учётная запись или подписка уже созданы.

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

Дизайн-система Semi Design: визуальная проверка не подтверждает корректность значения

Правильно используйте колбэк, который первым принимает значение

Компонент Input из Semi передаёт в onChange сначала значение, а затем событие. Поэтому в примере можно напрямую передать setName. Параметр validateStatus меняет только внешний вид; проверка имени на пустое значение — логика приложения, и её результат нужно объяснить пользователю.

Для текста, запускающего динамические запросы, колбэки можно отложить до подтверждения композиции через IME. Поле имени рабочего пространства не выполняет динамические запросы, поэтому в примере не используется это необязательное поведение и не создаётся впечатление, что оно требуется всегда.

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

Дизайн-система Semi Design: назначение настройки понятно и без подписи рядом с переключателем

Храните состояние в родительском компоненте

Switch использует checked и колбэк onChange, первым аргументом которого является логическое значение. Подпись должна объяснять настройку, например «Еженедельная сводка», а окружающий текст — смысл параметра. Длинные подписи для включённого и выключенного состояний размещайте вне небольшого элемента управления: компактные переключатели не поддерживают такие внутренние подписи.

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

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

Дизайн-система Semi Design: тип кнопки и её тема отвечают на разные вопросы

Семантическая роль и визуальное оформление

В Button из Semi параметр type задаёт роль, например primary или danger. Параметр theme задаёт визуальное оформление: light, solid, borderless или outline. В примере действие «Продолжить» оформлено как solid primary, а кнопка «Назад» — сдержаннее; danger не используется просто для того, чтобы сделать кнопку заметнее.

В офлайн-примере при смене шага фокус перемещается на заголовок нового раздела, а при ошибке проверки возвращается к полю с неверным значением. Мобильную версию и последовательность перехода с клавиатуры проверяют отдельно от примера с нативным React, сверенного с исходным кодом.

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

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

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

Сохраните документ целиком как index.html и откройте его в браузере. Офлайн-интерпретация HTML шкал темы Semi и поведения Steps/Input/Switch. Отдельный пример с нативным React.

html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Semi workspace setup interpretation</title><style>
*{box-sizing:border-box}body{margin:0;background:#f5f6f8;color:#1c1f23;font:14px/20px Inter,system-ui,sans-serif}button,input{font:inherit}button{cursor:pointer;min-height:32px;border:0;border-radius:3px;padding:6px 16px;background:rgba(46,50,56,.05);color:inherit}button.primary{background:#0064fa;color:white}button.primary:hover{background:#0062d6}button:focus-visible,input:focus-visible{outline:2px solid #0064fa;outline-offset:3px}header{padding:20px 32px;border-bottom:1px solid rgba(28,31,35,.08);background:white;display:flex;justify-content:space-between;gap:16px}header strong{font-size:16px}header span,.muted{color:#63656a}main{max-width:950px;margin:32px auto;padding:0 24px}h1{font-size:24px;line-height:32px;font-weight:600;margin:0 0 8px}h2{font-size:20px;line-height:28px;font-weight:600;margin:0 0 12px}p{margin:0 0 16px}.card{background:white;border:1px solid rgba(28,31,35,.08);border-radius:12px;overflow:hidden;margin-top:24px}.steps{padding:24px;display:flex;list-style:none;margin:0;border-bottom:1px solid rgba(28,31,35,.08);gap:12px}.steps li{flex:1;display:flex;align-items:center;gap:8px;color:#63656a;font-size:12px}.steps b{height:24px;width:24px;border-radius:50%;display:grid;place-items:center;background:#eee;flex-shrink:0}.steps [aria-current]{color:#0064fa}.steps [aria-current] b{background:#0064fa;color:white}.steps .done b{background:#eaf5ff;color:#0064fa}.workspace{display:grid;grid-template-columns:1fr 240px;min-height:300px}.panel{padding:32px}.illustration{background:#eaf5ff;display:flex;flex-direction:column;justify-content:center;padding:24px;gap:12px}.mini{background:white;box-shadow:0 6px 20px #0064fa12;border-radius:6px;padding:16px;transform:rotate(-3deg)}.mini i{display:block;height:8px;background:#eaf5ff;width:80%;margin:8px 0;border-radius:3px}.mini i:first-child{background:#0064fa;width:36%}.mini i:nth-child(3){width:55%}.mini:last-child{transform:rotate(4deg);margin-left:20px}.mini span{font-size:12px;color:#63656a}.form-label{display:block;font-weight:600;margin:20px 0 8px}input[type=text]{height:32px;background:rgba(46,50,56,.05);border:1px solid transparent;border-radius:3px;padding:5px 12px;width:100%}input[aria-invalid=true]{border-color:#d52515}.error{color:#b21b13;min-height:20px;font-size:12px;margin:8px 0}.preference{border:1px solid #eee;border-radius:6px;padding:16px;display:flex;align-items:center;justify-content:space-between;gap:20px}.preference p{margin:4px 0 0;font-size:12px}.toggle{appearance:none;width:40px;height:24px;border-radius:999px;background:#bbb;position:relative;cursor:pointer;flex-shrink:0}.toggle:checked{background:#0064fa}.toggle:before{content:'';position:absolute;left:3px;top:3px;background:white;border-radius:50%;width:18px;height:18px}.toggle:checked:before{left:19px}footer{display:flex;justify-content:space-between;padding:20px 32px;border-top:1px solid rgba(28,31,35,.08)}dl{margin:20px 0}dt{color:#63656a;font-size:12px}dd{margin:4px 0 20px;font-size:16px;font-weight:600;overflow-wrap:anywhere}#result{margin-top:16px;border-radius:6px;background:#eaf5ff;padding:16px}#result:empty{display:none}.boundary{font-size:12px;margin-top:20px;color:#63656a}h2:focus{outline:none}@media(max-width:600px){header{padding:16px}header span{display:none}main{margin:24px auto;padding:0 16px}.workspace{grid-template-columns:1fr}.illustration{display:none}.steps{padding:16px;gap:8px}.steps li{flex-direction:column;align-items:flex-start;gap:4px}.panel{padding:24px 20px}footer{padding:16px 20px;gap:12px}footer button{padding:6px 12px}}
</style><header><strong>◒ Workspace</strong><span>Configuration studio</span></header><main><h1>Make room for your team</h1><p class="muted">Three steps to prepare a workspace configuration.</p><div class="card"><ol class="steps" aria-label="Setup progress"><li><b>1</b>Name workspace</li><li><b>2</b>Choose updates</li><li><b>3</b>Review settings</li></ol><div class="workspace"><section class="panel" id="panel"></section><aside class="illustration" aria-hidden="true"><div class="mini"><i></i><i></i><i></i><span>A place for shared ideas</span></div><div class="mini"><i></i><i></i><i></i><span>Updates on your terms</span></div></aside></div><footer><button id="previous">Previous</button><button class="primary" id="next">Continue</button></footer></div><div id="result" role="status"></div><p class="boundary">Independent HTML interpretation of Semi’s theme and components. This example stores a draft only in memory; it does not create an account.</p></main><script>
let step=0,name='',digest=true;const panel=document.querySelector('#panel'),next=document.querySelector('#next'),previous=document.querySelector('#previous'),result=document.querySelector('#result');function render(focus=false){document.querySelectorAll('.steps li').forEach((el,i)=>{el.className=i<step?'done':'';el.removeAttribute('aria-current');if(i===step)el.setAttribute('aria-current','step')});previous.style.visibility=step?'visible':'hidden';next.textContent=step===2?'Prepare configuration':'Continue';if(step===0){panel.innerHTML='<h2 tabindex="-1">Name your workspace</h2><p class="muted">Choose a name your team will recognize.</p><label class="form-label" for="name">Workspace name</label><input id="name" type="text" placeholder="e.g. Studio North" autocomplete="organization" aria-describedby="help error"><p id="error" class="error" role="alert"></p><p id="help" class="muted">You can revisit this step before preparing the configuration.</p>';let input=document.querySelector('#name');input.value=name;input.oninput=()=>{name=input.value;input.removeAttribute('aria-invalid');document.querySelector('#error').textContent='';result.textContent=''};input.onkeydown=e=>{if(e.key==='Enter')next.click()}}else if(step===1){panel.innerHTML='<h2 tabindex="-1">Choose your updates</h2><p class="muted">Keep the weekly digest in your configuration, or switch it off.</p><label class="preference"><span><strong>Weekly digest</strong><p class="muted">A weekly summary of workspace activity.</p></span><input class="toggle" type="checkbox" role="switch" aria-label="Weekly digest" id="digest"></label>';let input=document.querySelector('#digest');input.checked=digest;input.onchange=()=>{digest=input.checked;result.textContent=''}}else{panel.innerHTML='<h2 tabindex="-1">Review settings</h2><p class="muted">Check the draft before preparing it.</p><dl><dt>Workspace name</dt><dd id="review-name"></dd><dt>Weekly digest</dt><dd id="review-digest"></dd></dl>';document.querySelector('#review-name').textContent=name.trim();document.querySelector('#review-digest').textContent=digest?'Enabled':'Disabled'}if(focus)panel.querySelector('h2').focus()}
next.onclick=()=>{if(step===0&&!name.trim()){document.querySelector('#error').textContent='Enter a workspace name.';let input=document.querySelector('#name');input.setAttribute('aria-invalid','true');input.focus();return}if(step<2){step++;render(true)}else result.textContent='Configuration prepared locally: '+name.trim()+' · Weekly digest '+(digest?'enabled':'disabled')+'. No account created.'};previous.onclick=()=>{step=Math.max(0,step-1);result.textContent='';render(true)};render();
</script></html>

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

  • Перед переходом к следующему шагу кнопка «Продолжить» проверяет имя рабочего пространства. В этом документе интерпретируется поведение шагов; в отдельной записи React указана граница между пакетами React 18 и 19.

Мастер настройки с проверкой и тремя шагами

Basic Steps показывает текущий шаг; Input и Switch сохраняют значения при переходе между страницами. Кнопка «Продолжить» проверяет имя, а последнее действие только подготавливает локальную конфигурацию.

jsx
// React 18 example. React 19 uses @douyinfe/semi-ui-19 instead.
// npm install react@18 react-dom@18 @douyinfe/semi-ui
import React,{useState} from 'react';
import {createRoot} from 'react-dom/client';
import {Steps,Input,Switch,Button} from '@douyinfe/semi-ui';
function WorkspaceSetup(){
 const [current,setCurrent]=useState(0),[name,setName]=useState('');
 const [digest,setDigest]=useState(true),[error,setError]=useState('');
 const [prepared,setPrepared]=useState(false);
 function next(){
  if(current===0&&!name.trim()){setError('Enter a workspace name.');return;}
  setError('');setCurrent(n=>Math.min(2,n+1));
 }
 return <main style={{maxWidth:760,margin:'auto',padding:24,color:'var(--semi-color-text-0)'}}>
  <h1>Workspace setup</h1>
  <Steps type="basic" current={current} status={error?'error':'process'}>
   <Steps.Step title="Name workspace"/>
   <Steps.Step title="Choose updates"/>
   <Steps.Step title="Review settings"/>
  </Steps>
  <section style={{padding:'24px 0'}}>
   {current===0&&<><label htmlFor="workspace-name">Workspace name</label>
    <Input id="workspace-name" value={name} onChange={setName}
      validateStatus={error?'error':'default'} aria-invalid={!!error} aria-describedby="error" />
    <p id="error" role="alert">{error}</p></>}
   {current===1&&<><h2>Weekly digest</h2><p>Include a weekly activity summary in the local configuration.</p>
    <Switch checked={digest} onChange={setDigest} aria-label="Weekly digest"/></>}
   {current===2&&<><h2>Review your draft</h2><dl><dt>Workspace</dt><dd>{name}</dd>
    <dt>Weekly digest</dt><dd>{digest?'Enabled':'Disabled'}</dd></dl>
    <p>No workspace or notification subscription is created.</p></>}
  </section>
  {current>0&&<Button onClick={()=>{setCurrent(n=>n-1);setPrepared(false);}}>Previous</Button>}
  {current<2 ? <Button theme="solid" type="primary" onClick={next}>Continue</Button> :
    <Button theme="solid" type="primary" onClick={()=>setPrepared(true)}>Prepare configuration</Button>}
  <p role="status">{prepared?'Configuration prepared locally. No account created.':''}</p>
 </main>;
}
createRoot(document.getElementById('root')).render(<WorkspaceSetup />);

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

  • В примере для React 18 намеренно устанавливается @douyinfe/semi-ui; для React 19 нужен пакет -19, указанный в кратком руководстве.
  • Компоненты JavaScript загружают связанные с ними CSS в поддерживаемых сборщиках; стандартная настройка не требует выдуманного шага с подключением глобальной таблицы стилей.
  • Встроенный пример HTML явно задаёт перемещение фокуса; реализуйте аналогичное поведение при работе с нативными компонентами в продукте.
04

Настройка агента дизайн-системы Semi Design

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

Выберите одну ветку зависимостей. В примере используется React 18. В актуальном кратком руководстве сказано, что компоненты JavaScript загружают связанные с ними CSS в Vite/Webpack/Rspack; для компиляции темы нужны дополнительные инструменты.

bash
npm install react@18 react-dom@18 @douyinfe/semi-ui
# For a React 19 application instead:
# npm install react@19 react-dom@19 @douyinfe/semi-ui-19

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

Промпт для AI-агента
Используйте базовый Steps из Semi с управляемыми Input и Switch. Версия пакета React должна соответствовать установленному мажорному выпуску React. Проверяйте данные перед переходом, сохраняйте их при нажатии «Назад» и показывайте итоговую локальную конфигурацию, не изображая несуществующее создание учётной записи.
05

Источники и область применения дизайн-системы Semi Design

Независимый справочник OpenDesign. Оригинальный пример рабочего пространства; учетная запись не создается, подписка на уведомления не оформляется.