Введение
Некоторое время назад ко мне обратился клиент с просьбой: показать их данные в адаптивной сетке.
Загвоздка? Количество колонок было динамическим, меняющимся в зависимости от набора данных. Более того, некоторые колонки содержали очень длинный текст, который ломал любой макет, который я пробовал. И вот в чем дело — мы даже не знали точные колонки заранее, только их типы (текст, число, email, дата, дата и время).
Я протестировал несколько существующих библиотек сеток и таблиц, но они были либо слишком тяжелыми, либо слишком жесткими, либо требовали явного объявления всех колонок. Ни одна из них не справлялась с этой смесью динамических колонок и длинного текста должным образом.
Поэтому я решил создать собственное решение. Так родился AutoFitGrid.
Проблема
Динамические данные непредсказуемы. Вы не можете жестко закодировать макеты, и не можете предполагать короткий текст везде — иногда вы получаете описания из нескольких предложений.
Если вы поместите это в обычную HTML таблицу:
- Колонки выходят за пределы, заставляя появляться горизонтальную прокрутку.
- Малые значения, такие как числа, в итоге занимают много места.
Вот как выглядел случай использования моего клиента.
Решение: AutoFitGrid
AutoFitGrid строит сетку, исходя из двух вещей:
- Объявленный тип каждой колонки (текст, число, email, дата, дата и время).
- Фактические значения внутри ячеек (короткое против длинного содержимого).
Исходя из этого, он автоматически рассчитывает ширину, применяет выравнивание и позволяет содержимому оборачиваться, чтобы сетка оставалась адаптивной. Вам не нужно устанавливать ширину или знать количество колонок заранее — библиотека справляется с этим.
Как я обрабатываю длинный текст (сложная часть)
Самой сложной частью этой проблемы было понять, как вписать длинный текст в сетку, когда количество колонок динамическое и неизвестное.
Я решил эту задачу, рассматривая каждую колонку как прямоугольник. Проблема заключается в том, чтобы найти правильное соотношение ширины и высоты, чтобы текст аккуратно вписывался, не ломая макет.
Вот логика:
- Посчитайте слова в тексте.
- Классифицируйте текст как короткий, средний или длинный.
- Выберите целевое соотношение в зависимости от категории (короткий текст = более узкий прямоугольник, длинный текст = более широкий прямоугольник).
- Рассчитайте подходящие ширину и высоту, чтобы текст аккуратно оборачивался внутри.
Таким образом, короткие значения, такие как имена, не занимают много места, в то время как длинные описания остаются читаемыми и аккуратными.

Инициализация с HTML/JavaScript
Вот как вы объявляете сетку в HTML. Обратите внимание, что нет ширин — только типы.
HTML
<div class="grid-container">
<div class="grid-header" data-type="text">Описание задачи</div>
<div class="grid-header" data-type="text">Назначено</div>
<div class="grid-header" data-type="email">Email</div>
<div class="grid-header" data-type="datetime">Дата начала</div>
<div class="grid-header" data-type="datetime">Срок</div>
<div class="grid-header" data-type="number">Приоритет</div>
<div class="grid-header" data-type="number">Оценочные часы</div>
<div class="grid-item">
Реализуйте очень длинное описание, чтобы протестировать, как макет сетки подстраивается
и оборачивает текст динамически на нескольких строках.
</div>
<div class="grid-item">Джейн Доу</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
Как только ваш разметка готова, вы даете сетке немного интеллекта с помощью одного вызова инициализации.
new AutoFitGrid({
container: document.querySelector('.grid-container'),
defaultMinWidth: 50,
defaultMaxWidth: Infinity,
adjustmentThreshold: 200,
headerSelector: '.grid-header',
columnSelector: '.grid-item',
showDebug: false
});
Если вы включите showDebug: true, вы увидите логи, показывающие, как AutoFitGrid измеряет и подстраивает колонки.
Использование в 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">Имя</div>
<div className="grid-header" data-type="email">Email</div>
<div className="grid-header" data-type="number">Оценка</div>
<div className="grid-item">Алиса Вондерленд</div>
<div className="grid-item">alice@example.com</div>
<div className="grid-item">88</div>
<div className="grid-item">Боб Бобсон</div>
<div className="grid-item">bob@example.com</div>
<div className="grid-item">95</div>
</div>
);
}
Установка и тестирование
Вы можете установить AutoFitGrid из npm:
npm install auto-fit-grid
Или посмотрите живые примеры и документацию: