Data table
Uma tabela para dados reais, com ordenação, busca, seleção de linhas, colunas fixadas, cabeçalho fixo e paginação.
| Method | Country | |||||
|---|---|---|---|---|---|---|
| [email protected] | Card | United States | 2026-01-01 | $5.00 | ||
| [email protected] | PayPal | Japan | 2026-02-02 | $84.20 | ||
| [email protected] | Bank | Germany | 2026-03-03 | $163.40 | ||
| [email protected] | Apple Pay | Brazil | 2026-04-04 | $242.60 | ||
| [email protected] | Card | India | 2026-05-05 | $321.80 | ||
| [email protected] | PayPal | United States | 2026-06-06 | $401.00 | ||
| [email protected] | Bank | Japan | 2026-07-07 | $480.10 | ||
| [email protected] | Apple Pay | Germany | 2026-08-08 | $559.30 | ||
| [email protected] | Card | Brazil | 2026-09-09 | $638.50 | ||
| [email protected] | PayPal | India | 2026-01-10 | $717.70 |
pnpm dlx shadcn@latest add https://hextaui.com/r/data-table.jsonAdiciona o componente, os tokens de tema do HextaUI e quaisquer componentes do HextaUI dos quais ele depende.
Adicione os tokens de tema ao seu CSS global, se ainda não o fez.
Instale as dependências.
pnpm add @base-ui/react @tabler/icons-react @tanstack/react-table class-variance-authority cnCopie e cole o código a seguir no seu projeto.
components/ui/data-table.tsx components/ui/table.tsx components/ui/button.tsx components/ui/checkbox.tsx components/ui/skeleton.tsx Atualize os caminhos de importação para corresponder à configuração do seu projeto.
O data table é o TanStack Table v9 com os recursos de ordenação, filtragem, paginação, seleção e visibilidade de colunas já ligados. Defina as colunas uma vez com createDataTableColumns, crie a tabela com useDataTable e componha as partes de que precisar.
Passe qualquer estado do TanStack que você queira controlar, como sorting ou row selection, com seu handler de mudança.
DataTableColumnHeader, DataTableSelectAll e DataTableSelectRow vão nas definições de coluna, como o header ou a célula de uma coluna.
Tabela simples
As partes simples de <Table /> com as quais o data table é construído. Use-as isoladamente para dados estáticos, com uma legenda e um total no rodapé.
Carregando
Com loading, as linhas de skeleton ocupam o mesmo espaço das linhas reais, então nada salta quando os dados chegam. A tabela fica marcada com aria-busy nesse meio-tempo.
Empty
emptyMessage preenche o corpo quando não há dados ou nada corresponde à busca.
Cabeçalho fixo
Dê ao contêiner uma altura máxima com containerClassName e defina stickyHeader. O cabeçalho permanece no lugar e ganha uma linha fina quando as linhas rolam por baixo dele. Shift-arrastar sobre os checkboxes rola a caixa conforme você se aproxima da borda.
Colunas fixadas
A coluna de seleção e a primeira coluna de dados são fixadas por padrão. Escolha as suas com pinStart. Uma sombra suave marca a borda quando a tabela rola na horizontal.
Da direita para a esquerda
Todo rótulo e contagem pode ser substituído com labels e as funções de formatação. As setas de paginação e as colunas fixadas se invertem com a direção.
- Clique em um cabeçalho ordenável para ordenar de forma crescente, de novo para decrescente e uma terceira vez para limpar. Shift-clique em outro cabeçalho para adicionar uma ordenação secundária.
- Shift-clique em um checkbox de linha para selecionar todas as linhas entre ele e a última em que você clicou. Segure Shift e arraste sobre os checkboxes para selecionar ou limpar um intervalo de uma só vez.
- A busca corresponde a todas as colunas, exceto a de seleção, e volta à primeira página.
- Ocultar colunas pelo menu View mantém o menu aberto, para que você possa alternar várias de uma vez.
| Tecla | Ação |
|---|---|
| Tab | Percorre a busca, o menu View, os cabeçalhos ordenáveis, os checkboxes das linhas e a paginação. |
| EnterSpace | Ordena pelo cabeçalho em foco. |
| Space | Alterna o checkbox em foco. |
| Esc | Limpa a busca quando ela tem texto. |
- Os cabeçalhos ordenáveis carregam
aria-sort, e uma região live educada (polite) anuncia a nova ordenação e, logo após a digitação, o número de resultados. - O indicador de página é uma região live, então os leitores de tela ouvem a nova página depois de pressionar próxima ou anterior.
- Os checkboxes têm rótulos por padrão. Substitua-os com
aria-labelem<DataTableSelectAll />e<DataTableSelectRow />.
Todas as partes abaixo precisam ser renderizadas dentro de <DataTable />, que compartilha a tabela com elas.
Recebe as opções do TanStack Table e retorna a tabela. As páginas têm 10 linhas, a menos que initialState.pagination diga o contrário.
| Prop | Tipo | Padrão |
|---|---|---|
data | TData[] | – |
columnsCrie-as com createDataTableColumns. | ColumnDef[] | – |
getRowIdMantém a seleção estável quando as linhas se movem. O padrão é o índice da linha. | (row: TData) => string | – |
initialState | Partial<TableState> | { pagination: { pageIndex: 0, pageSize: 10 } } |
stateControle sorting, rowSelection, globalFilter, pagination ou columnVisibility. | Partial<TableState> | – |
onSortingChangeCada estado controlável tem um handler correspondente, como onRowSelectionChange. | OnChangeFn<SortingState> | – |
enableRowSelection | boolean | (row) => boolean | true |
Retorna um column helper tipado com accessor, display e columns. Defina meta: { align: "end" } em colunas numéricas para alinhar o cabeçalho e as células.
| Prop | Tipo | Padrão |
|---|---|---|
tableA tabela retornada por useDataTable. | DataTableInstance<TData> | – |
className | string | – |
| Atributo | Descrição |
|---|---|
data-slot="data-table" | O wrapper em volta de todas as partes. |
data-slot="data-table-announcer" | A região live visualmente oculta. |
| Prop | Tipo | Padrão |
|---|---|---|
emptyMessage | ReactNode | "No results." |
loading | boolean | false |
loadingRowsNúmero de linhas de skeleton durante o carregamento. | number | 5 |
pinStartIds de colunas a fixar na borda inicial. | string[] | ["select", firstColumnId] |
stickyHeaderPrecisa de uma altura máxima no contêiner. | boolean | false |
containerClassNameAplicado ao contêiner de rolagem. | string | – |
swipeSelectShift-arraste sobre os checkboxes para selecionar um intervalo. | boolean | true |
classNameAplicado ao elemento da tabela. | string | – |
| Atributo | Descrição |
|---|---|
data-slot="table-container" | O contêiner de rolagem. |
data-scrolled-start | Presente no contêiner quando ele rolou para longe da borda inicial. |
data-scrolled-end | Presente enquanto há mais a rolar em direção à borda final. |
data-scrolled-top | Presente quando as linhas rolam na vertical. |
data-swipe-selecting | Presente no contêiner durante um shift-arrastar. |
data-state="selected" | Presente nas linhas selecionadas. |
data-row-id | O id da linha vindo de getRowId. |
data-slot="data-table-loading-row" | Cada linha de skeleton. |
data-slot="data-table-empty" | A linha vazia. |
Uma linha com quebra para a busca, o menu View e seus próprios filtros. Aceita todas as props de div e carrega data-table-toolbar como seu data-slot.
| Prop | Tipo | Padrão |
|---|---|---|
placeholder | string | "Search…" |
aria-label | string | "Search table" |
clearLabelNome acessível do botão de limpar. | string | "Clear search" |
| Atributo | Descrição |
|---|---|
data-slot="data-table-search" | O wrapper do campo de busca. |
| Prop | Tipo | Padrão |
|---|---|---|
label | string | "View" |
groupLabel | string | "Toggle columns" |
getLabelO padrão é o header em string da coluna, ou seu id com inicial maiúscula. | (column) => string | – |
Lista todas as colunas que podem ser ocultadas. Defina enableHiding: false em uma coluna para deixá-la de fora.
| Atributo | Descrição |
|---|---|
data-slot="data-table-view-options" | O popup do menu. |
| Prop | Tipo | Padrão |
|---|---|---|
column | Column | – |
title | string | – |
Renderiza um botão de ordenação para colunas ordenáveis e texto simples para as demais.
| Atributo | Descrição |
|---|---|
data-slot="data-table-column-header" | O wrapper do cabeçalho. |
data-sorted | Presente no botão de ordenação enquanto a coluna está ordenada. |
aria-sort | Na célula do cabeçalho: crescente, decrescente ou nenhuma. |
| Prop | Tipo | Padrão |
|---|---|---|
table | Table | – |
aria-label | string | "Select all rows on this page" |
Seleciona as linhas da página atual e mostra um estado indeterminado quando só algumas estão selecionadas.
| Prop | Tipo | Padrão |
|---|---|---|
row | Row | – |
aria-label | string | "Select row" |
| Prop | Tipo | Padrão |
|---|---|---|
pageSizes | number[] | [10, 20, 50, 100] |
showSelectionMostra a contagem de selecionados em vez da contagem de linhas. | boolean | true |
labelsrowsPerPage, firstPage, previousPage, nextPage e lastPage. | Partial<DataTablePaginationLabels> | – |
formatSelection | (selected: number, total: number) => ReactNode | "2 of 42 rows selected" |
formatRows | (total: number) => ReactNode | "42 rows" |
formatPage | (page: number, pageCount: number) => ReactNode | "Page 1 of 5" |
| Atributo | Descrição |
|---|---|
data-slot="data-table-pagination" | A barra de paginação. |
Retorna a tabela do <DataTable /> mais próximo. Use para criar seus próprios controles de barra de ferramentas, como um filtro de status.
| Prop | Tipo | Padrão |
|---|---|---|
stickyHeaderFixa a linha do cabeçalho dentro de um contêiner de rolagem. | boolean | false |
containerClassNameAplicado ao contêiner de rolagem. | string | – |
containerRef | Ref<HTMLDivElement> | – |
| Atributo | Descrição |
|---|---|
data-slot="table" | O elemento da tabela. |
data-sticky-header | Presente no contêiner quando stickyHeader está ativado. |
--table-bg | Fundo da linha e das células fixadas. Segue o card ou popover em que está. |
| Prop | Tipo | Padrão |
|---|---|---|
alignCélulas alinhadas ao fim também usam números tabulares. | "start" | "center" | "end" | "start" |
pinnedMantém a célula no lugar enquanto a tabela rola na horizontal. Ajuste o deslocamento com --pin-offset. | "start" | "end" | – |
pinnedEdgeDesenha uma sombra suave na última coluna fixada enquanto há rolagem. | boolean | false |
| Atributo | Descrição |
|---|---|
data-align | O alinhamento atual. |
data-pinned | start ou end quando fixada. |
data-pinned-edge | Presente na última célula fixada de um lado. |
--pin-offset | Distância da borda fixada, definida para você. |
TableHeader, TableBody, TableFooter, TableRow e TableCaption renderizam os elementos de tabela correspondentes e aceitam todas as props deles.
- ButtonBotões em todas as variantes e tamanhos, com um fluxo integrado de carregamento, sucesso e erro que dispensa o spinner em requisições rápidas.
- CheckboxUma caixa de seleção cujo check é desenhado na tela, com pais indeterminados, grupos e rótulos que compartilham seu hover.
- SkeletonPlaceholders que esperam 150ms antes de aparecer, assumem o tamanho exato do conteúdo que envolvem e o fazem surgir com fade sem mover nada.
- TableUma tabela responsiva com estilo de superfície, células com quebra de linha ou compactas, cabeçalhos fixos, colunas fixadas e indicações de rolagem.
- AvatarFotos de usuário com fallback de iniciais, badges de status e grupos empilhados que se recolhem em uma contagem.
- BadgeRótulos de status com pontos coloridos, tags removíveis que deslizam até fechar e contagens que rolam até o novo valor.