Throw the strip and let it coast. Each slide scales up, sharpens, and brightens as it nears the center, and dims and blurs as it drifts away, like Apple Photos. Drag it, or use the buttons or the arrow keys.
pnpm dlx shadcn@latest add "https://godui.design/r/lab/inertia-gallery.json"
The track is a single draggable element with momentum; its x motion value
drives a per-slide transform that maps distance-from-center to scale,
opacity, and a small blur. With snap, the nearest slide springs to center
when the throw settles.
import { InertiaGallery } from "@/components/godui/inertia-gallery";
<InertiaGallery onChange={(index) => setActive(index)}>
<Shot>One</Shot>
<Shot>Two</Shot>
<Shot>Three</Shot>
</InertiaGallery>
By default the strip coasts freely. Pass snap to settle the nearest slide to
center.
<InertiaGallery snap>{/* slides */}</InertiaGallery>
falloff scales the distance-based scale/blur/opacity effect; 0 renders a flat
strip.
<InertiaGallery falloff={0.5}>{/* slides */}</InertiaGallery>
The viewport is a focusable group: ← and → move between
slides, and the labelled buttons do the same. When prefers-reduced-motion is
set, the blur and scale/opacity falloff are disabled and the strip scrolls
plainly.
| Prop | Type | Default | Description |
|---|
itemWidth | number | 200 | Slide width in px. |
gap | number | 24 | Gap between slides in px. |
snap | boolean | false | Snap the nearest slide to center when the throw settles. |
falloff | number | 1 | Strength of the distance-from-center scale/blur/opacity effect. |
defaultIndex | number | 0 | Slide centered on mount. |
onChange | (index: number) => void | none | Fired when a new slide reaches center. |
InertiaGallery also forwards every standard <div> attribute to the root element.