Pagination
A row of page numbers. Every one of them is a real Button.
import { Pagination } from 'neba';
<Pagination count={24} page={page} onPageChange={setPage} showEdges />;Props
| Prop | Type | Default | Description |
|---|---|---|---|
| variantshared | 'solid' | 'outline' | 'text' | 'text' | How the pages look at rest. The current page is always solid — the one thing the row has to say without being read, which is also why the default here is text: nine filled buttons in a row say all nine are the primary action |
| sizeshared | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | The buttons’ height and type scale. They are real Buttons, so a lg pagination lines up with a lg button beside it |
| colorshared | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'primary' | Semantic colour role. Arbitrary colour values are not accepted |
| densityshared | 'default' | 'compact' | 'compact' | Padding only — never the height, never the type scale |
| elevationshared | 0 | 1 | 2 | 3 | 0 | Drop shadow depth. 0 means no shadow at all |
| count * | number | — | How many pages there are. Fewer than two and the whole control renders nothing: a row advertising that it has nothing to do is not a control |
| page | number | — | The current page, 1-based, for a controlled set |
| defaultPage | number | 1 | Which page starts current |
| onPageChange | (page: number) => void | — | Called when the page changes |
| siblingCount | number | 1 | How many pages are always shown on either side of the current one |
| boundaryCount | number | 1 | How many pages are always shown at each end. 0 drops the first and last page, leaving only the window |
| showEdges | boolean | false | Shows the jump-to-first and jump-to-last steppers |
| showArrows | boolean | true | Shows the previous and next steppers |
| disabled | boolean | false | Unavailable. Every button in the row stops answering |
| label | string | 'Pagination' | Accessible name of the nav landmark |
| pageLabel | (page: number) => string | — | Accessible name of a page button. `Page ${page}` by default |
| previousLabel | string | 'Previous page' | Accessible name of the previous stepper |
| nextLabel | string | 'Next page' | Accessible name of the next stepper |
| firstLabel | string | 'First page' | Accessible name of the first-page stepper |
| lastLabel | string | 'Last page' | Accessible name of the last-page stepper |
Examples
Variants
variant is how the page buttons look at rest. The current page is always filled, because it is the one thing here that has to be legible without being read.
That is also why the default is text rather than the solid a lone Button takes: nine filled buttons in a row say that all nine are the primary action.
Which pages it shows
Sizes
The row keeps its length
The window slides toward whichever end it is near rather than being clipped by it. Page 1 shows 1 2 3 4 5 … 20 and page 10 shows 1 … 9 10 11 … 20 — which slots are pages and which are ellipses changes, how many there are does not.
Without that, stepping from page 1 to page 2 would relayout the row and every button would move out from under the pointer that just pressed one.
A gap of exactly one page is filled with that page rather than with an ellipsis. 1 … 3 … 9 hides a single number behind a symbol wider than the number it replaced.
They are real Buttons
Every button in the row is a Button, and that is the point: a pagination is not a new kind of control, it is buttons in a row that happen to know about each other.
Reusing the component means the row inherits the acrylic surface, the press-instant/release-slow house signature, the focus ring, and every future change to any of them for free. It is also why a lg pagination lines up with a lg button beside it — because it is one.
One page renders nothing
A row that draws a lone disabled "1" is a control advertising that it has nothing to do.
Accessibility
The markup is a <nav> around a <ul>, because that is what a screen reader needs to hear: a named landmark it can skip, holding a list whose length says how far the pages go, with aria-current="page" marking where it is.
The ellipsis is not a button, and not a disabled button. It is punctuation, not a control that happens to be unavailable.
Every accessible name is a prop — label, pageLabel, previousLabel and the rest. With more than one pagination on a screen, use label to say what each one paginates.