Padrões de tela
Anatomia de uma tela
A ordem
| # | Bloco | Receita |
|---|---|---|
| 1 | Cabeçalho — barra de tela (sem sub-telas) ou palco (com sub-telas) | PageBar h-14 sticky · PageStage grade de 3 colunas |
| 2 | Cartões de número — informam o que mudou (não filtram) | grid gap-3 · rounded-xl border px-4 py-3 |
| 3 | Ferramentas — recorte + busca + filtros + ações da tela | flex flex-wrap gap-2/gap-3 · mb-phi-3 |
| 4 | Recorte de visão, quando a lista tem sub-coleções | segmented control: trilho rounded-full bg-ink-100 p-1 |
| 5 | A lista — cards (agenda) ou tabela (cadastros) | gap-phi-3 / rounded-xl |
| 6 | O detalhe — a própria linha expande em ficha, não navega | Gaveta + EditSurface |
| 7 | Ações em massa — barra flutuante na base | fixed bottom-4 · rounded-2xl · shadow-md ring-1 |
Qual cabeçalho
Sem sub-telas → barra de tela
Faixa de 56px que sangra de ponta a ponta e cola no topo. Cadastros é o molde; Hoje, Números, Atendente e Atendimento repetem. O título é o h1 da página.
Com sub-telas → palco de tela
Grade de três colunas onde o título vira endereço fixo e o rail inteiro mora na faixa. Cobre /ajustes (11 sub-telas) e /configuracoes. O rail NUNCA volta a ser coluna própria ao lado do conteúdo.
Números e recortes: duas peças, dois trabalhos
| Peça | O que faz | Receita |
|---|---|---|
| Cartão de número | INFORMA. Não é clicável. | rounded-xl border px-4 py-3 · valor text-2xl font-bold tabular-nums · rodapé text-xs |
| Chip de recorte | FILTRA a lista. Clicar aplica; clicar no ativo volta ao geral. | h-8 rounded-full border px-3 · ativo bg-brand-muted text-brand-strong · contagem tabular-nums opacity-70 · aria-pressed |
| Segmented control | Troca a VISÃO da mesma lista (Dia/Semana da Agenda, os recortes de Números). | trilho rounded-full bg-ink-100 p-1 · ativo bg-surface shadow-xs · role=tablist |
NotaDe três a cinco recortes
Ferramentas
{/* criar mora no topo: <PageBar action={<Button size="sm">Novo cadastro</Button>} /> */}
<div className="flex flex-wrap items-center gap-2 sm:flex-nowrap">
<Button variant="outline" size="sm" className="shrink-0">Filtros</Button>
{/* Importar, Exportar, Colunas: Button outline sm, shrink-0 */}
{/* ⋯ com o que não ganhou botão */}
<LupaDeBusca modo="empurra" className="hidden sm:flex" larguraClassName="w-75 min-w-0 shrink" />
</div>
<SearchInput wrapperClassName="w-full sm:hidden" />| Regra | Detalhe |
|---|---|
| Duas alturas, e só duas | h-9 no campo de busca (é um Input), h-8 nos chips, nos botões de toolbar e na pílula da LupaDeBusca. No dedo todos sobem um degrau sozinhos. |
| flex-wrap sempre | No celular a linha quebra em vez de espremer. |
| A busca tem largura própria | wrapperClassName="w-full sm:w-64" — largura no invólucro, nunca no input. Onde buscar é raro ou a barra é apertada, a busca é a LupaDeBusca (Funil, Números, Base de conhecimento, Cadastros): fechada ocupa só a lupa, aberta toma 240px empurrando os vizinhos (300px em Cadastros, cedendo quando a fileira aperta). Abaixo de 640px a lupa vira campo de linha inteira. |
| Ferramentas no corpo, não na barra | A barra de tela só recebe ferramentas quando a tela NÃO tem corpo rolável (o Atendimento) — ali não há onde pôr a toolbar. |
| Focar a busca não apaga a lista | O foco em camadas fica de fora da toolbar de propósito: focar a busca serve pra VER a lista. |
Lista, detalhe e vazio
Cards ou tabela
| Formato | Quando | Nota |
|---|---|---|
| Tabela | Muitas linhas com os MESMOS campos comparáveis (cadastros). | Cabeçalho em overline, hover ink-50, numérico à direita, telefone em tabular-nums. |
| Cards | Poucos itens com forma própria (compromissos, documentos). | gap-phi-3, e o card clicável tem o hover do canon. |
| Linhas com divide-y | Listas curtas dentro de um card (insumos, equipe). | divide-y divide-border no pai; a linha só cuida do próprio ritmo. |
Colunas: escolha de quem olha
Tabela de muitas linhas não tem coluna fixa por decreto. A tabela recebe um layout — a lista ordenada de coluna e largura — e pinta o que ele manda; quem diz rótulo, forma e valor de cada coluna é o catálogo em lib/pessoas/colunas.ts, e o rótulo é o MESMO do campo de filtro, pra recepção ler no topo da coluna a palavra que ela digitou no filtro.
| Regra | Como | Por quê |
|---|---|---|
| A primeira coluna é a pessoa | Não desliga e não sai do lugar. | É a porta pra ficha e a identidade da linha — tabela de pessoas sem a pessoa é lista de valores sem dono. |
| Ela congela na rolagem lateral | sticky z-10 isolate bg-surface na primeira célula do corpo, e a LINHA declara o fundo. | Célula grudada com fundo transparente deixa o texto que rola passar por baixo do nome. |
| O título das colunas fica preso | Cada th é sticky top-0 bg-inherit, com o fio de baixo em sombra (shadow-[inset_0_-1px_0_var(--border)]); na tela alta (tela-alta: 1024px de largura e 640px de altura) só a lista rola, e o rodapé de páginas fica no pé do cartão. O cartão é isolate: as camadas do título não passam por cima da barra de tela. | Numa tabela colapsada a borda fica na tabela e não acompanha a célula presa: sem a sombra, o título flutua sem fio. |
| A largura se puxa pela borda do cabeçalho | Alça de 6px, piso por coluna, teto de 480px, e ←/→ no teclado. | Arrasto não tem equivalente de teclado: sem as setas, largura de coluna vira gesto só de mouse. |
| A ordem se muda no painel | Arrastar pela alça (ui/alca-de-ordem.tsx; em foco, ↑/↓ no teclado) OU os botões ↑/↓ de cada linha. | Arrastar 19 itens dentro de um popover com o polegar é o gesto que ninguém acerta. |
| Grava no soltar, não no pixel | O arrasto mexe na tela; o soltar grava. | Uma escrita por quadro de animação. |
| No celular a tabela não existe | Cartão de uma coluna, e o botão Colunas só aparece de 640px pra cima. | Escolher coluna numa tela que não tem tabela é escolher nada. |
NotaColuna não é filtro
NotaO detalhe não navega
Cada tela precisa dos três estados prontos antes de ser considerada pronta: carregando (cabeçalho real + esqueleto do corpo), vazio (nas duas variantes: nunca teve, e o filtro não achou) e erro (painel calmo com “tentar de novo”).
No celular
| Bloco | O que muda |
|---|---|
| Barra de tela | Deixa de ser sticky: o topo já tem header + navegação grudados. |
| Palco | A grade se desfaz: faixa vira cabeçalho empilhado e o rail vira tira horizontal. |
| Fileira de resumo | Uma coluna, ou duas se os rótulos forem curtos. |
| Ferramentas | Quebram em linhas; o campo de busca ocupa a primeira inteira (a lupa divide a linha com o botão). |
| Tabela | Vira lista de linhas empilhadas — tabela com rolagem lateral é último recurso. |
| Ações em massa | A pílula flutuante encolhe e os rótulos viram só ícone + contagem. |