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:

import { Carousel } from '@ark-ui/solid/carousel'
import { Index } from 'solid-js'

export const Basic = () => {
  const images = [
    'https://tinyurl.com/5b6ka8jd',
    'https://tinyurl.com/7rmccdn5',
    'https://tinyurl.com/59jxz9uu',
    'https://tinyurl.com/6jurv23t',
    'https://tinyurl.com/yp4rfum7',
  ]
  return (
    <Carousel.Root>
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.IndicatorGroup>
        <Index each={images}>
          {(_, index) => <Carousel.Indicator index={index}>{index + 1}</Carousel.Indicator>}
        </Index>
      </Carousel.IndicatorGroup>
      <Carousel.Viewport>
        <Carousel.ItemGroup>
          <Index each={images}>
            {(image, index) => (
              <Carousel.Item index={index}>
                <img src={image()} alt={`Slide ${index}`} />
              </Carousel.Item>
            )}
          </Index>
        </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 { Carousel } from '@ark-ui/solid/carousel'
import { Index, createSignal } from 'solid-js'

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

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

  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.Viewport>
          <Carousel.ItemGroup>
            <Index each={images}>
              {(image, index) => (
                <Carousel.Item index={index}>
                  <img src={image()} alt={`Slide ${index}`} />
                </Carousel.Item>
              )}
            </Index>
          </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/solid/carousel'
import { Index } from 'solid-js'

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>
        <Index each={images}>
          {(_, index) => <Carousel.Indicator index={index}>{index + 1}</Carousel.Indicator>}
        </Index>
      </Carousel.IndicatorGroup>
      <Carousel.Viewport>
        <Carousel.ItemGroup>
          <Index each={images}>
            {(image, index) => (
              <Carousel.Item index={index}>
                <img src={image()} alt={`Slide ${index}`} />
              </Carousel.Item>
            )}
          </Index>
        </Carousel.ItemGroup>
      </Carousel.Viewport>
    </Carousel.Root>
  )
}

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.

import { Carousel, useCarousel } from '@ark-ui/solid/carousel'
import { Index } from 'solid-js'

export const RootProvider = () => {
  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()

  return (
    <>
      <button onClick={() => carousel().scrollToNext()}>Next</button>

      <Carousel.RootProvider value={carousel}>
        <Carousel.Control>
          <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
          <Carousel.NextTrigger>Next</Carousel.NextTrigger>
        </Carousel.Control>
        <Carousel.IndicatorGroup>
          <Index each={images}>
            {(_, index) => <Carousel.Indicator index={index}>{index + 1}</Carousel.Indicator>}
          </Index>
        </Carousel.IndicatorGroup>
        <Carousel.Viewport>
          <Carousel.ItemGroup>
            <Index each={images}>
              {(image, index) => (
                <Carousel.Item index={index}>
                  <img src={image()} alt={`Slide ${index}`} />
                </Carousel.Item>
              )}
            </Index>
          </Carousel.ItemGroup>
        </Carousel.Viewport>
      </Carousel.RootProvider>
    </>
  )
}

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

API Reference

Root

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

The alignment of the slides in the carousel.

asChild
(props: ParentProps<'div'>) => Element

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.

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.

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
(props: ParentProps<'div'>) => Element

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
(props: ParentProps<'div'>) => Element

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
(props: ParentProps<'button'>) => Element

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
(props: ParentProps<'div'>) => Element

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
(props: ParentProps<'div'>) => Element

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
(props: ParentProps<'button'>) => Element

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
(props: ParentProps<'button'>) => Element

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
UseCarouselReturn

asChild
(props: ParentProps<'div'>) => Element

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
(props: ParentProps<'div'>) => Element

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.