Carousel
Installation
npm install @radix-ui/react-slot@^1.2.4 @tabler/icons-react@^3.36.1 class-variance-authority@^0.7.1 clsx@^2.1.1 embla-carousel-react@^8.6.0 tailwind-merge@^3.4.0components/button-group/button-group-context.ts
components/button/button.tsx
components/button/index.ts
components/spinner/index.ts
components/spinner/spinner.tsx
lib/icons.ts
lib/utils.ts
components/carousel/carousel.tsx
components/carousel/index.tsCode
'use client';
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from '@/components/carousel/carousel';
const slides = [1, 2, 3, 4, 5];
export default function CarouselDemo() {
return (
<div className="nx:w-full nx:max-w-xs nx:px-12">
<Carousel className="nx:w-full" aria-label="Numbered slides">
<CarouselContent>
{slides.map((slide) => (
<CarouselItem
key={slide}
aria-label={`Slide ${slide} of ${slides.length}`}
>
<div className="nx:flex nx:aspect-square nx:items-center nx:justify-center nx:rounded-md nx:border-default nx:border-border-default nx:typography-heading-large">
{slide}
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
</div>
);
}
Props
Carousel
| Prop | Type | Default | Description |
|---|---|---|---|
opts | Partial<OptionsType> | No default documented | Embla options object (loop, align, dragFree, …). |
orientation | "horizontal" | "vertical" | "horizontal" | Scroll axis. |
plugins | CreatePluginType<LoosePluginType, {}>[] | No default documented | Embla plugins (autoplay, wheel-gestures, …). |
setApi | ((api: EmblaCarouselType) => void) | No default documented | Receives the Embla API once initialised, for external control. |
CarouselContent
CarouselContent adds no props of its own; it accepts the props of the element or primitive it wraps.
CarouselItem
CarouselItem adds no props of its own; it accepts the props of the element or primitive it wraps.
CarouselNext
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | When true, the button renders as its child element (via Radix Slot), applying button styling to e.g. an |
endIcon | ReactNode | No default documented | Decorative icon rendered after the button label. Use either |
loading | boolean | false | Shows a loading indicator and disables the button. While loading, the spinner replaces all visible content and any icon slots are hidden. |
size | "default" | "sm" | "lg" | "icon-sm" | "icon" | "icon-lg" | null | "icon" | No description |
startIcon | ReactNode | No default documented | Decorative icon rendered before the button label. Use either |
variant | "link" | "default" | "error" | "destructive" | "outline" | "dashed" | "secondary" | "ghost" | null | "outline" | No description |
CarouselPrevious
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | When true, the button renders as its child element (via Radix Slot), applying button styling to e.g. an |
endIcon | ReactNode | No default documented | Decorative icon rendered after the button label. Use either |
loading | boolean | false | Shows a loading indicator and disables the button. While loading, the spinner replaces all visible content and any icon slots are hidden. |
size | "default" | "sm" | "lg" | "icon-sm" | "icon" | "icon-lg" | null | "icon" | No description |
startIcon | ReactNode | No default documented | Decorative icon rendered before the button label. Use either |
variant | "link" | "default" | "error" | "destructive" | "outline" | "dashed" | "secondary" | "ghost" | null | "outline" | No description |
Examples
Vertical
'use client';
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from '@/components/carousel/carousel';
const slides = [1, 2, 3, 4, 5];
export default function CarouselVertical() {
return (
<div className="nx:w-full nx:max-w-xs nx:py-12">
<Carousel
orientation="vertical"
className="nx:w-full"
aria-label="Numbered slides"
>
<CarouselContent className="nx:h-48">
{slides.map((slide) => (
<CarouselItem
key={slide}
aria-label={`Slide ${slide} of ${slides.length}`}
>
<div className="nx:flex nx:h-full nx:items-center nx:justify-center nx:rounded-md nx:border-default nx:border-border-default nx:typography-heading-large">
{slide}
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
</div>
);
}