Display
Carousel
Scroll-snap slides with previous and next, dots and an opt-in autoplay that always has a Pause button.
<script>
import { Carousel, CarouselItem } from "@codeatlasdev/ui";
let index = $state(0);
</script>
<Carousel label="Product highlights" bind:index>
<CarouselItem>…</CarouselItem>
<CarouselItem>…</CarouselItem>
</Carousel>
The replacement for shadcn Carousel (Embla). The strip is native scroll-snap, so touch, trackpad and the browser’s own scrolling work with no pointer code; the buttons and dots only move it, and a scroll by touch updates the dots. No JavaScript carousel engine, nothing to install.
Highlights
Arrows, dots and a bound index.
Slide 1 of 4. Swipe, use the buttons, or focus the carousel and press the arrow keys.
Reference #964 · Pick in the gallery
Code
Several per view
`perView` shows three cards; `loop` wraps at the ends.
Reference #965 · Pick in the gallery
Code
Autoplay
Every 4 seconds, with Pause.
Reference #966 · Pick in the gallery
Code
Accessibility
It follows the WAI-ARIA carousel pattern. The carousel is a labelled role="region" with aria-roledescription="carousel"; each slide is a role="group" named “2 of 4”. Slides outside the view are inert, so their links and buttons leave the tab order and the reading order. The dots are labelled buttons with aria-current on the current one (the slides are not tab panels, so they are not a tablist). The slide strip is the one tab stop (it scrolls, so it must be reachable without a pointer, even when no slide holds a control). With it focused, Left and Right (mirrored in RTL), Home and End move the slides.
Autoplay behavior
Off unless you set autoplay (milliseconds). When on, a Pause / Start button appears, rotation stops while focus or the pointer is inside, and the strip is aria-live="off" while it rotates (a rotating live region would read every slide) and polite once it stops. A manual move stops it for good. Under prefers-reduced-motion: reduce it never runs, the button is not shown and scrolling is instant. Without loop it stops on the last slide.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | – | Accessible name of the carousel. Required. |
index | number | 0 | First visible slide, 0-based. Bindable. |
perView | number | 1 | Slides visible at once. |
loop | boolean | false | Wrap around at the ends. |
dots | boolean | true | Show the dots. |
arrows | boolean | true | Show previous and next. |
autoplay | number | undefined | Milliseconds between slides; unset means no autoplay. |
onchange | (index: number) => void | undefined | Called when the current slide changes. |
class | string | '' | Extra class names. |
CarouselItem takes only class; give it one child that carries the slide’s size and look.