MediaGrid
ExperimentalA gallery of images in even rows that adjusts to the screen, with optional selecting and an empty message.
Also known as gallery, image gallery, masonry, photo grid
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Gallery
6 images
<MediaGrid label="Trip photos" columns={3} items={items} />Every image has the same shape, so rows stay even.
When to use it
Lays out many images in even rows with one gap and one shape, so they are easy to scan. It can let people pick several, and shows an empty message when there is nothing.
Made of: Count line · Grid · Image tile · Select button · Empty message
Use it for
- A gallery of uploads or generated images.
- Picking several images to download, delete or reuse: turn on selectable.
Not for
- Picking one of several AI-made options: use VariantGrid.
- A single image: use MediaFrame.
Do and avoid
4 images
1 image
Do
- Give the grid a name that says what the images are.
- Use one shape for the whole grid.
- Replace the empty message when you know the reason, such as a filter.
Avoid
- Do not mix shapes in one grid.
- Do not show what is chosen with color alone. The check mark does that.
- Do not use it for a single image. Use MediaFrame.
On a phone
- The grid is two columns on a phone, and three or four only from the md and xl breakpoints.
- In select mode, each check button sits in the top right corner of the image. On touch screens it keeps its 28px size and has a 44px by 44px tap area.
- The count line is 12px text above the grid, and it is announced as a status when the count changes.
Seen in products
- No authoritative source was reached for gallery layouts. The shared ratio, column steps and selection pattern are Tattva decisions.
- The empty state follows the Carbon and Shopify guidance recorded on the EmptyState entry.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| itemsrequired | MediaGridItem[] | none | Each item is the MediaFrame props except ratio and className, plus an id. |
| labelrequired | string | none | Accessible name of the list. |
| columns | 2 | 3 | 4 | 4 | Maximum columns. Fewer show on narrower screens. |
| ratio | MediaRatio | "4:3" | Ratio shared by every tile. |
| selectable | boolean | none | Adds a checkbox button to each tile. |
| selected | string[] | none | Controlled selection as item ids. |
| onSelectedChange | (ids: string[]) => void | none | Called with the new selection. |
| empty | ReactNode | none | Replaces the default EmptyState. |
| countLabel | (count: number, selected: number) => string | none | Builds the count line. Defaults to a count of images and selected. |
| className | string | none | Extra classes for the wrapper. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one MediaGrid switches all of this from its properties panel, across 2 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Selectable | selectable | On or off |
Tokens
Change one of these and every part that uses it follows.
--lime--border-strong--fg--bg--radius-card
Built in
- The grid is a named list, so screen readers say how many images there are.
- Each select button is a checkbox named "Select" plus the image description. It works with Tab, Enter and Space.
- A chosen image shows a check mark and a ring, not just color.
- The count line is announced and updates when the choice changes.
What you need to do
- Give the grid a label that says what the images are, such as "Your uploads".
- Write a description for every image. A decorative image's select button is named only by its id.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide