Components
Carousel

Carousel

A slideshow component that cycles through elements.

Anatomy

To set up the carousel correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Examples

Learn how to use the Carousel component in your project. Let's take a look at the most basic example:

<script setup lang="ts">
import { Carousel } from '@ark-ui/vue/carousel'

const images = [
  'https://tinyurl.com/5b6ka8jd',
  'https://tinyurl.com/7rmccdn5',
  'https://tinyurl.com/59jxz9uu',
  'https://tinyurl.com/6jurv23t',
  'https://tinyurl.com/yp4rfum7',
]
</script>

<template>
  <Carousel.Root>
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <Carousel.IndicatorGroup>
      <Carousel.Indicator v-for="(_, idx) in images" :key="idx" :index="idx">
        {{ idx + 1 }}
      </Carousel.Indicator>
    </Carousel.IndicatorGroup>
    <Carousel.Viewport>
      <Carousel.ItemGroup>
        <Carousel.Item v-for="(image, idx) in images" :key="idx" :index="idx">
          <img
            :src="image"
            alt=""
            :style="{ height: '300px', width: '100%', objectFit: 'cover' }"
          />
        </Carousel.Item>
      </Carousel.ItemGroup>
    </Carousel.Viewport>
  </Carousel.Root>
</template>

To create a controlled Carousel component, you can manage the state of the carousel using the index prop and update it when the onIndexChange event handler is called:

<script setup lang="ts">
import { Carousel } from '@ark-ui/vue/carousel'
import { ref } from 'vue'

const images = [
  'https://tinyurl.com/5b6ka8jd',
  'https://tinyurl.com/7rmccdn5',
  'https://tinyurl.com/59jxz9uu',
  'https://tinyurl.com/6jurv23t',
  'https://tinyurl.com/yp4rfum7',
]
const index = ref(0)
</script>

<template>
  <Carousel.Root v-model:index="index">
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <Carousel.IndicatorGroup>
      <Carousel.Indicator v-for="(_, idx) in images" :key="idx" :index="idx">
        {{ idx + 1 }}
      </Carousel.Indicator>
    </Carousel.IndicatorGroup>
    <Carousel.Viewport>
      <Carousel.ItemGroup>
        <Carousel.Item v-for="(image, idx) in images" :key="idx" :index="idx">
          <img
            :src="image"
            alt=""
            :style="{ height: '300px', width: '100%', objectFit: 'cover' }"
          />
        </Carousel.Item>
      </Carousel.ItemGroup>
    </Carousel.Viewport>
  </Carousel.Root>
</template>

You can customize the Carousel component by setting various props. Here's an example of a customized Carousel:

<script setup lang="ts">
import { Carousel } from '@ark-ui/vue/carousel'

const images = [
  'https://tinyurl.com/5b6ka8jd',
  'https://tinyurl.com/7rmccdn5',
  'https://tinyurl.com/59jxz9uu',
  'https://tinyurl.com/6jurv23t',
  'https://tinyurl.com/yp4rfum7',
]
</script>

<template>
  <Carousel.Root
    :align="'center'"
    loop
    :slides-per-view="2"
    spacing="16px"
    orientation="horizontal"
  >
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <Carousel.IndicatorGroup>
      <Carousel.Indicator v-for="(_, idx) in images" :key="idx" :index="idx">
        {{ idx + 1 }}
      </Carousel.Indicator>
    </Carousel.IndicatorGroup>
    <Carousel.Viewport>
      <Carousel.ItemGroup>
        <Carousel.Item v-for="(image, idx) in images" :key="idx" :index="idx">
          <img
            :src="image"
            alt=""
            :style="{ height: '300px', width: '100%', objectFit: 'cover' }"
          />
        </Carousel.Item>
      </Carousel.ItemGroup>
    </Carousel.Viewport>
  </Carousel.Root>
</template>

Using the Root Provider

The RootProvider component provides a context for the carousel. It accepts the value of the useCarousel hook. You can leverage it to access the component state and methods from outside the carousel.

<script setup lang="ts">
import { Carousel, useCarousel } from '@ark-ui/vue/carousel'

const images = [
  'https://tinyurl.com/5b6ka8jd',
  'https://tinyurl.com/7rmccdn5',
  'https://tinyurl.com/59jxz9uu',
  'https://tinyurl.com/6jurv23t',
  'https://tinyurl.com/yp4rfum7',
]

const carousel = useCarousel()
</script>

<template>
  <button @click="carousel.scrollToNext()">Next</button>

  <Carousel.RootProvider :value="carousel">
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <Carousel.IndicatorGroup>
      <Carousel.Indicator v-for="(_, idx) in images" :key="idx" :index="idx">
        {{ idx + 1 }}
      </Carousel.Indicator>
    </Carousel.IndicatorGroup>
    <Carousel.Viewport>
      <Carousel.ItemGroup>
        <Carousel.Item v-for="(image, idx) in images" :key="idx" :index="idx">
          <img
            :src="image"
            alt=""
            :style="{ height: '300px', width: '100%', objectFit: 'cover' }"
          />
        </Carousel.Item>
      </Carousel.ItemGroup>
    </Carousel.Viewport>
  </Carousel.RootProvider>
</template>

If you're using the RootProvider component, you don't need to use the Root component.

API Reference

Root

PropDefaultType
align'start'
'start' | 'center' | 'end'

The alignment of the slides in the carousel.

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
defaultIndex
number

The initial index of the carousel when it is first rendered. Use this when you do not need to control the state of the carousel.

id
string

The unique identifier of the machine.

ids
Partial<{ root: string viewport: string item(index: number): string itemGroup: string nextTrigger: string prevTrigger: string indicatorGroup: string indicator(index: number): string }>

The ids of the elements in the carousel. Useful for composition.

index
number

The current slide index.

loopfalse
boolean

Whether the carousel should loop around.

orientation'horizontal'
'horizontal' | 'vertical'

The orientation of the carousel.

slidesPerView1
number | 'auto'

The number of slides to show at a time.

spacing'0px'
string

The amount of space between slides.

EmitEvent
indexChange
[details: SlideChangeDetails]

Function called when the slide changes.

update:index
[index: number]

Data AttributeValue
[data-scope]carousel
[data-part]root
[data-orientation]The orientation of the carousel

Control

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

IndicatorGroup

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]carousel
[data-part]indicator-group
[data-orientation]The orientation of the indicatorgroup

Indicator

PropDefaultType
index
number

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
readOnly
boolean

Data AttributeValue
[data-scope]carousel
[data-part]indicator
[data-orientation]The orientation of the indicator
[data-index]The index of the item
[data-readonly]Present when read-only
[data-current]Present when current

ItemGroup

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]carousel
[data-part]item-group
[data-orientation]The orientation of the item

Item

PropDefaultType
index
number

The index of the item.

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]carousel
[data-part]item
[data-current]Present when current
[data-inview]Present when in viewport
[data-orientation]The orientation of the item

NextTrigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]carousel
[data-part]next-trigger
[data-orientation]The orientation of the nexttrigger

PrevTrigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]carousel
[data-part]prev-trigger
[data-orientation]The orientation of the prevtrigger

RootProvider

PropDefaultType
value
MachineApi<PropTypes>

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Viewport

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]carousel
[data-part]viewport
[data-orientation]The orientation of the viewport

Accessibility

Complies with the Carousel WAI-ARIA design pattern.