Stacked Peek Carousel
A card stack carousel where the layers behind peek out, and the next card moves up to take the front on each swipe.
The current card sits centered, with the 2–3 cards behind it shrunk and offset upward so their edges peek out. On a drag or a button press the front card flies out with a rotation while the card behind springs up to take its place, with wraparound looping and dot indicators — well suited to browsing curated content such as trip cards or product cards.
npx shadcn@latest add https://webberui.com/r/stacked-peek-carousel.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<StackedPeekCarousel />
Installation
npx shadcn@latest add https://webberui.com/r/stacked-peek-carousel.jsonOr, once registries are configured in components.json, install it as @webberui/stacked-peek-carousel.
Usage
import { StackedPeekCarousel } from "@/components/ui/stacked-peek-carousel";
<StackedPeekCarousel
items={[
<TripCard key="kyoto" title="Kyoto · Arashiyama" />,
<TripCard key="swiss" title="Switzerland · Jungfrau" />,
<TripCard key="palau" title="Palau · Rock Islands" />,
]}
peek={2}
onIndexChange={(index) => console.log("now on card", index + 1)}
/>Each item fills the stage area (h-72 w-64 by default, overridable with stageClassName), so give the card itself h-full w-full and a rounded background.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | React.ReactNode[] | — | The list of carousel card content; each node fills the stage area |
peek | number | 2 | Number of stacked layers peeking out behind |
offset | number | 16 | Distance each stacked layer is offset upward (px) |
scaleStep | number | 0.06 | Scale reduction per stacked layer (0–1) |
loop | boolean | true | Whether to wrap around at the start and the end |
showDots | boolean | true | Whether to show the dot indicators |
showArrows | boolean | true | Whether to show the left and right switch buttons |
stageClassName | string | — | Sizing styles of the stage (the card stack area), h-72 w-64 by default |
onIndexChange | (index: number) => void | — | Callback fired when the current index changes |
className | string | — | Forwarded to the outermost container |
Accessibility
- The stage is marked
role="region"witharia-roledescription="carousel", and the total number of cards is stated in the label - The current position is announced live through an
aria-live="polite"block as "card X of N" - The peeking cards behind are hidden from assistive technology with
aria-hiddenand have interaction disabled withpointer-events-none - The left and right buttons and the dots are all native
buttons that can be focused and operated by keyboard, each carrying anaria-labelfor "previous / next / go to card N", with the current dot markedaria-current - When the user has "reduce motion" enabled at the system level, the drag gesture and the spring animation are disabled and switching completes instantly
Thumbnail Gallery
A gallery whose main image and thumbnail strip stay in sync, supporting drag to change images, arrow keys, slide/fade transitions, and a thumbnail strip on any of four sides.
Vertical Story Carousel
A stories-style vertical carousel: segmented progress bars at the top, autoplay, and tap to switch