Fan Gallery
Photo card carousel fanned out in an arc.
Usage
import { FanGallery } from '@/components/ui/fan-gallery'
<FanGallery />
// Your own photos, call to action, and motion
<FanGallery
images={[
{
id: 'dunes',
src: '/photos/dunes.webp',
alt: 'Orange dunes at sunset',
title: 'Erg Chebbi',
meta: 'Morocco · 2025',
tone: '#f08a4b',
},
// ...
]}
cta={{ label: 'See every trip', href: '/trips', variant: 'accent' }}
autoplay={5000}
tilt={10}
onSelect={(image) => console.log(image.title)}
/>
Install
pnpm dlx shadcn@latest add @pastaui-pro/fan-gallerynpx shadcn@latest add @pastaui-pro/fan-galleryyarn dlx shadcn@latest add @pastaui-pro/fan-gallerybunx --bun shadcn@latest add @pastaui-pro/fan-gallerySource
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| images | FanGalleryImage[] | = 9 gallery images | Each card: id, src, alt, title, meta (the small line above the title), and an optional tone color for the glow behind the card. Seven to nine photos fill the arc best. |
| cta | { label: string; href: string; variant?: 'charcoal' | 'accent' } | false | = { label: 'Explore the gallery', href: '#', variant: 'charcoal' } | Pill link centered below the fan, overlapping it slightly. Pass false to hide it. |
| autoplay | boolean | number | = false | Rotate the next card to the center on a timer; true uses 4000 ms, a number sets the interval. Pauses on hover, focus, drag, off-screen, in hidden tabs, and under reduced motion. |
| tilt | number | = 14 | Maximum rotation in degrees, reached three cards from the center. Narrow screens use 70% of it. |
| label | string | = 'Photo gallery' | Accessible name for the carousel region and its list of cards. |
| onSelect | (image: FanGalleryImage, index: number) => void | = — | Called when a card is clicked or activated with Enter or Space, as the lightbox opens. |
| className | string | = — | Additional classes for the section. The bleed is clipped inside it. |