Carousel

Swipeable slide carousel driven by one motion value: momentum drag that snaps to slides with rubber-band edges, seamless loop, responsive slidesPerView, dot or thumbnail indicators with a gliding active pill, and autoplay with a progress bar that pauses on hover, focus or hidden tabs.

Preview

Carousel preview width

Install

Add it with the shadcn CLI, or copy the source manually.

$ bunx --bun shadcn add @karaui/carousel
@karaui not found? Add it to components.json
{
  "registries": {
    "@karaui": "https://karaui.kamisama-v0.my.id/r/{name}.json"
  }
}

@karaui is in shadcn's public registry directory, so the latest CLI needs no setup. On an older CLI, merge this into the existing file once and every @karaui/… install resolves.

API Reference

children
ReactNode

One child per slide.

—
index?
number

Controlled index of the first visible slide.

—
defaultIndex?
number

Initial index for uncontrolled use.

0
onIndexChange?
((index: number) => void)
—
loop?
boolean

Wrap past either end. Seamless when there are at least `slidesPerView + 2` slides.

false
autoplay?
number | boolean

Advance automatically; `true` = every 5000ms, or pass the interval in ms. Pauses on hover, focus, drag and hidden tabs; off under reduced motion.

false
slidesPerView?
number | Record<number, number>

Slides shown at once: a number, or `{ minContainerWidthPx: count }`, e.g. `{ 0: 1, 480: 2, 768: 3 }`.

1
gap?
number

Space between slides in px.

16
indicators?
"none" | "dots" | "thumbnails"
dots
renderThumbnail?
((index: number) => ReactNode)

Thumbnail content per position, for `indicators="thumbnails"`.

—
showControls?
boolean

Render previous / next buttons.

true
aria-label?
string

Accessible name of the carousel.

Carousel
getSlideLabel?
((index: number, count: number) => string)

Accessible name per slide.

(i, n) => `${i + 1} of ${n}`
className?
string
—
slideClassName?
string
—

Updated