Adventureland Registry

Magazine Grid

A pure calculation utility that paginates a list of sized grid items across fixed-size pages, calling onPaginate with the result. Renders nothing.

MagazineGrid is a headless layout utility — it returns null and has no visual output. It accepts an array of items each tagged with a size (small | medium | large | full), maps them to a 12-column grid, calculates which items fit on each fixed-height page, and fires onPaginate with the resulting page arrays.

Use it to drive a separate paged rendering component; the pagination result is memoised and only fired when the inputs change.

Installation

npx shadcn@latest add @adv/magazine-grid

Usage

import MagazineGrid, { type GridItem } from '@/components/magazine-grid';

const items: GridItem[] = [
  { id: '1', content: <ArticleCard />, size: 'large' },
  { id: '2', content: <Snippet />, size: 'small' },
];

<MagazineGrid
  items={items}
  pageHeight={800}
  pageWidth={1200}
  columns={12}
  gap={16}
  onPaginate={(pages) => console.log(pages)}
/>

Example

MagazineGrid

This component renders null. It is a pure calculation utility that splits items into pages and calls onPaginate with the result.

Result: calculating…

Props

PropTypeDefaultDescription
itemsGridItem[]Required. The items to paginate. Each item has id, content, and size.
pageHeightnumberRequired. Available vertical space per page in pixels.
pageWidthnumberRequired. Available horizontal space per page in pixels.
columnsnumber12Number of grid columns.
gapnumber16Gap between grid items in pixels.
onPaginate(pages: GridItem[][]) => voidRequired. Called with the paginated result whenever inputs change.

GridItem

FieldTypeDescription
idstringUnique identifier.
contentReactNodeRendered content (not measured; size determines column span).
size"small" | "medium" | "large" | "full"Maps to 4, 6, 8, or 12 columns respectively.

On this page