DataTable
Tabela de dados com colunas declaradas: cada coluna diz o cabeçalho, de onde vem o valor (accessor), como aparece (cell), se ordena e o alinhamento. Tem cabeçalho fixo, estado vazio, carregamento e paginação, no cliente ou no servidor, como o DataList.
Uma coluna por ambiente
O caso que pede tabela: um Switch por ambiente, alinhado ao cabeçalho, com o estado em StatusBadge de tom genérico. Clique nos cabeçalhos para ordenar; o terceiro clique volta à ordem original. Flags fora do estado Ativa ficam travadas.
| assinatura-em-loteAssinar vários envelopes de uma vez | Ativa | 12/10/2026, 09:05 | |||
| checkout-v2Novo fluxo de pagamento | Ativa | 16/10/2026, 14:20 | |||
| lembrete-whatsappLembretes pelo WhatsApp | Ativa | 17/10/2026, 08:10 | |||
| painel-legadoPainel antigo de relatórios | Arquivada | 30/08/2026, 18:00 | |||
| selfie-obrigatoriaExige selfie em todo envelope | Revogada | 02/10/2026, 11:45 |
Servidor e paginação
mode="server": a tabela não ordena nem pagina; avisa a consulta em onQueryChange e mostra o que chegar, com total para a paginação. Aqui, 230 eventos de auditoria com 600ms de espera e cabeçalho fixo com altura máxima.
| Flag | O quê | ||
|---|---|---|---|
Vazio
Sem linhas, aparece o emptyState (ou um texto curto).
Nenhuma flag arquivadaFlags arquivadas aparecem aqui. | |||||
Uso
<DataTable
aria-label="Feature flags"
rows={flags}
getRowId={(flag) => flag.key}
columns={[
{ id: "key", header: "Flag", accessor: (flag) => flag.key, sortable: true },
{ id: "state", header: "Estado", cell: (flag) => <StatusBadge tone="success" label="Ativa" /> },
{ id: "prod", header: "prod", align: "center", cell: (flag) => <Switch checked={flag.prod} … /> },
]}
/>
<DataTable mode="server" rows={page.rows} total={page.total} onQueryChange={({ sort, page, pageSize }) => load(…)} … />Props
DataTableColumn = { id, header, accessor?, cell?, sortable?, align?, width?, className?, headerClassName? }.
| Prop | Tipo | Padrão | Descrição |
|---|---|---|---|
| columns · rows · getRowId | DataTableColumn[] · T[] · (row) => string | — | Colunas, linhas e a chave de cada linha. |
| aria-label · caption | string · ReactNode | — | Nome da tabela e legenda visível. |
| sort · defaultSort · onSortChange | { columnId, direction } | null | — | Ordenação. Clique no cabeçalho alterna crescente, decrescente e nenhuma; vazios ficam no fim. |
| page · pageSize · pageSizeOptions | number · number · number[] | 1 · 20 · [10, 20, 50, 100] | Paginação, controlada ou não, com onPageChange e onPageSizeChange. |
| pagination | boolean | — | Força mostrar ou esconder; por padrão aparece quando há mais linhas que pageSize ou no modo servidor. |
| mode · onQueryChange · total | "client" | "server" · (query) => void · number | "client" | No servidor, avisa { sort, page, pageSize } e usa total para as páginas. |
| loading · skeletonRows · emptyState | boolean · number · ReactNode | false · 5 | Carregamento e vazio. |
| stickyHeader · maxHeight | boolean · string | — | Cabeçalho fixo com rolagem dentro da tabela. |
| density · onRowClick · rowClassName | "compact" | "comfortable" · (row, event) => void · (row) => string | "comfortable" | Densidade, clique na linha e classe por linha. |