Skip to content
Sign in
EffectsGallery view transitionMenu

Gallery view transitionPro

A grid that opens into a lightbox with the tile morphing into the full image: the View Transitions API where the browser has it, a FLIP transform where it does not.

ProOpen a tile and it morphs into the lightbox, then back on close. Arrow keys step through.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/gallery-view-transition

Usage

tsx
import { GalleryViewTransition } from "@/components/ui/chatcn/pro/gallery-view-transition"

<GalleryViewTransition items={generations} columns={3} />

Each item is { src, alt, thumbSrc?, caption?, width?, height? }; give width and height so the lightbox reserves the right box before the file decodes. Only one element carries the shared view-transition-name at a time, so a grid of hundreds stays cheap. Where the API is missing, the lightbox image plays from the tile's box by transform, with a clip-path crop so the picture never distorts.

The same pieces are exported for your own layouts: runViewTransition(update) runs a React update inside a view transition (flushed synchronously, plain where unsupported) and flipFrom(element, fromRect) plays the fallback.

Examples

Transition paths

The same gallery with each path forced: View Transitions, the FLIP fallback and a plain fade, with tall tiles.

ProThe same gallery with View Transitions, the FLIP fallback or a fade forced.

Props

PropTypeNotes
itemsGalleryItem[]{ src, alt, thumbSrc?, caption?, width?, height? }
openIndex, defaultOpenIndex, onOpenIndexChangenumber | nullControlled or uncontrolled open item. null is closed
columnsnumberGrid columns. Default 3
tileAspectnumber | "3:4"Tile shape. Default 1
transition"auto" | "view-transition" | "flip" | "fade"Default auto: View Transitions when available, FLIP otherwise
labelstringAccessible name of the grid. Default "Gallery"
tileClassNamestringClasses for each tile

Keyboard

KeyAction
TabMoves through the tiles, and inside the open lightbox
Enter / SpaceOpens the focused tile, with a fade instead of the morph
ArrowLeft / ArrowRightPrevious and next image (mirrored in right to left)
EscapeCloses the lightbox and returns focus to the tile

Accessibility

  • Tiles are buttons named Open <alt> with aria-haspopup=dialog, in a list named by label.
  • The lightbox is a Base UI modal dialog named by the image's alt: focus is trapped and returns to the tile on close. Its title is the position, for example 2 of 6.
  • Previous, Next and Close are labeled icon buttons with 44 px hit areas on touch screens. A click on the empty space around the image closes too.

Motion

  • The morph is 280 ms on the default out curve; closing plays it back to the tile, with the FLIP close at 0.75 of the open.
  • Opening from the keyboard fades over 200 ms: keyboard actions never morph. Stepping with the arrow keys swaps the image at once.
  • Under reduced motion every open and close is a fade.
  • Tiles press to 0.97 over 100 ms and never scale on hover.