Inicio / Trilha 2 / Modulo 2.3
MODULO 2.3

πŸ“‹ Tabelas e DataGrids

Sorting, paginacao, virtualizacao e data tables profissionais para grandes volumes de dados em dashboards.

πŸ“š
6
Topicos
⏱️
50min
Duracao
πŸ“Š
Intermediario
Nivel
🎯
Pratico
Tipo
1

πŸ“Š Anatomia de uma Data Table

Estrutura completa de tabelas profissionais

Data Tables sao componentes complexos para exibir dados tabulares com funcionalidades como ordenacao, filtragem, selecao e acoes. Diferem de tabelas HTML simples por serem interativas e otimizadas para grandes volumes.

Tabelas sao o coracao de dashboards administrativos. Lista de clientes, pedidos, transacoes - tudo vira tabela. Uma tabela mal projetada torna o sistema inutilizavel; bem projetada, e extremamente poderosa.

πŸ” Estrutura de uma Data Table

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ ☐ Selecionar todos    [πŸ” Buscar...]    [Filtros] [Exportar]β”‚ ← Toolbar
β”œβ”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ ☐   β”‚ Nome ↑↓        β”‚ Email      β”‚ Status   β”‚ Acoes        β”‚ ← Header
β”œβ”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ ☐   β”‚ Ana Silva      β”‚ ana@...    β”‚ ● Ativo  β”‚ [✏️] [πŸ—‘οΈ]   β”‚ ← Row
β”‚ ☐   β”‚ Bruno Lima     β”‚ bruno@...  β”‚ β—‹ Inativoβ”‚ [✏️] [πŸ—‘οΈ]   β”‚
β”‚ ☐   β”‚ Carla Dias     β”‚ carla@...  β”‚ ● Ativo  β”‚ [✏️] [πŸ—‘οΈ]   β”‚
β”œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Mostrando 1-10 de 156           [β—€] [1] [2] [3] ... [β–Ά]    β”‚ ← Footer
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🧩 Componentes da Data Table

1. Toolbar

Busca global, filtros avancados, acoes em lote, exportacao.

2. Header

Titulos ordenaveis, checkbox global, resize de colunas.

3. Body (Rows)

Dados, selecao individual, hover states, linhas expandiveis.

4. Footer

Paginacao, contador de resultados, itens por pagina.

πŸ‘οΈ Exemplo: Mini Data Table

Nome ↕ Email Status
Ana Silva ana@exemplo.com Ativo
Bruno Lima bruno@exemplo.com Inativo

πŸ’‘ Dica Pratica

Comece simples: Adicione funcionalidades incrementalmente. Uma tabela basica bem estilizada e melhor que uma super complexa cheia de bugs. Comece com ordenacao, depois adicione paginacao, depois filtros.

2

πŸ”€ Ordenacao (Sorting)

Reorganizar dados por qualquer coluna

Ordenacao permite reorganizar dados por qualquer coluna em ordem crescente ou decrescente. Usuarios esperam clicar no cabecalho para ordenar. Suportar ordenacao multipla (shift+click) e um diferencial.

Ordenacao e a funcionalidade mais usada em tabelas. "Quem sao os maiores clientes?", "Quais pedidos sao mais recentes?" - tudo requer ordenacao. Sem ela, tabelas sao estaticas e frustrantes.

πŸ”„ Estados de Ordenacao

↕️
Nao ordenado

Estado inicial, clicavel

⬆️
Ascendente (A-Z)

Menor para maior

⬇️
Descendente (Z-A)

Maior para menor

πŸ’» Codigo: Logica de Ordenacao

// Funcao de ordenacao generica
function sortTable(data, column, direction = 'asc') {
  return [...data].sort((a, b) => {
    let valA = a[column];
    let valB = b[column];

    // Normalizar strings para comparacao
    if (typeof valA === 'string') {
      valA = valA.toLowerCase();
      valB = valB.toLowerCase();
    }

    // Comparacao
    if (valA < valB) return direction === 'asc' ? -1 : 1;
    if (valA > valB) return direction === 'asc' ? 1 : -1;
    return 0;
  });
}

// Uso
const sortedData = sortTable(users, 'name', 'asc');

// Header clicavel (HTML)
<th class="cursor-pointer hover:bg-dark-700 select-none px-4 py-3"
    onclick="handleSort('name')">
  <span class="flex items-center">
    Nome
    <span class="ml-2 text-neutral-500">
      {sortColumn === 'name' ? (sortDir === 'asc' ? '↑' : '↓') : '↕'}
    </span>
  </span>
</th>

βœ… Fazer vs ❌ Evitar

βœ… Fazer
  • β€’ Indicar visualmente coluna ordenada
  • β€’ Ciclo: neutro β†’ asc β†’ desc β†’ neutro
  • β€’ Manter ordenacao ao paginar
  • β€’ Ordenar no backend se muitos dados
❌ Evitar
  • β€’ Ordenar coluna sem feedback visual
  • β€’ Ordenar 10k+ registros no frontend
  • β€’ Ignorar tipos (numero vs string)
  • β€’ Perder ordenacao ao mudar de pagina
3

πŸ“„ Paginacao

Dividir dados em paginas gerenciaveis

Paginacao divide grandes conjuntos de dados em paginas menores. Tipicamente 10, 25, 50 ou 100 itens por pagina. Essencial para performance e usabilidade quando ha centenas ou milhares de registros.

Tabelas com 1000+ linhas sem paginacao travam o navegador e sao impossiveis de navegar. Paginacao melhora performance, facilita navegacao e permite o backend enviar dados em chunks.

πŸ“Š Tipos de Paginacao

Numerada (mais comum)
...
Load More (scroll progressivo)

Botao "Carregar mais" no final da lista. Bom para feeds infinitos.

Infinite Scroll

Carrega automaticamente ao scrollar. Use com cuidado - pode ser confuso.

πŸ’» Codigo: Componente de Paginacao

<!-- Paginacao completa -->
<div class="flex items-center justify-between px-4 py-3 border-t border-dark-600">

  <!-- Info de resultados -->
  <p class="text-sm text-neutral-400">
    Mostrando <span class="font-medium text-white">1</span> a
    <span class="font-medium text-white">10</span> de
    <span class="font-medium text-white">156</span> resultados
  </p>

  <!-- Navegacao -->
  <div class="flex items-center space-x-1">
    <button class="px-3 py-1.5 rounded bg-dark-700 hover:bg-dark-600
                   disabled:opacity-50 disabled:cursor-not-allowed"
            disabled>β—€ Anterior</button>

    <button class="px-3 py-1.5 rounded bg-blue-600 text-white">1</button>
    <button class="px-3 py-1.5 rounded bg-dark-700 hover:bg-dark-600">2</button>
    <button class="px-3 py-1.5 rounded bg-dark-700 hover:bg-dark-600">3</button>
    <span class="px-2 text-neutral-500">...</span>
    <button class="px-3 py-1.5 rounded bg-dark-700 hover:bg-dark-600">16</button>

    <button class="px-3 py-1.5 rounded bg-dark-700 hover:bg-dark-600">
      Proximo β–Ά
    </button>
  </div>
</div>

// Calculo de paginacao (JavaScript)
const itemsPerPage = 10;
const currentPage = 1;
const totalItems = 156;

const totalPages = Math.ceil(totalItems / itemsPerPage); // 16
const startIndex = (currentPage - 1) * itemsPerPage;     // 0
const endIndex = startIndex + itemsPerPage;              // 10
const pageData = allData.slice(startIndex, endIndex);

πŸ’‘ Dica Pratica

Permita configurar itens por pagina: Adicione um seletor (10, 25, 50, 100) para usuarios que preferem ver mais ou menos dados de uma vez. Power users geralmente preferem 50-100.

4

⚑ Virtualizacao de Tabelas

Performance com milhares de linhas

Virtualizacao renderiza apenas as linhas visiveis na tela, mesmo com milhares de registros. Conforme o usuario scrolla, linhas sao recicladas. Permite scroll "infinito" sem paginacao tradicional.

Para datasets enormes (10k+ linhas), paginacao ainda pode ser lenta. Virtualizacao mantem 60fps mesmo com 100k linhas. Bibliotecas como react-window e TanStack Virtual facilitam a implementacao.

πŸ” Como a Virtualizacao Funciona

Dados totais: 10.000 linhas
Viewport visivel: ~20 linhas

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Espaco vazio (padding-top)      β”‚  ← Altura simulada
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Linha 245  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β”‚
β”‚ Linha 246  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β”‚  ← Apenas linhas
β”‚ Linha 247  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β”‚    visiveis sao
β”‚ Linha 248  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β”‚    renderizadas
β”‚ Linha 249  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β”‚    no DOM
β”‚ Linha 250  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚      Espaco vazio (padding-bottom)   β”‚  ← Altura simulada
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Processo ao scrollar:
1. Detecta posicao do scroll
2. Calcula quais linhas estao visiveis
3. Renderiza apenas essas + buffer
4. Recicla elementos DOM existentes
5. Ajusta padding para manter scrollbar correta

πŸ“¦ Bibliotecas de Virtualizacao

react-window

Leve (~6KB), API simples. Recomendado para React.

npm install react-window
TanStack Virtual

Framework-agnostic. React, Vue, Solid, Svelte.

npm install @tanstack/virtual-core
vue-virtual-scroller

Especifico para Vue.js. Bem documentado.

npm install vue-virtual-scroller
AG Grid

Enterprise-grade. Virtualizacao built-in.

npm install ag-grid-community

⚠️ Quando Usar Virtualizacao

βœ… Use quando
  • β€’ 1000+ linhas de dados
  • β€’ Scroll infinito e necessario
  • β€’ Paginacao nao e desejada pelo UX
❌ Nao precisa quando
  • β€’ Menos de 500 linhas
  • β€’ Paginacao resolve o problema
  • β€’ Adiciona complexidade desnecessaria
5

β˜‘οΈ Selecao e Acoes em Lote

Operar em multiplos registros

Selecao em lote permite selecionar multiplas linhas para executar acoes: deletar varios, exportar selecionados, alterar status em massa. Checkboxes nas linhas + checkbox "selecionar todos" no header.

Usuarios administrativos frequentemente precisam agir em multiplos registros. Sem selecao em lote, teriam que repetir a mesma acao dezenas de vezes. Produtividade aumenta exponencialmente.

πŸ“‹ Estados do Checkbox Principal

☐
Nenhum selecionado

Checkbox vazio

β–£
Alguns selecionados

Checkbox indeterminado

β˜‘οΈ
Todos selecionados

Checkbox marcado

πŸ’» Codigo: Logica de Selecao

// Estado de selecao (usando Set para performance)
const [selectedIds, setSelectedIds] = useState(new Set());

// Toggle selecao individual
function toggleSelect(id) {
  const newSet = new Set(selectedIds);
  if (newSet.has(id)) {
    newSet.delete(id);
  } else {
    newSet.add(id);
  }
  setSelectedIds(newSet);
}

// Toggle selecionar todos
function toggleSelectAll() {
  if (selectedIds.size === data.length) {
    setSelectedIds(new Set());  // deseleciona todos
  } else {
    setSelectedIds(new Set(data.map(item => item.id)));  // seleciona todos
  }
}

// Barra de acoes em lote (aparece quando ha selecao)
{selectedIds.size > 0 && (
  <div class="bg-blue-900/50 border-b border-blue-500/30 px-4 py-3
              flex items-center justify-between">
    <span class="text-blue-300">
      {selectedIds.size} item(s) selecionado(s)
    </span>
    <div class="flex space-x-3">
      <button class="text-red-400 hover:text-red-300">
        πŸ—‘οΈ Excluir
      </button>
      <button class="text-blue-400 hover:text-blue-300">
        πŸ“€ Exportar
      </button>
    </div>
  </div>
)}

πŸ’‘ Dica Pratica

Confirmacao para acoes destrutivas: Sempre peca confirmacao antes de deletar multiplos registros. Um modal simples "Voce esta prestes a excluir 15 registros. Esta acao nao pode ser desfeita." evita desastres.

6

πŸ“± Tabelas Responsivas

Adaptar para todas as telas

Em telas menores, nem todas as colunas cabem. Estrategias incluem: scroll horizontal, esconder colunas menos importantes, ou transformar em cards.

Dashboards sao acessados em tablets e celulares. Uma tabela de 10 colunas em mobile e inutilizavel. Definir estrategia responsiva e essencial para usabilidade multiplataforma.

πŸ“ Estrategias Responsivas

1. Esconder Colunas por Breakpoint

Use classes Tailwind para mostrar/ocultar colunas.

class="hidden md:table-cell"
2. Scroll Horizontal

Container com overflow-x-auto.

<div class="overflow-x-auto"><table>...</table></div>
3. Cards em Mobile

Tabela em desktop, cards em mobile.

class="hidden sm:block" / class="sm:hidden"

πŸ’» Codigo: Tabela Responsiva

<!-- Estrategia 1: Esconder colunas -->
<table class="w-full">
  <thead>
    <tr>
      <th>Nome</th>                               <!-- sempre visivel -->
      <th class="hidden sm:table-cell">Email</th>  <!-- sm+ -->
      <th class="hidden md:table-cell">Telefone</th><!-- md+ -->
      <th class="hidden lg:table-cell">Empresa</th> <!-- lg+ -->
      <th>Acoes</th>                              <!-- sempre visivel -->
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ana Silva</td>
      <td class="hidden sm:table-cell">ana@email.com</td>
      <td class="hidden md:table-cell">(11) 99999</td>
      <td class="hidden lg:table-cell">Acme Inc</td>
      <td>[Edit]</td>
    </tr>
  </tbody>
</table>

<!-- Estrategia 3: Card em mobile -->
<div class="hidden sm:block">
  <table>...tabela completa...</table>
</div>

<div class="sm:hidden space-y-4">
  {data.map(item => (
    <div class="bg-dark-800 rounded-lg p-4 border border-dark-600">
      <div class="font-bold">{item.name}</div>
      <div class="text-sm text-neutral-400">{item.email}</div>
      <div class="mt-2">[Acoes]</div>
    </div>
  ))}
</div>

πŸ“Š Prioridade de Colunas

Alta prioridade ID, Nome, Status, Acoes
Media prioridade Email, Data, Valor
Baixa prioridade Telefone, Empresa, Notas

πŸ“ Resumo do Modulo

βœ“
Anatomia da Data Table - Toolbar, Header, Body, Footer
βœ“
Ordenacao - Click no header, indicadores visuais, asc/desc
βœ“
Paginacao - Numerada, load more, itens por pagina configuravel
βœ“
Virtualizacao - Para 10k+ linhas, renderiza apenas visivel
βœ“
Selecao em Lote - Checkboxes, acoes em massa, confirmacao
βœ“
Responsividade - Esconder colunas, scroll horizontal, cards mobile