# Masonry grid

> Pinterest-style columns: each item lands in the shortest column and the grid deals in with a stagger. Includes MasonryTile, a picture with its name on a scrim that presses down under the finger.

- Type: Component (data)
- Access: Free, open source (MIT)
- Page: https://goodui.dev/native/components/masonry-grid
- Markdown: https://goodui.dev/native/components/masonry-grid.md
- Registry item: https://goodui.dev/native/r/masonry-grid.json
- Dependencies: react-native-reanimated
- Keywords: react native masonry, pinterest layout, staggered grid, waterfall layout, style gallery

## When to use

- A browsable set of pictures with mixed proportions, such as styles or templates.
- A gallery of a person's results.

## When not to use

- Long or endless feeds: it renders every item, so use a virtualized list.
- Pictures of one size: use a plain grid.

## Installation

With the shadcn CLI (needs a components.json in the Expo app), then `npx expo install --fix` so native dependencies match your Expo SDK. The foundation comes along the first time.

```bash
npx shadcn@latest add https://goodui.dev/native/r/masonry-grid.json
npx expo install --fix
```

The component lands in `components/goodui-native/masonry-grid/` and imports the foundation from `components/goodui-native/foundation/` with relative paths; it also installs locale.

Built-in strings follow `<GooduiLocaleProvider>` (one [language pack](https://goodui.dev/native/r/locale-tr.json) translates the whole kit); the `labels` prop overrides them for one instance.

## Usage

```tsx
import { MasonryGrid, MasonryTile } from "@/components/goodui-native/masonry-grid/masonry-grid";

<MasonryGrid
  items={styles}
  keyOf={(s) => s.id}
  aspect={(s) => s.aspect}
  renderItem={(s) => <MasonryTile image={s.image} title={s.name} aspectRatio={s.aspect} onPress={() => pick(s.id)} />}
/>
```

## API reference

### MasonryGrid

`import { MasonryGrid } from "@/components/goodui-native/masonry-grid/masonry-grid";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `items` (required) | `T[]` | – | – |
| `aspect` (required) | `(item: T) => number` | – | Width over height of an item. Items go to the shorter column. |
| `renderItem` (required) | `(item: T, index: number) => ReactNode` | – | – |
| `keyOf` (required) | `(item: T) => string` | – | – |
| `columns` | `number` | `2` | – |
| `gap` | `number` | `10` | – |
| `style` | `StyleProp<ViewStyle>` | – | Style for the outer container. |
| `testID` | `string` | – | Identifier for end-to-end tests. |

### MasonryTile

`import { MasonryTile } from "@/components/goodui-native/masonry-grid/masonry-grid";`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `image` (required) | `ImageSourcePropType` | – | – |
| `title` (required) | `string` | – | – |
| `subtitle` | `string` | – | – |
| `aspectRatio` (required) | `number` | – | Width over height. |
| `corner` | `ReactNode` | – | Something in the corner: a new badge, a cost. |
| `cornerLabel` | `string` | – | What `corner` says, added to the spoken name: "4 credits". |
| `onPress` | `() => void` | – | – |
| `labels` | `Partial<MasonryGridLabels>` | – | – |

## Accessibility

- MasonryTile is a button that reads its title and subtitle, with a hint from the labels.
- Screen readers follow column order, not the order of the array.

## Motion

- Tiles rise in with a stagger capped at the tenth item.
- A tile springs to 95.5 percent under the finger.
- Reduced motion: tiles fade in and do not press down.

## Haptics

- The tap cue on press.

## Performance

- Not virtualized. Keep it to a few dozen items, and use appropriately sized thumbnails.

## Notes for AI

- `aspect` must match the tile's aspectRatio, or the column balance is off.
- It has no scrolling of its own: put it in a ScrollView.
- The default hint says Opens this item. Override labels.open to name what opens.

## Related

- [Carousel](https://goodui.dev/native/components/carousel.md): A snapping card carousel that follows the finger 1:1, shrinks and dims the neighbours, stretches its pagination pill with the drag, and turns that pill into a timer when it autoplays.
- [Image viewer](https://goodui.dev/native/components/image-viewer.md): Tap a thumbnail and the photo flies out of it into a full-screen viewer, its crop opening up as it lands; pinch or double-tap to zoom at your fingers, drag to pan, swipe between photos, and drag down to send it back into its thumbnail while the background fades. On the web the wheel zooms toward the pointer.
- [Generation queue](https://goodui.dev/native/components/generation-queue.md): Cards for long AI jobs: each one shows its status, a fill and a light sweep while running, a rolling percentage, and cancel, retry and open actions.

## Guidance for AI tools

Masonry grid: Pinterest-style columns: each item lands in the shortest column and the grid deals in with a stagger. Includes MasonryTile, a picture with its name on a scrim that presses down under the finger. Use only the documented props. Keep accessibility, reduced motion and both color schemes intact when adapting it.

Full library index: https://goodui.dev/native/llms.txt
