Installation
Complete project setup first. Your configuration
must select react/base and include your Design System ID.
pnpm exec frontfriend download carousel -f react --primitive baseReview dependencies reported by the downloader and keep your source changes in version control.
Usage
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
} from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
function Slide({ value, square = true }: { value: number; square?: boolean }) {
return (
<div className="p-1">
<Card>
<CardContent
className={`flex items-center justify-center p-6${square ? " aspect-square" : ""}`}
>
<span className="text-3xl font-semibold">{value}</span>
</CardContent>
</Card>
</div>
);
}
<Carousel className="w-full max-w-xs" orientation="horizontal">
<CarouselContent>
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index}>
<Slide value={index + 1} />
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>; Examples
Default
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
} from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
function Slide({ value, square = true }: { value: number; square?: boolean }) {
return (
<div className="p-1">
<Card>
<CardContent
className={`flex items-center justify-center p-6${square ? " aspect-square" : ""}`}
>
<span className="text-3xl font-semibold">{value}</span>
</CardContent>
</Card>
</div>
);
}
<Carousel className="w-full max-w-xs" >
<CarouselContent>
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index}>
<Slide value={index + 1} />
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>; Sizes
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
} from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
function Slide({ value, square = true }: { value: number; square?: boolean }) {
return (
<div className="p-1">
<Card>
<CardContent
className={`flex items-center justify-center p-6${square ? " aspect-square" : ""}`}
>
<span className="text-3xl font-semibold">{value}</span>
</CardContent>
</Card>
</div>
);
}
<Carousel opts={{ align: "start" }} className="w-full max-w-sm">
<CarouselContent>
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index} className="md:basis-1/2 lg:basis-1/3">
<Slide value={index + 1} />
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>; Spacing
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
} from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
function Slide({ value, square = true }: { value: number; square?: boolean }) {
return (
<div className="p-1">
<Card>
<CardContent
className={`flex items-center justify-center p-6${square ? " aspect-square" : ""}`}
>
<span className="text-3xl font-semibold">{value}</span>
</CardContent>
</Card>
</div>
);
}
<Carousel className="w-full max-w-sm">
<CarouselContent className="-ml-1">
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index} className="pl-1 md:basis-1/2 lg:basis-1/3">
<Slide value={index + 1} />
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>; Orientation
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
} from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
function Slide({ value, square = true }: { value: number; square?: boolean }) {
return (
<div className="p-1">
<Card>
<CardContent
className={`flex items-center justify-center p-6${square ? " aspect-square" : ""}`}
>
<span className="text-3xl font-semibold">{value}</span>
</CardContent>
</Card>
</div>
);
}
<Carousel
opts={{ align: "start" }}
orientation="vertical"
className="w-full max-w-xs"
>
<CarouselContent className="-mt-1 h-[200px]">
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index} className="pt-1 md:basis-1/2">
<Slide value={index + 1} square={false} />
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>; Api
import {
CarouselApi,
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
} from "@/components/ui/carousel";
import { Card, CardContent } from "@/components/ui/card";
import * as React from "react";
function Slide({ value, square = true }: { value: number; square?: boolean }) {
return (
<div className="p-1">
<Card>
<CardContent
className={`flex items-center justify-center p-6${square ? " aspect-square" : ""}`}
>
<span className="text-3xl font-semibold">{value}</span>
</CardContent>
</Card>
</div>
);
}
export default function CarouselExample() {
const [api, setApi] = React.useState<CarouselApi>();
const [current, setCurrent] = React.useState(0);
const [count, setCount] = React.useState(0);
React.useEffect(() => {
if (!api) return;
setCount(api.scrollSnapList().length);
setCurrent(api.selectedScrollSnap() + 1);
api.on("select", () => setCurrent(api.selectedScrollSnap() + 1));
}, [api]);
return (
<div className="mx-auto max-w-xs">
<Carousel setApi={setApi} className="w-full max-w-xs">
<CarouselContent>
{Array.from({ length: 5 }).map((_, index) => (
<CarouselItem key={index}>
<Slide value={index + 1} />
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious />
<CarouselNext />
</Carousel>
<div className="py-2 text-center text-sm text-neutral-mid">
Slide {current} of {count}
</div>
</div>
);
} API reference
Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Base UI.
| Prop | Type | Default | Description |
|---|---|---|---|
opts | CarouselOptions | — | |
orientation | "horizontal" | "vertical" | "horizontal" | Set the orientation of the carousel. |
plugins | CarouselPlugin | — | |
setApi | (api: CarouselApi) => void | — |
Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.