Dojo NG is being built in the open, one section at a time — follow along on Heptapod.

API REFERENCE · LAYOUT

<dj-carousel>

A slotted, swipeable carousel. Each top-level element in the default slot is one item: a card, an image, a tile, or any other content.

Swiping is native scrolling. The item strip is a horizontal scroll container with CSS scroll-snap, so touch and trackpad work with no drag code, and the prev/next buttons give a way to move that needs no dragging (WCAG 2.5.7). Give the carousel a label so the region has an accessible name.

Try it in the playground

@dojo-ng/carousel · v0.1.1

npm install @dojo-ng/carousel

import "@dojo-ng/carousel";

Layout

  • per-view shows that many items at once, sized to fit with the gap between them.
  • dots adds one dot per page. With per-view above 1, the last items cannot start a page, so the number of pages is items − per-view + 1.
  • nav (on by default) shows prev/next buttons. They are disabled at the first and last page; the carousel does not loop.

Moving between items

  • next(), previous(), and goTo(index) scroll smoothly to the item.
  • Under prefers-reduced-motion, the carousel jumps to the item instead of scrolling.
  • dj-slide-change fires when the current item changes, from swiping, a button, a key, or a method call.

Accessibility

  • The carousel follows the APG carousel pattern. The region has aria-roledescription="carousel" and the label as its name.
  • Each item gets role="group", aria-roledescription="slide", and an "{n} of {total}" label. These update when items are added or removed and when the locale changes.
  • With the strip focused, ArrowRight and ArrowLeft move forward and back in the reading direction, so they also work in right-to-left pages.

Not built

  • Looping, autoplay (an accessibility problem), and vertical orientation.

Need one of these? Make a request on Discord or add an issue (work item) on Heptapod.

Properties

PropertyAttributeTypeDefault
perViewItems shown at once; each item gets 1/n of the viewport, gap-adjusted. per-view number 1
navShow prev/next buttons (disabled at the ends). nav boolean true
dotsShow one navigation dot per page (a page is a leading position; see per-view). dots boolean false
labelAccessible name for the carousel region (recommended). label string None

Events

EventDescription
dj-slide-changedetail { index }

Slots

SlotDescription
Default sloteach top-level element is one carousel item

CSS parts

Style these with dj-carousel::part(name).

PartDescription
viewportthe scroller
prev
next
dots
dot

CSS custom properties

PropertyDefaultDescription
--dj-carousel-gap1remGap between items (also subtracted from the per-view basis).

Methods

next()previous()goTo(index: number)