# Carousel

URL: https://ark-ui.com/docs/components/carousel
Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/carousel.mdx

An interactive slideshow component for cycling through elements.

---

<ComponentPreview id="Carousel" />

## Features

- Native CSS Scroll Snap integration for smooth, performant animations
- Flexible orientation support (horizontal and vertical layouts)
- Customizable slide alignment (start, center, or end positions)
- Multi-slide display capabilities for complex layouts
- Automatic playback with configurable looping behavior
- Adjustable slide spacing and gap controls

## 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.

<Anatomy id="carousel" />

## Examples

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

**Example: basic**

#### React

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

export const Basic = () => {
  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

  return (
    <Carousel.Root defaultPage={0} slideCount={images.length}>
      <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} />
        ))}
      </Carousel.IndicatorGroup>
      <Carousel.ItemGroup>
        {images.map((image, index) => (
          <Carousel.Item key={index} index={index}>
            <img src={image} alt={`Slide ${index}`} />
          </Carousel.Item>
        ))}
      </Carousel.ItemGroup>
    </Carousel.Root>
  )
}

```

#### Solid

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const Basic = () => {
  return (
    <Carousel.Root slideCount={images.length}>
      <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>
      </Carousel.IndicatorGroup>
      <Carousel.ItemGroup>
        <Index each={images}>
          {(image, index) => (
            <Carousel.Item index={index}>
              <img src={image()} alt={`Slide ${index}`} />
            </Carousel.Item>
          )}
        </Index>
      </Carousel.ItemGroup>
    </Carousel.Root>
  )
}

```

#### Vue

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<template>
  <Carousel.Root :slide-count="images.length">
    <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" />
    </Carousel.IndicatorGroup>
    <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.Root>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel } from '@ark-ui/svelte/carousel'

  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<Carousel.Root defaultPage={0} slideCount={images.length}>
  <Carousel.Control>
    <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
    <Carousel.NextTrigger>Next</Carousel.NextTrigger>
  </Carousel.Control>
  <Carousel.IndicatorGroup>
    {#each images as _, index}
      <Carousel.Indicator {index} />
    {/each}
  </Carousel.IndicatorGroup>
  <Carousel.ItemGroup>
    {#each images as image, index}
      <Carousel.Item {index}>
        <img src={image} alt="Slide {index}" />
      </Carousel.Item>
    {/each}
  </Carousel.ItemGroup>
</Carousel.Root>

```

### Controlled

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

**Example: controlled**

#### React

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const Controlled = () => {
  const [page, setPage] = useState(0)

  return (
    <Carousel.Root slideCount={images.length} page={page} onPageChange={(e) => setPage(e.page)}>
      <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} />
        ))}
      </Carousel.IndicatorGroup>
      <Carousel.ItemGroup>
        {images.map((image, index) => (
          <Carousel.Item key={index} index={index}>
            <img src={image} alt={`Slide ${index}`} />
          </Carousel.Item>
        ))}
      </Carousel.ItemGroup>
    </Carousel.Root>
  )
}

```

#### Solid

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const Controlled = () => {
  const [page, setPage] = createSignal(0)

  return (
    <Carousel.Root slideCount={images.length} page={page()} onPageChange={(details) => setPage(details.page)}>
      <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>
      </Carousel.IndicatorGroup>
      <Carousel.ItemGroup>
        <Index each={images}>
          {(image, index) => (
            <Carousel.Item index={index}>
              <img src={image()} alt={`Slide ${index}`} />
            </Carousel.Item>
          )}
        </Index>
      </Carousel.ItemGroup>
    </Carousel.Root>
  )
}

```

#### Vue

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
const page = ref(0)
</script>

<template>
  <Carousel.Root v-model:page="page" :slide-count="images.length">
    <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" />
    </Carousel.IndicatorGroup>
    <Carousel.ItemGroup>
      <Carousel.Item v-for="(image, idx) in images" :key="idx" :index="idx">
        <img :src="image" alt="" />
      </Carousel.Item>
    </Carousel.ItemGroup>
  </Carousel.Root>
  <p>Current page: {{ page }}</p>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel } from '@ark-ui/svelte/carousel'

  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
  let page = $state(0)
</script>

<div>
  <div>Current page: {page}</div>
  <Carousel.Root bind:page slideCount={images.length}>
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <Carousel.IndicatorGroup>
      {#each images as _, index}
        <Carousel.Indicator {index} />
      {/each}
    </Carousel.IndicatorGroup>
    <Carousel.ItemGroup>
      {#each images as image, index}
        <Carousel.Item {index}>
          <img src={image} alt="Slide {index}" />
        </Carousel.Item>
      {/each}
    </Carousel.ItemGroup>
  </Carousel.Root>
</div>

```

### Root Provider

Use the `useCarousel` hook to create the carousel store and pass it to the `Carousel.RootProvider` component. This
allows you to have maximum control over the carousel programmatically.

**Example: root-provider**

#### React

```tsx
import { Carousel, useCarousel } from '@ark-ui/react/carousel'

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const RootProvider = () => {
  const carousel = useCarousel({ slideCount: images.length })
  return (
    <>
      <button onClick={() => carousel.scrollToIndex(2)}>Scroll to #3</button>
      <Carousel.RootProvider value={carousel}>
        <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} />
          ))}
        </Carousel.IndicatorGroup>
        <Carousel.ItemGroup>
          {images.map((image, index) => (
            <Carousel.Item key={index} index={index}>
              <img src={image} alt={`Slide ${index}`} />
            </Carousel.Item>
          ))}
        </Carousel.ItemGroup>
      </Carousel.RootProvider>
    </>
  )
}

```

#### Solid

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const RootProvider = () => {
  const carousel = useCarousel({ slideCount: images.length })
  return (
    <>
      <button onClick={() => carousel().scrollToIndex(2)}>Scroll to #3</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>
        </Carousel.IndicatorGroup>
        <Carousel.ItemGroup>
          <Index each={images}>
            {(image, index) => (
              <Carousel.Item index={index}>
                <img src={image()} alt={`Slide ${index}`} />
              </Carousel.Item>
            )}
          </Index>
        </Carousel.ItemGroup>
      </Carousel.RootProvider>
    </>
  )
}

```

#### Vue

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

const carousel = useCarousel({ slideCount: images.length })
</script>

<template>
  <button @click="carousel.scrollToIndex(2)">Scroll to #3</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" />
    </Carousel.IndicatorGroup>
    <Carousel.ItemGroup>
      <Carousel.Item v-for="(image, idx) in images" :key="idx" :index="idx">
        <img :src="image" alt="" />
      </Carousel.Item>
    </Carousel.ItemGroup>
  </Carousel.RootProvider>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel, useCarousel } from '@ark-ui/svelte/carousel'

  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

  const id = $props.id()
  const carousel = useCarousel({
    id,
    defaultPage: 0,
    slideCount: images.length,
  })
</script>

<div>
  <div>Current page: {carousel().page}</div>
  <Carousel.RootProvider value={carousel}>
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <Carousel.IndicatorGroup>
      {#each images as _, index}
        <Carousel.Indicator {index} />
      {/each}
    </Carousel.IndicatorGroup>
    <Carousel.ItemGroup>
      {#each images as image, index}
        <Carousel.Item {index}>
          <img src={image} alt="Slide {index}" />
        </Carousel.Item>
      {/each}
    </Carousel.ItemGroup>
  </Carousel.RootProvider>
</div>

```

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

### Autoplay

Pass the `autoplay` and `loop` props to `Carousel.Root` to make the carousel play automatically.

> **Note:** Adding `loop` ensures the carousel keeps going after the last slide.

**Example: autoplay**

#### React

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const Autoplay = () => {
  return (
    <Carousel.Root slideCount={images.length} autoplay loop>
      <Carousel.Control>
        <Carousel.AutoplayTrigger>
          <Carousel.AutoplayIndicator fallback="Play">Pause</Carousel.AutoplayIndicator>
        </Carousel.AutoplayTrigger>
        <Carousel.ProgressText />
      </Carousel.Control>
      <Carousel.IndicatorGroup>
        {images.map((_, index) => (
          <Carousel.Indicator key={index} index={index} />
        ))}
      </Carousel.IndicatorGroup>
      <Carousel.ItemGroup>
        {images.map((image, index) => (
          <Carousel.Item key={index} index={index}>
            <img src={image} alt={`Slide ${index}`} />
          </Carousel.Item>
        ))}
      </Carousel.ItemGroup>
    </Carousel.Root>
  )
}

```

#### Solid

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const Autoplay = () => {
  return (
    <Carousel.Root slideCount={images.length} autoplay loop>
      <Carousel.Control>
        <Carousel.AutoplayTrigger>
          <Carousel.AutoplayIndicator fallback="Play">Pause</Carousel.AutoplayIndicator>
        </Carousel.AutoplayTrigger>
        <Carousel.ProgressText />
      </Carousel.Control>
      <Carousel.IndicatorGroup>
        <Index each={images}>{(_, index) => <Carousel.Indicator index={index} />}</Index>
      </Carousel.IndicatorGroup>
      <Carousel.ItemGroup>
        <Index each={images}>
          {(image, index) => (
            <Carousel.Item index={index}>
              <img src={image()} alt={`Slide ${index}`} />
            </Carousel.Item>
          )}
        </Index>
      </Carousel.ItemGroup>
    </Carousel.Root>
  )
}

```

#### Vue

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<template>
  <Carousel.Root :slide-count="images.length" autoplay loop>
    <Carousel.Control>
      <Carousel.AutoplayTrigger>
        <Carousel.AutoplayIndicator fallback="Play">Pause</Carousel.AutoplayIndicator>
      </Carousel.AutoplayTrigger>
      <Carousel.ProgressText />
    </Carousel.Control>
    <Carousel.IndicatorGroup>
      <Carousel.Indicator v-for="(_, idx) in images" :key="idx" :index="idx" />
    </Carousel.IndicatorGroup>
    <Carousel.ItemGroup>
      <Carousel.Item v-for="(image, idx) in images" :key="idx" :index="idx">
        <img :src="image" alt="" />
      </Carousel.Item>
    </Carousel.ItemGroup>
  </Carousel.Root>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel } from '@ark-ui/svelte/carousel'

  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<Carousel.Root defaultPage={0} slideCount={images.length} autoplay={{ delay: 3000 }}>
  <Carousel.Control>
    <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
    <Carousel.AutoplayTrigger>
      <Carousel.AutoplayIndicator>
        {#snippet fallback()}Play{/snippet}
        Pause
      </Carousel.AutoplayIndicator>
    </Carousel.AutoplayTrigger>
    <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    <Carousel.ProgressText />
  </Carousel.Control>
  <Carousel.IndicatorGroup>
    {#each images as _, index}
      <Carousel.Indicator {index} />
    {/each}
  </Carousel.IndicatorGroup>
  <Carousel.ItemGroup>
    {#each images as image, index}
      <Carousel.Item {index}>
        <img src={image} alt="Slide {index}" />
      </Carousel.Item>
    {/each}
  </Carousel.ItemGroup>
</Carousel.Root>

```

### Pause on Hover

This feature isn't built-in, but you can use the `play()` and `pause()` methods from `Carousel.Context` to implement
pause on hover.

Add the `autoplay` and `loop` props to `Carousel.Root`, then attach `onPointerOver` and `onPointerLeave` handlers to
`Carousel.ItemGroup` that call `api.pause()` and `api.play()` respectively.

**Example: pause-on-hover**

#### React

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const PauseOnHover = () => {
  return (
    <Carousel.Root slideCount={images.length} autoplay loop>
      <Carousel.Control>
        <Carousel.Context>{({ isPlaying }) => `Autoplay is: ${isPlaying ? 'playing' : 'paused'}`}</Carousel.Context>
      </Carousel.Control>
      <Carousel.Context>
        {(api) => (
          <Carousel.ItemGroup onPointerOver={() => api.pause()} onPointerLeave={() => api.play()}>
            {images.map((image, index) => (
              <Carousel.Item key={index} index={index}>
                <img src={image} alt={`Slide ${index}`} />
              </Carousel.Item>
            ))}
          </Carousel.ItemGroup>
        )}
      </Carousel.Context>
      <Carousel.IndicatorGroup>
        {images.map((_, index) => (
          <Carousel.Indicator key={index} index={index} />
        ))}
      </Carousel.IndicatorGroup>
    </Carousel.Root>
  )
}

```

#### Solid

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const PauseOnHover = () => {
  return (
    <Carousel.Root slideCount={images.length} autoplay loop>
      <Carousel.Control>
        <Carousel.Context>
          {(carousel) => `Autoplay is: ${carousel().isPlaying ? 'playing' : 'paused'}`}
        </Carousel.Context>
      </Carousel.Control>
      <Carousel.Context>
        {(api) => (
          <Carousel.ItemGroup onPointerOver={() => api().pause()} onPointerLeave={() => api().play()}>
            <Index each={images}>
              {(image, index) => (
                <Carousel.Item index={index}>
                  <img src={image()} alt={`Slide ${index}`} />
                </Carousel.Item>
              )}
            </Index>
          </Carousel.ItemGroup>
        )}
      </Carousel.Context>
      <Carousel.IndicatorGroup>
        <Index each={images}>{(_, index) => <Carousel.Indicator index={index} />}</Index>
      </Carousel.IndicatorGroup>
    </Carousel.Root>
  )
}

```

#### Vue

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<template>
  <Carousel.Root :slide-count="images.length" autoplay loop>
    <Carousel.Control>
      <Carousel.Context v-slot="context">Autoplay is: {{ context.isPlaying ? 'playing' : 'paused' }}</Carousel.Context>
    </Carousel.Control>
    <Carousel.Context v-slot="api">
      <Carousel.ItemGroup @pointerover="api.pause()" @pointerleave="api.play()">
        <Carousel.Item v-for="(image, idx) in images" :key="idx" :index="idx">
          <img :src="image" alt="" />
        </Carousel.Item>
      </Carousel.ItemGroup>
    </Carousel.Context>
    <Carousel.IndicatorGroup>
      <Carousel.Indicator v-for="(_, idx) in images" :key="idx" :index="idx" />
    </Carousel.IndicatorGroup>
  </Carousel.Root>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel } from '@ark-ui/svelte/carousel'

  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<Carousel.Root slideCount={images.length} autoplay loop>
  <Carousel.Control>
    <Carousel.Context>
      {#snippet render(api)}
        Autoplay is: {api().isPlaying ? 'playing' : 'paused'}
      {/snippet}
    </Carousel.Context>
  </Carousel.Control>
  <Carousel.Context>
    {#snippet render(api)}
      <Carousel.ItemGroup onpointerover={() => api().pause()} onpointerleave={() => api().play()}>
        {#each images as image, index}
          <Carousel.Item {index}>
            <img src={image} alt="Slide {index}" />
          </Carousel.Item>
        {/each}
      </Carousel.ItemGroup>
    {/snippet}
  </Carousel.Context>
  <Carousel.IndicatorGroup>
    {#each images as _, index}
      <Carousel.Indicator {index} />
    {/each}
  </Carousel.IndicatorGroup>
</Carousel.Root>

```

### Custom Indicators

Replace default indicator dots with custom content by wrapping `Carousel.IndicatorGroup` in `Carousel.Context`. Use
`api.page` to determine the active indicator and render image thumbnails for each slide:

**Example: custom-indicator**

#### React

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

export const CustomIndicator = () => {
  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

  return (
    <Carousel.Root defaultPage={0} slideCount={images.length}>
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.ItemGroup>
        {images.map((image, index) => (
          <Carousel.Item key={index} index={index}>
            <img src={image} alt={`Slide ${index}`} style={{ width: '100%', height: '300px', objectFit: 'cover' }} />
          </Carousel.Item>
        ))}
      </Carousel.ItemGroup>
      <Carousel.Context>
        {(api) => (
          <Carousel.IndicatorGroup style={{ display: 'flex', gap: '8px', marginTop: '16px' }}>
            {images.map((image, index) => (
              <Carousel.Indicator key={index} index={index}>
                <img
                  src={image}
                  alt={`Thumbnail ${index}`}
                  style={{
                    width: '60px',
                    height: '40px',
                    objectFit: 'cover',
                    cursor: 'pointer',
                    border: api.page === index ? '2px solid #0066ff' : '2px solid transparent',
                    borderRadius: '4px',
                    opacity: api.page === index ? 1 : 0.6,
                    transition: 'all 0.2s',
                  }}
                />
              </Carousel.Indicator>
            ))}
          </Carousel.IndicatorGroup>
        )}
      </Carousel.Context>
    </Carousel.Root>
  )
}

```

#### Solid

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const CustomIndicator = () => {
  return (
    <Carousel.Root slideCount={images.length}>
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.ItemGroup>
        <Index each={images}>
          {(image, index) => (
            <Carousel.Item index={index}>
              <img
                src={image()}
                alt={`Slide ${index}`}
                style={{ width: '100%', height: '300px', 'object-fit': 'cover' }}
              />
            </Carousel.Item>
          )}
        </Index>
      </Carousel.ItemGroup>
      <Carousel.Context>
        {(api) => (
          <Carousel.IndicatorGroup style={{ display: 'flex', gap: '8px', 'margin-top': '16px' }}>
            <Index each={images}>
              {(image, index) => (
                <Carousel.Indicator index={index}>
                  <img
                    src={image()}
                    alt={`Thumbnail ${index}`}
                    style={{
                      width: '60px',
                      height: '40px',
                      'object-fit': 'cover',
                      cursor: 'pointer',
                      border: api().page === index ? '2px solid #0066ff' : '2px solid transparent',
                      'border-radius': '4px',
                      opacity: api().page === index ? 1 : 0.6,
                      transition: 'all 0.2s',
                    }}
                  />
                </Carousel.Indicator>
              )}
            </Index>
          </Carousel.IndicatorGroup>
        )}
      </Carousel.Context>
    </Carousel.Root>
  )
}

```

#### Vue

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<template>
  <Carousel.Root :slide-count="images.length">
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <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.Context v-slot="api">
      <Carousel.IndicatorGroup :style="{ display: 'flex', gap: '8px', marginTop: '16px' }">
        <Carousel.Indicator v-for="(image, idx) in images" :key="idx" :index="idx">
          <img
            :src="image"
            :alt="`Thumbnail ${idx}`"
            :style="{
              width: '60px',
              height: '40px',
              objectFit: 'cover',
              cursor: 'pointer',
              border: api.page === idx ? '2px solid #0066ff' : '2px solid transparent',
              borderRadius: '4px',
              opacity: api.page === idx ? 1 : 0.6,
              transition: 'all 0.2s',
            }"
          />
        </Carousel.Indicator>
      </Carousel.IndicatorGroup>
    </Carousel.Context>
  </Carousel.Root>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel } from '@ark-ui/svelte/carousel'

  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<Carousel.Root defaultPage={0} slideCount={images.length}>
  <Carousel.Control>
    <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
    <Carousel.NextTrigger>Next</Carousel.NextTrigger>
  </Carousel.Control>
  <Carousel.ItemGroup>
    {#each images as image, index}
      <Carousel.Item {index}>
        <img src={image} alt="Slide {index}" style="width: 100%; height: 300px; object-fit: cover;" />
      </Carousel.Item>
    {/each}
  </Carousel.ItemGroup>
  <Carousel.Context>
    {#snippet render(api)}
      <Carousel.IndicatorGroup style="display: flex; gap: 8px; margin-top: 16px;">
        {#each images as image, index}
          <Carousel.Indicator {index}>
            <img
              src={image}
              alt="Thumbnail {index}"
              style="
                width: 60px;
                height: 40px;
                object-fit: cover;
                cursor: pointer;
                border: {api().page === index ? '2px solid #0066ff' : '2px solid transparent'};
                border-radius: 4px;
                opacity: {api().page === index ? 1 : 0.6};
                transition: all 0.2s;
              "
            />
          </Carousel.Indicator>
        {/each}
      </Carousel.IndicatorGroup>
    {/snippet}
  </Carousel.Context>
</Carousel.Root>

```

### Vertical Orientation

Set the `orientation="vertical"` prop on `Carousel.Root` to change the carousel from horizontal to vertical scrolling.
This is useful for vertical galleries or content feeds.

**Example: vertical**

#### React

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

export const Vertical = () => {
  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

  return (
    <Carousel.Root defaultPage={0} orientation="vertical" slideCount={images.length}>
      <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} />
        ))}
      </Carousel.IndicatorGroup>
      <Carousel.ItemGroup>
        {images.map((image, index) => (
          <Carousel.Item key={index} index={index}>
            <img src={image} alt={`Slide ${index}`} />
          </Carousel.Item>
        ))}
      </Carousel.ItemGroup>
    </Carousel.Root>
  )
}

```

#### Solid

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)

export const Vertical = () => {
  return (
    <Carousel.Root orientation="vertical" slideCount={images.length}>
      <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>
      </Carousel.IndicatorGroup>
      <Carousel.ItemGroup>
        <Index each={images}>
          {(image, index) => (
            <Carousel.Item index={index}>
              <img src={image()} alt={`Slide ${index}`} />
            </Carousel.Item>
          )}
        </Index>
      </Carousel.ItemGroup>
    </Carousel.Root>
  )
}

```

#### Vue

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

const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<template>
  <Carousel.Root orientation="vertical" :slide-count="images.length">
    <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" />
    </Carousel.IndicatorGroup>
    <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.Root>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel } from '@ark-ui/svelte/carousel'

  const images = Array.from({ length: 5 }, (_, i) => `https://picsum.photos/seed/${i + 1}/500/300`)
</script>

<Carousel.Root defaultPage={0} orientation="vertical" slideCount={images.length}>
  <Carousel.Control>
    <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
    <Carousel.NextTrigger>Next</Carousel.NextTrigger>
  </Carousel.Control>
  <Carousel.IndicatorGroup>
    {#each images as _, index}
      <Carousel.Indicator {index} />
    {/each}
  </Carousel.IndicatorGroup>
  <Carousel.ItemGroup>
    {#each images as image, index}
      <Carousel.Item {index}>
        <img src={image} alt="Slide {index}" />
      </Carousel.Item>
    {/each}
  </Carousel.ItemGroup>
</Carousel.Root>

```

### Dynamic Slides

Manage slides dynamically by storing them in state and syncing the carousel page. Pass the `page` prop and
`onPageChange` handler to `Carousel.Root`, and update `slideCount` when slides are added or removed. This demonstrates
bidirectional state synchronization between your component state and the carousel.

**Example: dynamic-slides**

#### React

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

export const DynamicSlides = () => {
  const [slides, setSlides] = useState([0, 1, 2, 3, 4])
  const [page, setPage] = useState(0)

  const addSlide = () => {
    setSlides((prevSlides) => {
      const max = Math.max(...prevSlides)
      return [...prevSlides, max + 1]
    })
  }

  return (
    <div>
      <Carousel.Root slideCount={slides.length} page={page} onPageChange={(details) => setPage(details.page)}>
        <Carousel.Control>
          <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
          <Carousel.NextTrigger>Next</Carousel.NextTrigger>
        </Carousel.Control>
        <Carousel.IndicatorGroup>
          {slides.map((_, index) => (
            <Carousel.Indicator key={index} index={index} />
          ))}
        </Carousel.IndicatorGroup>
        <Carousel.ItemGroup>
          {slides.map((slide, index) => (
            <Carousel.Item key={index} index={index}>
              <div
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  width: '100%',
                  height: '300px',
                  backgroundColor: `hsl(${(slide * 60) % 360}, 70%, 60%)`,
                  color: 'white',
                  fontSize: '24px',
                  fontWeight: 'bold',
                  borderRadius: '8px',
                }}
              >
                Slide {slide}
              </div>
            </Carousel.Item>
          ))}
        </Carousel.ItemGroup>
      </Carousel.Root>
      <button onClick={addSlide} style={{ marginTop: '16px', padding: '8px 16px', cursor: 'pointer' }}>
        Add Slide
      </button>
    </div>
  )
}

```

#### Solid

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

export const DynamicSlides = () => {
  const [slides, setSlides] = createSignal([0, 1, 2, 3, 4])
  const [page, setPage] = createSignal(0)

  const addSlide = () => {
    setSlides((prevSlides) => {
      const max = Math.max(...prevSlides)
      return [...prevSlides, max + 1]
    })
  }

  return (
    <div>
      <Carousel.Root slideCount={slides().length} page={page()} onPageChange={(details) => setPage(details.page)}>
        <Carousel.Control>
          <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
          <Carousel.NextTrigger>Next</Carousel.NextTrigger>
        </Carousel.Control>
        <Carousel.IndicatorGroup>
          <Index each={slides()}>{(_, index) => <Carousel.Indicator index={index} />}</Index>
        </Carousel.IndicatorGroup>
        <Carousel.ItemGroup>
          <Index each={slides()}>
            {(slide, index) => (
              <Carousel.Item index={index}>
                <div
                  style={{
                    display: 'flex',
                    'align-items': 'center',
                    'justify-content': 'center',
                    width: '100%',
                    height: '300px',
                    'background-color': `hsl(${(slide() * 60) % 360}, 70%, 60%)`,
                    color: 'white',
                    'font-size': '24px',
                    'font-weight': 'bold',
                    'border-radius': '8px',
                  }}
                >
                  Slide {slide()}
                </div>
              </Carousel.Item>
            )}
          </Index>
        </Carousel.ItemGroup>
      </Carousel.Root>
      <button onClick={addSlide} style={{ 'margin-top': '16px', padding: '8px 16px', cursor: 'pointer' }}>
        Add Slide
      </button>
    </div>
  )
}

```

#### Vue

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

const slides = ref([0, 1, 2, 3, 4])
const page = ref(0)

const addSlide = () => {
  const max = Math.max(...slides.value)
  slides.value = [...slides.value, max + 1]
}
</script>

<template>
  <div>
    <Carousel.Root v-model:page="page" :slide-count="slides.length">
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.IndicatorGroup>
        <Carousel.Indicator v-for="(_, idx) in slides" :key="idx" :index="idx" />
      </Carousel.IndicatorGroup>
      <Carousel.ItemGroup>
        <Carousel.Item v-for="(slide, idx) in slides" :key="idx" :index="idx">
          <div
            :style="{
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              height: '300px',
              width: '100%',
              backgroundColor: `hsl(${(slide * 60) % 360}, 70%, 60%)`,
              color: 'white',
              fontSize: '24px',
              fontWeight: 'bold',
              borderRadius: '8px',
            }"
          >
            Slide {{ slide }}
          </div>
        </Carousel.Item>
      </Carousel.ItemGroup>
    </Carousel.Root>
    <button @click="addSlide" :style="{ marginTop: '16px', padding: '8px 16px', cursor: 'pointer' }">Add Slide</button>
  </div>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel } from '@ark-ui/svelte/carousel'

  let slides = $state([0, 1, 2, 3, 4])
  let page = $state(0)

  function addSlide() {
    const max = Math.max(...slides)
    slides = [...slides, max + 1]
  }
</script>

<div>
  <Carousel.Root bind:page slideCount={slides.length}>
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <Carousel.IndicatorGroup>
      {#each slides as _, index}
        <Carousel.Indicator {index} />
      {/each}
    </Carousel.IndicatorGroup>
    <Carousel.ItemGroup>
      {#each slides as slide, index}
        <Carousel.Item {index}>
          <div
            style="
              display: flex;
              align-items: center;
              justify-content: center;
              width: 100%;
              height: 300px;
              background-color: hsl({(slide * 60) % 360}, 70%, 60%);
              color: white;
              font-size: 24px;
              font-weight: bold;
              border-radius: 8px;
            "
          >
            Slide {slide}
          </div>
        </Carousel.Item>
      {/each}
    </Carousel.ItemGroup>
  </Carousel.Root>
  <button onclick={addSlide} style="margin-top: 16px; padding: 8px 16px; cursor: pointer;">Add Slide</button>
</div>

```

### Scroll to Slide

Use `Carousel.Context` to access the carousel API and call `api.scrollToIndex(index)` to programmatically navigate to a
specific slide. This is useful for creating custom navigation or jump-to-slide functionality.

**Example: scroll-to**

#### React

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

export const ScrollTo = () => {
  return (
    <Carousel.Root slideCount={5}>
      <Carousel.Context>
        {(api) => <button onClick={() => api.scrollToIndex(3)}>Go to slide 4</button>}
      </Carousel.Context>
      <Carousel.ItemGroup>
        {Array.from({ length: 5 }, (_, index) => (
          <Carousel.Item key={index} index={index}>
            <div
              style={{
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                width: '100%',
                height: '300px',
                backgroundColor: '#f0f0f0',
                fontSize: '24px',
                fontWeight: 'bold',
                borderRadius: '8px',
              }}
            >
              Slide {index + 1}
            </div>
          </Carousel.Item>
        ))}
      </Carousel.ItemGroup>
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.IndicatorGroup>
        {Array.from({ length: 5 }, (_, index) => (
          <Carousel.Indicator key={index} index={index} />
        ))}
      </Carousel.IndicatorGroup>
    </Carousel.Root>
  )
}

```

#### Solid

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

export const ScrollTo = () => {
  return (
    <Carousel.Root slideCount={5}>
      <Carousel.Context>
        {(api) => <button onClick={() => api().scrollToIndex(3)}>Go to slide 4</button>}
      </Carousel.Context>
      <Carousel.ItemGroup>
        <Index each={Array.from({ length: 5 })}>
          {(_, index) => (
            <Carousel.Item index={index}>
              <div
                style={{
                  display: 'flex',
                  'align-items': 'center',
                  'justify-content': 'center',
                  width: '100%',
                  height: '300px',
                  'background-color': '#f0f0f0',
                  'font-size': '24px',
                  'font-weight': 'bold',
                  'border-radius': '8px',
                }}
              >
                Slide {index + 1}
              </div>
            </Carousel.Item>
          )}
        </Index>
      </Carousel.ItemGroup>
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.IndicatorGroup>
        <Index each={Array.from({ length: 5 })}>{(_, index) => <Carousel.Indicator index={index} />}</Index>
      </Carousel.IndicatorGroup>
    </Carousel.Root>
  )
}

```

#### Vue

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

<template>
  <Carousel.Root :slide-count="5">
    <Carousel.Context v-slot="carousel">
      <button @click="carousel.scrollToIndex(3)">Go to slide 4</button>
    </Carousel.Context>
    <Carousel.ItemGroup>
      <Carousel.Item v-for="index in 5" :key="index" :index="index - 1">
        <div
          :style="{
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            width: '100%',
            height: '300px',
            backgroundColor: '#f0f0f0',
            fontSize: '24px',
            fontWeight: 'bold',
            borderRadius: '8px',
          }"
        >
          Slide {{ index }}
        </div>
      </Carousel.Item>
    </Carousel.ItemGroup>
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <Carousel.IndicatorGroup>
      <Carousel.Indicator v-for="index in 5" :key="index" :index="index - 1" />
    </Carousel.IndicatorGroup>
  </Carousel.Root>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel } from '@ark-ui/svelte/carousel'
</script>

<Carousel.Root slideCount={5}>
  <Carousel.Context>
    {#snippet render(carousel)}
      <button onclick={() => carousel().scrollToIndex(3)}>Go to slide 4</button>
    {/snippet}
  </Carousel.Context>
  <Carousel.ItemGroup>
    {#each Array.from({ length: 5 }) as _, index}
      <Carousel.Item {index}>
        <div
          style="display: flex; align-items: center; justify-content: center; width: 100%; height: 300px; background-color: #f0f0f0; font-size: 24px; font-weight: bold; border-radius: 8px;"
        >
          Slide {index + 1}
        </div>
      </Carousel.Item>
    {/each}
  </Carousel.ItemGroup>
  <Carousel.Control>
    <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
    <Carousel.NextTrigger>Next</Carousel.NextTrigger>
  </Carousel.Control>
  <Carousel.IndicatorGroup>
    {#each Array.from({ length: 5 }) as _, index}
      <Carousel.Indicator {index} />
    {/each}
  </Carousel.IndicatorGroup>
</Carousel.Root>

```

### Slides Per Page

Display multiple slides simultaneously by setting the `slidesPerPage` prop on `Carousel.Root`. Use `api.pageSnapPoints`
from `Carousel.Context` to render the correct number of indicators based on pages rather than individual slides. Add the
`spacing` prop to control the gap between slides.

**Example: slides-per-page**

#### React

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

export const SlidesPerPage = () => {
  const slides = Array.from({ length: 5 }, (_, i) => i)

  return (
    <Carousel.Root slideCount={slides.length} slidesPerPage={2} spacing="20px">
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.ItemGroup>
        {slides.map((_, index) => (
          <Carousel.Item key={index} index={index}>
            <div
              style={{
                width: '100%',
                height: '300px',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                background: '#f0f0f0',
              }}
            >
              Slide {index + 1}
            </div>
          </Carousel.Item>
        ))}
      </Carousel.ItemGroup>
      <Carousel.Context>
        {(api) => (
          <Carousel.IndicatorGroup>
            {api.pageSnapPoints.map((_, index) => (
              <Carousel.Indicator key={index} index={index} />
            ))}
          </Carousel.IndicatorGroup>
        )}
      </Carousel.Context>
    </Carousel.Root>
  )
}

```

#### Solid

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

const slides = Array.from({ length: 5 }, (_, i) => i)

export const SlidesPerPage = () => {
  return (
    <Carousel.Root slideCount={slides.length} slidesPerPage={2} spacing="20px">
      <Carousel.Control>
        <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
        <Carousel.NextTrigger>Next</Carousel.NextTrigger>
      </Carousel.Control>
      <Carousel.ItemGroup>
        <Index each={slides}>
          {(_, index) => (
            <Carousel.Item index={index}>
              <div
                style={{
                  width: '100%',
                  height: '300px',
                  display: 'flex',
                  'align-items': 'center',
                  'justify-content': 'center',
                  background: '#f0f0f0',
                }}
              >
                Slide {index + 1}
              </div>
            </Carousel.Item>
          )}
        </Index>
      </Carousel.ItemGroup>
      <Carousel.Context>
        {(api) => (
          <Carousel.IndicatorGroup>
            <Index each={api().pageSnapPoints}>{(_, index) => <Carousel.Indicator index={index} />}</Index>
          </Carousel.IndicatorGroup>
        )}
      </Carousel.Context>
    </Carousel.Root>
  )
}

```

#### Vue

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

const slides = Array.from({ length: 5 }, (_, i) => i)
</script>

<template>
  <Carousel.Root :slide-count="slides.length" :slides-per-page="2" spacing="20px">
    <Carousel.Control>
      <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
      <Carousel.NextTrigger>Next</Carousel.NextTrigger>
    </Carousel.Control>
    <Carousel.ItemGroup>
      <Carousel.Item v-for="(_, idx) in slides" :key="idx" :index="idx">
        <div
          :style="{
            width: '100%',
            height: '300px',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            background: '#f0f0f0',
          }"
        >
          Slide {{ idx + 1 }}
        </div>
      </Carousel.Item>
    </Carousel.ItemGroup>
    <Carousel.Context v-slot="api">
      <Carousel.IndicatorGroup>
        <Carousel.Indicator v-for="(_, idx) in api.pageSnapPoints" :key="idx" :index="idx" />
      </Carousel.IndicatorGroup>
    </Carousel.Context>
  </Carousel.Root>
</template>

```

#### Svelte

```svelte
<script>
  import { Carousel } from '@ark-ui/svelte/carousel'

  const slides = Array.from({ length: 5 }, (_, i) => i)
</script>

<Carousel.Root slideCount={slides.length} slidesPerPage={2} spacing="20px">
  <Carousel.Control>
    <Carousel.PrevTrigger>Previous</Carousel.PrevTrigger>
    <Carousel.NextTrigger>Next</Carousel.NextTrigger>
  </Carousel.Control>
  <Carousel.ItemGroup>
    {#each slides as _, index}
      <Carousel.Item {index}>
        <div
          style="width: 100%; height: 300px; display: flex; align-items: center; justify-content: center; background: #f0f0f0;"
        >
          Slide {index + 1}
        </div>
      </Carousel.Item>
    {/each}
  </Carousel.ItemGroup>
  <Carousel.Context>
    {#snippet render(api)}
      <Carousel.IndicatorGroup>
        {#each api().pageSnapPoints as _, index}
          <Carousel.Indicator {index} />
        {/each}
      </Carousel.IndicatorGroup>
    {/snippet}
  </Carousel.Context>
</Carousel.Root>

```

## API Reference

### Props

**Component API Reference**

#### React

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `slideCount` | `number` | Yes | The total number of slides.
Useful for SSR to render the initial ating the snap points. |
| `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. |
| `defaultPage` | `number` | No | The initial page to scroll to when rendered.
Use when you don't need to control the page of the carousel. |
| `ids` | `Partial<{
  root: string
  item: (index: number) => string
  itemGroup: string
  nextTrigger: string
  prevTrigger: string
  indicatorGroup: string
  indicator: (index: number) => string
}>` | No | The ids of the elements in the carousel. Useful for composition. |
| `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. |
| `loop` | `boolean` | No | Whether the carousel should loop around. |
| `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. |
| `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. |
| `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. |
| `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. |
| `padding` | `string` | No | Defines the extra space added around the scrollable area,
enabling nearby items to remain partially in view. |
| `page` | `number` | No | The controlled page of the carousel. |
| `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time.

When set to `auto`, the number of slides to scroll is determined by the
`slidesPerPage` property. |
| `slidesPerPage` | `number` | No | The number of slides to show at a time. |
| `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. |
| `spacing` | `string` | No | The amount of space between items. |
| `translations` | `IntlTranslations` | No | The localized messages to use. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | root |
| `[data-orientation]` | The orientation of the carousel |


**AutoplayIndicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `paused` | `string | number | bigint | boolean | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<...>` | No | The content to render when autoplay is paused. |
| `playing` | `string | number | bigint | boolean | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<...>` | No | The content to render when autoplay is playing. |


**AutoplayTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**AutoplayTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | autoplay-trigger |
| `[data-orientation]` | The orientation of the autoplaytrigger |
| `[data-pressed]` | Present when pressed |


**Control Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Control Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | control |
| `[data-orientation]` | The orientation of the control |


**IndicatorGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**IndicatorGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | indicator-group |
| `[data-orientation]` | The orientation of the indicatorgroup |


**Indicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `index` | `number` | Yes | The index of the indicator. |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `readOnly` | `boolean` | No | Whether the indicator is read only. |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | item-group |
| `[data-orientation]` | The orientation of the item |
| `[data-dragging]` | Present when in the dragging state |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `index` | `number` | Yes | The index of the item. |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `snapAlign` | `'center' | 'start' | 'end'` | No | The snap alignment of the item. |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | item |
| `[data-index]` | The index of the item |
| `[data-inview]` | Present when in viewport |
| `[data-orientation]` | The orientation of the item |


**NextTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**NextTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | next-trigger |
| `[data-orientation]` | The orientation of the nexttrigger |


**PrevTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**PrevTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | prev-trigger |
| `[data-orientation]` | The orientation of the prevtrigger |


**ProgressText Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseCarouselReturn` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


#### Solid

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `slideCount` | `number` | Yes | The total number of slides.
Useful for SSR to render the initial ating the snap points. |
| `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. |
| `defaultPage` | `number` | No | The initial page to scroll to when rendered.
Use when you don't need to control the page of the carousel. |
| `ids` | `Partial<{
  root: string
  item: (index: number) => string
  itemGroup: string
  nextTrigger: string
  prevTrigger: string
  indicatorGroup: string
  indicator: (index: number) => string
}>` | No | The ids of the elements in the carousel. Useful for composition. |
| `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. |
| `loop` | `boolean` | No | Whether the carousel should loop around. |
| `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. |
| `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. |
| `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. |
| `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. |
| `padding` | `string` | No | Defines the extra space added around the scrollable area,
enabling nearby items to remain partially in view. |
| `page` | `number` | No | The controlled page of the carousel. |
| `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time.

When set to `auto`, the number of slides to scroll is determined by the
`slidesPerPage` property. |
| `slidesPerPage` | `number` | No | The number of slides to show at a time. |
| `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. |
| `spacing` | `string` | No | The amount of space between items. |
| `translations` | `IntlTranslations` | No | The localized messages to use. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | root |
| `[data-orientation]` | The orientation of the carousel |


**AutoplayTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**AutoplayTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | autoplay-trigger |
| `[data-orientation]` | The orientation of the autoplaytrigger |
| `[data-pressed]` | Present when pressed |


**Control Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Control Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | control |
| `[data-orientation]` | The orientation of the control |


**IndicatorGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**IndicatorGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | indicator-group |
| `[data-orientation]` | The orientation of the indicatorgroup |


**Indicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `index` | `number` | Yes | The index of the indicator. |
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `readOnly` | `boolean` | No | Whether the indicator is read only. |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | item-group |
| `[data-orientation]` | The orientation of the item |
| `[data-dragging]` | Present when in the dragging state |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `index` | `number` | Yes | The index of the item. |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | item |
| `[data-index]` | The index of the item |
| `[data-inview]` | Present when in viewport |
| `[data-orientation]` | The orientation of the item |


**NextTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**NextTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | next-trigger |
| `[data-orientation]` | The orientation of the nexttrigger |


**PrevTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**PrevTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | prev-trigger |
| `[data-orientation]` | The orientation of the prevtrigger |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseCarouselReturn` | Yes |  |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


#### Vue

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `slideCount` | `number` | Yes | The total number of slides.
Useful for SSR to render the initial ating the snap points. |
| `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. |
| `defaultPage` | `number` | No | The initial page to scroll to when rendered.
Use when you don't need to control the page of the carousel. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  root: string
  item(index: number): string
  itemGroup: string
  nextTrigger: string
  prevTrigger: string
  indicatorGroup: string
  indicator(index: number): string
}>` | No | The ids of the elements in the carousel. Useful for composition. |
| `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. |
| `loop` | `boolean` | No | Whether the carousel should loop around. |
| `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. |
| `padding` | `string` | No | Defines the extra space added around the scrollable area,
enabling nearby items to remain partially in view. |
| `page` | `number` | No | The controlled page of the carousel. |
| `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time.

When set to `auto`, the number of slides to scroll is determined by the
`slidesPerPage` property. |
| `slidesPerPage` | `number` | No | The number of slides to show at a time. |
| `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. |
| `spacing` | `string` | No | The amount of space between items. |
| `translations` | `IntlTranslations` | No | The localized messages to use. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | root |
| `[data-orientation]` | The orientation of the carousel |


**AutoplayTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**AutoplayTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | autoplay-trigger |
| `[data-orientation]` | The orientation of the autoplaytrigger |
| `[data-pressed]` | Present when pressed |


**Control Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Control Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | control |
| `[data-orientation]` | The orientation of the control |


**IndicatorGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**IndicatorGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | indicator-group |
| `[data-orientation]` | The orientation of the indicatorgroup |


**Indicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `index` | `number` | Yes | The index of the indicator. |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `readOnly` | `boolean` | No | Whether the indicator is read only. |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**ItemGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | item-group |
| `[data-orientation]` | The orientation of the item |
| `[data-dragging]` | Present when in the dragging state |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `index` | `number` | Yes | The index of the item. |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | item |
| `[data-index]` | The index of the item |
| `[data-inview]` | Present when in viewport |
| `[data-orientation]` | The orientation of the item |


**NextTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**NextTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | next-trigger |
| `[data-orientation]` | The orientation of the nexttrigger |


**PrevTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**PrevTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | prev-trigger |
| `[data-orientation]` | The orientation of the prevtrigger |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `CarouselApi<PropTypes>` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


#### Svelte

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `slideCount` | `number` | Yes | The total number of slides.
Useful for SSR to render the initial ating the snap points. |
| `allowMouseDrag` | `boolean` | No | Whether to allow scrolling via dragging with mouse |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `autoplay` | `boolean | { delay: number }` | No | Whether to scroll automatically. The default delay is 4000ms. |
| `defaultPage` | `number` | No | The initial page to scroll to when rendered.
Use when you don't need to control the page of the carousel. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
  root: string
  item: (index: number) => string
  itemGroup: string
  nextTrigger: string
  prevTrigger: string
  indicatorGroup: string
  indicator: (index: number) => string
}>` | No | The ids of the elements in the carousel. Useful for composition. |
| `inViewThreshold` | `number | number[]` | No | The threshold for determining if an item is in view. |
| `loop` | `boolean` | No | Whether the carousel should loop around. |
| `onAutoplayStatusChange` | `(details: AutoplayStatusDetails) => void` | No | Function called when the autoplay status changes. |
| `onDragStatusChange` | `(details: DragStatusDetails) => void` | No | Function called when the drag status changes. |
| `onPageChange` | `(details: PageChangeDetails) => void` | No | Function called when the page changes. |
| `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the element. |
| `padding` | `string` | No | Defines the extra space added around the scrollable area,
enabling nearby items to remain partially in view. |
| `page` | `number` | No | The controlled page of the carousel. |
| `ref` | `Element` | No |  |
| `slidesPerMove` | `number | 'auto'` | No | The number of slides to scroll at a time.

When set to `auto`, the number of slides to scroll is determined by the
`slidesPerPage` property. |
| `slidesPerPage` | `number` | No | The number of slides to show at a time. |
| `snapType` | `'proximity' | 'mandatory'` | No | The snap type of the item. |
| `spacing` | `string` | No | The amount of space between items. |
| `translations` | `IntlTranslations` | No | The localized messages to use. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | root |
| `[data-orientation]` | The orientation of the carousel |


**AutoplayTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**AutoplayTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | autoplay-trigger |
| `[data-orientation]` | The orientation of the autoplaytrigger |
| `[data-pressed]` | Present when pressed |


**Context Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseCarouselContext]>` | Yes |  |


**Control Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Control Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | control |
| `[data-orientation]` | The orientation of the control |


**IndicatorGroup Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**IndicatorGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | indicator-group |
| `[data-orientation]` | The orientation of the indicatorgroup |


**Indicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `index` | `number` | Yes | The index of the indicator. |
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `readOnly` | `boolean` | No | Whether the indicator is read only. |
| `ref` | `Element` | No |  |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[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 Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**ItemGroup Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | item-group |
| `[data-orientation]` | The orientation of the item |
| `[data-dragging]` | Present when in the dragging state |


**Item Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `index` | `number` | Yes | The index of the item. |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |
| `snapAlign` | `'start' | 'end' | 'center'` | No | The snap alignment of the item. |


**Item Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | item |
| `[data-index]` | The index of the item |
| `[data-inview]` | Present when in viewport |
| `[data-orientation]` | The orientation of the item |


**NextTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**NextTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | next-trigger |
| `[data-orientation]` | The orientation of the nexttrigger |


**PrevTrigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**PrevTrigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | carousel |
| `[data-part]` | prev-trigger |
| `[data-orientation]` | The orientation of the prevtrigger |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseCarouselReturn` | Yes |  |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


### Context

These are the properties available when using `Carousel.Context`, `useCarouselContext` hook or `useCarousel` hook.

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `page` | `number` | The current index of the carousel |
| `pageSnapPoints` | `number[]` | The current snap points of the carousel |
| `isPlaying` | `boolean` | Whether the carousel is auto playing |
| `isDragging` | `boolean` | Whether the carousel is being dragged. This only works when `draggable` is true. |
| `canScrollNext` | `boolean` | Whether the carousel is can scroll to the next view |
| `canScrollPrev` | `boolean` | Whether the carousel is can scroll to the previous view |
| `scrollToIndex` | `(index: number, instant?: boolean) => void` | Function to scroll to a specific item index |
| `scrollTo` | `(page: number, instant?: boolean) => void` | Function to scroll to a specific page |
| `scrollNext` | `(instant?: boolean) => void` | Function to scroll to the next page |
| `scrollPrev` | `(instant?: boolean) => void` | Function to scroll to the previous page |
| `getProgress` | `() => number` | Returns the current scroll progress as a percentage |
| `getProgressText` | `() => string` | Returns the progress text |
| `play` | `VoidFunction` | Function to start/resume autoplay |
| `pause` | `VoidFunction` | Function to pause autoplay |
| `isInView` | `(index: number) => boolean` | Whether the item is in view |
| `refresh` | `VoidFunction` | Function to re-compute the snap points
and clamp the page |


## Accessibility

Complies with the [Carousel WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/carousel/).