Como montar a estrutura de um painel com shadcn/ui: boas práticas de Sidebar e Layout

Um guia passo a passo para montar a estrutura escalável de um sistema administrativo, desde o componente Sidebar até sua integração com o Layout do Next.js, com código completo pronto para você adaptar.
Na semana passada, comecei um projeto de sistema administrativo e pensei imediatamente no shadcn/ui. Para ser sincero, eu já tinha usado Ant Design e MUI, mas sempre achei trabalhoso personalizar os estilos: ou era preciso sobrescrever uma pilha de regras, ou o projeto ficava preso às decisões visuais do framework.
O shadcn/ui é diferente. Ele segue o modelo de copiar e colar: o código vai direto para o seu projeto e você pode alterá-lo como quiser. Depois de duas semanas de uso, a experiência realmente me convenceu. O componente Sidebar, em especial, combinado com o App Router do Next.js, deixa a estrutura do painel muito mais limpa.
Neste artigo, reuni o processo que usei na prática. Vamos partir do zero e criar um layout administrativo escalável.
1. Por que escolher a Sidebar do shadcn/ui?
Antes de começar, vale falar sobre alguns problemas que encontrei.
Eu já havia usado o Ant Design Pro. Ele realmente é conveniente logo de saída, mas, com o tempo, começa a dar trabalho: para mudar o estilo da barra lateral, você passa um bom tempo consultando a documentação; para criar uma interação mais específica, esbarra nas limitações do framework. O MUI tem problemas parecidos. A personalização do tema é flexível, mas parte do princípio de que você domina Material Design.
Problemas das soluções tradicionais
Ant Design: oferece muitos recursos, mas custa caro para personalizar. Para mudar apenas o arredondamento da barra lateral, talvez seja necessário sobrescrever três camadas de estilos.
MUI: possui um design system completo, mas a curva de aprendizado é acentuada. Um integrante novo da equipe pode levar uma semana para se acostumar com Styled Components.
Criar tudo por conta própria: dá controle total, mas implementar do zero uma barra lateral responsiva, acessível e com navegação por teclado pode facilmente consumir três dias.
A proposta do shadcn/ui
O shadcn/ui segue outro caminho:
- Modelo de copiar e colar: o código do componente fica diretamente no seu projeto, sem dependências tratadas como caixa-preta
- Base em Radix UI: a acessibilidade já vem integrada, incluindo navegação por teclado e atributos ARIA
- Estilos com Tailwind CSS: os estilos são classes que você pode alterar livremente, sem a dor de sobrescrever regras existentes
Já vi várias equipes migrarem do MUI para o shadcn/ui por um motivo simples: elas querem controle, e não apenas um template pronto para uso.
Quando usar
Vale experimentar a Sidebar do shadcn/ui se você estiver criando:
- Um sistema administrativo de pequeno ou médio porte
- O console de um produto SaaS
- Uma ferramenta interna ou plataforma de operações
Ela não entrega um template administrativo completo, mas oferece uma estrutura flexível o bastante para você construir o que precisa.
2. Entendendo a arquitetura do componente Sidebar
Antes de colocar a mão no código, é importante entender o conjunto de componentes da Sidebar do shadcn/ui. Essa parte está bem explicada na documentação oficial; aqui faremos uma passagem rápida.
Principais componentes
A Sidebar é formada por um conjunto de componentes com responsabilidades bem definidas:
SidebarProvider // Contexto de estado que envolve toda a aplicação
Sidebar // Contêiner da barra lateral
SidebarHeader // Área fixa superior para o logotipo
SidebarContent // Área rolável para os menus
SidebarGroup // Grupo de menus
SidebarMenu // Lista do menu
SidebarMenuItem // Item do menu
SidebarMenuButton // Botão do menu, com suporte a Link
SidebarFooter // Área fixa inferior para informações do usuário
SidebarTrigger // Botão para recolher ou expandir
SidebarInset // Wrapper da área de conteúdo principal
Embora pareça haver muitos componentes, a relação entre eles é clara:
SidebarProvider
├── Sidebar
│ ├── SidebarHeader
│ ├── SidebarContent
│ │ └── SidebarGroup
│ │ └── SidebarMenu
│ │ └── SidebarMenuItem
│ │ └── SidebarMenuButton
│ └── SidebarFooter
└── SidebarInset
└── {children}
Como o estado é gerenciado
O estado recolhido ou expandido da Sidebar é gerenciado pelo SidebarProvider. Há dois modos de uso.
Modo não controlado (recomendado):
<SidebarProvider defaultOpen={true}>
<Sidebar />
</SidebarProvider>
Modo controlado:
const [open, setOpen] = useState(true);
<SidebarProvider open={open} onOpenChange={setOpen}>
<Sidebar />
</SidebarProvider>
Na maioria dos casos, o modo não controlado é suficiente. Use o modo controlado somente quando precisar alterar o estado da Sidebar a partir de outro ponto da aplicação, como uma opção nas preferências do usuário.
Como funciona o design responsivo
A Sidebar já possui suporte responsivo integrado:
- No desktop: a barra lateral permanece fixa à esquerda e pode ser recolhida por meio de
SidebarTrigger - Em dispositivos móveis: ela se transforma automaticamente em um painel deslizante do tipo Sheet, aberto ao tocar no Trigger
Essa lógica é resolvida internamente pelo componente. Você só precisa configurar corretamente o SidebarProvider.
3. Integração prática com o Layout do Next.js
Agora que os conceitos principais estão claros, vamos à parte mais importante: integrar a Sidebar ao sistema de Layout do Next.js.
3.1 Estrutura do projeto
Recomendo organizar os layouts com Route Groups do Next.js. Assim, diferentes grupos de páginas podem usar layouts distintos sem afetar a estrutura das URLs.
app/
├── layout.tsx # Root Layout (global)
├── (marketing)/ # Grupo de páginas de marketing (Landing, About)
│ ├── layout.tsx # Sem Sidebar
│ └── page.tsx # Página inicial
├── (dashboard)/ # Grupo de páginas administrativas
│ ├── layout.tsx # Layout com Sidebar
│ ├── page.tsx # Página inicial do Dashboard
│ ├── users/
│ │ └── page.tsx # Gestão de usuários
│ └── settings/
│ └── page.tsx # Configurações do sistema
└── (auth)/ # Grupo de páginas de autenticação
├── layout.tsx # Layout centralizado
├── login/
│ └── page.tsx # Login
└── register/
└── page.tsx # Cadastro
Essa estrutura traz três vantagens:
- Isolamento de layouts: páginas de marketing não precisam de Sidebar, enquanto páginas administrativas precisam; os Route Groups separam isso naturalmente
- URLs simples:
(dashboard)não aparece na URL, portanto/userscontinua sendo/users - Facilidade de expansão: para adicionar outro grupo de páginas, basta criar uma pasta
3.2 Configuração do Root Layout
O Root Layout é a entrada de toda a aplicação. Nele, configuramos itens globais como tema, fonte e SidebarProvider.
// app/layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { SidebarProvider } from "@/components/ui/sidebar";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Admin Dashboard",
description: "Built with shadcn/ui and Next.js",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="zh-CN">
<body className={inter.className}>
<SidebarProvider>
{children}
</SidebarProvider>
</body>
</html>
);
}
Observe que o SidebarProvider está no Root Layout, e não no Dashboard Layout. Isso permite preservar o estado da Sidebar entre páginas: se você sair de /users e entrar em /settings, por exemplo, o estado recolhido não será perdido.
3.3 Implementação do Dashboard Layout
O Dashboard Layout é o núcleo da área administrativa; é nele que a Sidebar é incluída.
// app/(dashboard)/layout.tsx
import { AppSidebar } from "@/components/app-sidebar";
import { SidebarInset, SidebarTrigger } from "@/components/ui/sidebar";
import { Separator } from "@/components/ui/separator";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<AppSidebar />
<SidebarInset>
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
<SidebarTrigger className="-ml-1" />
<Separator orientation="vertical" className="mr-2 h-4" />
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem className="hidden md:block">
<BreadcrumbLink href="/dashboard">
后台管理
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator className="hidden md:block" />
<BreadcrumbItem>
<BreadcrumbPage>概览</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</header>
<main className="flex-1 p-4 pt-6">{children}</main>
</SidebarInset>
</>
);
}
Esse layout contém:
- AppSidebar: o componente personalizado da barra lateral, que implementaremos na próxima seção
- SidebarInset: o wrapper do conteúdo principal, que ajusta automaticamente a largura quando a Sidebar é recolhida
- Header: a barra de navegação superior, com SidebarTrigger e breadcrumbs
- Main: a área principal do conteúdo
3.4 Implementação do componente AppSidebar
Agora vamos implementar a barra lateral em si. Recomendo uma abordagem orientada por configuração: os menus ficam em um arquivo de configuração e o componente os renderiza a partir desses dados.
Primeiro, defina a configuração de navegação:
// lib/navigation.ts
import {
Home,
Users,
Settings,
FileText,
BarChart3,
Shield,
} from "lucide-react";
export interface NavItem {
title: string;
href: string;
icon: React.ComponentType<{ className?: string }>;
badge?: string;
}
export const navConfig: NavItem[] = [
{
title: "概览",
href: "/dashboard",
icon: Home,
},
{
title: "用户管理",
href: "/users",
icon: Users,
badge: "12", // 角标
},
{
title: "数据分析",
href: "/analytics",
icon: BarChart3,
},
{
title: "内容管理",
href: "/content",
icon: FileText,
},
{
title: "系统设置",
href: "/settings",
icon: Settings,
},
{
title: "权限管理",
href: "/permissions",
icon: Shield,
},
];
Em seguida, implemente o AppSidebar:
// components/app-sidebar.tsx
"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/components/ui/sidebar";
import { navConfig } from "@/lib/navigation";
import { Logo } from "@/components/logo";
import { UserNav } from "@/components/user-nav";
export function AppSidebar() {
const pathname = usePathname();
return (
<Sidebar>
<SidebarHeader className="border-b border-border">
<Logo />
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>导航菜单</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{navConfig.map((item) => {
const isActive = pathname === item.href;
return (
<SidebarMenuItem key={item.href}>
<SidebarMenuButton
asChild
isActive={isActive}
tooltip={item.title}
>
<Link href={item.href}>
<item.icon className="h-4 w-4" />
<span>{item.title}</span>
{item.badge && (
<span className="ml-auto text-xs bg-primary text-primary-foreground rounded-full px-2 py-0.5">
{item.badge}
</span>
)}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
);
})}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
<SidebarFooter className="border-t border-border">
<UserNav />
</SidebarFooter>
</Sidebar>
);
}
Há um detalhe fundamental aqui: o destaque da rota ativa. Usamos usePathname() para obter o caminho atual e compará-lo com item.href. Quando há correspondência, passamos isActive={true} para SidebarMenuButton, e o componente aplica automaticamente o estilo ativo.
3.5 Implementação de menus com vários níveis
Se o seu painel tiver submenus, você pode envolver SidebarGroup com Collapsible:
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import { ChevronDown } from "lucide-react";
// Dentro de SidebarMenu
<Collapsible defaultOpen>
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton>
<Settings className="h-4 w-4" />
<span>系统设置</span>
<ChevronDown className="ml-auto h-4 w-4 transition-transform group-data-[state=open]/collapsible:rotate-180" />
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent>
<SidebarMenuSub>
<SidebarMenuSubItem>
<SidebarMenuSubButton href="/settings/general">
<span>基础设置</span>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
<SidebarMenuSubItem>
<SidebarMenuSubButton href="/settings/security">
<span>安全设置</span>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
</Collapsible>
4. Recursos avançados
Com o layout básico pronto, podemos avançar para alguns recursos úteis em projetos reais.
4.1 Controle de acesso (RBAC)
Muitos sistemas administrativos precisam exibir menus diferentes conforme a função do usuário. A implementação é simples: adicione um campo roles à configuração de navegação e filtre os itens durante a renderização.
Primeiro, atualize a configuração:
// lib/navigation.ts
export interface NavItem {
title: string;
href: string;
icon: React.ComponentType<{ className?: string }>;
roles?: string[]; // Funções autorizadas a acessar o item
}
export const navConfig: NavItem[] = [
{
title: "概览",
href: "/dashboard",
icon: Home,
// Sem roles: todos podem ver
},
{
title: "用户管理",
href: "/users",
icon: Users,
roles: ["admin", "manager"], // Visível apenas para admin e manager
},
{
title: "权限管理",
href: "/permissions",
icon: Shield,
roles: ["admin"], // Visível apenas para admin
},
];
Depois, filtre os itens no AppSidebar conforme as funções do usuário:
// components/app-sidebar.tsx
import { useAuth } from "@/hooks/use-auth"; // Supondo que exista um hook de autenticação
export function AppSidebar() {
const pathname = usePathname();
const { user } = useAuth(); // Obtém o usuário atual
const filteredNav = navConfig.filter((item) => {
if (!item.roles) return true; // Sem restrição de função: todos podem ver
return item.roles.some((role) => user?.roles?.includes(role));
});
return (
<Sidebar>
{/* ... */}
<SidebarMenu>
{filteredNav.map((item) => {
// ...
})}
</SidebarMenu>
{/* ... */}
</Sidebar>
);
}
Com isso, depois que um usuário comum entrar no sistema, ele não verá o item de menu de gerenciamento de permissões.
4.2 Links externos e separadores
Às vezes, a barra lateral precisa incluir links externos, como documentação e central de ajuda, ou separar o menu em grupos. A Sidebar do shadcn/ui também permite isso:
<SidebarGroup>
<SidebarGroupLabel>主要功能</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{/* Itens principais do menu */}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
<SidebarGroup>
<SidebarGroupLabel>帮助支持</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<a href="https://docs.example.com" target="_blank" rel="noopener">
<BookOpen className="h-4 w-4" />
<span>使用文档</span>
<ExternalLink className="ml-auto h-3 w-3" />
</a>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton asChild>
<a href="mailto:[email protected]">
<HelpCircle className="h-4 w-4" />
<span>联系我们</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
4.3 Campo de busca e ações rápidas
Muitos painéis incluem um campo de busca ou uma busca global acionada por Cmd+K na barra lateral. O componente Command do shadcn/ui atende bem a esse caso:
import { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem } from "@/components/ui/command";
<SidebarGroup>
<SidebarGroupContent>
<Command className="rounded-lg border shadow-md">
<CommandInput placeholder="搜索菜单..." />
<CommandList>
<CommandEmpty>未找到结果</CommandEmpty>
<CommandGroup heading="建议">
{navConfig.map((item) => (
<CommandItem key={item.href} onSelect={() => router.push(item.href)}>
<item.icon className="mr-2 h-4 w-4" />
{item.title}
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</SidebarGroupContent>
</SidebarGroup>
5. Otimização de desempenho e boas práticas
Para terminar, vale destacar alguns pontos de otimização que fazem diferença na prática.
Priorize Server Components
No App Router do Next.js, todos os componentes são Server Components por padrão. As partes estáticas da Sidebar, como o logotipo e itens fixos do menu, podem permanecer no servidor. Apenas as partes que exigem interação, como o destaque de rota e o estado recolhido, precisam de "use client".
Minha abordagem é a seguinte:
- Marcar
AppSidebarcom"use client", pois ele usausePathname - Extrair as partes estáticas de
SidebarHeadereSidebarFooterpara Server Components separados - Gerar a configuração de navegação no servidor e passá-la ao Client Component
Isso reduz o volume de JavaScript enviado ao navegador.
Carregue menus grandes sob demanda
Se o seu painel tiver dezenas de itens de menu, vale considerar o carregamento sob demanda com React.lazy ou dynamic do Next.js:
import dynamic from "next/dynamic";
const AdminMenu = dynamic(() => import("./admin-menu"), {
loading: () => <SidebarMenuSkeleton />,
});
Na prática, porém, a maioria dos painéis não possui tantos itens. Por isso, esse tipo de otimização costuma ser necessário apenas em casos específicos.
Pontos importantes de acessibilidade
A Sidebar do shadcn/ui é baseada no Radix UI e já inclui boa parte dos recursos de acessibilidade. Ainda assim, você deve observar alguns pontos:
- Ícone e texto: não use apenas ícones, pois usuários de leitores de tela não receberão contexto suficiente
- Foco visível: não sobrescreva os estilos padrão de foco
- Navegação por teclado: as teclas Tab e de direção devem funcionar corretamente
O Radix UI cuida da maior parte disso, mas, se você personalizar os componentes, teste a navegação por teclado.
6. Perguntas frequentes
P1: o estado da Sidebar é perdido depois de atualizar ou trocar de página?
Se você colocou o SidebarProvider no Dashboard Layout, e não no Root Layout, o estado será redefinido durante a troca de rota. Mova o Provider para o Root Layout.
P2: como fechar automaticamente a Sidebar em dispositivos móveis?
Em telas móveis, a Sidebar do shadcn/ui se transforma automaticamente em um Sheet. Você precisa fechá-la manualmente depois do clique em um item do menu:
const { setOpenMobile } = useSidebar();
<SidebarMenuButton
onClick={() => setOpenMobile(false)}
>
P3: como personalizar a largura da Sidebar?
Use variáveis CSS:
<Sidebar
style={{
"--sidebar-width": "280px",
"--sidebar-width-mobile": "100%",
}}
>
Outra opção é alterar a constante SIDEBAR_WIDTH em sidebar.tsx.
Conclusão
Combinar a Sidebar do shadcn/ui com o Layout do Next.js é uma forma eficiente de montar a estrutura de um painel administrativo. Estes são os pontos principais:
- Sistema de componentes: entenda as responsabilidades de SidebarProvider, Sidebar, SidebarContent e dos demais componentes
- Integração com Layout: use Route Groups para isolar layouts diferentes e coloque
SidebarProviderno Root Layout - Configuração centralizada: mantenha o menu de navegação em um arquivo de configuração e renderize-o a partir dos dados para facilitar a manutenção
- Destaque de rota: combine
usePathname()com a propriedadeisActivepara uma solução simples e direta - Controle de acesso: adicione
rolesà configuração e filtre os itens durante a renderização
Já usei essa arquitetura em vários projetos, e ela se mostrou bastante escalável. Para incluir uma nova página, basta adicionar uma entrada ao navConfig; o componente cuida do restante.
Se tiver alguma dúvida, deixe um comentário. No próximo artigo, vou abordar o uso prático do DataTable do shadcn/ui.
Referências
- Documentação da Sidebar do shadcn/ui
- Tutorial do App Router do Next.js
- Projeto de código aberto shadcn-ui-sidebar
Montar a estrutura de um painel com Sidebar do shadcn/ui e Layout do Next.js
Crie do zero um layout escalável para um sistema administrativo, com barra lateral, destaque de rota e controle de acesso
⏱️ Estimated time: 45 min
- 1
Step 1: Instale o shadcn/ui e adicione o componente Sidebar
Execute os comandos da CLI para inicializar o projeto e adicionar o componente:
```bash
npx shadcn@latest init
npx shadcn@latest add sidebar
```
Durante a instalação, serão solicitadas algumas opções de estilo; você pode manter as configurações padrão. Ao terminar, o arquivo sidebar.tsx será criado no diretório components/ui. - 2
Step 2: Configure o Root Layout
Envolva o conteúdo com SidebarProvider em app/layout.tsx:
• Importe o componente SidebarProvider
• Envolva {children} dentro da tag body
• Defina o atributo de idioma lang="pt-BR"
Isso garante que o estado da Sidebar seja preservado em toda a aplicação. - 3
Step 3: Crie o Dashboard Layout
Crie um layout exclusivo para o painel em app/(dashboard)/layout.tsx:
• Use a sintaxe de Route Groups (dashboard)
• Importe AppSidebar e SidebarInset
• Adicione o Header superior e a navegação por breadcrumbs
Os Route Groups não afetam a estrutura da URL; o caminho /dashboard é mapeado diretamente sem incluir o nome do grupo. - 4
Step 4: Defina a configuração de navegação
Crie o arquivo de configuração lib/navigation.ts:
• Defina a interface NavItem (title, href, icon e badge)
• Exporte o array navConfig
• Se quiser, adicione o campo roles para implementar controle de acesso
Com essa abordagem orientada por configuração, novos itens de menu exigem alteração em apenas um lugar. - 5
Step 5: Implemente o componente AppSidebar
Crie components/app-sidebar.tsx:
• Use "use client" para marcar o arquivo como Client Component
• Obtenha a rota atual com usePathname
• Percorra navConfig para renderizar os itens do menu
• Quando a rota corresponder, defina isActive para destacar o item - 6
Step 6: Adicione controle de acesso (opcional)
Implemente a filtragem de permissões com RBAC:
• Adicione o campo roles à interface NavItem
• Obtenha as funções do usuário por meio de useAuth no AppSidebar
• Filtre os itens de menu com o método filter
Itens sem o campo roles ficam visíveis para todos os usuários por padrão.
FAQ
Qual é a diferença entre a Sidebar do shadcn/ui e a barra lateral do Ant Design?
O SidebarProvider deve ficar no Root Layout ou no Dashboard Layout?
Como fechar automaticamente a Sidebar em dispositivos móveis?
```tsx
const { setOpenMobile } = useSidebar();
<SidebarMenuButton onClick={() => setOpenMobile(false)}>
```
Assim, o painel será recolhido automaticamente depois da seleção.
Como personalizar a largura da Sidebar?
1. Use uma variável CSS (recomendado):
```tsx
<Sidebar style={{ "--sidebar-width": "280px" }} />
```
2. Altere a constante SIDEBAR_WIDTH em sidebar.tsx
A variável CSS é mais flexível e permite definir larguras diferentes para cada Sidebar.
Como implementar um menu com vários níveis?
• CollapsibleTrigger contém o botão do menu de primeiro nível
• CollapsibleContent contém SidebarMenuSub e os itens de segundo nível
• O ícone ChevronDown indica o estado expandido
O código completo está na seção 3.5 deste artigo.
Como funciona a acessibilidade da Sidebar do shadcn/ui?
16 min de leitura · Publicado em: 27 mar 2026 · Atualizado em: 4 set 2026
Tailwind e shadcn/ui na prática
Se você chegou pela busca, o caminho mais rápido é ir para o post anterior ou próximo desta série.
Anterior
Guia completo para instalar e personalizar temas do shadcn/ui (com variáveis CSS)
Aprenda a instalar e configurar o shadcn/ui e a personalizar temas com variáveis CSS, cores OKLCH e modo escuro. Domine boas práticas para criar uma interface alinhada à sua marca e faça a configuração inicial em 5 minutos.
Parte 4 de 14
Próximo
Layout responsivo com Tailwind na prática: container queries e estratégia de breakpoints
Um guia aprofundado sobre container queries e estratégias de breakpoints no Tailwind CSS, da responsividade baseada na viewport aos layouts responsivos no nível dos componentes.
Parte 6 de 14



Comentários
Entre com GitHub para comentar