Skip to content

Components

Carousel and AspectRatio

A horizontal rail of items, built on the platform's own scroll-snap engine — so momentum, touch, trackpad gestures and RTL come for free — plus the two things it does not have: controls and a keyboard contract.

Examples

import { Carousel, CarouselControls, CarouselItem, CarouselTrack } from "@luc/ui";

A real rail

The track is a labelled region with a tab stop, so a keyboard user can arrow-scroll it. Dots are a tablist, arrows disable at the ends, and the live region announces the current slide only when it changes.

Autoplay, when it is on

Autoplay is opt-in, pauses on hover and focus, stops while the tab is hidden, and never starts at all under prefers-reduced-motion.

AspectRatio

Space is reserved before the media loads, so a card grid never shifts under a slow image. Use a preset, or pass any number.

square
video
photo
portrait

API

Component props
PropTypeDefaultNotes
Carousel labelstring—Required — a carousel is a named landmark.
Carousel autoplay / intervalboolean · numberfalse · 6000Off by default; pauses on hover, focus and a hidden tab.
CarouselTrack itemWidth / gapstring"min(20rem, 82%)" · "1rem"The rhythm lives on the track, so every item matches.
CarouselItem labelstring—Accessible name per slide; defaults to “Slide n of m”.
CarouselControls dots / arrowsbooleantrueDots are a tablist; arrows disable at the ends.
AspectRatio rationumber | preset"square"square · video · photo · wide · portrait · ultrawide, or any number.

Usage

import { Carousel, CarouselTrack, CarouselControls, CarouselItem } from "@luc/ui";
<Carousel label="Release notes">
  <CarouselTrack>
    <CarouselItem>…</CarouselItem>
  </CarouselTrack>
  <CarouselControls />
</Carousel>

Guidelines

Do

  • Use `CarouselControls` rather than custom buttons: they carry the names, the `aria-controls` tie and the position announcement.
  • Keep `label` describing the set (“Release notes”), and write `itemLabel` as the position of each slide.
  • Leave `autoplay` off when a slide holds text a reader needs; the interval only stops for a reader who pauses it.

Don't

  • Put a long document in a carousel: a reader who navigates by heading should not have to page through it.

Accessibility

The rail is a region with `aria-roledescription="carousel"` and the carousel's own name. Controls are real buttons tied to the rail with `aria-controls`, and a polite live region announces the position as it changes.

Luc UI v1.0Carouseldark theme