GitHub ↗

Examples

Loading preview…

carousel

A headless, accessible slideshow with drag, keyboard and autoplay.


A compound carousel that shows one slide per view and translates a track to the active slide. Drive it with the buttons, the dots, arrow keys or a pointer drag/swipe — controlled or uncontrolled — with optional autoplay.

import {
  Carousel, CarouselViewport, CarouselSlide,
  CarouselPrevious, CarouselNext, CarouselDots,
} from '@fluixi-ui/carousel';

<Carousel loop autoplay>
  <CarouselViewport>
    <CarouselSlide><img src="/1.jpg" alt="" /></CarouselSlide>
    <CarouselSlide><img src="/2.jpg" alt="" /></CarouselSlide>
    <CarouselSlide><img src="/3.jpg" alt="" /></CarouselSlide>
  </CarouselViewport>
  <CarouselPrevious /><CarouselNext />
  <CarouselDots />
</Carousel>
  • Controlled (index) or uncontrolled (defaultIndex) with onIndexChange.
  • loop wraps past the ends; orientation picks the axis (and the arrow keys).
  • autoplay auto-advances (a boolean uses autoplayInterval, or pass an interval in ms); it pauses on hover/focus and while dragging, and never animates under prefers-reduced-motion.
  • draggable (default on) enables pointer drag/swipe with snap; a real drag suppresses the click that would follow.
  • Give CarouselViewport a height (it clips the track); slides are one-per-view.

Anatomy

<Carousel>
  <CarouselViewport>   {/* clips + translates the track */}
    <CarouselSlide />   {/* one per view; registers itself */}
  </CarouselViewport>
  <CarouselPrevious />  {/* disabled at the start unless loop */}
  <CarouselNext />      {/* disabled at the end unless loop */}
  <CarouselDots />      {/* one dot per slide, click to jump */}
</Carousel>

Props (Carousel)

Prop Type Default Description
index number Controlled active slide.
defaultIndex number 0 Uncontrolled initial slide.
onIndexChange (index: number) => void Fires when the active slide changes.
loop boolean false Wrap past the first/last slide.
orientation 'horizontal' | 'vertical' 'horizontal' Layout axis + arrow-key axis.
autoplay boolean | number Auto-advance; true uses autoplayInterval, or pass ms.
autoplayInterval number 4000 Interval when autoplay is true.
pauseOnHover boolean true Pause autoplay on hover/focus.
draggable boolean true Enable pointer drag/swipe.

Keyboard

Key Action
/ (horizontal) Previous / next slide
/ (vertical) Previous / next slide
Home / End First / last slide

Accessibility

The root is role="region" with aria-roledescription="carousel"; each slide is role="group" with aria-roledescription="slide" and an "n of total" label, and off-screen slides are aria-hidden. A polite live region announces the current slide as it changes.

Styling

The root is [data-carousel]; the clip is [data-carousel-viewport] and the moving strip is [data-carousel-track] ([data-dragging] while dragging). Slides are [data-carousel-slide] ([data-active] for the current one), controls are [data-carousel-prev] / [data-carousel-next], and dots are [data-carousel-dot] ([data-active]). The material and soft skins restyle the dots and controls.

Authoring

Works under both JSX and html `` authoring — the components compile to the same runtime either way.


Part of the Fluixi UI component library. Made with ☕ by the Fluixi team.