Use the Carousel component to display a list of items in a carousel.
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
:items="items"
class="mx-auto max-w-xs w-full"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
Use the items prop as an array and render each item using the default slot:
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
:items="items"
class="mx-auto max-w-xs w-full"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
You can also pass an array of objects with the following properties:
class?: anypohon?: { item?: ClassNameValue }You can control how many items are visible by using the flex-basis or width utility classes on the item:
<script setup lang="ts">
const items = [
'https://picsum.photos/468/468?random=1',
'https://picsum.photos/468/468?random=2',
'https://picsum.photos/468/468?random=3',
'https://picsum.photos/468/468?random=4',
'https://picsum.photos/468/468?random=5',
'https://picsum.photos/468/468?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
:items="items"
:pohon="{ item: 'akar:basis-1/3' }"
>
<img
:src="item"
width="234"
height="234"
class="rounded-lg"
>
</PCarousel>
</template>
Use the orientation prop to change the orientation of the Progress. Defaults to horizontal.
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
orientation="vertical"
:items="items"
:pohon="{ container: 'h-[336px]' }"
class="mx-auto max-w-xs w-full"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
height on the container in vertical orientation.Use the arrows prop to display prev and next buttons.
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
arrows
:items="items"
class="mx-auto max-w-xs w-full"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
Use the prev and next props to customize the prev and next buttons with any Button props.
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
arrows
:prev="{ color: 'primary' }"
:next="{ variant: 'solid' }"
:items="items"
class="mx-auto max-w-xs w-full"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
Use the prev-icon and next-icon props to customize the buttons Icon. Defaults to i-lucide:arrow-left / i-lucide:arrow-right.
<script setup lang="ts">
defineProps<{
prevIcon?: string;
nextIcon?: string;
}>();
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
arrows
:prev-icon="prevIcon"
:next-icon="nextIcon"
:items="items"
class="mx-auto max-w-xs w-full"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
app.config.ts under pohon.icons.arrowLeft / pohon.icons.arrowRight key.vite.config.ts under pohon.icons.arrowLeft / pohon.icons.arrowRight key.Use the dots prop to display a list of dots to scroll to a specific slide.
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
dots
:items="items"
class="mx-auto max-w-xs w-full"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
The number of dots is based on the number of slides displayed in the view:
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
dots
:items="items"
:pohon="{ item: 'akar:basis-1/3' }"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
The Carousel component implements the official Embla Carousel plugins.
This plugin is used to extend Embla Carousel with autoplay functionality.
Use the autoplay prop as a boolean or an object to configure the Autoplay plugin.
<script setup lang="ts">
const items = [
'https://picsum.photos/468/468?random=1',
'https://picsum.photos/468/468?random=2',
'https://picsum.photos/468/468?random=3',
'https://picsum.photos/468/468?random=4',
'https://picsum.photos/468/468?random=5',
'https://picsum.photos/468/468?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
loop
arrows
dots
:autoplay="{ delay: 2000 }"
:items="items"
:pohon="{ item: 'akar:basis-1/3' }"
>
<img
:src="item"
width="234"
height="234"
class="rounded-lg"
>
</PCarousel>
</template>
loop prop for an infinite carousel.This plugin is used to extend Embla Carousel with auto scroll functionality.
Use the auto-scroll prop as a boolean or an object to configure the Auto Scroll plugin.
<script setup lang="ts">
const items = [
'https://picsum.photos/468/468?random=1',
'https://picsum.photos/468/468?random=2',
'https://picsum.photos/468/468?random=3',
'https://picsum.photos/468/468?random=4',
'https://picsum.photos/468/468?random=5',
'https://picsum.photos/468/468?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
loop
dots
arrows
auto-scroll
:items="items"
:pohon="{ item: 'akar:basis-1/3' }"
>
<img
:src="item"
width="234"
height="234"
class="rounded-lg"
>
</PCarousel>
</template>
loop prop for an infinite carousel.This plugin is used to extend Embla Carousel with auto height functionality. It changes the height of the carousel container to fit the height of the highest slide in view.
Use the auto-height prop as a boolean or an object to configure the Auto Height plugin.
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/320?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/320?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/320?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
auto-height
arrows
dots
:items="items"
:pohon="{
container: 'transition-[height]',
controls: 'absolute -top-8 inset-x-12',
dots: '-top-7',
dot: 'w-6 h-1',
}"
class="mx-auto max-w-xs w-full"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
transition-[height] class on the container to animate the height change.Class Names is a class name toggle utility plugin for Embla Carousel that enables you to automate the toggling of class names on your carousel.
Use the class-names prop as a boolean or an object to configure the Class Names plugin.
<script setup lang="ts">
const items = [
'https://picsum.photos/528/528?random=1',
'https://picsum.photos/528/528?random=2',
'https://picsum.photos/528/528?random=3',
'https://picsum.photos/528/528?random=4',
'https://picsum.photos/528/528?random=5',
'https://picsum.photos/528/528?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
class-names
arrows
:items="items"
:pohon="{
item: 'akar:basis-[70%] transition-opacity [&:not(.is-snapped)]:opacity-10',
}"
class="mx-auto max-w-sm"
>
<img
:src="item"
width="264"
height="264"
class="rounded-lg"
>
</PCarousel>
</template>
transition-opacity [&:not(.is-snapped)]:opacity-10 classes on the item to animate the opacity change.This plugin is used to replace the Embla Carousel scroll functionality with fade transitions.
Use the fade prop as a boolean or an object to configure the Fade plugin.
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
fade
arrows
dots
:items="items"
class="mx-auto max-w-xs w-full"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
</template>
This plugin is used to extend Embla Carousel with the ability to use the mouse/trackpad wheel to navigate the carousel.
Use the wheel-gestures prop as a boolean or an object to configure the Wheel Gestures plugin.
<script setup lang="ts">
const items = [
'https://picsum.photos/468/468?random=1',
'https://picsum.photos/468/468?random=2',
'https://picsum.photos/468/468?random=3',
'https://picsum.photos/468/468?random=4',
'https://picsum.photos/468/468?random=5',
'https://picsum.photos/468/468?random=6',
];
</script>
<template>
<PCarousel
v-slot="{ item }"
loop
wheel-gestures
:items="items"
:pohon="{ item: 'akar:basis-1/3' }"
>
<img
:src="item"
width="234"
height="234"
class="rounded-lg"
>
</PCarousel>
</template>
You can use the emblaApi function scrollTo to display thumbnails under the carousel that allows you to navigate to a specific slide.
<script setup lang="ts">
import { ref, useTemplateRef } from 'vue';
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6',
];
const carousel = useTemplateRef('carousel');
const activeIndex = ref(0);
function onClickPrev() {
activeIndex.value--;
}
function onClickNext() {
activeIndex.value++;
}
function onSelect(index: number) {
activeIndex.value = index;
}
function select(index: number) {
activeIndex.value = index;
carousel.value?.emblaApi?.scrollTo(index);
}
</script>
<template>
<div class="flex-1 w-full">
<PCarousel
ref="carousel"
v-slot="{ item }"
arrows
:items="items"
:prev="{ onClick: onClickPrev }"
:next="{ onClick: onClickNext }"
class="mx-auto max-w-xs w-full"
@select="onSelect"
>
<img
:src="item"
width="320"
height="320"
class="rounded-lg"
>
</PCarousel>
<div class="mx-auto pt-4 flex gap-1 max-w-xs justify-between">
<div
v-for="(item, index) in items"
:key="index"
class="size-11 transition-opacity hover:opacity-100"
:class="[activeIndex === index ? 'opacity-100' : 'opacity-25']"
@click="select(index)"
>
<img
:src="item"
width="44"
height="44"
class="rounded-lg"
>
</div>
</div>
</div>
</template>
| Prop | Default | Type |
|---|
| Slot | Type |
|---|
| Event | Type |
|---|
You can access the typed component instance using useTemplateRef.
<script setup lang="ts">
const carousel = useTemplateRef('carousel');
</script>
<template>
<PCarousel ref="carousel" />
</template>
This will give you access to the following:
| Name | Type |
|---|---|
emblaRef | Ref<HTMLElement | null> |
emblaApi | Ref<EmblaCarouselType | null> |
Below is the theme configuration skeleton for the PCarousel. Since the component is provided unstyled by default, you will need to fill in these values to apply your own custom look and feel. If you prefer to use our pre-built, opinionated styling, you can instead use our UnoCSS preset, this docs is using it as well.
export default defineAppConfig({
pohon: {
carousel: {
slots: {
root: '',
viewport: '',
container: '',
item: '',
controls: '',
arrows: '',
prev: '',
next: '',
dots: '',
dot: ''
},
variants: {
orientation: {
vertical: {
container: '',
item: '',
prev: '',
next: ''
},
horizontal: {
container: '',
item: '',
prev: '',
next: ''
}
},
active: {
true: {
dot: ''
}
}
}
}
}
};
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import pohon from 'pohon-ui/vite'
export default defineAppConfig({
pohon: {
carousel: {
slots: {
root: '',
viewport: '',
container: '',
item: '',
controls: '',
arrows: '',
prev: '',
next: '',
dots: '',
dot: ''
},
variants: {
orientation: {
vertical: {
container: '',
item: '',
prev: '',
next: ''
},
horizontal: {
container: '',
item: '',
prev: '',
next: ''
}
},
active: {
true: {
dot: ''
}
}
}
}
}
};