shadcn/ui
Um framework para construir UI, componentes e sistemas de design. Os componentes são adicionados como código fonte ao projeto do usuário via CLI.
IMPORTANTE: Execute todos os comandos da CLI usando o executor de pacotes do projeto:
npx shadcn@latest,pnpm dlx shadcn@latest, oubunx --bun shadcn@latest— com base nopackageManagerdo projeto. Os exemplos abaixo usamnpx shadcn@latestmas substitua pelo executor correto para o projeto.
Contexto Atual do Projeto
!`npx shadcn@latest info --json`
O JSON acima contém a configuração do projeto e os componentes instalados. Use npx shadcn@latest docs <component> para obter URLs de documentação e exemplos para qualquer componente.
Princípios
- Use componentes existentes primeiro. Use
npx shadcn@latest searchpara verificar registries antes de escrever UI personalizada. Verifique também registries da comunidade. - Componha, não reinvente. Página de configurações = Tabs + Card + controles de formulário. Dashboard = Sidebar + Card + Chart + Table.
- Use variantes embutidas antes de estilos personalizados.
variant="outline",size="sm", etc. - Use cores semânticas.
bg-primary,text-muted-foreground— nunca valores brutos comobg-blue-500.
Regras Críticas
Estas regras são sempre aplicadas. Cada uma linka para um arquivo com pares Incorreto/Correto.
Estilização & Tailwind → styling.md
classNamepara layout, não para estilização. Nunca sobrescreva cores ou tipografia de componentes.- Sem
space-x-*ouspace-y-*. Useflexcomgap-*. Para pilhas verticais,flex flex-col gap-*. - Use
size-*quando largura e altura são iguais.size-10nãow-10 h-10. - Use o atalho
truncate. Nãooverflow-hidden text-ellipsis whitespace-nowrap. - Sem sobrescrita manual de
dark:. Use tokens semânticos (bg-background,text-muted-foreground). - Use
cn()para classes condicionais. Não escreva ternários manuais com template literals. - Sem
z-indexmanual em componentes de sobreposição. Dialog, Sheet, Popover, etc. gerenciam seu próprio empilhamento.
Formulários & Inputs → forms.md
- Formulários usam
FieldGroup+Field. Nunca usedivbruto comspace-y-*ougrid gap-*para layout de formulário. InputGroupusaInputGroupInput/InputGroupTextarea. NuncaInput/Textareabruto dentro deInputGroup.- Botões dentro de inputs usam
InputGroup+InputGroupAddon. - Conjuntos de opções (2–7 escolhas) usam
ToggleGroup. Não use loop deButtoncom estado ativo manual. FieldSet+FieldLegendpara agrupar checkboxes/radios relacionados. Não use umdivcom título.- Validação de campo usa
data-invalid+aria-invalid.data-invalidnoField,aria-invalidno controle. Para desabilitado:data-disablednoField,disabledno controle.
Estrutura de Componentes → composition.md
- Itens sempre dentro de seu Grupo.
SelectItem→SelectGroup.DropdownMenuItem→DropdownMenuGroup.CommandItem→CommandGroup. - Use
asChild(radix) ourender(base) para triggers personalizados. Verifique o campobasedenpx shadcn@latest info. → base-vs-radix.md - Dialog, Sheet e Drawer sempre precisam de um Title.
DialogTitle,SheetTitle,DrawerTitleobrigatórios para acessibilidade. UseclassName="sr-only"se estiver visualmente oculto. - Use a composição completa de Card.
CardHeader/CardTitle/CardDescription/CardContent/CardFooter. Não jogue tudo emCardContent. - Button não tem
isPending/isLoading. Componha comSpinner+data-icon+disabled. TabsTriggerdeve estar dentro deTabsList. Nunca renderize triggers diretamente emTabs.Avatarsempre precisa deAvatarFallback. Para quando a imagem falhar ao carregar.
Use Componentes, Não Marcação Personalizada → composition.md
- Use componentes existentes antes de marcação personalizada. Verifique se um componente existe antes de escrever um
divestilizado. - Callouts usam
Alert. Não construa divs estilizados personalizados. - Estados vazios usam
Empty. Não construa marcação de estado vazio personalizada. - Toast segue a base do projeto. Use
toastdo componentetoastpara projetos Base UI. Usetoast()desonnerpara projetos Radix e React Aria. - Use
Separatorem vez de<hr>ou<div className="border-t">. - Use
Skeletonpara placeholders de carregamento. Sem divsanimate-pulsepersonalizados. - Use
Badgeem vez de spans estilizados personalizados.
Ícones → icons.md
- Ícones em
Buttonusamdata-icon.data-icon="inline-start"oudata-icon="inline-end"no ícone. - Sem classes de tamanho em ícones dentro de componentes. Componentes lidam com o tamanho do ícone via CSS. Sem
size-4ouw-4 h-4. - Passe ícones como objetos, não como chaves de string.
icon={CheckIcon}, não uma busca por string.
Chat & Mensagens → chat.md
- UI de Chat compõe os primitivos de chat. Conversas usam
MessageScroller, linhas usamMessage, superfícies usamBubble. Nunca divs de bolha feitos à mão ou um contêiner de scroll bruto. MessageScrolleré dono do comportamento de scroll. Acompanhamento de streaming, ancoragem e salto para o último (MessageScrollerButton) são embutidos. Não escreva um hookuseStickToBottom/ResizeObserver.- Anexos usam
Attachment; notas de sistema e divisores usamMarker. Não cartõesItemouSeparator+ um rótulo.
CLI
- Nunca decodifique códigos de preset ou construa URLs de preset manualmente. Use
npx shadcn@latest preset decode <code>,preset url <code>, oupreset open <code>. Para detecção de preset ciente do projeto, usenpx shadcn@latest preset resolve. - Aplique códigos de preset diretamente com a CLI. Use
npx shadcn@latest apply <code>para projetos existentes, ounpx shadcn@latest init --preset <code>ao inicializar.
Padrões Chave
Estes são os padrões mais comuns que diferenciam o código shadcn/ui correto. Para casos extremos, veja os arquivos de regras linkados acima.
// Layout de formulário: FieldGroup + Field, não div + Label.
<FieldGroup>
<Field>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input id="email" />
</Field>
</FieldGroup>
// Validação: data-invalid no Field, aria-invalid no controle.
<Field data-invalid>
<FieldLabel>Email</FieldLabel>
<Input aria-invalid />
<FieldDescription>Email inválido.</FieldDescription>
</Field>
// Ícones em botões: data-icon, sem classes de tamanho.
<Button>
<SearchIcon data-icon="inline-start" />
Pesquisar
</Button>
// Espaçamento: gap-*, não space-y-*.
<div className="flex flex-col gap-4"> // correto
<div className="space-y-4"> // errado
// Dimensões iguais: size-*, não w-* h-*.
<Avatar className="size-10"> // correto
<Avatar className="w-10 h-10"> // errado
// Cores de status: variantes Badge ou tokens semânticos, não cores brutas.
<Badge variant="secondary">+20.1%</Badge> // correto
<span className="text-emerald-600">+20.1%</span> // errado
Seleção de Componentes
| Necessidade | Use |
|---|---|
| Botão/ação | Button com variante apropriada |
| Inputs de formulário | Input, Select, Combobox, Switch, Checkbox, RadioGroup, Textarea, InputOTP, Slider |
| Alternar entre 2–5 opções | ToggleGroup + ToggleGroupItem |
| Exibição de dados | Table, Card, Badge, Avatar |
| Navegação | Sidebar, NavigationMenu, Breadcrumb, Tabs, Pagination |
| Sobreposições | Dialog (modal), Sheet (painel lateral), Drawer (inferior), AlertDialog (confirmação) |
| Feedback | toast (Base UI), sonner (Radix/Aria), Alert, Progress, Skeleton, Spinner |
| Paleta de comandos | Command dentro de Dialog |
| Gráficos | Chart (encapsula Recharts) |
| Layout | Card, Separator, Resizable, ScrollArea, Accordion, Collapsible |
| Estados vazios | Empty |
| Menus | DropdownMenu, ContextMenu, Menubar |
| Dicas/informações | Tooltip, HoverCard, Popover |
| UI de chat / conversa | MessageScroller, Message, Bubble, Attachment, Marker |
Campos Chave
O contexto do projeto injetado contém estes campos chave:
aliases→ use o prefixo de alias real para imports (ex.:@/,~/), nunca hardcode.isRSC→ quandotrue, componentes que usamuseState,useEffect, manipuladores de eventos ou APIs de navegador precisam de"use client"no topo do arquivo. Sempre referencie este campo ao aconselhar sobre a diretiva.tailwindVersion→"v4"usa blocos@theme inline;"v3"usatailwind.config.js.tailwindCssFile→ o arquivo CSS global onde as variáveis CSS personalizadas são definidas. Sempre edite este arquivo, nunca crie um novo.style→ tratamento visual do componente (ex.:nova,vega).base→ biblioteca primitiva (radixoubase). Afeta as APIs dos componentes e as props disponíveis.iconLibrary→ determina os imports de ícones. Uselucide-reactparalucide,@tabler/icons-reactparatabler, etc. Nunca assumalucide-react.resolvedPaths→ destinos exatos no sistema de arquivos para componentes, utils, hooks, etc.framework→ convenções de roteamento e arquivo (ex.: Next.js App Router vs Vite SPA).packageManager→ use isso para qualquer instalação de dependência não-shadcn (ex.:pnpm add date-fnsvsnpm install date-fns).preset→ código de preset resolvido e valores para o projeto atual. Usenpx shadcn@latest preset resolve --jsonquando precisar apenas de informações do preset.
Veja cli.md — comando info para a referência completa de campos.
Documentação, Exemplos e Uso de Componentes
Execute npx shadcn@latest docs <component> para obter as URLs da documentação, exemplos e referência de API de um componente. Busque estas URLs para obter o conteúdo real.
npx shadcn@latest docs button dialog select
Ao criar, corrigir, depurar ou usar um componente, sempre execute npx shadcn@latest docs e busque as URLs primeiro. Isso garante que você está trabalhando com a API e os padrões de uso corretos, em vez de adivinhar.
Fluxo de Trabalho
- Obtenha o contexto do projeto — já injetado acima. Execute
npx shadcn@latest infonovamente se precisar atualizar. - Verifique componentes instalados primeiro — antes de executar
add, sempre verifique a lista decomponentsdo contexto do projeto ou liste o diretórioresolvedPaths.ui. Não importe componentes que não foram adicionados e não readicione aqueles já instalados. - Encontre componentes —
npx shadcn@latest search. - Obtenha documentação e exemplos — execute
npx shadcn@latest docs <component>para obter URLs, depois as busque. Usenpx shadcn@latest viewpara navegar por itens do registry que você não instalou. Para pré-visualizar alterações em componentes instalados, usenpx shadcn@latest add --diff. - Instale ou atualize —
npx shadcn@latest add. Ao atualizar componentes existentes, use--dry-rune--diffpara pré-visualizar alterações primeiro (veja Atualizando Componentes abaixo). - Corrija imports em componentes de terceiros — Após adicionar componentes de registries da comunidade (ex.:
@bundui,@magicui), verifique os arquivos não-UI adicionados para caminhos de import hardcoded como@/components/ui/.... Estes podem não corresponder aos aliases reais do projeto. Usenpx shadcn@latest infopara obter o aliasuicorreto (ex.:@workspace/ui/components) e reescreva os imports de acordo. A CLI reescreve imports para seus próprios arquivos UI, mas componentes de registries de terceiros podem usar caminhos padrão que não correspondem ao projeto. - Revise componentes adicionados — Após adicionar um componente ou bloco de qualquer registry, sempre leia os arquivos adicionados e verifique se estão corretos. Verifique a falta de subcomponentes (ex.:
SelectItemsemSelectGroup), imports ausentes, composição incorreta ou violações das Regras Críticas. Substitua também quaisquer imports de ícones pelaiconLibrarydo projeto no contexto do projeto (ex.: se o item do registry usalucide-reactmas o projeto usahugeicons, troque os imports e nomes de ícones de acordo). Corrija todos os problemas antes de prosseguir. - Registry deve ser explícito — Quando o usuário pedir para adicionar um bloco ou componente, não adivinhe o registry. Se nenhum registry for especificado (ex.: o usuário disser "adicione um bloco de login" sem especificar
@shadcn,@tailark,owner/repo, etc.), pergunte qual registry usar. Nunca assuma um registry em nome do usuário. - Alternando presets — Pergunte ao usuário primeiro: sobrescrever, parcial, mesclar ou pular?
- Inspecione o preset atual:
npx shadcn@latest preset resolve. Use--jsonquando precisar de valores estruturados. - Inspecione o preset recebido:
npx shadcn@latest preset decode <code>. Usepreset url <code>oupreset open <code>para compartilhar ou abrir o construtor de presets. - Sobrescrever:
npx shadcn@latest apply <code>. Sobrescreve componentes detectados, fontes e variáveis CSS. - Parcial:
npx shadcn@latest apply <code> --only theme,font. Atualiza apenas as partes do preset selecionadas sem reinstalar componentes UI. Os valores suportados sãothemeefont; combinações separadas por vírgula são permitidas. O valoriconnão é intencionalmente suportado, porque mudanças de ícone podem exigir reinstalação completa do componente. - Mesclar: quando presets sobrepõem o mesmo conjunto de valores CSS ou tokens, mescle as regras manualmente e depois use
preset applycom o resultado mesclado. - Pular: não faça nada.
- Inspecione o preset atual:
Atualizando Componentes
# Pré-visualize todas as atualizações
npx shadcn@latest add --dry-run
# Diff de componentes específicos
npx shadcn@latest add button card --diff
# Atualize tudo
npx shadcn@latest add --all
Criando Novos Projetos
# Use shadcn init com ou sem um preset
npx shadcn@latest init
npx shadcn@latest init --preset <code_or_name>
Solução de Problemas & Depuração
- Componente não renderizando? Use
npx shadcn@latest infopara verificarisRSC. Setrue, adicione"use client"no topo. - Importações erradas? Verifique
resolvedPathsemnpx shadcn@latest info. Use os aliases corretos do projeto. - Componente antigo? Atualize com
npx shadcn@latest add --all. - Estilização quebrada? Execute
npx shadcn@latest add --allpara restaurar arquivos de utilitários e tokens CSS.