Além dos tokens: ensinando sua component library para agentes IA com DESIGN.md
Além dos tokens: ensinando sua component library para agentes IA com DESIGN.md
Você investiu meses construindo uma component library. Tem Button com 6 variantes, Card com 4, Modal com 3 tamanhos, um Table system completo. Tudo testado, documentado no Storybook, com demos interativos. Daí pede pro agente criar uma tela nova e ele ignora tudo — gera componentes do zero com div e classes inline.
O motivo é simples: o agente não lê Storybook. Não navega URLs interativos. Não abre iframes de demos. Ele lê texto. Se seus componentes não existem como texto no contexto dele, eles não existem. Ponto.
O paradoxo: library perfeita, agente cego
Tenho visto esse cenário repetidamente:
- Time constrói design system bonito com Storybook
- Time adota Cursor/Copilot/Claude para codar mais rápido
- Agente gera UI que não usa nenhum componente do design system
- Time: 😠
A reação natural é “agente burro”. A realidade é “agente sem contexto”. Se você não declarou no DESIGN.md que existe um <AlertDialog> com variantes info | warning | destructive, o agente vai construir um modal genérico com div, backdrop manual, e botões escritos à mão.
A spec oficial do Google Labs (Design Spec para agentes) trata isso explicitamente na seção Do/Don’t:
Use the Do/Don’t format to give the agent clear boundaries. “Do: use AlertDialog for destructive actions. Don’t: build custom modals when a system component exists.”
Parece óbvio. Mas quase ninguém faz. A maioria dos DESIGN.md que vejo por aí termina depois dos tokens — como se o agente fosse magicamente adivinhar que existe um <Tooltip> component disponível.
O que o agente precisa saber sobre cada componente
Não é tudo. O agente não precisa da API reference completa — pra isso ele olha o código-fonte ou a tipagem TypeScript. O que ele precisa é:
- Que o componente existe (nome, import path)
- Quando usar (contexto de uso)
- Quando NÃO usar (anti-patterns)
- Quais variantes (e quando cada uma se aplica)
- Slots/children (o que vai dentro)
- Composição (com quais outros componentes combina)
Isso é surpreendentemente pouco texto por componente — mas resolve o problema inteiro.
Anatomia de um componente documentado para agentes
Vou mostrar como documento um Card component de forma que qualquer agente use corretamente:
### Card
**Import:** `@/components/ui/card`
**Variants:**
- `default` — fundo branco, border sutil, sem elevação
- `elevated` — shadow-md, usado para highlight/destaque
- `interactive` — cursor pointer, hover state, clicável inteiro
- `outlined` — border mais forte, sem sombra, para grids densos
**When to use:**
- Content containers that group related information
- Pricing cards, feature cards, testimonial cards, user profile cards
- Dashboard widgets and metrics
**When NOT to use:**
- ❌ Wrapping a single form field (use the field directly)
- ❌ Navigation items (use NavItem or Link)
- ❌ Full-width content that spans the viewport (use Section)
- ❌ Nested inside another Card (flat hierarchy only)
**Slots:**
- `CardHeader` — title + optional description + optional action button
- `CardContent` — main body content
- `CardFooter` — actions (buttons, links) aligned right
**Composition:**
- Inside: Grid layouts, Dashboard panels
- Contains: Form fields, Lists, Charts, Stats
- Never inside: Another Card, Modal body (use plain content)
**Do/Don't:**
- ✅ DO: Use `elevated` for the ONE highlighted card in a pricing grid
- ✅ DO: Use `interactive` when the entire card navigates somewhere
- ❌ DON'T: Mix `elevated` and `outlined` in the same grid
- ❌ DON'T: Put more than 2 action buttons in CardFooter
- ❌ DON'T: Use Card for less than 3 lines of content (too small, looks weird)
Isso são ~30 linhas. O agente lê em milissegundos. E com essa informação, ele nunca vai:
- Aninhar card dentro de card
- Usar elevated pra todos os cards do grid
- Colocar 5 botões no footer
- Criar um card wrapper para um input solo
Cada linha é um erro prevenido.
Template copy-paste: documente seus componentes
Aqui está o template que uso. Copie, cole, preencha pra cada componente da sua library:
### [ComponentName]
**Import:** `[path]`
**Variants:**
- `variant1` — [quando usar, aparência]
- `variant2` — [quando usar, aparência]
**When to use:**
- [Caso de uso 1]
- [Caso de uso 2]
- [Caso de uso 3]
**When NOT to use:**
- ❌ [Anti-pattern 1]
- ❌ [Anti-pattern 2]
**Slots:**
- `[SlotName]` — [o que vai dentro]
**Composition:**
- Inside: [onde este componente vive]
- Contains: [o que vai dentro dele]
- Never with: [combinações proibidas]
**Do/Don't:**
- ✅ DO: [comportamento correto]
- ❌ DON'T: [erro comum que o agente cometeria]
Leva 5 minutos por componente. Se sua library tem 30 componentes, são 2.5 horas de trabalho que vão te poupar semanas de correção manual no output dos agentes.
Exemplo completo: uma library de 5 componentes
Vou mostrar como fica uma seção Components real e funcional no DESIGN.md:
## Components
### Button
**Import:** `@/components/ui/button`
**Variants:**
- `primary` — ação principal, fundo sólido primary color
- `secondary` — ação alternativa, fundo sutil
- `ghost` — sem fundo, sem border, hover sutil. Toolbars, ações terciárias
- `destructive` — vermelho, ações irreversíveis
- `link` — parece texto link, sem padding
**Sizes:** `sm`, `md` (default), `lg`, `icon` (quadrado, apenas ícone)
**Rules:**
- ✅ Maximum ONE primary button per visible viewport
- ✅ Destructive always paired with confirmation dialog
- ✅ Icon button always has aria-label or tooltip
- ❌ NEVER two primary buttons side by side
- ❌ NEVER destructive without explicit text label (not just icon)
- ❌ NEVER ghost button as main CTA
---
### Dialog (Modal)
**Import:** `@/components/ui/dialog`
**Sizes:** `sm` (400px), `md` (560px), `lg` (720px)
**When to use:**
- Confirmations that require explicit user decision
- Forms that don't warrant a full page
- Detail views triggered from lists/tables
**When NOT to use:**
- ❌ Notifications or alerts (use Toast)
- ❌ Simple yes/no (use AlertDialog, not full Dialog)
- ❌ Content that needs URL/bookmark (use page route instead)
**Structure:**
- `DialogHeader` — title (required) + description (optional)
- `DialogBody` — content, scrollable if long
- `DialogFooter` — actions, right-aligned. Cancel left, confirm right.
**Do/Don't:**
- ✅ DO: Close on Escape and backdrop click (unless destructive)
- ✅ DO: Focus trap inside dialog
- ❌ DON'T: Dialog inside dialog (nested modals)
- ❌ DON'T: Dialog wider than 720px
- ❌ DON'T: Dialog for content longer than 2 scrolls (use page)
---
### Toast (Notification)
**Import:** `@/components/ui/toast`
**Variants:**
- `default` — informational, neutral
- `success` — ação completada com sucesso
- `error` — algo falhou
- `warning` — atenção necessária mas não bloqueante
**Rules:**
- Auto-dismiss after 5s (success, default) or persistent (error, warning)
- Position: bottom-right (desktop), bottom-center (mobile)
- Max 3 toasts stacked simultaneously
- ✅ DO: Use for async operation results (save, delete, send)
- ❌ DON'T: Use for validation errors (use inline field errors)
- ❌ DON'T: Use for critical actions that need response (use Dialog)
---
### DataTable
**Import:** `@/components/ui/data-table`
**Features available:** sorting, filtering, pagination, row selection, column resizing
**When to use:**
- Structured data with 5+ columns
- Data that benefits from sorting/filtering
- Lists where bulk actions are needed
**When NOT to use:**
- ❌ Less than 4 columns (use simple List component)
- ❌ Media-heavy content (use Grid/Cards)
- ❌ Timeline/activity feeds (use ActivityFeed)
**Do/Don't:**
- ✅ DO: Always include pagination for 20+ rows
- ✅ DO: Skeleton loading state with 5 placeholder rows
- ✅ DO: Empty state with illustration + CTA
- ❌ DON'T: Horizontal scroll on desktop (reduce columns instead)
- ❌ DON'T: More than 8 visible columns (use column toggle)
- ❌ DON'T: Sortable columns without visual indicator
---
### Sidebar Navigation
**Import:** `@/components/ui/sidebar`
**Structure:**
- `SidebarHeader` — logo/brand + collapse toggle
- `SidebarContent` — nav groups with items
- `SidebarFooter` — user avatar + settings
**Behavior:**
- Desktop: fixed, 280px wide, collapsible to 64px (icons only)
- Mobile: overlay drawer, opened by hamburger menu
- Active item: highlighted background, bold text
- Groups: collapsible sections with chevron
**Do/Don't:**
- ✅ DO: Max 2 nesting levels (groups → items)
- ✅ DO: Icons on every item for collapsed state
- ❌ DON'T: More than 8 top-level items (group them)
- ❌ DON'T: Sidebar + top navbar simultaneously (choose one)
- ❌ DON'T: Links that open in new tab from sidebar
A diferença no output
Sem documentação de componentes, pedi a um agente: “Crie um dashboard com sidebar, tabela de usuários, e cards de métricas.”
Resultado sem docs: Sidebar com 12 itens desagrupados, tabela sem paginação com scroll horizontal, 6 cards de métricas todos do mesmo tamanho, modal genérico para editar usuário (construído com divs manuais).
Resultado com docs: Sidebar com 3 grupos colapsáveis (7 itens no total), DataTable com paginação e sorting, 4 cards em grid responsivo (um elevated para métrica principal), Dialog de 560px com formulário para editar usuário.
A diferença é gritante. Não é ajuste cosmético — é a diferença entre “isso funciona como produto” e “isso é um protótipo de hackathon”.
Quanto documentar: a regra 80/20
Você não precisa documentar TODOS os componentes no dia 1. A regra prática:
Documente primeiro:
- Componentes de layout (Grid, Container, Section, Sidebar)
- Componentes de ação (Button, Link, IconButton)
- Componentes de feedback (Toast, Dialog, AlertDialog)
- Componentes de dados (Table, List, Card)
Documente depois (quando o agente errar): 5. Componentes de form (Input, Select, Checkbox, DatePicker) 6. Componentes de navegação (Tabs, Breadcrumb, Pagination) 7. Componentes decorativos (Badge, Avatar, Tooltip, Skeleton)
Os primeiros 10-15 componentes cobrem 80% das decisões que o agente toma. O resto você adiciona incrementalmente quando vê o agente errando.
Padrões que emergem: o agente aprende composição
Uma coisa bonita acontece quando você documenta composição (o que vai dentro do quê): o agente começa a compor componentes corretamente sem instrução explícita para cada tela.
Se ele sabe que:
- Card contém FormFields
- Dialog tem DialogHeader + DialogBody + DialogFooter
- DialogFooter tem Button (cancel ghost left, confirm primary right)
- DataTable tem empty state com illustration + CTA
Ele extrapola:
- “Formulário de edição de perfil” → Dialog md + form fields no body + cancel/save no footer
- “Lista de projetos vazia” → DataTable com empty state customizado
- “Pricing cards” → Grid de Cards, um elevated (destaque)
A composição é o superpoder. Tokens dizem “como parece”. Componentes dizem “o que usar”. Composição diz “como montar”.
Integrando com seu workflow existente
Se você já tem Storybook, a migração é mecânica:
- Abra cada componente no Storybook
- Extraia: variantes, quando usar, quando não usar
- Adicione ao DESIGN.md no formato do template
- Priorize os 15 componentes mais usados
Se você não tem Storybook (usa Tailwind components copiados, shadcn/ui, ou custom):
- Liste os componentes que existem no seu
/componentsfolder - Para cada um, defina variantes e regras de uso
- Pense nos erros que um dev junior cometeria — documente como Don’t
O investimento é mínimo comparado ao retorno. Cada componente documentado são dezenas de correções manuais economizadas.
O anti-pattern: documentação que vira impedimento
Um aviso: não transforme a seção Components em uma bíblia de 500 linhas por componente. O agente precisa de decisão rápida, não de spec exhaustiva.
Bom: 20-30 linhas por componente focando em decisões Ruim: 200 linhas por componente com toda a prop API documentada
Se o agente precisa saber que Button aceita leftIcon e rightIcon, ele descobre olhando o TypeScript. Ele não descobre sozinho que “máximo um primary button por viewport” é regra do design system. Documente o que não é óbvio pelo código.
DESIGN.md como contrato vivo
A seção Components não é estática. Ela evolui assim:
- Agente gera algo errado → identifique qual regra faltou
- Adicione a regra no componente relevante como Do/Don’t
- Teste pedindo ao agente para gerar algo similar
- Se acertou → regra funcionou. Se errou → reescreva com mais clareza.
Esse loop transforma o DESIGN.md num contrato vivo entre você e o agente. Cada iteração melhora o output. Depois de 2-3 semanas de uso, o DESIGN.md estabiliza — o agente raramente erra, e quando erra, é em edge cases exóticos.
Conclusão: componentes são o multiplicador
Tokens fazem o agente acertar cores. Componentes fazem o agente acertar tudo mais. Se eu tivesse que escolher entre um DESIGN.md com 100 tokens perfeitos e um DESIGN.md com 15 componentes bem documentados, escolheria os componentes sem pensar duas vezes.
Cores o agente resolve com um hex code. Saber que AlertDialog existe, se diferencia de Dialog, tem tamanho max sm, e sempre precisa de botão de confirmar explícito — isso o agente só sabe se você contar.
Comece hoje. Pegue seus 5 componentes mais usados. Documente com o template. Peça ao agente para gerar uma tela. Veja a diferença.
Quer um DESIGN.md com componentes já mapeados automaticamente? O designmd.app analisa seu site, identifica componentes recorrentes, e gera documentação estruturada com variantes, composição e anti-patterns. Sua component library, traduzida para agentes. Teste agora.