Ajuda do Up Web DS
Como classificar, importar, criar, validar e distribuir componentes do Design System interno da Up Web Studio.
Importar não significa aprovar.
Todo item externo entra como matéria-prima e precisa passar por normalização, examples, testes, preview e validação antes de stable.
Introdução
O Up Web DS é uma camada de normalização entre fontes externas, componentes internos e os produtos da equipe. Nada entra por conveniência: cada item declara o que é, de onde veio, sob qual licença, e o que já foi verificado nele.
Esta página é a referência rápida para pessoas. AGENTS.md continua sendo a referência de engenharia para agentes, e as duas descrevem a mesma política — a taxonomia e as tabelas aqui são lidas de src/catalog/taxonomy.ts, o mesmo módulo que o CLI e o ds:validate usam para aceitar ou recusar um item.
Como classificar um item
A metadata tem três eixos independentes. Responder aos três é o que transforma um arquivo em um item do design system.
- type
- Onde o item vive na arquitetura.
- category
- O que o item faz na interface.
- domain
- Em qual contexto de produto ele ganha significado.
Os três eixos são independentes. Nunca use um deles para representar outro: category não é layer, domain não é categoria, e type não é o lugar onde o arquivo mora.
Guia de decisão
- É uma unidade genérica de UI?
- primitive
- É só uma aparência diferente de um primitive existente?
- recipe
- É uma composição reutilizável com significado?
- component
- Resolve um fluxo recorrente?
- pattern
- É uma seção grande de página?
- block
- É um ponto de partida de página ou app?
- template
Type
type é o nível de abstração — o que o item é arquiteturalmente. São seis valores, e a lista é fechada.
layout não é um type. Uma estrutura pequena e genérica é primitive com category: 'layout'; uma estrutura grande é block ou template. Foundation também não é um type: tokens, tipografia e a escala de motion vivem na folha de estilo da Foundation, não em um diretório de item.
Category
category é a família funcional: o que o item faz na interface. Não representa layer e não representa domínio.
Primitives e recipes
Um Select abre um popup para funcionar, mas a função é escolher um valor: ele é selection, não overlay.
Por domínio
Componentes de domínio não são forçados nas categorias de primitive quando isso destrói o significado. O domínio application reaproveita as famílias funcionais: uma Command Palette é overlay e uma Filter Bar é selection.
Domain
domain é o contexto de produto em que o item ganha significado. primitive e recipe são sempre null; os demais types exigem um domínio.
Domínio é classificação, nunca comportamento: nenhum item muda o que faz em runtime por causa do seu domain.
Exemplos de classificação
Na interface, domain: null aparece como Domain-free. No código continua sendo null.
Lifecycle
Todo item nasce incoming e sobe por prova, não por decisão. Somente stable entra no registry consumível.
- incomingAparece no catálogo, fora do registry.Scaffold ou matéria-prima recém-ingerida. A normalização ainda não aconteceu.
- experimentalAparece no catálogo, fora do registry.Implementação em avaliação: existe, funciona, mas o contrato ainda pode mudar.
- stableÚnico status publicado no registry consumível.Contrato aprovado. Exige metadata, examples, testes, tokens, acessibilidade, dark mode, responsivo, ícones semânticos, motion e validators verdes.
- deprecatedAparece no catálogo, não é distribuído como item novo.Mantido por compatibilidade e documentação, com substituto planejado.
Adicionar do shadcn/ui
O caminho tem duas etapas separadas de propósito: inspecionar não baixa nada para src/, e promover é uma decisão explícita.
1. Inspecionar
Mostra staging, licença, dependências, ícones semânticos, normalizações conhecidas e findings — sem escrever em src/.
2. Adicionar — fluxo interativo
O CLI pergunta se deve criar o scaffold. Responder `y` cria o item em src/ como incoming.
3. Adicionar — fluxo explícito
Sem --promote, ds:add escreve apenas em .tmp/ds-ingest (staging) e .ds/ingestion (proveniência).
Um scaffold, não dois
Não execute --promote depois de já responder y ao scaffold. O item já existe e o CLI reporta conflito — corretamente.
Outros exemplos
Adicionar de outras fontes
A fonte não define o type. Um item do Magic UI pode ser uma recipe, um do Kibo pode ser um component, e o mesmo registry pode fornecer os dois — a classificação é decidida depois do inspect, com o código à vista.
Magic UI — recipe sobre primitive
Se é aparência de Button, é uma recipe do Button oficial. Não se cria um segundo primitive.
Kibo UI — componente composto
A categoria final é confirmada semanticamente depois do inspect, não deduzida da fonte.
Coss UI — primitive que já existe
Comportamento genérico melhor → incorporar ao primitive oficial. Aparência diferente → recipe.
Não existe Button2, CossButton nem ButtonV2. Se o item externo tem comportamento genérico melhor, ele é incorporado ao primitive existente para que todas as recipes herdem.
Cult UI e Chánh Đại
Criar do zero
Antes de implementar: procure primitives existentes, componha Button/Radio/Badge em vez de duplicar comportamento de foundation, e não acople o item a Firebase, Supabase, Prisma, Server Actions ou autenticação. Um item recebe dados e devolve eventos por props.
O scaffold nasce incoming: implementação, examples, testes e revisão de acessibilidade são do autor.
Adicionar código licenciado
Fontes comerciais não são baixadas automaticamente. O código chega por --from-file, sob revisão humana de licença.
Acrescente --promote quando a revisão terminar; sem ele o item fica em staging.
Uso não é redistribuição
Tailwind Plus e outras bibliotecas comerciais nascem distribution: 'restricted'. O build do registry as exclui automaticamente (DS004). Usar em uma entrega da Up Web Studio não dá direito de redistribuir por registry.
Restrito não é isento: o código licenciado passa pelos mesmos tokens, primitives, API pública, light/dark, acessibilidade, responsividade, testes e preview que qualquer outro item.
Quando o componente já existe
Se ds:add reportar conflito, não force outro nome. Compare.
Normalização obrigatória
A automação detecta e relata; ela não decide semântica. Qual token um azul representa é decisão de quem tem contexto de produto. Esta é a lista que um item precisa fechar antes de reivindicar stable.
Classificação e origem
- type, category e domain corretos
- source e licença registrados
- primitives existentes reutilizados
- API pública normalizada
Foundation
- tokens semânticos de cor, radius e sombra
- ícones semânticos do adapter
- motion semântico (duration-fast / default / slow)
- light mode
- dark mode
- responsivo
Acessibilidade
- teclado
- foco visível
- leitor de tela quando aplicável
- touch quando aplicável
- reduced motion quando aplicável
Prova
- examples
- testes unitários e de integração
- E2E quando a afirmação depende de layout
- preview
Validação
npm run check encadeia biome, typecheck, testes, ds:catalog --check, ds:validate, ds:icons:validate e registry:validate. É o portão que precisa estar verde antes de concluir qualquer tarefa.
test:e2e quando a mudança envolve layout, toque ou reduced motion; ds:registry quando o item realmente virou stable.
Publicação no registry
Catálogo e registry respondem perguntas diferentes. O preview documenta o que a equipe está construindo; o registry distribui o que um produto pode instalar.
Interface oficial de consumo
Só este CLI lê components.json → iconLibrary, instala o provider certo e gera o adapter de ícones. O registry por baixo é infraestrutura que ele consome.
Não é o caminho oficial
npx shadcn add @up-web-ds/dialog instala os arquivos sem resolver a biblioteca de ícones do projeto. O componente chega sem o adapter que ele importa.