Ark Logo

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:

import { Carousel } from '@ark-ui/react'

export const Basic = () => {
  const images = [
    'https://tinyurl.com/5b6ka8jd',
    'https://tinyurl.com/7rmccdn5',
    'https://tinyurl.com/59jxz9uu',
  ]
  return (
    <Carousel.Root>
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.IndicatorGroup>
        {images.map((_, index) => (
          <Carousel.Indicator key={index} index={index}>
            {index + 1}
          </Carousel.Indicator>
        ))}
      </Carousel.IndicatorGroup>
      <Carousel.Viewport>
        <Carousel.ItemGroup>
          {images.map((image, index) => (
            <Carousel.Item key={index} index={index}>
              <img src={image} alt={`Slide ${index}`} />
            </Carousel.Item>
          ))}
        </Carousel.ItemGroup>
      </Carousel.Viewport>
    </Carousel.Root>
  )
}

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:

import { useState } from 'react'
import { Carousel } from '@ark-ui/react'

export const Controlled = () => {
  const [currentIndex, setCurrentIndex] = useState(0)

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

  return (
    <Carousel.Root index={currentIndex} onIndexChange={(details) => setCurrentIndex(details.index)}>
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.IndicatorGroup>
        {images.map((_, index) => (
          <Carousel.Indicator key={index} index={index}>
            {index + 1}
          </Carousel.Indicator>
        ))}
      </Carousel.IndicatorGroup>
      <Carousel.Viewport>
        <Carousel.ItemGroup>
          {images.map((image, index) => (
            <Carousel.Item key={index} index={index}>
              <img src={image} alt={`Slide ${index}`} />
            </Carousel.Item>
          ))}
        </Carousel.ItemGroup>
      </Carousel.Viewport>
    </Carousel.Root>
  )
}

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

import { Carousel } from '@ark-ui/react'

export const Customized = () => {
  const images = [
    'https://tinyurl.com/5b6ka8jd',
    'https://tinyurl.com/7rmccdn5',
    'https://tinyurl.com/59jxz9uu',
  ]
  return (
    <Carousel.Root
      align="center"
      loop={true}
      slidesPerView={2}
      spacing="16px"
      orientation="horizontal"
    >
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.IndicatorGroup>
        {images.map((_, index) => (
          <Carousel.Indicator key={index} index={index}>
            {index + 1}
          </Carousel.Indicator>
        ))}
      </Carousel.IndicatorGroup>
      <Carousel.Viewport>
        <Carousel.ItemGroup>
          {images.map((image, index) => (
            <Carousel.Item key={index} index={index}>
              <img src={image} alt={`Slide ${index}`} />
            </Carousel.Item>
          ))}
        </Carousel.ItemGroup>
      </Carousel.Viewport>
    </Carousel.Root>
  )
}

API Reference

Root

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

The alignment of the slides in the carousel.

asChild
boolean

Render as a different element type.

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 slide(index: number): string slideGroup: string nextSlideTrigger: string prevSlideTrigger: 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.

onIndexChange
(details: SlideChangeDetails) => void

Function called when the slide changes.

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.

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

Control

PropDefaultType
asChild
boolean

Render as a different element type.

IndicatorGroup

PropDefaultType
asChild
boolean

Render as a different element type.

Data AttributeValue
[data-scope]carousel
[data-part]indicator-group
[data-orientation]The orientation of the indicatorgroup

Indicator

PropDefaultType
index
number

asChild
boolean

Render as a different element type.

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

Render as a different element type.

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

Render as a different element type.

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

Render as a different element type.

Data AttributeValue
[data-scope]carousel
[data-part]next-trigger
[data-orientation]The orientation of the nexttrigger

PrevTrigger

PropDefaultType
asChild
boolean

Render as a different element type.

Data AttributeValue
[data-scope]carousel
[data-part]prev-trigger
[data-orientation]The orientation of the prevtrigger

Viewport

PropDefaultType
asChild
boolean

Render as a different element type.

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

Accessibility

Complies with the Carousel WAI-ARIA design pattern.