Browse album art, product shots, or covers. Drag across the stage and the row telescopes in 3D, then snaps to the nearest slide when you let go. You can also click a side slide, use the buttons, or press the arrow keys.
pnpm dlx shadcn@latest add "https://godui.design/r/lab/cover-flow.json"
Each slide derives its translateX, rotateY, translateZ, scale, and
opacity from its signed distance to center, a single motion value the drag
updates. A release snaps that value to the nearest index with a spring, and a
fast flick advances an extra slide.
import { CoverFlow } from "@/components/godui/cover-flow";
<CoverFlow defaultIndex={0} onChange={(index) => select(index)}>
<Cover>One</Cover>
<Cover>Two</Cover>
<Cover>Three</Cover>
</CoverFlow>
Slides are absolutely positioned on the stage, so give them a size with
itemWidth / itemHeight. gap adds space between slide centers on top of the
overlap.
<CoverFlow itemWidth={240} itemHeight={300} gap={16}>
{/* slides */}
</CoverFlow>
reflection (on by default) renders a fading mirror of each slide on the floor.
<CoverFlow reflection={false}>{/* slides */}</CoverFlow>
The stage is a focusable group: ← and → move between
slides, and the labelled buttons do the same. When prefers-reduced-motion is
set, the 3D rotation and depth are dropped for a flat cross-fade.
| Prop | Type | Default | Description |
|---|
defaultIndex | number | 0 | Slide centered on mount. |
onChange | (index: number) => void | none | Fired when a new slide settles at center. |
itemWidth | number | 240 | Slide width in px. |
itemHeight | number | 300 | Slide height in px. |
gap | number | 0 | Extra px between slide centers. |
perspective | number | 1200 | CSS perspective depth for the 3D stage. |
reflection | boolean | true | Render a fading floor reflection under each slide. |
CoverFlow also forwards every standard <div> attribute to the root element.