VayuUI

Carousel

A composable image and content carousel with autoplay, keyboard navigation, touch swipe, and speed control.

Installation

npx vayu-ui-cli@latest add carousel

Usage

Featured Gallery

WCAG Compliant Interactive Media

Slide 1 of 5
Abstract Landscape 1
Jump to item:
Product Showcase

Responsive — 1 on mobile, 2 on sm, 3 on lg

Slide 1 of 8
Product 1

Anatomy

<Carousel>
  {' '}
  // Root — provides context and autoplay state
  <Carousel.PlayPause /> // Toggle play/pause for autoplay
  <Carousel.SpeedControl /> // Adjust playback speed (0.5x–2x)
  <Carousel.Viewport>
    {' '}
    // Touch-swipe and keyboard-navigable wrapper
    <Carousel.Slide index={0}> // Individual slide content</Carousel.Slide>
  </Carousel.Viewport>
  <Carousel.Previous /> // Navigate to the previous slide
  <Carousel.Next /> // Navigate to the next slide
  <Carousel.Bullets /> // Dot indicators for slide navigation
  <Carousel.Gallery /> // Horizontal thumbnail strip
</Carousel>

Accessibility

  • Keyboard navigation — ArrowLeft / ArrowRight to move slides, Home / End to jump to first / last slide
  • ARIA attributes — role="region" on root, aria-roledescription="carousel", role="group" and aria-roledescription="slide" on each slide, aria-hidden on inactive slides, aria-current on active bullet and gallery thumbnail
  • Focus behavior — Viewport is focusable (tabIndex={0}) for keyboard users; navigation buttons receive visible focus rings on focus-visible
  • Reduced motion — Autoplay is disabled when the user's system prefers-reduced-motion setting is set to reduce

Screen reader behavior

The viewport includes an aria-live="polite" region that announces "Slide X of Y" whenever the active slide changes. Inactive slides are marked aria-hidden="true" so they are skipped by screen readers. Bullet indicators use role="tablist" and role="tab" with aria-selected on the active bullet. Gallery thumbnails use aria-current="true" on the active item. The play/pause button uses aria-pressed to communicate its toggled state.

Component Folder Structure

Carousel/
├── Carousel.tsx               # Root component and context provider
├── CarouselViewport.tsx       # Touch/keyboard navigation wrapper
├── CarouselSlide.tsx          # Individual slide wrapper
├── CarouselPrevious.tsx       # Previous button
├── CarouselNext.tsx           # Next button
├── CarouselBullets.tsx        # Dot indicators
├── CarouselPlayPause.tsx      # Play/pause toggle
├── CarouselSpeedControl.tsx   # Speed selector dropdown
├── CarouselGallery.tsx        # Thumbnail gallery strip
├── hooks.ts                   # useCarouselContext, usePrefersReducedMotion
├── types.ts                   # Shared TypeScript types
├── index.ts                   # Public exports
└── README.md                  # Component readme

Props

PropTypeDefaultDescription
totalItemsnumber—Total number of slides.
autoPlaybooleanfalseEnable autoplay on mount.
intervalnumber3000Autoplay interval in milliseconds.
loopbooleantrueWrap around from last to first slide.
defaultSpeed0.5 | 1 | 1.5 | 21Default playback speed multiplier.
defaultIndexnumber0Initial slide index.

Carousel.Viewport

PropTypeDefaultDescription
childrenReact.ReactNode—Carousel.Slide elements.

Carousel.Slide

PropTypeDefaultDescription
indexnumber—Zero-based slide index.
childrenReact.ReactNode—Slide content.

Carousel.Previous

PropTypeDefaultDescription
showLabelbooleanfalseShow "Previous" text next to icon.

Carousel.Next

PropTypeDefaultDescription
showLabelbooleanfalseShow "Next" text next to icon.

Carousel.Bullets

PropTypeDefaultDescription
—Extends HTMLAttributes<HTMLDivElement>—No additional required props.

Carousel.PlayPause

PropTypeDefaultDescription
showLabelbooleanfalseShow "Play"/"Pause" text next to icon.

Carousel.SpeedControl

PropTypeDefaultDescription
showLabelbooleantrueShow "Speed:" label next to dropdown.

Carousel.Gallery

PropTypeDefaultDescription
itemsGalleryItem[]—Array of { src: string, alt: string } thumbnails.

On this page