Software empresarial · Novo recurso

Sistema de design Semi Design.

Crie uma configuração sequencial do espaço de trabalho com os componentes Steps básicos recomendados pelo Semi, Input e Switch controlados, tokens reais do tema e uma escolha explícita entre os pacotes React 18 e React 19.

Guia OpenDesign8 capítulos38 entradas de referênciaGuia de aplicação original
01

Prévia da interface do sistema de design Semi Design

Valide um nome, escolha uma preferência para o resumo, revisite etapas anteriores e inspecione a configuração local final.

Assistente de configuração do espaço de trabalhoAbrir exemplo completo
Interpretação offline HTML das escalas do tema Semi e do comportamento de Steps/Input/Switch. O exemplo nativo de React é independente. · Referência de implementação
02

Referência de design do sistema de design Semi Design

Documentação oficial do Semi e captura do SCSS do tema padrão. Os nomes $ são constantes Sass avaliadas em tempo de compilação; os nomes --semi-* são variáveis CSS de tempo de execução. Os dados do fluxo de trabalho da aplicação são originais.

Espaçamento e tamanhos dos controles

Fonte
Nome / RegraValor / ConfiguraçãoUso
$height-control-small / default / large24 / 32 / 40pxAlturas de controle publicadas.
$spacing-super-tight2pxEspaçamento mais reduzido.
$spacing-extra-tight4pxEspaçamento muito reduzido.
$spacing-tight8pxEspaçamento reduzido.
$spacing-base-tight12pxEspaçamento compacto entre grupos.
$spacing-base16pxEspaçamento padrão.
$spacing-base-loose20pxAgrupamento mais espaçado.
$spacing-loose24pxEspaçamento entre seções.
$spacing-extra-loose32pxSeparação ampla.
$spacing-super-loose40pxMaior espaçamento nomeado deste conjunto.

Combinações tipográficas

Fonte
Nome / RegraValor / ConfiguraçãoUso
font-size-small mixin12 / 16pxTamanho de variables.scss; altura da linha do mixin.
font-size-regular mixin14 / 20pxTexto do corpo.
font-size-header-6 mixin16 / 22pxTítulo pequeno.
font-size-header-4 mixin20 / 28pxTítulo da seção.
font-size-header-3 mixin24 / 32pxOpção de título da página.
font-size-header-1 mixin32 / 44pxMaior título nomeado.

Mapeamentos de funções do tema

Fonte
Nome / RegraValor / ConfiguraçãoUso
--semi-color-primaryrgba(var(--semi-blue-5),1)A paleta clara resulta em rgb(0,100,250).
--semi-color-primary-hoverrgba(var(--semi-blue-6),1)A paleta clara resulta em rgb(0,98,214).
--semi-color-text-0rgba(var(--semi-grey-9),1)O texto principal no tema claro resulta em rgb(28,31,35).
--semi-color-text-2Grey 9 at .62 opacity in light modeTexto secundário; no tema escuro, a opacidade é diferente.
--semi-color-fill-0Grey 8 at .05 opacity in light modeO preenchimento sutil se adapta à superfície.
--semi-border-radius-small3pxControles comuns.
--semi-border-radius-medium6pxMenus e superfícies semelhantes.
--semi-border-radius-large12pxFunção de contêiner grande.
--semi-border-radius-full9999pxEstilo em formato de pílula.

Contrato de Steps

Fonte
Nome / RegraValor / ConfiguraçãoUso
type="basic"Recommended simple step barO estilo padrão anterior está obsoleto na documentação.
currentZero-based numberComeça em 0.
statuswait / process / finish / error / warningStatus da etapa atual.
type="nav"Non-interactive navigation appearanceNão é um atalho para um assistente clicável.
onChange(index)Index includes initial offsetA aplicação decide se a navegação é permitida.

Input e Switch

Fonte
Nome / RegraValor / ConfiguraçãoUso
Input onChange(value,event)O primeiro argumento é o novo valor.
Input validateStatusdefault / error / warningApenas altera o estilo visual; não valida dados de negócio.
Input compositionBoolean, false by defaultQuando ativado, adia onChange até a confirmação da composição do IME.
Input aria-describedbyDescription IDAssocie os textos de ajuda e de erro.

Variantes de switch e botão

Fonte
Nome / RegraValor / ConfiguraçãoUso
Switch checkedControlled BooleanMantenha a preferência no estado do componente pai.
Switch onChange(checked,event)Use o valor booleano diretamente.
Switch aria-labelMeaningful state labelDescreva a preferência, não o controle visual.
Switch size="small"No checkedText / uncheckedText treatmentMantenha os rótulos longos fora do switch.
03

Guia completo do sistema de design Semi Design

Um guia prático para escolher, aplicar e avaliar este sistema em uma interface real.

DESIGN-semi-design.md

Orientações completas, um ponto de partida para a implementação e links para o código-fonte.

Baixar o guia

Sistema de design Semi Design: escolha o pacote para a versão principal real React

O sufixo altera a integração

O Quick Start atual do Semi separa o pacote React 19 daquele usado nas versões React anteriores. Este exemplo escolhe explicitamente React 18 e @douyinfe/semi-ui. Para usar React 19, é necessário adotar as importações documentadas de @douyinfe/semi-ui-19 e escolher a dependência correspondente.

Com base neste guia de OpenDesign

Os empacotadores compatíveis carregam os CSS relacionados a partir do componente JavaScript. Alterações em tempo de compilação, como prefixo personalizado, compilação de tema ou camadas CSS, exigem considerações específicas sobre as ferramentas. Não transforme um exemplo básico de importação em uma afirmação de que toda personalização de tema funciona sem configuração.

Consulte a especificação de apoio

Sistema de design Semi Design: escalas Sass nomeadas tornam a densidade concreta

Use as alturas de controle publicadas: 24, 32 e 40px

As três constantes de altura de controle do Semi são 24, 32 e 40px. Os nomes de espaçamento abrangem de 2 a 40px, com uma progressão não uniforme. Um campo padrão no assistente pode usar um espaçamento de 12px para a ajuda e uma separação de 24px até a próxima seção, sem introduzir uma nova escala de espaçamento.

Esses valores são constantes Sass, não variáveis de tempo de execução automáticas. O exemplo usa as dimensões resultantes na página CSS original. Essa diferença importa quando o desenvolvedor quer aplicar um tema ao layout em tempo de execução, em vez de recompilar uma folha de estilos.

Consulte a especificação de apoio

Sistema de design Semi Design: use pares reais de tamanho e altura de linha

O texto do corpo e os títulos têm ritmos diferentes

O mixin regular combina texto de 14px com altura de linha de 20px; o mixin pequeno combina 12px com 16px. O título 3 usa 24/32 e o título 1, 32/44. Um título curto para o assistente pode usar o primeiro par, reservando o segundo para uma hierarquia de página mais marcante.

A família de fontes de origem começa com Inter, seguida de fontes alternativas da plataforma e para caracteres CJK. A prévia offline usa uma pilha de fontes do sistema disponível e não afirma ter baixado uma fonte específica. Mantenha os nomes das etapas curtos para que continuem claros quando a barra de etapas quebrar em uma janela estreita.

Consulte a especificação de apoio

Sistema de design Semi Design: funções do tema e canais da paleta são coisas distintas

Use funções resolvidas na aplicação CSS

A função de cor primária envolve uma variável de canal da paleta com rgba. Usar --semi-color-primary é adequado para uma propriedade de cor comum; uma lista bruta de canais como --semi-blue-5, por si só, não é uma cor CSS completa. As paletas clara e escura alteram esses valores de canal.

As funções de texto também usam opacidade. O texto secundário não é apenas um código hexadecimal qualquer mais claro, e o texto desativado não deve ser reutilizado para informações de ajuda importantes. O assistente mantém neutra a mensagem de conclusão porque preparar a configuração não cria uma conta ativa.

Consulte a especificação de apoio

Sistema de design Semi Design: Basic Steps comunica o progresso, não a permissão para ignorar a validação

A aplicação controla as regras de transição

O Semi recomenda type="basic" para uma barra de etapas simples. current começa em zero, e a etapa atual pode ter um status compatível, como process ou error. A aparência padrão antiga está marcada como obsoleta na documentação.

O exemplo avança intencionalmente pelos controles Continuar e Anterior. Ele não associa cada clique em uma etapa a setCurrent, o que permitiria ao usuário chegar à Revisão sem informar um nome. A aparência nav, documentada separadamente, não é interativa e não deve ser confundida com a navegação do assistente.

  1. Valide o nome antes de sair da primeira etapa.
  2. Mantenha o valor booleano escolhido para o resumo semanal ao voltar.
  3. Mostre todas as configurações na etapa Revisão.
  4. Prepare a configuração local sem afirmar que uma conta ou assinatura já existe.

Consulte a especificação de apoio

Sistema de design Semi Design: a validação visual não valida o valor

Use corretamente o callback que recebe o valor primeiro

O Input do Semi chama onChange com o valor antes do evento. Portanto, o exemplo pode passar setName diretamente. validateStatus altera apenas a aparência; a verificação de nome vazio é uma lógica da aplicação e precisa de uma explicação visível.

Para textos que acionam consultas em tempo real, a composição pode adiar os callbacks até que a composição do IME seja confirmada. O campo de nome do workspace não faz consultas em tempo real, então o exemplo omite esse comportamento opcional, em vez de tratá-lo como uma exigência universal.

Consulte a especificação de apoio

Sistema de design Semi Design: uma preferência continua clara junto ao switch

Mantenha o estado no componente pai

O Switch usa checked e um callback onChange cujo primeiro argumento é booleano. O rótulo deve explicar a preferência, por exemplo, Resumo semanal, enquanto o texto ao redor explica o significado da configuração. As opções longas de ativado e desativado devem ficar fora do controle pequeno, que não oferece suporte a esse tipo de texto interno.

  • Use um nome acessível e claro que identifique a preferência.
  • Mantenha o valor da preferência ao navegar entre as etapas do assistente.
  • Exiba o valor final em texto simples na página de revisão.

Consulte a especificação de apoio

Sistema de design Semi Design: type e theme do botão respondem a perguntas diferentes

Função semântica versus aparência visual

No Button do Semi, type define uma função, como primary ou danger. theme define a aparência: light, solid, borderless ou outline. O exemplo usa uma ação Continuar com aparência solid e função primary, e uma ação Anterior mais discreta, em vez de usar danger indevidamente para dar mais destaque ao botão.

A demonstração offline move o foco para o título da nova seção quando a etapa muda e de volta para o campo inválido quando a validação falha. O layout para dispositivos móveis e a sequência de navegação por teclado são testados independentemente do exemplo nativo React, cuja implementação foi conferida na fonte.

Consulte a especificação de apoio

Exemplos de componentes do sistema de design Semi Design

Exemplo interativo completo e independente

Salve o documento completo como index.html e abra-o em um navegador. Interpretação offline de HTML das escalas de tema do Semi e do comportamento de Steps/Input/Switch. O exemplo nativo React é separado.

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>

Referência de código

  • Continuar valida o nome do workspace antes de avançar. Este documento interpreta as etapas; a entrada React separada especifica a diferença entre os pacotes React 18 e 19.

Assistente de configuração validada em três etapas

Basic Steps acompanha o progresso atual; Input e Switch preservam os valores entre páginas. Continuar valida o nome, e a ação final apenas prepara a configuração local.

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 />);

Referência de código

  • O exemplo React 18 instala intencionalmente @douyinfe/semi-ui; React 19 exige o pacote -19 documentado no Quick Start.
  • Nos empacotadores compatíveis, o componente JavaScript do Semi importa os CSS relacionados; a configuração padrão não exige uma etapa inventada para incluir uma folha de estilos global.
  • A demonstração incorporada de HTML define explicitamente o movimento do foco; reproduza esse comportamento nos componentes nativos do produto.
04

Configuração do agente do sistema de design Semi Design

Ponto de partida para implementação

Escolha uma das opções de dependência. O exemplo usa React 18. O Quick Start atual informa que o componente JavaScript importa os CSS relacionados no Vite/Webpack/Rspack; a compilação de temas exige ferramentas adicionais.

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

Um prompt para seu projeto

Prompt para agente de IA
Use Steps básico do Semi com Input e Switch controlados. Combine o pacote React com a versão principal instalada do React. Valide antes de avançar, preserve os dados ao voltar e apresente a configuração local final sem fingir que uma conta foi criada.
05

Fontes e escopo do sistema de design Semi Design

Referência independente de OpenDesign. Exemplo original de workspace; nenhuma conta ou assinatura de notificações é criada.