# Zoom Lightbox: Gallery

> A photo grid. Tap a photo, swipe or use the arrow keys to page, then drag it down and it lands back in its tile.

A shadcn/ui block from the [@keyframeui](https://keyframeui.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/keyframeui/zoom-lightbox-demo).

- Page, with a live preview: https://shadcn.exchange/r/keyframeui/zoom-lightbox-demo
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/keyframeui/zoom-lightbox-demo-light-fd6816a9f22a475c.png
- Registry item: https://keyframeui.com/r/zoom-lightbox-demo.json
- Categories: gallery, gesture, motion
- Listed: 2026-10-14, source last changed 2026-10-15

## Install

```bash
npx shadcn@latest add https://keyframeui.com/r/zoom-lightbox-demo.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `https://keyframeui.com/r/zoom-lightbox.json`

## Notes from the registry

Live preview, examples and props: https://keyframeui.com/components/zoom-lightbox#zoom-lightbox-demo

## Files

### `registry/demos/zoom-lightbox-demo.tsx`

```tsx
import { ZoomLightbox, ZoomLightboxItem } from "@/components/ui/zoom-lightbox";

const photos = [
  { id: "1506905925346-21bda4d32df4", width: 4878, height: 3252, alt: "Snowy peaks rising out of a sea of clouds at sunrise", caption: "Above the cloud line, first light" },
  { id: "1433086966358-54859d0ed716", width: 4000, height: 6000, alt: "A tall waterfall under a stone footbridge in a green gorge", caption: "The falls, after a week of rain" },
  { id: "1493246507139-91e8fad9978e", width: 5472, height: 3648, alt: "Jagged mountains reflected in a turquoise lake at dusk", caption: "Still water, last light" },
  { id: "1500530855697-b586d89ba3ee", width: 3648, height: 5472, alt: "A two-lane road running through red desert cliffs", caption: "Somewhere past the last gas station" },
  { id: "1519681393784-d120267933ba", width: 4096, height: 2733, alt: "The Milky Way above snow-covered mountains", caption: "Twenty-second exposure, no moon" },
  { id: "1505144808419-1957a94ca61e", width: 3070, height: 5464, alt: "Aerial view of a wave breaking onto dark sand", caption: "From above the tide line" },
  { id: "1490750967868-88aa4486c946", width: 7952, height: 5304, alt: "Orange poppies against a blue sky", caption: "Poppies along the trail" },
  { id: "1501785888041-af3ef285b470", width: 5979, height: 3986, alt: "A rowing boat on a clear green alpine lake", caption: "Morning row across the lake" },
  { id: "1502082553048-f009c37129b9", width: 3741, height: 2494, alt: "A lone broad tree in a grassy field", caption: "The tree everyone stops for" },
];

const image = (id: string, width: number) =>
  `https://images.unsplash.com/photo-${id}?auto=format&fit=max&q=80&w=${width}`;

export function ZoomLightboxDemo() {
  return (
    <div className="w-full max-w-sm">
      <div className="mb-3 flex items-baseline justify-between px-0.5">
        <p className="text-sm font-medium text-zinc-900 dark:text-zinc-50">Recents</p>
        <p className="font-mono text-xs text-zinc-500 tabular-nums">{photos.length} photos</p>
      </div>
      <ZoomLightbox className="grid grid-cols-3 gap-1">
        {photos.map((photo) => (
          <ZoomLightboxItem
            key={photo.id}
            src={image(photo.id, 2000)}
            thumbnail={image(photo.id, 400)}
            width={photo.width}
            height={photo.height}
            alt={photo.alt}
            caption={photo.caption}
            className="aspect-square rounded-md"
          />
        ))}
      </ZoomLightbox>
      <p className="mt-4 text-center font-mono text-xs text-zinc-500">
        Tap a photo. Drag it down to put it back.
      </p>
    </div>
  );
}
```
