Carousel
scroll-snap-type and scroll-snap-align on a real scrolling container, not a JS carousel engine. Touch dragging, trackpad scrolling, and momentum all come from the browser for free. The only JavaScript is wiring the Prev/Next buttons and dot indicators to scrollIntoView, and an IntersectionObserver that watches which slide is actually visible so the right control state and dot can be highlighted.
Usage
import { Carousel, CarouselSlide } from "@kernelui/react";
const slides = ["Slide 1", "Slide 2", "Slide 3"];
function ProductGallery() {
return (
<Carousel aria-label="Product photos">
{slides.map((label) => (
<CarouselSlide key={label}>{label}</CarouselSlide>
))}
</Carousel>
);
}Props
| Prop | Type | Default |
|---|---|---|
children | ReactNode (required) — each direct child is one slide | — |
aria-label | string (required) | — |
Parts
| Component | Renders |
|---|---|
Carousel | <div role="region"> wrapping the scroll container, Prev/Next buttons, and dots |
CarouselSlide | <div role="group" aria-roledescription="slide"> |
Accessibility
- The outer wrapper is
role="region"with thearia-labelyou pass, plusaria-roledescription="carousel", the standard ARIA Authoring Practices pattern for identifying this as a carousel landmark to assistive tech. - Each slide is
role="group"witharia-roledescription="slide". - The scroll container has
tabIndex={0}so it's keyboard-focusable at all: a plain<div>withoverflow: autois not in the tab order by default. Once focused, arrow keys, Page Up/Down, Home, and End scroll it natively, no key handler required. IntersectionObserver-driven "current slide" tracking (for highlighting the active dot and disabling Prev/Next at the ends) is a progressive enhancement layered on top of that native scrolling, not a requirement for basic usability: scrolling, snapping, and keyboard navigation all work without it.