Copy to clipboard
1
2
3
<Carousel class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">1</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">2</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">3</span>
</CardContent>
</Card>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
<Carousel class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">1</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">2</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">3</span>
</CardContent>
</Card>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel><Carousel class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">1</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">2</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-4xl font-semibold">3</span>
</CardContent>
</Card>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
Installation
Copy to clipboard
npx bearnie add carousel
npx bearnie add carouselnpx bearnie add carousel
bunx bearnie add carousel
bunx bearnie add carouselbunx bearnie add carousel
pnpm dlx bearnie add carousel
pnpm dlx bearnie add carouselpnpm dlx bearnie add carousel
yarn dlx bearnie add carousel
yarn dlx bearnie add carouselyarn dlx bearnie add carousel
External dependency: This component requires Keen Slider, a lightweight touch slider library.
Usage
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
CarouselDots,
} from "@/components/bearnie/carousel"<Carousel>
<CarouselContent>
<CarouselItem>Slide 1</CarouselItem>
<CarouselItem>Slide 2</CarouselItem>
<CarouselItem>Slide 3</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>Examples
With dots
Copy to clipboard
Slide 1
Slide 2
Slide 3
<Carousel class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
<CarouselDots count={3} />
</Carousel>
<Carousel class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
<CarouselDots count={3} />
</Carousel><Carousel class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
<CarouselDots count={3} />
</Carousel>
With thumbnails
Clickable previews below the carousel; the active thumbnail is highlighted as slides change.
Copy to clipboard
Slide 1
Slide 2
Slide 3
<Carousel class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselThumbnails>
<CarouselThumbnail>
<div class="flex h-12 w-20 items-center justify-center bg-muted text-xs">1</div>
</CarouselThumbnail>
<CarouselThumbnail>
<div class="flex h-12 w-20 items-center justify-center bg-muted text-xs">2</div>
</CarouselThumbnail>
<CarouselThumbnail>
<div class="flex h-12 w-20 items-center justify-center bg-muted text-xs">3</div>
</CarouselThumbnail>
</CarouselThumbnails>
</Carousel>
<Carousel class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselThumbnails>
<CarouselThumbnail>
<div class="flex h-12 w-20 items-center justify-center bg-muted text-xs">1</div>
</CarouselThumbnail>
<CarouselThumbnail>
<div class="flex h-12 w-20 items-center justify-center bg-muted text-xs">2</div>
</CarouselThumbnail>
<CarouselThumbnail>
<div class="flex h-12 w-20 items-center justify-center bg-muted text-xs">3</div>
</CarouselThumbnail>
</CarouselThumbnails>
</Carousel><Carousel class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-muted">
<span class="text-2xl font-semibold">Slide 3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselThumbnails>
<CarouselThumbnail>
<div class="flex h-12 w-20 items-center justify-center bg-muted text-xs">1</div>
</CarouselThumbnail>
<CarouselThumbnail>
<div class="flex h-12 w-20 items-center justify-center bg-muted text-xs">2</div>
</CarouselThumbnail>
<CarouselThumbnail>
<div class="flex h-12 w-20 items-center justify-center bg-muted text-xs">3</div>
</CarouselThumbnail>
</CarouselThumbnails>
</Carousel>
Loop
Copy to clipboard
1
2
3
<Carousel loop class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span class="text-2xl font-semibold">1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span class="text-2xl font-semibold">2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span class="text-2xl font-semibold">3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
<Carousel loop class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span class="text-2xl font-semibold">1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span class="text-2xl font-semibold">2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span class="text-2xl font-semibold">3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel><Carousel loop class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span class="text-2xl font-semibold">1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span class="text-2xl font-semibold">2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-primary text-primary-foreground">
<span class="text-2xl font-semibold">3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
Autoplay
Copy to clipboard
Auto 1
Auto 2
Auto 3
<Carousel autoplay autoplayDelay={3000} loop class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-rose-200 text-rose-900">
<span class="text-2xl font-semibold">Auto 1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-sky-200 text-sky-900">
<span class="text-2xl font-semibold">Auto 2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-amber-200 text-amber-900">
<span class="text-2xl font-semibold">Auto 3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselDots count={3} />
</Carousel>
<Carousel autoplay autoplayDelay={3000} loop class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-rose-200 text-rose-900">
<span class="text-2xl font-semibold">Auto 1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-sky-200 text-sky-900">
<span class="text-2xl font-semibold">Auto 2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-amber-200 text-amber-900">
<span class="text-2xl font-semibold">Auto 3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselDots count={3} />
</Carousel><Carousel autoplay autoplayDelay={3000} loop class="w-full max-w-md">
<CarouselContent>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-rose-200 text-rose-900">
<span class="text-2xl font-semibold">Auto 1</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-sky-200 text-sky-900">
<span class="text-2xl font-semibold">Auto 2</span>
</div>
</CarouselItem>
<CarouselItem>
<div class="flex aspect-video items-center justify-center rounded-lg bg-amber-200 text-amber-900">
<span class="text-2xl font-semibold">Auto 3</span>
</div>
</CarouselItem>
</CarouselContent>
<CarouselDots count={3} />
</Carousel>
Multiple slides per view
Copy to clipboard
1
2
3
4
5
<Carousel slidesPerView={3} spacing={16} class="w-full max-w-2xl">
<CarouselContent>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">1</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">2</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">3</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">4</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">5</span>
</CardContent>
</Card>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
<Carousel slidesPerView={3} spacing={16} class="w-full max-w-2xl">
<CarouselContent>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">1</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">2</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">3</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">4</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">5</span>
</CardContent>
</Card>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel><Carousel slidesPerView={3} spacing={16} class="w-full max-w-2xl">
<CarouselContent>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">1</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">2</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">3</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">4</span>
</CardContent>
</Card>
</CarouselItem>
<CarouselItem>
<Card>
<CardContent class="flex aspect-square items-center justify-center p-6">
<span class="text-2xl font-semibold">5</span>
</CardContent>
</Card>
</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
Responsive breakpoints
Override slidesPerView and spacing per media query with the breakpoints prop. This example shows one slide on mobile, two from 768px, and three from 1024px — resize the window to see it change.
Copy to clipboard
1
2
3
4
5
<Carousel
slidesPerView={1}
breakpoints={{
"(min-width: 768px)": { slidesPerView: 2 },
"(min-width: 1024px)": { slidesPerView: 3, spacing: 24 },
}}
class="w-full max-w-2xl"
>
<CarouselContent>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
<Carousel
slidesPerView={1}
breakpoints={{
"(min-width: 768px)": { slidesPerView: 2 },
"(min-width: 1024px)": { slidesPerView: 3, spacing: 24 },
}}
class="w-full max-w-2xl"
>
<CarouselContent>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel><Carousel
slidesPerView={1}
breakpoints={{
"(min-width: 768px)": { slidesPerView: 2 },
"(min-width: 1024px)": { slidesPerView: 3, spacing: 24 },
}}
class="w-full max-w-2xl"
>
<CarouselContent>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
<CarouselItem>...</CarouselItem>
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
Props
Carousel
| Prop | Type | Default | Description |
|---|---|---|---|
| loop | boolean | false | Enable infinite loop |
| autoplay | boolean | false | Auto-advance slides |
| autoplayDelay | number | 4000 | Delay between slides in ms |
| pauseOnHover | boolean | true | Pause autoplay on hover |
| slidesPerView | number | “auto” | 1 | Slides visible at once |
| spacing | number | 16 | Gap between slides in px |
| orientation | “horizontal” | “vertical” | “horizontal” | Slide direction |
| breakpoints | Record<string, { slidesPerView?, spacing? }> | - | Per-media-query overrides, e.g. { "(min-width: 768px)": { slidesPerView: 2 } } |
CarouselDots
| Prop | Type | Default | Description |
|---|---|---|---|
| count | number | required | Number of dots to display |
CarouselThumbnails / CarouselThumbnail
Container and clickable thumbnail buttons rendered below the carousel — one CarouselThumbnail per slide, in slide order. The active thumbnail gets a data-active attribute (styled with a primary border by default). Both accept class for additional CSS classes.
Accessibility
- Navigation buttons have proper aria-labels
- Dots indicate current slide position
- Touch and swipe gestures supported
- Keyboard navigation supported (arrow keys when focused)