Installation
Complete project setup first. Your configuration
must select vue/reka and include your Design System ID.
pnpm exec frontfriend download carousel -f vue --primitive rekaReview dependencies reported by the downloader and keep your source changes in version control.
Usage
<script setup lang="ts">
import { Carousel } from "@/components/ui/carousel";
import { CarouselContent } from "@/components/ui/carousel";
import { CarouselItem } from "@/components/ui/carousel";
import { Card } from "@/components/ui/card";
import { CardContent } from "@/components/ui/card";
import { CarouselPrevious } from "@/components/ui/carousel";
import { CarouselNext } from "@/components/ui/carousel";
import * as UI from "@/components/ui/carousel";
const Component = UI.Carousel;
const args = {
"orientation": "horizontal",
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & { orientation?: "horizontal" | "vertical" };
</script>
<template>
<Carousel class="w-full max-w-xs" v-bind="args"
><CarouselContent
><CarouselItem v-for="index in 5" :key="index"
><div class="p-1">
<Card
><CardContent
class="flex aspect-square items-center justify-center p-6"
><span class="text-4xl font-semibold">{{
index
}}</span></CardContent
></Card
>
</div></CarouselItem
></CarouselContent
><CarouselPrevious /><CarouselNext
/></Carousel>
</template> Examples
Default
<script setup lang="ts">
import { Carousel } from "@/components/ui/carousel";
import { CarouselContent } from "@/components/ui/carousel";
import { CarouselItem } from "@/components/ui/carousel";
import { Card } from "@/components/ui/card";
import { CardContent } from "@/components/ui/card";
import { CarouselPrevious } from "@/components/ui/carousel";
import { CarouselNext } from "@/components/ui/carousel";
import * as UI from "@/components/ui/carousel";
const Component = UI.Carousel;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<Carousel class="w-full max-w-xs" v-bind="args"
><CarouselContent
><CarouselItem v-for="index in 5" :key="index"
><div class="p-1">
<Card
><CardContent
class="flex aspect-square items-center justify-center p-6"
><span class="text-4xl font-semibold">{{
index
}}</span></CardContent
></Card
>
</div></CarouselItem
></CarouselContent
><CarouselPrevious /><CarouselNext
/></Carousel>
</template> Sizes
<script setup lang="ts">
import { Carousel } from "@/components/ui/carousel";
import { CarouselContent } from "@/components/ui/carousel";
import { CarouselItem } from "@/components/ui/carousel";
import { Card } from "@/components/ui/card";
import { CardContent } from "@/components/ui/card";
import { CarouselPrevious } from "@/components/ui/carousel";
import { CarouselNext } from "@/components/ui/carousel";
import * as UI from "@/components/ui/carousel";
const Component = UI.Carousel;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<Carousel class="w-full max-w-sm" :opts="{ align: 'start' }"
><CarouselContent
><CarouselItem
v-for="index in 5"
:key="index"
class="md:basis-1/2 lg:basis-1/3"
><div class="p-1">
<Card
><CardContent
class="flex aspect-square items-center justify-center p-6"
><span class="text-3xl font-semibold">{{
index
}}</span></CardContent
></Card
>
</div></CarouselItem
></CarouselContent
><CarouselPrevious /><CarouselNext
/></Carousel>
</template> Spacing
<script setup lang="ts">
import { Carousel } from "@/components/ui/carousel";
import { CarouselContent } from "@/components/ui/carousel";
import { CarouselItem } from "@/components/ui/carousel";
import { Card } from "@/components/ui/card";
import { CardContent } from "@/components/ui/card";
import { CarouselPrevious } from "@/components/ui/carousel";
import { CarouselNext } from "@/components/ui/carousel";
import * as UI from "@/components/ui/carousel";
const Component = UI.Carousel;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<Carousel class="w-full max-w-sm"
><CarouselContent class="-ml-1"
><CarouselItem
v-for="index in 5"
:key="index"
class="pl-1 md:basis-1/2 lg:basis-1/3"
><div class="p-1">
<Card
><CardContent
class="flex aspect-square items-center justify-center p-6"
><span class="text-2xl font-semibold">{{
index
}}</span></CardContent
></Card
>
</div></CarouselItem
></CarouselContent
><CarouselPrevious /><CarouselNext
/></Carousel>
</template> Orientation
<script setup lang="ts">
import { Carousel } from "@/components/ui/carousel";
import { CarouselContent } from "@/components/ui/carousel";
import { CarouselItem } from "@/components/ui/carousel";
import { Card } from "@/components/ui/card";
import { CardContent } from "@/components/ui/card";
import { CarouselPrevious } from "@/components/ui/carousel";
import { CarouselNext } from "@/components/ui/carousel";
import * as UI from "@/components/ui/carousel";
const Component = UI.Carousel;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<Carousel
class="w-full max-w-xs"
orientation="vertical"
:opts="{ align: 'start' }"
><CarouselContent class="-mt-1 h-[200px]"
><CarouselItem v-for="index in 5" :key="index" class="pt-1 md:basis-1/2"
><div class="p-1">
<Card
><CardContent class="flex items-center justify-center p-6"
><span class="text-3xl font-semibold">{{
index
}}</span></CardContent
></Card
>
</div></CarouselItem
></CarouselContent
><CarouselPrevious /><CarouselNext
/></Carousel>
</template> Api
<script setup lang="ts">
import { ref } from "vue";
import * as UI from "@/components/ui/carousel";
import { watch } from "vue";
import { Carousel } from "@/components/ui/carousel";
import { CarouselContent } from "@/components/ui/carousel";
import { CarouselItem } from "@/components/ui/carousel";
import { Card } from "@/components/ui/card";
import { CardContent } from "@/components/ui/card";
import { CarouselPrevious } from "@/components/ui/carousel";
import { CarouselNext } from "@/components/ui/carousel";
const Component = UI.Carousel;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
const api = ref<UI.CarouselApi>();
const current = ref(0);
const count = ref(0);
function setApi(val: UI.CarouselApi) {
api.value = val;
}
watch(api, (value) => {
if (!value) return;
count.value = value.scrollSnapList().length;
current.value = value.selectedScrollSnap() + 1;
value.on("select", () => {
current.value = value.selectedScrollSnap() + 1;
});
});
</script>
<template>
<div class="mx-auto max-w-xs">
<Carousel class="w-full max-w-xs" @init-api="setApi"
><CarouselContent
><CarouselItem v-for="index in 5" :key="index"
><div class="p-1">
<Card
><CardContent
class="flex aspect-square items-center justify-center p-6"
><span class="text-4xl font-semibold">{{
index
}}</span></CardContent
></Card
>
</div></CarouselItem
></CarouselContent
><CarouselPrevious /><CarouselNext
/></Carousel>
<div class="py-2 text-center text-sm text-neutral-mid">
Slide {{ current }} of {{ count }}
</div>
</div>
</template> API reference
Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Reka UI.
CarouselNext
| Prop | Type | Default | Description |
|---|---|---|---|
size | ButtonVariants["size"] | — | |
variant | ButtonVariants["variant"] | — |
CarouselPrevious
| Prop | Type | Default | Description |
|---|---|---|---|
size | ButtonVariants["size"] | — | |
variant | ButtonVariants["variant"] | — |
Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.