Skip to main content

CoverGrid

Every example on this page is live, drawn by the library's Storybook, where you can also change its props and see the result.

A gallery of square pictures that fills its box: the latest posts of an account, a camera roll, a shelf of album covers. It shows as many whole frames as fit, centered, and leaves out the pictures past them, so you hand it the whole list and the room you have.

Each frame is a Cover, so pictures are shown in greys, a missing picture shows its fallback glyph, and a mark says what a picture is.

Import​

import { CoverGrid } from "~lib/data-display/cover-grid";

Props​

NameTypeRequiredDefaultDescription
itemsCoverGridItem[]YesN/AThe pictures, in order. Those that do not fit are left out
columnsnumberNoN/AHow many frames across. Leave it out for as many as the box's width allows
minCellnumberNo96Without columns, the smallest a frame may be when working out the columns
gapnumberNo8Space between the frames, in pixels
radius"none" | "sm" | "md" | "lg" | "full"No"md"How rounded the frames' corners are
widthnumber | stringNo"100%"Width in pixels, or any CSS width
heightnumber | stringNo"100%"Height in pixels, or any CSS height

Each item takes what a Cover does:

NameTypeRequiredDefaultDescription
srcstring | nullNoN/AThe picture's address. Leave it out, or pass null, when there is none
altstringNo""What the picture shows, for screen readers
fallbackIconNameNo"image"The Icon shown when there is no picture
markIconNameNoN/AA glyph in the corner, such as "film" for a video or "clone" for an album

The grid fills its parent by default, so put it somewhere that has a height, such as a min-h-0 flex-1 box in a column.

How It Fills the Box​

Without columns, the grid takes as many columns as frames of minCell fit across, then makes the frames as big as fills the box's height with whole rows. A row that nearly fits is kept, with every frame a little smaller, rather than left out. So:

  • a square box fills with rows of frames,
  • a short, wide band shows one row of frames as tall as it,
  • a narrow column shows one frame across, as wide as it.

The layout is worked out by the browser from the box, so it holds in every size of box your widget is shown in, with nothing measured.

Examples​

Default​

Open Default in Storybook
import { CoverGrid } from "~lib/data-display/cover-grid";
import { Heading } from "~lib/typography";

const Feed = ({ account, posts }: { account: string; posts: Post[] }) => (
<div className="flex h-full flex-col gap-2">
<Heading size="sm">@{account}</Heading>
<div className="min-h-0 flex-1">
<CoverGrid
items={posts.map((post) => ({
src: post.thumbnailUrl,
mark: post.isVideo ? "film" : post.isAlbum ? "clone" : undefined,
}))}
/>
</div>
</div>
);

Columns​

Set columns to keep that many frames across whatever the box. The frames are as big as that many columns and the box's height allow.

Open Columns in Storybook

A Band​

Open Band in Storybook

A Wide Box​

Open Wide in Storybook

A Narrow Column​

Open Narrow in Storybook

Beside a Featured Post​

The newest post large on the left, as a grid of one, and the rest of the feed filling the room beside it.

Open Beside A Featured Post in Storybook
<div className="flex h-full gap-3">
<div className="aspect-square h-full">
<CoverGrid items={posts.slice(0, 1)} columns={1} />
</div>
<div className="min-w-0 flex-1">
<CoverGrid items={posts.slice(1)} />
</div>
</div>

Fewer Pictures Than Fit​

The frames keep their size, and the rest of the grid stays empty.

Open Fewer Than Fit in Storybook

See Also​

  • Cover - One picture in a frame
  • Icon - The glyphs a frame falls back to or is marked with