Introdução

Há algum tempo, um cliente veio até mim com um pedido: mostrar seus dados em uma grade responsiva.

O problema? O número de colunas era dinâmico, mudando dependendo do conjunto de dados. Além disso, algumas colunas continham textos muito longos que quebravam todos os layouts que eu tentei. E aqui está a parte complicada — nós nem sabíamos as colunas exatas com antecedência, apenas seus tipos (texto, número, e-mail, data, data e hora).

Eu testei algumas bibliotecas de grade e tabela existentes, mas elas eram muito pesadas, muito rígidas ou exigiam que todas as colunas fossem declaradas explicitamente. Nenhuma delas lidava bem com essa mistura de colunas dinâmicas mais texto longo.

Então, decidi construir minha própria solução. Assim nasceu AutoFitGrid.

O Problema

Dados dinâmicos são imprevisíveis. Você não pode codificar layouts de forma rígida, e não pode assumir textos curtos em todos os lugares — às vezes você recebe descrições de várias frases.

Se você jogar isso em uma tabela HTML simples:

  • As colunas transbordam, forçando a rolagem horizontal.
  • Valores pequenos como números acabam desperdiçando espaço.

Era exatamente assim que o caso de uso do meu cliente se apresentava.

A Solução: AutoFitGrid

O AutoFitGrid constrói uma grade observando duas coisas:

  1. O tipo declarado de cada coluna (texto, número, e-mail, data, data e hora).
  2. Os valores reais dentro das células (conteúdo curto vs. longo).

A partir disso, ele calcula automaticamente as larguras, aplica o alinhamento e permite que o conteúdo se envolva para que a grade permaneça responsiva. Você não precisa definir larguras ou saber o número de colunas com antecedência — a biblioteca cuida disso.

Como Eu Lido com Texto Longo (a parte complicada)

A parte mais difícil desse problema foi descobrir como encaixar texto longo em uma grade quando o número de colunas é dinâmico e desconhecido.

Eu resolvi isso tratando cada coluna como um retângulo. O desafio é encontrar a proporção largura-altura correta para que o texto flua de forma organizada sem quebrar o layout.

Aqui está a lógica:

  1. Conte as palavras no texto.
  2. Classifique o texto como curto, médio ou longo.
  3. Escolha uma proporção alvo dependendo da categoria (texto curto = retângulo mais estreito, texto longo = retângulo mais largo).
  4. Calcule uma largura e altura apropriadas para que o texto se envolva de forma limpa.

Dessa forma, valores curtos como nomes não desperdiçam espaço, enquanto descrições longas permanecem legíveis e contidas.

Inicializando com HTML/JavaScript

Aqui está como você declara uma grade em HTML. Note que não há larguras — apenas tipos.

HTML

<div class="grid-container">
  <div class="grid-header" data-type="text">Descrição da Tarefa</div>
  <div class="grid-header" data-type="text">Atribuído a</div>
  <div class="grid-header" data-type="email">E-mail</div>
  <div class="grid-header" data-type="datetime">Data de Início</div>
  <div class="grid-header" data-type="datetime">Data de Vencimento</div>
  <div class="grid-header" data-type="number">Prioridade</div>
  <div class="grid-header" data-type="number">Horas Estimadas</div>

  <div class="grid-item">
    Implemente uma descrição muito longa para testar como o layout da grade se ajusta
    e envolve texto dinamicamente em várias linhas.
  </div>
  <div class="grid-item">Jane Doe</div>
  <div class="grid-item">jane.doe@example.com</div>
  <div class="grid-item">2024-01-15 08:30:00</div>
  <div class="grid-item">2024-07-15 17:00:00</div>
  <div class="grid-item">1</div>
  <div class="grid-item">100</div>
</div>

JavaScript

Uma vez que sua marcação esteja pronta, você dá inteligência à grade com uma chamada de inicialização.

new AutoFitGrid({
  container: document.querySelector('.grid-container'),
  defaultMinWidth: 50,
  defaultMaxWidth: Infinity,
  adjustmentThreshold: 200,
  headerSelector: '.grid-header',
  columnSelector: '.grid-item',
  showDebug: false
});

Se você ativar showDebug: true, verá logs mostrando como o AutoFitGrid mede e ajusta as colunas.

Usando no React

import React, { useEffect, useRef } from 'react';
import AutoFitGrid from 'auto-fit-grid';

function MyGrid() {
  const ref = useRef(null);

  useEffect(() => {
    if (ref.current) {
      new AutoFitGrid({
        container: ref.current,
        headerSelector: '.grid-header',
        columnSelector: '.grid-item'
      });
    }
  }, []);

  return (
    <div className="grid-container" ref={ref}>
      <div className="grid-header" data-type="text">Nome</div>
      <div className="grid-header" data-type="email">E-mail</div>
      <div className="grid-header" data-type="number">Pontuação</div>

      <div className="grid-item">Alice Wonderland</div>
      <div className="grid-item">alice@example.com</div>
      <div className="grid-item">88</div>

      <div className="grid-item">Bob Bobson</div>
      <div className="grid-item">bob@example.com</div>
      <div className="grid-item">95</div>
    </div>
  );
}

Instalando e Testando

Você pode instalar o AutoFitGrid pelo npm:

npm install auto-fit-grid

Ou explore os exemplos ao vivo e a documentação: