PageHeader, FilterTabs, Tabs, Card, seções simples). Esta página documenta o que está onde e — para colaboradores — quando usar cada primitivo, para que novas telas tenham a mesma aparência e comportamento do restante do produto.
Estrutura da barra lateral
A barra lateral esquerda usa grupos recolhíveis. Cada grupo é uma rota pai; seus filhos são uma lista simples de destinos de primeira classe abaixo dela.Inbox
Simples — sem subgrupo. Leva direto ao inbox do operador.
Contacts
Simples. Filtros e segmentos vivem dentro da página, não na barra lateral.
Agents
Grupo recolhível. Filhos:
Overview, Templates e rotas de detalhe por agente.Campaigns
Grupo recolhível. Filhos:
All campaigns, Audiences, Schedules.Journeys
Grupo recolhível. Filhos:
All journeys, Templates, Runs.Settings
Simples; abas internas cuidam das várias sub-páginas.
localStorage, para que a estrutura não se recolha novamente a cada navegação.
Sub-rotas sob um registro pai
Páginas de detalhe para Agents, Campaigns e Journeys usam um formato de URL consistente:PageHeader. Cada aba é uma rota real — pode ser acessada por link direto, compartilhada e é preservada entre recarregamentos. As trocas de aba usam navegação shallow do Next.js, então a posição de scroll e o estado transitório não se perdem.
As abas de sub-rota não são o mesmo primitivo que os
Tabs de página. Veja Abas de filtro vs. abas de conteúdo abaixo.Breadcrumbs
A barra superior renderiza uma trilha de breadcrumb que é, por padrão, auto-derivada da rota atual. O sistema percorre os segmentos do pathname, consulta cada um em um pequeno registro (/apps/app/lib/breadcrumbs.ts) para obter um rótulo legível e renderiza migalhas clicáveis para cada segmento, exceto o último.
Modo automático (o padrão)
Toda página recebe breadcrumbs auto-derivados sem fazer nada:/agents/abc123/runs, isso renderiza: Agents › Acme support bot › Runs. O rótulo do meio é resolvido pelo loader [id] do registro (ele busca o nome de exibição do agente no cache).
Use o modo automático quando:
- Os segmentos de rota mapeiam de forma clara para rótulos legíveis (o caso comum).
- Você já está dentro de uma hierarquia de registro pai/filho já cadastrada no registro.
Modo explícito
Passebreadcrumbs como um array quando a trilha auto-derivada estaria errada ou sem contexto suficiente:
- A URL não reflete o local mental do usuário (por exemplo, rotas modais, wizards).
- Você precisa exibir um rótulo que ainda não está no registro e não quer adicioná-lo.
- Você está renderizando uma página pontual (migrações, ferramentas administrativas) em que manter o registro atualizado não vale o esforço.
Abas de filtro vs. abas de conteúdo
O Switchbord fornece dois primitivos de abas que parecem semelhantes, mas cumprem papéis diferentes.FilterTabs — controle segmentado
Uma linha compacta de botões segmentados. Escolhe qual recorte da mesma lista você está visualizando. Não tem painéis de conteúdo próprios — apenas controla o estado de query/filtro abaixo.
Use FilterTabs quando:
- Estiver alternando entre visualizações do mesmo conjunto de dados subjacente (por exemplo,
All / Draft / Pending / Approvedem templates). - Você quiser um visual de controle segmentado que não sugira “páginas” separadas.
- For navegação de sub-rota para um registro de detalhe (
config | tools | mcp | runs).
Tabs — regiões de conteúdo
O primitivo Tabs completo, baseado em Radix, com TabsList, TabsTrigger e TabsContent. Cada aba possui uma região de conteúdo distinta, com seu próprio cabeçalho, seus próprios dados e, potencialmente, suas próprias mutações.
Use Tabs quando:
- As abas renderizam interfaces estruturalmente diferentes (por exemplo, Overview vs. JSON vs. Logs).
- Cada aba tem conteúdo substancial — tabelas, formulários, gráficos.
- De outra forma, seria necessário dividir em rotas irmãs, mas as telas estão fortemente acopladas demais para justificar navegação em nível de URL.
Cards vs. seções — composição de página
O erro mais comum em telas novas é envolver tudo em umCard. Nossa gramática de página é:
PageHeaderno topo — título, descrição, breadcrumbs, ação principal.- Seções simples abaixo — um
<h2>(ou um pequeno componente de cabeçalho de seção) seguido de conteúdo diretamente sobre o fundo da página. Cardapenas para painéis laterais, seletores modulares, ou coisas que genuinamente precisam de um contêiner com borda.
Prefira seções simples
Cards completos produz páginas pesadas e “encaixotadas” que não escalam bem além de três seções.
Use Card quando
- Painéis laterais — um resumo na coluna direita ao lado do conteúdo principal.
- Seletores modulares — seletor de modelo, seletor de template, caixa de filtro de audiência. Widgets autocontidos que podem viver em qualquer lugar da página.
- Estados vazios e prompts de onboarding — um único elemento centralizado em uma página, do contrário, vazia.
- Blocos de dashboard — cards de métrica em páginas de visão geral.
Checklist rápido para novas páginas
Antes de abrir um PR para uma nova tela, confirme:-
PageHeaderé o primeiro elemento;breadcrumbsestá ou omitido (automático) ou é um array explícito — nunca os dois. - As sub-rotas sob um registro usam
FilterTabsconectadas a URLs reais, e nãoTabsde página. - A entrada na barra lateral é simples, a menos que existam 3 ou mais rotas irmãs, caso em que se torna um grupo recolhível com um ícone apropriado.
- A estrutura de nível superior é
PageHeader+ seções.Cardaparece apenas para painéis laterais, seletores, estados vazios ou blocos de dashboard. - Todo novo segmento
[id]tem um loader de rótulo registrado em/apps/app/lib/breadcrumbs.ts(ou breadcrumbs explícitos são passados em cada ponto de uso).
Entregue neste projeto
O projeto de navegação e polimento de interface (BORD-329 → BORD-333) entregou:- BORD-329 — grupos recolhíveis na barra lateral para Agents / Campaigns / Journeys ✅
- BORD-330 — abas de sub-rota por registro (
config | tools | mcp | runse afins) ✅ - BORD-331 — breadcrumbs auto-derivados com um pequeno registro + escape hatch de override explícito ✅
- BORD-332 — refatoração da gramática de página:
PageHeader+ seções,Cardrebaixado para função de painel lateral ✅ - BORD-333 — este documento + uma limpeza de design tokens no CTA da landing page
/web✅