Carousel Indicator
- Stable
- WCAG 2.2 evidence
- RTL
Shows which slide of a carousel is current, and lets people jump to a slide. There is no carousel engine: you render the slides and show the one at
index. Dots, lines and thumbnails are a list of React Aria Buttons named "Go to slide 3 of 5"; the current one has
aria-current="true" and is shown by shape (pill, filled segments, frame), not colour alone. Tab reaches each button,
Enter and Space go to that slide, keyboard focus shows the focus ring, and every button is at least 24 x 24 px (WCAG
1.4.1, 2.1.1, 2.4.7, 2.5.8, 4.1.2). The counter is text: "2 / 5" on screen, "Slide 2 of 5" for assistive technology.
Dots and lines follow the reading direction in right-to-left layouts; the counter's numbers stay left to right. Consumer duties: the carousel pattern around it (see CarouselControls), translated labels, and announcing slide changes
through the slide container (aria-live="polite" while not rotating).
import { CarouselIndicator } from "@nexera-ui/react";- 5
- examples
- 14
- props
- 2
- live controls
- 1
- platform
- 9
- WCAG criteria
- 1
- block uses it
Try every prop. Copy the code.
Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.
import { CarouselIndicator } from "@nexera-ui/react";
<CarouselIndicator />Examples 4
The same examples as Storybook, rendered live. Open Code to copy one.
Lines
Type=Lines: segments up to the current slide; progress fills the current one (for timed rotation).
import { CarouselIndicator } from "@nexera-ui/react";
<CarouselIndicator
count={5}
defaultIndex={1}
aria-label="Choose a slide"
type="lines"
progress={0.45}
/>;
Counter
Type=Counter: "2 / 5" on screen, "Slide 2 of 5" for assistive technology. Not interactive.
import { CarouselIndicator } from "@nexera-ui/react";
<CarouselIndicator count={5} defaultIndex={1} aria-label="Choose a slide" type="counter" />;
Thumbnails
Type=Thumbnails: small pictures of the slides; each button is named "Go to slide n of N".
import { CarouselIndicator } from "@nexera-ui/react";
const THUMBNAILS = [
"fill-chart-2",
"fill-chart-1",
"fill-chart-3",
"fill-chart-6",
"fill-chart-4",
].map((fill) => (
<svg key={fill} viewBox="0 0 48 36" preserveAspectRatio="xMidYMid slice">
<rect width="48" height="36" className={fill} />
</svg>
));
export function Thumbnails() {
return (
<CarouselIndicator
type="thumbnails"
thumbnails={THUMBNAILS}
defaultIndex={1}
aria-label="Choose a slide"
/>
);
}
Many slides
Many slides wrap onto a second row in a narrow container instead of overflowing (WCAG 1.4.10).
import { CarouselIndicator } from "@nexera-ui/react";
export function ManySlides() {
return (
<div className="max-w-40">
<CarouselIndicator count={14} defaultIndex={6} aria-label="Choose a slide" />
</div>
);
}
Props 14
Press "Try it" on a card to load that prop into the playground.
14 props shown
surfaceNexera"on-light" | "on-media"Background the indicator sits on: on-light (brand marks on the page) or on-media (white marks
over a picture).
indexNexeranumberIndex of the current slide, from 0 (controlled). Pair it with onIndexChange.
defaultIndexNexeranumberIndex of the current slide at first render (uncontrolled).
onIndexChangeNexera(index: number) => voidCalled with the index of the indicator that was pressed. Show that slide.
progressNexeranumberlines only: how far the current slide has played, from 0 to 1, for
carousels that rotate on a timer. You update it; the library has no timer.
slidesIdNexerastringId of the element that holds the slides; set as aria-controls on every indicator button.
isDisabledNexerabooleanDisables every indicator (skipped by Tab).
getItemLabelNexera(index: number, count: number) => stringAccessible name of each indicator button. Translate it.
getCounterLabelNexera(index: number, count: number) => stringText read by assistive technology for type="counter" (the visible "2 / 5" is hidden from it). Translate it.
classNameNexerastringExtra classes for the root, merged last so they win over the defaults.
styleNexeraCSSPropertiesInline style for the root.
typeNexera"dots" | "lines" | "counter" | "thumbnails"Look: dots (a pill marks the current slide), lines (segments that fill up to the current slide),
counter (text "2 / 5", not interactive) or thumbnails (small pictures of the slides).
Small pictures of the slides.
countNexeranumberNumber of slides.
Taken from thumbnails.
thumbnailsNexerareadonly ReactNode[]Only with type="thumbnails".
One picture per slide, 48 x 36 px (cropped to fill), for example <img src={slide.thumb} alt="" />. Decorative: each
button is named by getItemLabel. The number of slides is the length of this list.
* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.
Accessible by default.
Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.
WCAG 2.2 evidence
6 direct · 3 supporting- 1.1.1Non-text ContentLevel A · tested directly
- 1.3.1Info and RelationshipsLevel A · tested directly
- 1.3.2Meaningful SequenceLevel A · supporting test
- 1.4.1Use of ColorLevel A · tested directly
- 1.4.11Non-text ContrastLevel AA · supporting test
- 2.1.1KeyboardLevel A · tested directly
- 2.4.7Focus VisibleLevel AA · tested directly
- 2.5.8Target Size (Minimum)Level AA · supporting test
- 4.1.2Name, Role, ValueLevel A · tested directly
Fits any width.
Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.
Styling hooks
Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.
data-disabled
<CarouselIndicator className="data-disabled:opacity-90 shadow-sm" />Used in blocks
Related components
- CarouselA carousel: slides in a scroll-snap strip with Previous / Next, indicators and, when you opt in, automatic rotation with a visible pause button.
- CarouselControlsPrevious / Next buttons for a carousel, and optionally a button that stops and starts automatic rotation.
- ImageA picture in a rounded frame with a fixed aspect ratio: Figma `State=Loading` (a `bg/sunken` frame with a shimmer), `Loaded` and `Error` ("Image unavailable") follow the load lifecycle of the `<img>`; they are not props.
- ImageTileA square picture in a gallery or picker, with overlay actions on hover and a selected state.
- VideoControlsThe control bar of a video: scrubber, play / pause, back, mute and volume, time, captions, settings, picture in picture and full screen, over a dark gradient.
- VideoPlayerA video with a poster, Nexera controls and captions.