Clinia UI

Carousel

A row of slides the user can swipe or step through.

shadcn docs →

When to use

  • A set of images or cards users browse one at a time, where missing one is fine.

When not to use

  • Content everyone must see: lay it out on the page.
  • Views of the same subject: use Tabs.

Install

npx shadcn@latest add @clinia/carousel
A clinician in natural light
Two people in conversation
A person working in a café

Anatomy

A clinic storefront
A clinician by a window
  1. 1Regiondata-slot="carousel"role=region
  2. 2Slidedata-slot="carousel-item"basis-full · pl-4
  3. 3Previousdata-slot="carousel-previous"outline · icon-sm
  4. 4Nextdata-slot="carousel-next"outline · icon-sm

Clinia rules

  • Never add autoplay: slides that move on their own fail WCAG 2.2.2.
  • Previous and next are outline icon-sm buttons outside the slides. Leave 48px on each side for them.
  • The buttons disable at the first and last slide, unless you pass opts={{ loop: true }}.

Accessibility

Built in

  • The previous and next buttons are labelled and keyboard-reachable; the carousel never auto-advances.
  • The root is role="region" with aria-roledescription="carousel", and each slide is role="group" with aria-roledescription="slide".
  • Arrow Left and Arrow Right move between slides while focus is inside the carousel.

Your responsibility

  • Give the carousel an aria-label, such as Clinic photos: the region has no name by default.
  • Label each slide with its position, such as aria-label="2 of 5".
  • Give each slide image its own alt text.
  • If slides hold links or buttons, keep the hidden slides out of the tab order.

How to test

  1. Press Tab to the next button, then Enter: the next slide shows.
  2. With focus inside the carousel, press Arrow Right and Arrow Left: it moves one slide each way.
  3. With a screen reader, the region is announced as a carousel with its label, and each slide as a slide.
  4. Wait on a slide: nothing moves on its own.

API

PropValuesDefaultDescription
opts
Partial<OptionsType>
–

Embla options, such as loop or align.

plugins
CreatePluginType<LoosePluginType, {}>[]
–

Embla plugins. Don't add autoplay: slides that move on their own fail WCAG 2.2.2.

orientation
horizontalvertical
horizontal

Slide direction.

setApi
((api: CarouselApi) => void)
–

Receives the Embla API, to build your own dots or read the current slide.

All other props come from Embla Carousel.