PageIndicator
Where a carousel, a product's photos or an onboarding sequence is, as dots or as a "2 / 9" chip. The visual is decorative; a visually hidden "2 of 9" tells a screen reader the same.
Import
import { PageIndicator } from '@nizivo/react/page-indicator';
// Once per app (Getting started), after
// @nizivo/tokens/tokens.css and @nizivo/react/css/base.css
import '@nizivo/react/css/page-indicator.css';Static or interactive
Server. No client JavaScript. It shows a position the page already knows; the carousel or the steps around it own the controls. How to choose.
Dots or fraction
variant="dots" (the default) draws one dot per page, and the current one longer and in the brand
colour, so the position does not rest on colour alone. variant="fraction" shows "2 / 9" in a
pill, better for more than about seven pages. count is how many there are and current the one
shown now, from 1; current is kept between 1 and count.
On a photo
tone="media" is for an indicator over a photo or a video: white dots, and a dark chip with white
text. Design has not drawn an on-media colour family yet, so it uses bg/code and text/on-dark,
as the storefront patterns do; their contrast holds in light and dark because neither flips.
Screen readers
The dots and the chip are aria-hidden. A visually hidden "2 of 9" says the position instead;
labels.position (with {current} and {count}) replaces it, for example
labels={{ position: 'Photo {current} of {count}' }}, and locale formats the numbers. It is a
server part, so a NizivoConfig's labels do not reach it: pass labels on each instance.
Examples
Basic
Dots under a product's photos, and a "2 / 9" chip for a longer set.
import type { JSX } from 'react';
import { PageIndicator } from '@nizivo/react/page-indicator';
export function PageIndicatorExample(): JSX.Element {
return (
<div style={{ display: 'grid', gap: 16, justifyItems: 'start' }}>
<PageIndicator count={4} current={1} />
<PageIndicator count={9} current={2} variant="fraction" />
</div>
);
}
Media
Over a photo (tone="media"): white dots, and a dark chip with white text.
import type { JSX } from 'react';
import { PageIndicator } from '@nizivo/react/page-indicator';
export function PageIndicatorMediaExample(): JSX.Element {
return (
<div
style={{
display: 'flex',
alignItems: 'flex-end',
justifyContent: 'space-between',
boxSizing: 'border-box',
inlineSize: 320,
blockSize: 200,
padding: 12,
borderRadius: 12,
background: 'linear-gradient(135deg, #c9b79c, #8a6e4b)',
}}
>
<PageIndicator count={4} current={3} tone="media" />
<PageIndicator count={4} current={3} variant="fraction" tone="media" />
</div>
);
}
Props
Server component Renders data-slot="page-indicator" with the class nz-page-indicator. Props: PageIndicatorProps. Source: src/page-indicator/page-indicator.tsx.
| Name | Type | Default | Description |
|---|---|---|---|
countrequired | number | – | How many pages, slides or photos there are. |
currentrequired | number | – | The one shown now, from 1. |
labels | Partial<PageIndicatorLabels> | – | Overrides the screen-reader position, for example |
locale | string | 'en-US' | BCP 47 tag for the numbers. |
render | RenderProp<Record<string, never>> | – | Must render a |
tone | "surface" | "media" | 'surface' |
|
variant | "dots" | "fraction" | 'dots' | Dots, one per page, or a "1 / 4" chip for longer sets. |
- Also takes every attribute of
<div>exceptchildren. (Omit<ComponentPropsWithRef<"div">, "children">)
render takes an element, or, in client code, a function of the props and no state.
Other exports
PageIndicatorLabelstypeimport type { PageIndicatorLabels } from '@nizivo/react/page-indicator'PageIndicator's own strings (§16.4): serialisable, English defaults.
Name Type Default Description positionrequiredstring'{current} of {count}'The position, read by a screen reader instead of the visual:
{current}and{count}.PageIndicatorPropstypeimport type { PageIndicatorProps } from '@nizivo/react/page-indicator'The props of
PageIndicator, listed above.
Data attributes and slots
Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.
| Slot | Rendered by | Data attributes |
|---|---|---|
page-indicator.nz-page-indicator | PageIndicatorroot (takes render) |
|
page-indicator-dot.nz-page-indicator-dot | PageIndicatorinner element (CSS only) |
|
page-indicator-dots.nz-page-indicator-dots | PageIndicatorinner element (CSS only) | none |
page-indicator-fraction.nz-page-indicator-fraction | PageIndicatorinner element (CSS only) | none |
CSS hooks
Set a hook on the component's class or any ancestor to restyle it without specificity games; leave it unset for the default shown.
| Hook | Default | Read as |
|---|---|---|
--nz-page-indicator-chip-bg |
|
|
--nz-page-indicator-chip-fg |
|
|
--nz-page-indicator-current |
|
|
--nz-page-indicator-dot |
|
|
Layers: nz.components. Classes: .nz-page-indicator, .nz-page-indicator-dot, .nz-page-indicator-dots, .nz-page-indicator-fraction.
Tokens this stylesheet reads (15)
--nz-bg-brand, --nz-bg-code, --nz-bg-subtle, --nz-border-strong, --nz-duration-fast, --nz-easing-standard, --nz-font-label-m, --nz-radius-full, --nz-space-0-5, --nz-space-1-5, --nz-space-2, --nz-space-4, --nz-text-on-dark, --nz-text-primary, --nz-tracking-label-m
Accessibility
Nothing in this component takes focus or keyboard input.
Keyboard
None.
Figma
Node ids from design/component-map.json, which nz gen writes from component.json. The links open the Nizivo Figma library, which may ask you to sign in.
- Canonical: none
- Ghost masters: none
PageHeader
The top of a page, under the shell's top bar. The page's one <h1>, an optional status beside it and a line under it, and the page's controls at the row's end. Server-rendered, no client JS.
Pagination
Page links for a list whose page is in the URL, with an optional summary ("Showing 1–20 of 248"). A navigation landmark with previous and next links, the page numbers with aria-current="page" on the current one, and gaps that keep the number of slots constant while you page.