Componentes
shadcn/ui, shared components e Lucide icons
O frontend trabalha com três camadas de componentes:
src/components/ui/— primitivos do shadcn/ui (código próprio, editável)src/components/shared/— componentes compartilhados de alto nível, obrigatórios para padronizaçãosrc/components/layout/— shell do app (AppLayout,AppSidebar,AppHeader)
Shared Components
Localizados em src/components/shared/. Obrigatórios para qualquer nova página. Nunca construa esses padrões manualmente inline — use os componentes.
| Componente | Uso |
|---|---|
PageHeader | Cabeçalho de página (title, description, children = ação principal) |
KpiCard | Cartão de métrica (label, value, tooltip, delta) |
ChartCard | Wrapper de gráficos (title, description, action, legend, narrative) |
EmptyState | Estado vazio de página (icon, title, description, action) |
SectionOverline | Texto de rótulo de seção |
HubLayout | Layout de hub (sidebar + área principal) |
HubSidebarSection | Seção colapsável na sidebar do hub |
HubTimeline | Timeline de eventos do hub |
InlineEditField | Campo editável inline (click-to-edit) |
SearchableSelect | Combobox com busca accent-insensitive e opção "Criar X" |
LoadingState | Skeleton de carregamento de página |
RouteErrorBoundary | Error boundary global da rota raiz |
SuspenseWrapper | Wrapper para lazy loading com Suspense |
Nunca use <h1>, <h2> ou <h3> soltos como título de página — sempre PageHeader. Nunca envolva um gráfico em Card + CardHeader + CardTitle direto — use ChartCard. Nunca construa um cartão de KPI manualmente — use KpiCard.
Exemplo: PageHeader
import { PageHeader } from "@/components/shared/PageHeader";
<PageHeader title="Negócios" description="Gerencie seu pipeline de vendas.">
<Button>Novo negócio</Button>
</PageHeader>Exemplo: KpiCard
import { KpiCard } from "@/components/shared/KpiCard";
<KpiCard
label="Negócios ganhos"
value="R$ 42.000"
tooltip="Total de negócios marcados como ganhos no período"
delta={{ value: "+12%", direction: "up" }}
/>Exemplo: ChartCard
import { ChartCard } from "@/components/shared/ChartCard";
<ChartCard title="Negócios por semana" description="Criados vs ganhos">
{/* loading skeleton, error state, empty state ou o chart */}
</ChartCard>shadcn/ui
Style radix-nova. Configuração em apps/app/components.json, tokens (oklch) em src/index.css.
A lista atual de componentes instalados está em apps/app/src/components/ui/. Antes de adicionar, verifique se já existe.
Adicionar componentes
cd apps/app && bunx shadcn@latest add <component>Componentes recomendados
Antes de hand-buildar UI, veja se shadcn já tem:
- Tabelas com sorting/filtering →
table+ TanStack Table - Charts →
chart - Command palette →
command - Paginação →
pagination - Date picking →
calendar/date-picker - Drawers →
drawer - Toasts →
sonner(usetoast()desonner)
Imports
Importe diretamente — sem wrappers:
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";Customização
Os componentes em src/components/ui/ são código próprio. Edite o arquivo diretamente quando precisar customizar.
cn()
Utilitário para merge condicional de classes (clsx + tailwind-merge):
import { cn } from "@/lib/utils";
<div className={cn("px-4 py-2", isActive && "bg-primary text-white")} />Ícones
Apenas Lucide React:
import { Settings, Users, Kanban } from "lucide-react";
<Settings className="size-4" />