shadcn/ui
Um framework para construir UI, componentes e sistemas de design. Os componentes são adicionados como código-fonte no projeto do usuário via CLI.
IMPORTANTE: Execute todos os comandos da CLI usando o gerenciador de pacotes do projeto:
npx shadcn@latest,pnpm dlx shadcn@latestoubunx --bun shadcn@latest— com base nopackageManagerdo projeto. Os exemplos abaixo usamnpx shadcn@latest, mas substitua pelo runner 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 registros antes de escrever UI personalizada. Verifique também registros da comunidade. - Componha, não reinvente. Página de configurações = Tabs + Card + controles de formulário. Dashboard = Sidebar + Card + Chart + Table.
- Use variantes internas 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 possui um link para um arquivo com pares de código Incorreto/Correto.
Estilização e Tailwind → styling.md
classNamepara layout, não para estilização. Nunca sobrescreva cores ou tipografia dos 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 a abreviação
truncate. Nãooverflow-hidden text-ellipsis whitespace-nowrap. - Sem substituições manuais de cor
dark:. Use tokens semânticos (bg-background,text-muted-foreground). - Use
cn()para classes condicionais. Não escreva ternários com template literal manual. - Sem
z-indexmanual em componentes de sobreposição. Dialog, Sheet, Popover, etc. gerenciam seu próprio empilhamento.
Formulários e Inputs → forms.md
- Formulários usam
FieldGroup+Field. Nunca usedivbruto comspace-y-*ougrid gap-*para layout de formulário. InputGroupusaInputGroupInput/InputGroupTextarea. NuncaInput/Textareabrutos dentro deInputGroup.- Botões dentro de inputs usam
InputGroup+InputGroupAddon. - Conjuntos de opções (2–7 escolhas) usam
ToggleGroup. Não faça loop deButtoncom estado ativo manual. FieldSet+FieldLegendpara agrupar checkboxes/radios relacionados. Não use umadivcom um 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 seus Grupos.
SelectItem→SelectGroup.DropdownMenuItem→DropdownMenuGroup.CommandItem→CommandGroup. - Use
asChild(radix) ourender(base) para gatilhos personalizados. Verifique o campobasedonpx shadcn@latest info. → base-vs-radix.md - Dialog, Sheet e Drawer sempre precisam de um Title.
DialogTitle,SheetTitle,DrawerTitlesão obrigatórios para acessibilidade. UseclassName="sr-only"se estiver oculto visualmente. - Use a composição completa do Card.
CardHeader/CardTitle/CardDescription/CardContent/CardFooter. Não coloque 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 falha 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 uma
divestilizada. - Callouts usam
Alert. Não crie divs estilizadas personalizadas. - Estados vazios usam
Empty. Não crie marcação de estado vazio personalizada. - Toast via
sonner. Usetoast()desonner. - Use
Separatorem vez de<hr>ou<div className="border-t">. - Use
Skeletonpara placeholders de carregamento. Sem divsanimate-pulsepersonalizadas. - 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 dimensionamento em ícones dentro de componentes. Os componentes lidam com o dimensionamento de ícones 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.
CLI
- Nunca decodifique ou busque códigos de preset manualmente. Passe-os diretamente para
npx shadcn@latest init --preset <code>.
Padrões Principais
Estes são os padrões mais comuns que diferenciam o código shadcn/ui correto. Para casos extremos, consulte os arquivos de regras vinculados 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 dimensionamento.
<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 de 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 a 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 (folha inferior), AlertDialog (confirmação) |
| Feedbacks | sonner (toast), 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 |
Campos Principais
O contexto do projeto injetado contém estes campos principais:
aliases→ use o prefixo de alias real para importações (ex.:@/,~/), nunca codifique.isRSC→ quandotrue, componentes que usamuseState,useEffect, manipuladores de eventos ou APIs do navegador precisam de"use client"no topo do arquivo. Consulte sempre 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. Edite sempre 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 as importações de ícones. Uselucide-reactparalucide,@tabler/icons-reactparatabler, etc. Nunca presumalucide-react.resolvedPaths→ destinos exatos do sistema de arquivos para componentes, utilitários, hooks, etc.framework→ roteamento e convenções de arquivos (ex.: Next.js App Router vs Vite SPA).packageManager→ use este para qualquer instalação de dependência que não seja shadcn (ex.:pnpm add date-fnsvsnpm install date-fns).
Veja cli.md — comando info para a referência completa dos 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 essas URLs para obter o conteúdo real.
npx shadcn@latest docs button dialog select
Ao criar, corrigir, depurar ou usar um componente, execute sempre 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
- Obter contexto do projeto — já injetado acima. Execute
npx shadcn@latest infonovamente se precisar atualizar. - Verificar componentes instalados primeiro — antes de executar
add, verifique sempre a lista decomponentsdo contexto do projeto ou liste o diretórioresolvedPaths.ui. Não importe componentes que não foram adicionados e não adicione novamente os que já estão instalados. - Encontrar componentes —
npx shadcn@latest search. - Obter documentação e exemplos — execute
npx shadcn@latest docs <component>para obter as URLs e, em seguida, busque-as. Usenpx shadcn@latest viewpara navegar pelos itens do registro que você não instalou. Para visualizar alterações em componentes instalados, usenpx shadcn@latest add --diff. - Instalar ou atualizar —
npx shadcn@latest add. Ao atualizar componentes existentes, use--dry-rune--diffpara visualizar as alterações primeiro (veja Atualizando Componentes abaixo). - Corrigir importações em componentes de terceiros — Após adicionar componentes de registros da comunidade (ex.:
@bundui,@magicui), verifique os arquivos não-UI adicionados em busca de caminhos de importação codificados 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 as importações de acordo. A CLI reescreve as importações para seus próprios arquivos de UI, mas os componentes de registro de terceiros podem usar caminhos padrão que não correspondem ao projeto. - Revisar componentes adicionados — Após adicionar um componente ou bloco de qualquer registro, sempre leia os arquivos adicionados e verifique se estão corretos. Verifique a falta de subcomponentes (ex.:
SelectItemsemSelectGroup), importações ausentes, composição incorreta ou violações das Regras Críticas. Substitua também quaisquer importações de ícones pelaiconLibrarydo projeto a partir do contexto do projeto (ex.: se o item do registro usalucide-reactmas o projeto usahugeicons, troque as importações e os nomes dos ícones de acordo). Corrija todos os problemas antes de prosseguir. - O registro deve ser explícito — Quando o usuário pedir para adicionar um bloco ou componente, não adivinhe o registro. Se nenhum registro for especificado (ex.: o usuário diz "adicione um bloco de login" sem especificar
@shadcn,@tailark, etc.), pergunte qual registro usar. Nunca presuma um registro em nome do usuário. - Alternando presets — Pergunte ao usuário primeiro: reinstalar, mesclar ou pular?
- Reinstalar:
npx shadcn@latest init --preset <code> --force --reinstall. Sobrescreve todos os componentes. - Mesclar:
npx shadcn@latest init --preset <code> --force --no-reinstall, em seguida, executenpx shadcn@latest infopara listar os componentes instalados e, para cada componente instalado, use--dry-rune--diffpara mesclar inteligentemente individualmente. - Pular:
npx shadcn@latest init --preset <code> --force --no-reinstall. Apenas atualiza a configuração e o CSS, deixando os componentes como estão. - Importante: Execute sempre os comandos de preset dentro do diretório do projeto do usuário. A CLI preserva automaticamente a base atual (
basevsradix) decomponents.json. Se você precisar usar um diretório temporário/scratch (ex.: para comparações com--dry-run), passe--base <base-atual>explicitamente — os códigos de preset não codificam a base.
- Reinstalar:
Atualizando Componentes
Quando o usuário pedir para atualizar um componente de upstream mantendo suas alterações locais, use --dry-run e --diff para mesclar inteligentemente. NUNCA busque arquivos brutos do GitHub manualmente — sempre use a CLI.
- Execute
npx shadcn@latest add <component> --dry-runpara ver todos os arquivos que seriam afetados. - Para cada arquivo, execute
npx shadcn@latest add <component> --diff <file>para ver o que mudou entre upstream e local. - Decida por arquivo com base no diff:
- Sem alterações locais → seguro sobrescrever.
- Com alterações locais → leia o arquivo local, analise o diff e aplique as atualizações de upstream preservando as modificações locais.
- Usuário diz "apenas atualize tudo" → use
--overwrite, mas confirme primeiro.
- Nunca use
--overwritesem a aprovação explícita do usuário.
Referência Rápida
# Criar um novo projeto.
npx shadcn@latest init --name my-app --preset base-nova
npx shadcn@latest init --name my-app --preset a2r6bw --template vite
# Criar um projeto monorepo.
npx shadcn@latest init --name my-app --preset base-nova --monorepo
npx shadcn@latest init --name my-app --preset base-
…
[truncado para tradução]