# Image Viewer

Full-screen photo viewer that pinches around your fingers, pans with momentum, pages past a zoomed edge and swipes down to close. Photos grow out of the tile you tapped and fly back into the one showing.

> Composed · Pro · Mobile-Native — React Native, Expo Go incompatible (dev build required).

## Install

```bash
npx @lumioui/cli add pro/image-viewer
```

## Import

```tsx
import { ImageViewer } from "@/components/ui/image-viewer/image-viewer";
```

## Variants

- `gallery` — Gallery: `npx @lumioui/cli add pro/image-viewer-gallery`

## Props

| Prop | Type | Notes |
| --- | --- | --- |
| `open` | `boolean` | — |
| `onOpenChange` | `(open: boolean) => void` | — |
| `images` | `ImageSourcePropType[]` | Remote or local images, paged left-to-right. |
| `index?` | `number` | Controlled index of the visible image. Omit for uncontrolled. |
| `defaultIndex?` | `number` | Uncontrolled initial image. Default 0. |
| `onIndexChange?` | `(index: number) => void` | — |
| `captions?` | `(string | null | undefined)[]` | Caption per image, shown at the bottom and read with the photo. |
| `alts?` | `(string | null | undefined)[]` | Screen-reader description per image (falls back to the caption). |
| `thumbnails?` | `ImageSourcePropType[]` | Small versions of `images` — shows a filmstrip that scrubs with the  swipe; tap a thumbnail to jump. Only with 2+ images. |
| `previews?` | `(ImageSourcePropType | null | undefined)[]` | Already-loaded small source per image — normally the tile's own. It is  drawn where the tile showed it while the full image decodes, so the  open morph starts from real pixels; the full image then switches on in  place. Pass it whenever `images` are larger than the tiles. |
| `showCounter?` | `boolean` | "3 of 12" counter. Default true (shown only with 2+ images). |
| `showClose?` | `boolean` | Close control. Default true. |
| `tapToToggleChrome?` | `boolean` | Single tap shows/hides the chrome. Default true. |
| `origins?` | `(ViewerOrigin | null | undefined)[]` | Thumbnail rect per image index — enables the shared-element open/close. |
| `onExitComplete?` | `() => void` | Fires once the exit animation has finished and the viewer unmounted —  the moment to un-hide a thumbnail that was hidden while it flew. |
| `className?` | `string` | — |

## Icons rendered

- `x` — /icons.html?i=x
- `chevron-left` — /icons.html?i=chevron-left
- `chevron-right` — /icons.html?i=chevron-right

Source: https://lumioui.com/components/image-viewer