Carousel

Glass slide gallery with prev/next controls, indicators, and arrow-key navigation when focused.

Preview

Live

<div class="carousel" role="region" aria-roledescription="carousel"
  aria-label="Product highlights" tabindex="0">
  <div class="carousel__viewport">
    <div class="carousel__track">
      <div class="carousel__slide" role="group" aria-roledescription="slide"
        aria-label="Overview, 1 of 3">…</div>
      <div class="carousel__slide" role="group" aria-roledescription="slide"
        aria-label="Details, 2 of 3" aria-hidden="true">…</div>
    </div>
  </div>
  <div class="carousel__controls">
    <button type="button" class="carousel__btn carousel__btn--prev"
      aria-label="Previous slide">…</button>
    <button type="button" class="carousel__btn carousel__btn--next"
      aria-label="Next slide">…</button>
  </div>
  <div class="carousel__indicators" role="group" aria-label="Slide indicators">
    <button type="button" class="carousel__indicator is-active"
      aria-label="Go to slide 1 of 2" aria-current="true"></button>
    <button type="button" class="carousel__indicator"
      aria-label="Go to slide 2 of 2"></button>
  </div>
</div>

Variants

Loop (default)

React loop defaults to true — wraps last → first.

Omit loop={false} or set data-loop="false" in HTML demos to clamp.

No loop

Prev disabled on first slide; next disabled on last.

Indicators

Dot buttons jump to a slide; active uses .is-active + aria-current.

Autoplay

React autoplayMs — off by default. Pauses on hover/focus; skipped under prefers-reduced-motion.

Pass a positive interval in ms when you need timed advance.

Accessibility

  • Root uses role="region", aria-roledescription="carousel", and a required aria-label.
  • Each slide is a role="group" with aria-roledescription="slide" and a position label (“Name, N of M”).
  • Inactive slides set aria-hidden="true".
  • Prev/next and the indicator group require host-owned aria-labels. Focus the carousel and use ArrowLeft / ArrowRight / Home / End.
  • Autoplay (React) pauses while hovered or focused and respects reduced motion.

API

HTML classes

Class Description
.carousel Root glass region.
.carousel__viewport Overflow-hidden clip for the track.
.carousel__track Flex row translated by slide index.
.carousel__slide One full-width slide.
.carousel__controls Prev/next row layout.
.carousel__btn / --prev / --next Control buttons.
.carousel__indicators / .carousel__indicator Dot navigation; active uses .is-active.

React props

From src/core/Carousel.tsx — compound Carousel / CarouselTrack / CarouselSlide / CarouselPrev / CarouselNext / CarouselIndicators / CarouselControls.

Prop Type Default Description
aria-label string Required accessible name for the carousel region.
index / defaultIndex number 0 Controlled or uncontrolled 0-based slide index.
onIndexChange (index: number) => void Fires when the active slide changes.
loop boolean true Wrap from last → first and first → last.
autoplayMs number Optional autoplay interval; off by default.
CarouselSlide label string Short name included in the slide’s accessible label.
CarouselPrev / Next aria-label string Required host-owned control names.
CarouselIndicators aria-label string Required host-owned name for the indicator group.
CarouselIndicators getLabel (i, count) => string Go to slide N of M Optional; customize each indicator’s accessible name (host should localize).