Accent theme

Base radius

Accent theme

Base radius

Colour scheme
Components

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

PropTypeDefault
childrenReactNode (required) — each direct child is one slide
aria-labelstring (required)

Parts

ComponentRenders
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 the aria-label you pass, plus aria-roledescription="carousel", the standard ARIA Authoring Practices pattern for identifying this as a carousel landmark to assistive tech.
  • Each slide is role="group" with aria-roledescription="slide".
  • The scroll container has tabIndex={0} so it's keyboard-focusable at all: a plain <div> with overflow: auto is 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.