---import { Carousel, CarouselSlide } from '@bejamas/registry/ui/carousel';---
<Carousel aria-label="Horizontal single cards" class="mx-auto max-w-86.5"> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">1</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">2</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">3</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">4</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">5</div></CarouselSlide></Carousel>Installation
Section titled “Installation”bunx bejamas add carouselnpx bejamas add carouselpnpm dlx bejamas add carouselyarn dlx bejamas add carousel---import { Carousel, CarouselSlide } from '@bejamas/registry/ui/carousel';---
<Carousel aria-label="Featured cards" class="max-w-sm"> <CarouselSlide><div class="rounded-lg bg-muted p-6">Card 1</div></CarouselSlide> <CarouselSlide><div class="rounded-lg bg-muted p-6">Card 2</div></CarouselSlide> <CarouselSlide><div class="rounded-lg bg-muted p-6">Card 3</div></CarouselSlide></Carousel>| Prop | Type | Default |
|---|---|---|
orientation |
"horizontal" | "vertical" |
axis === "y" ? "vertical" : "horizontal" |
variant |
"single" | "multiple" |
"single" |
defaultIndex |
number |
0 |
“data-loop” |
boolean | string |
false |
drag |
boolean |
true |
controls |
boolean |
true |
showCounter |
boolean |
orientation === "horizontal" && variant === "single" |
counterLabel |
string |
variant === "multiple" ? "Page" : "Card" |
previousLabel |
string |
"Previous slide" |
nextLabel |
string |
"Next slide" |
contentClass |
string |
|
axis |
"x" | "y" |
"x" |
snapType |
"mandatory" | "proximity" |
"mandatory" |
fade |
boolean |
false |
class |
string |
Examples
Section titled “Examples”Horizontal single
Section titled “Horizontal single”---import { Carousel, CarouselSlide } from '@bejamas/registry/ui/carousel';---
<Carousel aria-label="Horizontal single cards" class="mx-auto max-w-86.5"> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">1</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">2</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">3</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">4</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">5</div></CarouselSlide></Carousel>Horizontal multiple
Section titled “Horizontal multiple”---import { Carousel, CarouselSlide } from '@bejamas/registry/ui/carousel';---
<Carousel aria-label="Horizontal multiple cards" variant="multiple" class="mx-auto max-w-108"> <CarouselSlide> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">1</div> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">2</div> </CarouselSlide> <CarouselSlide> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">3</div> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">4</div> </CarouselSlide> <CarouselSlide> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">5</div> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">6</div> </CarouselSlide></Carousel>Vertical single
Section titled “Vertical single”---import { Carousel, CarouselSlide } from '@bejamas/registry/ui/carousel';---
<Carousel aria-label="Vertical single cards" orientation="vertical" class="mx-auto max-w-75" contentClass="h-50"> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold h-full">1</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold h-full">2</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold h-full">3</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold h-full">4</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold h-full">5</div></CarouselSlide></Carousel>Vertical multiple
Section titled “Vertical multiple”---import { Carousel, CarouselSlide } from '@bejamas/registry/ui/carousel';---
<Carousel aria-label="Vertical multiple cards" orientation="vertical" variant="multiple" class="mx-auto max-w-75" contentClass="h-79"> <CarouselSlide> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold min-h-0">1</div> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold min-h-0">2</div> </CarouselSlide> <CarouselSlide> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold min-h-0">3</div> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold min-h-0">4</div> </CarouselSlide> <CarouselSlide> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold min-h-0">5</div> <div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold min-h-0">6</div> </CarouselSlide></Carousel>Header controls
Section titled “Header controls”Use CarouselRoot to compose your own layout. Place CarouselPrevious and CarouselNext anywhere inside the root, including a header above CarouselContent. The runtime keeps their disabled states in sync. Place slides directly inside CarouselContent.
CarouselRoot accepts orientation, axis, variant, defaultIndex, data-loop, and drag. CarouselContent inherits orientation and drag from the root and accepts snapType, fade, and class; give vertical content a height. Controls accept button attributes, variant, size, and class, with an optional slot for a custom icon or text and aria-label for a custom accessible name. The composed root renders only its slot; the existing Carousel continues to provide its default controls, viewport, and counter.
Featured cards
---import { CarouselContent, CarouselNext, CarouselPrevious, CarouselRoot, CarouselSlide } from '@bejamas/registry/ui/carousel';---
<CarouselRoot aria-label="Featured cards" class="mx-auto max-w-sm space-y-4"> <header class="flex items-center justify-between gap-4"> <h3 class="font-semibold">Featured cards</h3> <div class="flex gap-2"> <CarouselPrevious /> <CarouselNext /> </div> </header> <CarouselContent> <CarouselSlide><div class="rounded-lg bg-muted p-6">Card 1</div></CarouselSlide> <CarouselSlide><div class="rounded-lg bg-muted p-6">Card 2</div></CarouselSlide> <CarouselSlide><div class="rounded-lg bg-muted p-6">Card 3</div></CarouselSlide> </CarouselContent></CarouselRoot>Looping
Section titled “Looping”Set data-loop="true" to wrap button, keyboard, and programmatic navigation from the last slide to the first and back. Looping defaults to false.
---import { Carousel, CarouselSlide } from '@bejamas/registry/ui/carousel';---
<Carousel aria-label="Looping cards" data-loop="true" class="mx-auto max-w-86.5"> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">1</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">2</div></CarouselSlide> <CarouselSlide><div class="flex items-center justify-center rounded-lg bg-muted text-muted-foreground font-semibold aspect-4/5">3</div></CarouselSlide></Carousel>API Reference
Section titled “API Reference”Events
Section titled “Events”The carousel emits custom events on its root element:
| Event | Detail | Description |
|---|---|---|
carousel:change |
{ index: number } |
Fired when the active slide changes. The index is zero-based. |
<Carousel id="my-carousel" aria-label="Featured cards" class="max-w-sm"> <CarouselSlide><div class="rounded-lg bg-muted p-6">Card 1</div></CarouselSlide> <CarouselSlide><div class="rounded-lg bg-muted p-6">Card 2</div></CarouselSlide> <CarouselSlide><div class="rounded-lg bg-muted p-6">Card 3</div></CarouselSlide></Carousel>const carousel = document.getElementById('my-carousel');
carousel.addEventListener('carousel:change', (event) => { console.log('Active slide:', event.detail.index);});Programmatic Control
Section titled “Programmatic Control”Dispatch carousel:set on the root to select a slide or navigate:
const carousel = document.getElementById('my-carousel');
// Select the third slide (zero-based index).carousel.dispatchEvent(new CustomEvent('carousel:set', { detail: { index: 2 }}));
// Move to the next slide.carousel.dispatchEvent(new CustomEvent('carousel:set', { detail: { action: 'next' }}));
// Move to the previous slide.carousel.dispatchEvent(new CustomEvent('carousel:set', { detail: { action: 'prev' }}));Data Attributes
Section titled “Data Attributes”The carousel exposes these attributes for styling and state queries:
| Attribute | Element | Description |
|---|---|---|
data-orientation |
carousel | Current orientation (horizontal or vertical) |
data-variant |
carousel | Layout variant (single or multiple) |
data-loop |
carousel | Set to "true" to wrap navigation at either end; defaults to "false" |
data-index |
carousel | Zero-based index of the active slide |
data-dragging |
carousel | Present during an active drag gesture |
data-state |
carousel-item | Current slide state (active or inactive) |