API движка
createMasonryEngine(container, options?) — framework-agnostic движок, на котором построена вся остальная часть пакета. Элементы карточек и их содержимое остаются за вами — это измеряет их и упаковывает по колонкам/строкам.
function createMasonryEngine(container: HTMLElement, options?: MasonryOptions): MasonryEngineСам задаёт container CSS-позицию relative — вручную задавать CSS не нужно. При direction: 'vertical' также ставит overflow-x: clip на контейнер: при смене числа колонок на ресайзе карточка мгновенно получает новую ширину, а на новую позицию FLIP-анимируется 250ms, и в этот момент может на мгновение выступить за правый край — clip не даёт этому превратиться в горизонтальный скролл страницы. При direction: 'horizontal' вместо этого ставится overflow-x: auto; overflow-y: hidden — контейнер сам становится горизонтальным скролл-вьюпортом (подробнее ниже). Эта страница описывает основные опции упаковки движка, его методы и единственное событие. Опции виртуализации, анимации и SSR-фолбэка живут на своих страницах — смотрите Виртуализацию, Анимации и SSR-рендеринг.
Опции
direction
'vertical' | 'horizontal' · по умолчанию: 'vertical'
'vertical' упаковывает по колонкам (главная ось растёт вниз); 'horizontal' — по строкам (главная ось растёт вправо, а контейнер скроллится по горизонтали — см. ниже).
columns
LaneSpec · по умолчанию: 'auto'
Число колонок при direction: 'vertical'. 'auto' вмещает столько колонок размером не меньше minLaneSize, сколько позволяет ширина контейнера; обычное number фиксирует количество; объект с брейкпоинтами ({ default: 2, 768: 3, 1200: 4 }) выбирает значение по наименьшему ключу >= текущей ширины контейнера, либо default, если ни один не подошёл.
rows
LaneSpec · по умолчанию: 'auto'
Та же форма, что у columns, используется при direction: 'horizontal'.
minLaneSize
number · по умолчанию: 240
Обязателен для columns/rows: 'auto' — гибкий размер колонки, от которого зависит, сколько их поместится.
gap
number | { main?: number; cross?: number } · по умолчанию: 16 по обеим осям
Одно число применяется к обеим осям. main — отступ вдоль оси упаковки/роста (вертикальный отступ между карточками, сложенными в одной колонке); cross — отступ между самими колонками.
placement
'balanced' | 'ordered' · по умолчанию: 'balanced'
'balanced' кладёт каждую карточку в ту колонку (или группу колонок, для карточки со спаном), где на данный момент меньше всего содержимого — классическая skyline-упаковка. 'ordered' — строгий round-robin: менее сбалансирован визуально, но сохраняет физический порядок размещения равным порядку карточек.
Пример — все опции упаковки сразу:
const engine = createMasonryEngine(gridEl, {
direction: 'vertical', // колонки; 'horizontal' упаковывал бы по строкам
columns: { default: 2, 768: 3, 1200: 4 }, // 2 колонки уже 768px, 3 до 1200px, 4 дальше
minLaneSize: 240, // учитывается только если columns был бы 'auto' — не действует при фиксированном значении/брейкпоинтах
gap: { main: 20, cross: 16 }, // 20px между карточками в стопке, 16px между колонками
placement: 'balanced', // каждая карточка идёт в наименее заполненную колонку(и), не строгий round-robin
})Методы
setItems(items: MasonryItemDescriptor[]): void
Заменяет весь набор карточек, которые измеряет и упаковывает движок. Форму MasonryItemDescriptor смотрите на странице Элементы и бенто-спаны. Вызывает немедленный пересчёт раскладки.
updateItem(id: string, patch: Partial<Omit<MasonryItemDescriptor, 'id'>>): void
Примешивает patch к карточке с указанным id — например, чтобы изменить её colSpan, не передавая заново все остальные карточки. Не делает ничего, если id сейчас не зарегистрирован.
addItem(item: MasonryItemDescriptor, index?: number): void
Добавляет одну карточку, не заменяя остальные, на позицию index (в конец списка, если не задано).
removeItem(id: string): void
Удаляет одну карточку по id.
relayout(): void
Принудительно пересчитывает раскладку немедленно, в обход батчинга через requestAnimationFrame движка — полезно сразу после ручного изменения содержимого, которое движок иначе не заметил бы (собственный ResizeObserver уже покрывает изменения размера элементов автоматически; это — для всего остального).
getLayout(): MasonryItemLayout[]
Последняя посчитанная раскладка — по одному прямоугольнику { id, x, y, width, height } на каждую упакованную карточку, уже переведённому в физические координаты независимо от direction.
getVisibleIds(): string[]
Id, у которых прямо сейчас должен быть реальный DOM-элемент. Каждая упакованная карточка, если virtualize выключен — смотрите Виртуализацию про то, что это значит при включённой виртуализации.
setDragging(id: string | null): void
Полностью исключает id из упаковки/позиционирования — все остальные немедленно перестраиваются, как будто этой карточки нет в списке, а transform/opacity/классы её элемента на 100% отданы вызывающей стороне, пока метод не будет вызван снова с null — тогда карточка возвращается в следующий пересчёт. Поскольку её transform — это то, что вызывающая сторона задала последним (не пустая строка), она FLIP-анимируется оттуда в свою упакованную позицию, а не появляется рывком. Это тот самый примитив, на котором построена клавиатурная пересортировка sortable в адаптерах Vue/React — смотрите Компонент MasonryGrid.
on(event, handler): () => void
Подписывается на событие движка (см. «События» ниже). Возвращает функцию отписки.
destroy(): void
Снимает все подписки (resize/scroll), очищает все карточки и убирает распорку для горизонтального режима скролла, если та была создана. Вызывайте это, когда контейнер вот-вот покинет DOM — <MasonryGrid> и useMasonry() уже делают это сами при размонтировании.
События
Подписка через engine.on(eventName, handler).
layout
{ items: MasonryItemLayout[]; visibleIds: string[] }
Срабатывает в конце каждого пересчёта раскладки (начальный, структурное изменение, resize- или scroll-триггер) с посчитанным прямоугольником каждой карточки. visibleIds — тот же набор, что возвращает getVisibleIds() для этого прохода.