6 min

UI consistente em apps React com tokens de design e regras

Aprenda a gerar UI consistente em apps React usando tokens de design e regras de componente para que telas geradas por IA respeitem espaçamento, tipografia e comportamento de formulários.

UI consistente em apps React com tokens de design e regras

Por que telas React geradas costumam ficar inconsistentes

A inconsistência de UI geralmente aparece em pequenos detalhes que parecem estranhos conforme você navega. Uma página tem padding generoso, outra parece apertada. Headings pulam entre tamanhos, botões mudam de forma e cor, e o mesmo input se comporta de modo diferente dependendo da tela.

Na maior parte das vezes, o desvio vem de alguns elementos básicos:

  • Espaçamento: padding, gaps e ritmo das seções variam
  • Tipografia: tamanhos de fonte, pesos e alturas de linha não são estáveis
  • Componentes: botões, cards, bordas e sombras mudam ligeiramente
  • Formulários: timing de validação, posicionamento de erros e estados desabilitados diferem

Isso é comum quando telas são geradas a partir de prompts separados. Cada prompt é, efetivamente, um novo começo, então o modelo preenche decisões faltantes chutando. Mesmo “use um estilo moderno” ainda deixa centenas de escolhas pequenas: gaps de 8px vs 12px, texto corpo 14px vs 16px, quando mostrar erros, qual é a aparência de um botão primário.

Você pode limpar manualmente duas ou três páginas, mas não escala. Você acaba correndo atrás de correções pontuais de CSS, copiando estilos entre arquivos e refazendo formulários. As regras estão na sua cabeça, não no projeto.

Imagine gerar uma tela de login hoje e uma de perfil amanhã. Se uma mostra erros só no submit e a outra no blur, os usuários percebem. Se a altura do botão primário muda entre telas, o app parece costurado.

A consistência vira padrão quando cada tela segue o mesmo sistema compartilhado: design tokens (espaçamento, tipografia, cor) mais um pequeno conjunto de regras de componente e formulário.

Design tokens em linguagem simples

Design tokens são valores nomeados simples que você reutiliza pela UI. Em vez de pedir “padding confortável” em cada tela, você usa um token como space-4. Em vez de “levemente arredondado”, você usa radius-md. O nome permanece estável mesmo se você mudar o que ele representa depois.

Tokens são o conjunto de decisões que você quer que cada tela compartilhe. Eles eliminam gosto e chute — que é exatamente o que causa drift quando você gera ou constrói novas páginas.

Tokens típicos cobrem espaçamento, tipografia, cores, forma e uma pequena quantidade de elevação. O ganho é prático: um cabeçalho sempre usa o mesmo tamanho, um card sempre usa o mesmo padding, e um botão primário mantém a mesma cor e radius.

O que deve ser tokenizado vs flexível?

Tokenize as coisas que afetam a sensação geral do produto: escala de espaçamento, tamanhos de fonte e alturas de linha, cores principais (texto, fundo, primary, danger, borda) e um pequeno conjunto de raios de borda.

Mantenha escolhas dirigidas por conteúdo flexíveis, como comprimento do texto, qual ícone usar, ou se uma seção precisa de dois ou três cards.

Quando você gera telas (incluindo com ferramentas como Koder.ai), fornecer um pequeno conjunto de tokens desde o início reduz a quantidade de chute e torna o resultado visivelmente mais consistente.

Escolha um conjunto de tokens pequeno mas completo

Um conjunto de tokens é apenas um menu curto de valores permitidos. Menor é melhor porque deixa menos espaço para escolhas aleatórias, mas ainda precisa cobrir o básico que faz as telas parecerem fora do lugar.

Comece pelo espaçamento. Escolha uma escala e use-a em todo lugar para padding, gaps e layout. Um conjunto como 4, 8, 12, 16, 24, 32 cobre a maior parte da UI. Se um design pede 10px ou 18px, arredonde para o token mais próximo em vez de introduzir novos números.

Depois defina padrões tipográficos para que headings e texto corpo parem de derivar. Você não precisa de um sistema tipográfico enorme. Precisa de passos claros e repetíveis.

Um conjunto compacto que continua útil sem inchar:

  • Espaçamento: 4, 8, 12, 16, 24, 32
  • Tipo: um tamanho de body, dois tamanhos de heading, uma altura de linha para body e uma para headings
  • Cores: text-primary, text-muted, bg, surface, border, accent
  • Radius: dois valores (por exemplo 4 e 12)
  • Elevação: none, small, medium (no máximo três níveis)

Acessibilidade também faz parte do sistema. Defina um estilo de outline de foco (cor, espessura, offset) para que usuários de teclado obtenham estados de foco consistentes. Defina um tamanho mínimo de alvo por toque (como 44x44) para mobile. Limite cores de texto a um conjunto pequeno e confiável para manter contraste previsível.

Se botões às vezes parecem apertados, muitas vezes é porque uma tela usou padding 10 e outra usou 12. Com tokens, você pode dizer: “Botões usam paddingY=8, paddingX=16, radius=12, token de outline de foco, altura mínima 44.” Uma vez que esses números estão fixos, o gerador para de improvisar.

Regras de componente que mantêm cada tela alinhada

Tokens definem os números. Regras de componente definem os hábitos.

Escolha um pequeno conjunto de componentes core e trate-os como os únicos blocos de construção para telas. Mantenha-os simples e reutilizáveis: Button, Input, Select, Checkbox, Card. Você pode adicionar TextArea e Modal, mas eles devem seguir o mesmo sistema (labels, espaçamento, estados).

Em seguida, limite variantes e defina quando são permitidas. Por exemplo: Button tem primary, secondary e danger. Primary é para a ação principal da tela (normalmente uma). Secondary é para cancelar ou ações de baixa prioridade. Danger é só para ações destrutivas como deletar. Se a variante não puder ser justificada, use secondary por padrão.

Regras de espaçamento evitam drift sutil. Defina padrões dentro dos componentes: padding do Button, altura do Input, gap entre label e campo, o gap padrão entre campos empilhados. Adicione algumas regras de layout também: Cards têm padding interno fixo e espaçamento consistente entre header/body; Modals usam os mesmos passos de largura e alinhamento do footer.

Por fim, torne estados não-negociáveis porque é aí que UIs costumam começar a parecer aleatórias:

  • Loading: desabilite o controle, mostre um spinner, mantenha a largura estável
  • Disabled: contraste reduzido, mas não remova completamente hover/focus styles
  • Empty states: mensagem curta mais uma ação clara
  • Validation: erros aparecem sob os campos e não causam grandes shifts de layout

Quando você gera uma tela com muitos formulários como “Create project”, essas regras evitam tamanhos mistos de botão, posições de label que mudam, ou um “card especial” que só aparece em uma página.

Regras de comportamento de formulários: os detalhes que geralmente derivam

Ganhe créditos enquanto aprende
Compartilhe o que você constrói com Koder.ai e ganhe créditos por criar conteúdo útil.

Mesmo com visuais estáveis, muitas queixas do tipo “isso parece errado” vêm do comportamento dos formulários. Se cada tela trata labels, erros e foco de forma diferente, os usuários percebem inconsistência.

Escolha um padrão de formulário e use-o em todo lugar: label, marcador opcional/obrigatório, helper text, depois texto de erro. Mantenha a redação consistente também (por exemplo, labels em sentence case, helper text curto, e mensagens de erro que começam com um verbo).

As regras que previnem a maior parte do drift:

  • Labels sempre acima dos campos (não usar placeholders como rótulos)
  • Helper text sempre abaixo do campo, mesmo tamanho e cor, nunca usado para erros
  • Timing de validação: mostrar erros após blur ou submit, limpar ao digitar
  • Posicionamento de erro: uma linha de erro diretamente sob o campo, alinhada com o helper text
  • Comportamento de foco: ordem de Tab segue o layout visual; Enter só submete no último campo ou quando o botão primário estiver focado

Trave tamanhos e layout para que as telas não “respirem” de forma diferente. Defina uma altura de input, uma altura de botão e uma largura padrão de campo. No desktop, alinhe campos a uma grid consistente e empilhe labels acima dos inputs. No mobile, faça campos com largura total e evite formulários em duas colunas a menos que realmente necessário.

Um exemplo simples: uma tela “Create project” pode ter Name, Region e Description. Mesmo que Region seja um select, trate-o como qualquer outro campo: mesma altura, mesma posição de label, mesma linha de erro. Se o usuário submeter com Name vazio, o foco vai para Name, o erro aparece embaixo e o layout permanece estável.

Se você gera telas no Koder.ai, coloque essas regras de formulário no seu prompt uma vez e reutilize-as entre features para que cada novo formulário se comporte igual sem limpeza repetida.

Como expressar tokens e regras no seu prompt

Trate seu prompt como um pequeno contrato de UI. Mantenha-o curto, específico e reutilizável para que cada nova tela alinhe ao mesmo espaçamento, tipografia, componentes e comportamentos.

Um padrão prático é colar um spec compacto de UI no topo da sua requisição e depois descrever a tela em linguagem simples.

Um template compacto de prompt

UI SPEC (apply to every screen)
Tokens:
- Spacing: 4, 8, 12, 16, 24, 32
- Radius: 8
- Typography: H1 24/32, H2 18/26, Body 14/20
- Colors: text, muted, bg, primary, danger (no custom hex)

Components (must use): PageShell, Section, Card, Button, Input, Select, TextArea, FormRow, HelperText, Toast

Layout rules:
- Page padding: 24 desktop, 16 mobile
- Section spacing: 24
- Card padding: 16
- Grid: 12 cols desktop, 4 cols mobile, gap 16

Do:
- Reuse components and tokens only
- Keep labels above inputs, helper text below

Do not:
- Invent new spacing values, font sizes, or one-off CSS
- Mix different button heights or input styles

If a new component is needed:
- Extend an existing component pattern and document it in the output
- Do not create new visual styles outside tokens

Após o spec, adicione algumas checagens de aceitação que peguem o drift cedo:

  • “Use only the tokens above; no inline styles.”
  • “All forms must use FormRow and show errors the same way.”
  • “If you must add a component, base it on Card plus existing typography.”

Se estiver usando um gerador baseado em chat, mantenha esse spec estável entre requisições. Mudá-lo toda vez derrota o propósito.

Um workflow que mantém telas consistentes

Escreva o contrato de UI antes de gerar qualquer coisa: um pequeno conjunto de tokens (espaçamento, tipo, cores, radius, sombras) mais um inventário curto de componentes (Button, Input, Select, Card, Modal, Table, Toast). Se faltar um token ou componente, o modelo vai inventar um e sua UI vai derivar.

Depois crie uma tela de referência que exercite as regras. Uma página com muitos formulários é um bom teste porque inclui headers, helper text, erros de validação, botões primário e secundário, e um toast de sucesso. Trate essa tela como baseline.

A partir daí, construa novas telas compondo o que você já definiu. Não peça “estilo novo”. Peça o mesmo Card, a mesma escala de espaçamento, os mesmos passos tipográficos e o mesmo padrão de campo.

Um fluxo simples:

  • Confirme tokens e regras de componente, então congele-os para a feature
  • Gere uma tela de referência e ajuste o spec até ficar certo
  • Construa novas telas reutilizando componentes, não refazendo estilos
  • Revise por consistência, então mude as regras (tokens/componentes), não pixels individuais
  • Salve o spec como um snippet reutilizável para a próxima feature

Se uma tela “Search users” acabar com espaçamento mais apertado que a referência, não corrija margens manualmente. Atualize os tokens de espaçamento ou a regra de padding do Card uma vez, então regenere.

Se estiver trabalhando no Koder.ai, snapshots e rollback ajudam: bloqueie uma baseline, experimente com segurança e reverta rápido se uma mudança começar a introduzir drift.

Erros comuns a evitar

Vá da UI ao app em produção
Faça deploy e hospede seu app depois de confirmar espaçamento, escala tipográfica e regras de componentes.

A maneira mais rápida de perder consistência é tratar tokens e regras como sugestões. Pequenas exceções se multiplicam ao longo de novas telas.

Uma armadilha comum é mudar a escala de espaçamento no meio do projeto. Telas iniciais usam 8, 16, 24. Uma nova tela introduz 10 e 18 “porque parece certo.” Agora o drift está permitido, e telas antigas nunca são atualizadas.

Outra fonte de drift é deixar o gerador inventar novos estilos de componente. Se você não disser “apenas essas variantes de botão existem”, ele pode criar um novo radius ou um padding de input diferente em uma tela.

Estados são outro erro frequente. Loading, empty e error states frequentemente mudam espaçamento e comportamento. Se você os acrescenta no final, geralmente obtém padrões apressados que não combinam com o resto.

Também fique atento ao tipo errado de especificidade: “faça moderno com sombras suaves” é vago, enquanto regras de comportamento como “erros mostram abaixo do campo”, “botões desabilitados mantêm estilos de foco” e “Enter submete só no último campo” são concretas e repetíveis.

Se quiser um bloco leve de guardrail para colar em prompts, mantenha curto:

  • Use a mesma escala de espaçamento e tokens tipográficos das telas existentes; não invente novos valores
  • Use apenas componentes e variantes aprovados
  • Inclua estados de loading, empty e error usando os mesmos tokens
  • Especifique comportamentos (validação, ordem de foco, submit, disabled) tão claramente quanto os visuais

Checklist rápido de consistência antes de aceitar uma tela

Antes de mergear uma tela gerada, faça uma varrida de dois minutos.

Comece pelo espaçamento. Procure valores aleatórios como 13px ou margens pontuais adicionadas “só para encaixar”. Se você usa tokens, todo gap deve vir do conjunto aprovado, incluindo gutters, padding de card e espaçamento entre campos de formulário.

Depois cheque tipografia contra sua escala. Headings devem seguir passos previsíveis. Texto corpo não deve trocar de tamanho entre seções similares. Altura de linha importa também, especialmente em telas densas como páginas de configurações.

Escaneie os botões em seguida. Variantes e tamanhos devem seguir suas regras: primary para a ação principal, secondary para ações menos importantes, danger só quando realmente deleta. Altura do botão, posicionamento de ícone e estilo do label devem bater.

Para formulários, consistência é sobretudo estrutura. Labels ficam em um lugar só, indicadores de obrigatório seguem uma regra, helper text e erros não competem, e erros aparecem em local consistente.

Um checklist curto:

  • Espaçamento usa só valores de token (sem números aleatórios)
  • Tipografia bate com a escala (incluindo altura de linha)
  • Botões seguem mesmas variantes e tamanhos
  • Formulários usam um padrão para rótulos, helper text e erros
  • Estados existem: hover, focus, disabled, loading, empty

Por fim, faça um rápido check em mobile. Reduza a largura e confirme que o layout se adapta sem inventar novos tamanhos de fonte ou espaçamentos.

Exemplo: gerar uma pequena feature React sem drift de estilo

Mantenha o comportamento de formulários consistente
Gere telas com muitos formulários mantendo rótulos, erros e tamanhos de botão estáveis entre páginas.

Imagine um fluxo de onboarding simples: três telas (Profile, Preferences, Confirm), mais uma página de Settings depois. Você quer que cada tela pareça vinda do mesmo designer, mesmo que tenham sido geradas em runs separados.

Antes de gerar qualquer coisa, forneça um pequeno conjunto de tokens e algumas regras de componente:

TOKENS
- spacing: xs=4, sm=8, md=12, lg=16, xl=24
- radius: sm=8, md=12
- type: body=14/20, title=20/28, label=12/16
- layout: pageMax=960, sectionGap=24, fieldGap=12

COMPONENT RULES
- Page: max width=pageMax, padding=xl, sectionGap between blocks
- Card: padding=lg, radius=md
- Field: label above, helper below, fieldGap between fields
- Button row: primary on right, gap=sm
- Errors: shown under field, same copy style, no alerts

Agora gere “Profile” e “Preferences” separadamente. Como ambas as telas devem usar Page, Card, Field e Button row conforme definido, elas chegam com as mesmas margens, espaçamento de rótulos e posicionamento de botões. O passo Confirm ainda encaixa, mesmo com mais texto em modo read-only.

Comportamento de formulário é onde o drift costuma se infiltrar, então defina-o uma vez e reutilize: submit desabilitado até ser válido, erros inline só após blur ou submit, Enter submete só no último passo, e o botão Voltar nunca limpa valores já preenchidos.

Quando precisar de um novo pedaço de UI, não deixe o modelo improvisar. Adicione uma regra, então regenere com reuso em mente:

  • ProgressStepper: height=32, spacing=md, current step bold, completed steps clickable

Próximos passos: faça da consistência o padrão

Transforme tokens e regras em um spec reutilizável que você realmente use. Se for longo demais para colar, não será seguido.

Um spec prático normalmente inclui: sua tabela de tokens (espaçamento, tipo, radii, cores), um conjunto curto de regras de componente (botões, inputs, cards, headings), regras de comportamento de formulário (timing de validação, erros, disabled/loading), defaults de layout (padding da página, largura máxima, espaçamento entre seções), e uma pequena lista de “nunca faça” (margens aleatórias, tamanhos de fonte ad-hoc).

Então crie um hábito: atualize o spec primeiro, não pixels individuais.

Se estiver usando Koder.ai (koder.ai), o modo de planejamento é um bom lugar para reiterar e confirmar o spec antes de gerar UI. Quando quiser testar alternativas, snapshots e rollback ajudam a explorar sem perder uma baseline estável.

Perguntas frequentes

Por que telas React geradas ficam inconsistentes mesmo quando peço “estilo moderno”?

Porque cada requisição de tela é um começo do zero. Se você não fornece um sistema compartilhado, o gerador preenche os detalhes faltantes chutando — espaçamentos, tamanhos de fonte, padding de botões, sombras e comportamento de formulários — e pequenas diferenças se acumulam entre páginas.

O que são design tokens em linguagem simples e por que ajudam?

Design tokens são valores nomeados e reutilizáveis para coisas como espaçamento, tamanhos de fonte, cores e radius.

Ao invés de “padding confortável”, você usa algo como space-md. O nome permanece estável e cada tela reaplica as mesmas decisões, então a UI para de derivar.

Qual é um bom conjunto de tokens “pequeno mas completo” para começar?

Comece pequeno e cubra apenas o que causa drift visível:

  • Espaçamento: 4, 8, 12, 16, 24, 32
  • Tipo: 1 tamanho de corpo + 2 tamanhos de heading + alturas de linha fixas
  • Cores: texto, muted, bg, surface, border, primary, danger
  • Radius: 2 valores (por exemplo 8 e 12)
  • Elevação: none, small, medium

Se precisar de um “novo” valor, arredonde para o token mais próximo em vez de inventar 10px ou 18px.

Como escrevo um prompt que mantém todas as telas geradas consistentes?

Coloque um bloco compacto de UI spec no topo de cada requisição e trate-o como um contrato:

  • Liste tokens (espaçamento/tipografia/cores/radius)
  • Liste componentes permitidos (Button, Input, Card, etc.)
  • Adicione regras rígidas (sem novos valores de espaçamento, sem CSS ad-hoc)

Depois descreva a tela abaixo. A chave é manter o spec inalterado entre as telas.

Quais regras de componente previnem mais drift na UI?

Tokens definem os números; regras de componente definem os hábitos. Regras úteis incluem:

  • Button: altura fixa, padding fixo e poucos variantes (primary/secondary/danger)
  • Inputs: uma altura, espaçamento consistente do rótulo, estilo de borda/foco consistente
  • Cards: padding fixo e espaçamento previsível entre header/body
  • Layout: padding padrão da página e espaçamento entre seções

Regra padrão: se um variante não for justificável, retorne ao padrão.

Qual é o melhor padrão para timing de validação e posicionamento de erros?

Escolha um padrão e não quebre:

  • Rótulo sempre acima do campo (não use placeholder como rótulo)
  • Helper text abaixo do campo (nunca usado para erros)
  • Uma linha de erro diretamente sob o campo
  • Mostrar erros após blur ou submit, e limpar/atualizar ao digitar

Isso evita a situação comum de “uma tela valida no blur, outra só no submit”.

Quais estados devo padronizar para evitar uma sensação aleatória nas telas?

Padronize alguns estados não-negociáveis:

  • Loading: desabilitar o controle, mostrar spinner, manter largura estável
  • Disabled: contraste mais baixo, mas manter comportamento de foco consistente
  • Empty state: mensagem curta + uma ação clara
  • Errors: inline sob o campo; evitar grandes shifts de layout

Se você não especificar estados, cada tela tende a inventar seu próprio padrão.

O que fazer quando uma tela precisa de um novo componente que não está na minha lista?

Não deixe o gerador improvisar o estilo. Adicione o novo componente como uma extensão documentada de um padrão existente:

  • Baseie o novo componente em tokens atuais e em um container familiar (frequentemente Card)
  • Defina seu tamanho, espaçamento e estados usando tokens existentes
  • Adicione-o à lista de componentes aprovados para futuras telas

Se você não consegue descrevê-lo com tokens, geralmente é custom demais e causará drift.

Qual fluxo de trabalho mantém consistência quando gero telas em várias sessões?

Crie uma tela de referência que teste o sistema (uma página com muitos formulários funciona bem) e reutilize o mesmo spec para todas as novas telas.

No Koder.ai (koder.ai), use o modo de planejamento para reavaliar e confirmar o spec antes de gerar, e use snapshots/rollback para manter uma base estável enquanto experimenta.

Qual é um checklist rápido para pegar inconsistências antes de aceitar uma tela?

Faça um rápido scan antes de aceitar a tela gerada:

  • Espaçamento usa só valores do token (sem números aleatórios)
  • Tipografia bate com a escala (incluindo altura de linha)
  • Botões seguem os mesmos variantes e tamanhos
  • Formulários seguem um padrão único para rótulos/helper/erros
  • Estados existem: hover, focus, disabled, loading, empty

Se algo estiver fora, atualize o spec/tokens e regenere — não corrija margens pontuais.

Related posts