Overview
Composable slide rotator with controls, indicators, keyboard support, and optional autoplay.
Usage
loopdefaults tofalse.Previous/Nextclamp and disable at the ends instead of wrapping. Setloopto wrap past the first/last slide. Wrapping is seamless only for the first cycle through the deck —slidesis rendered in a rotated physical order (via CSSorder) starting from the initialactiveIndex, so the first wrap navigation lines up with an adjacent physical slide. Repeated wraps after that reuse the same rotated order and are not guaranteed to be adjacent, so they animate as a longer traversal rather than a single seamless step.
slidesPerViewandloopare mutually exclusive. SettingslidesPerViewabove1whileloopis also set logs a dev warning and ignoresloop— wrapping a multi-slide range across the physical-order rotation boundary would leave a partial-width gap.slidesPerViewabove1also widens the active range: more than one slide is non-inertat once, and the live region announces"Slides N–M of Total"instead of a single labelled slide. Seecarousel.a11y.mdfor the full review.
Mouse users get click-and-drag scrolling, with momentum, automatically. On a fine pointer (
(hover: hover) and (pointer: fine)) withprefers-reduced-motionoff, clicking and dragging the track scrolls it with the same physics a released swipe would have, snapping to the nearest slide on release. There is no prop to opt out per-instance today — it degrades automatically under reduced motion, and never engages for touch or pen (they already pan the native scroller directly). Seecarousel.a11y.mdfor the full review.
When to use
- Presenting a finite set of visual highlights with sequential browsing controls.
- Cycling between promotional or tutorial panels inside a single region.
- Content should remain simultaneously visible and scannable. Use Grid instead
- You only need one static hero panel with no sequence controls.
Examples
Basic carousel
Prev/next navigation with indicator dots and autoplay support.
Multi-slide peek
slidesPerView shows more than one slide at once; a fractional value peeks the next slide.
Props
| Name | Type | Default | Description |
|---|---|---|---|
slides required | TSlide[] | Ordered list of slides. | |
activeIndex bindable | number | 0 | Zero-based active index (bindable). |
autoplay | boolean | false | Enables interval-based auto-advance. |
autoplayInterval | number | 5000 | Milliseconds between auto-advance ticks. |
loop | boolean | false | Wraps navigation past the first/last slide back around. Default false:
Previous/Next clamp and disable at the ends instead of wrapping. |
label | text | 'Carousel' | Accessible name for the carousel region. |
description | text | Optional accessible description linked to the region. | |
controlLabels | {
previous?: string;
next?: string;
picker?: string;
pause?: string;
play?: string;
} | Override labels for controls and picker. | |
indicators | 'dots' | 'counter' | 'none' | How the slide picker is rendered. 'dots' below indicatorLimit
degrades automatically to 'counter' above it when left unset. | |
indicatorLimit | number | 8 | Slide count above which the auto-resolved picker switches to a counter. Default 8. |
slidesPerView | number | 1 | How many slides are visible at once. A fraction (e.g. 1.2) peeks the
next slide. 'auto' lets each slide size itself via its own CSS.
Default 1. Not supported together with loop — loop is ignored
(with a dev warning) while this is set above 1. |
gap | text | Gap between slides, as a CSS length (e.g. '1rem'). Only applied when slidesPerView is not 1. | |
align | 'start' | 'center' | 'start' | Snap alignment of the active slide(s) within the viewport. Default 'start'. |
onSlideChange | (index: number, slide: TSlide) => void | Called after the active slide changes as a result of the carousel's own navigation (never for a parent-driven activeIndex update). | |
slide | snippet | Renders inside each slide's <article>, replacing the built-in
image/title/description/link body. slides remains the identity and
accessible-labeling source of truth — this only replaces slide content. | |
onkeydown | KeyboardEventHandler<T>undefinednull | ||
onmouseenter | MouseEventHandler<T> | undefined | null | ||
onmouseleave | MouseEventHandler<T> | undefined | null | ||
onfocusin | FocusEventHandler<T> | undefined | null | ||
onfocusout | FocusEventHandler<T> | undefined | null |