Pagination
A navigation landmark of page controls: previous and next, boundary and sibling windows with ellipsis truncation, and button or real-link modes.
Import
import { Pagination } from "@hyzer-labs/ui"Demo
In button mode, page is bindable and onchange fires on every move.
The previous and next controls disable natively at the ends, and clicking the current page
does nothing.
let page = $state(1);
<Pagination count={10} bind:page />boundaries pages stay pinned at the ends, and siblings pages flank
the current page. A gap collapses to an ellipsis only when it spans two or more pages, so
the item count stays constant while you page. Drag the knobs and page around.
<Pagination count={42} page={21} siblings={1} boundaries={1} />With href, every item is a real anchor and the component navigates nothing
itself: drive page from the URL. The demo links are inert # hrefs so this page stays put. A real app returns ?page=n URLs like the sample.
<!-- Real anchors: they work without JS, middle-click, and copy link. -->
<Pagination
count={8}
page={pageFromUrl}
href={(p) => `?page=${p}`}
ariaLabel="Course results"
/>Props
| Name | Type | Default | Note |
|---|---|---|---|
count | number | — | Required. Total pages. |
page | number | 1 | Bindable. 1-based. |
siblings | number | 1 | Pages shown on each side of the current page. |
boundaries | number | 1 | Pages pinned at each end. |
href | (page: number) => string | — | Link mode: items render as real anchors; omit for button mode. |
onchange | (page: number) => void | — | |
ariaLabel | string | 'Pagination' | Names the landmark. |
prevLabel | string | 'Previous page' | |
nextLabel | string | 'Next page' | |
pageLabel | (page: number) => string | `Page ${page}` | Accessible name per page item. |
class | string | — | Merged after the hz-pagination class. |
Theme hooks
What this component promises your CSS. The reference theme styles exactly these — from @layer hz-theme, so your unlayered rules win. See Styling Components for the how.
Root class: .hz-pagination
Part classes
| Hook | Values | Styles |
|---|---|---|
.hz-pagination-list | child element | The row of page controls. |
.hz-pagination-page | on a Button | Rides through Button’s class prop, so it lands on a .hz-button — target it accordingly. Tabular numerals and a min-width keep the row from jittering. |
.hz-pagination-prev | on a Button | Previous control. Also a .hz-button. |
.hz-pagination-next | on a Button | Next control. Also a .hz-button. |
.hz-pagination-ellipsis | child element | The aria-hidden gap marker. |
Accessibility
Pagination renders a <nav> landmark named by ariaLabel. Give it a distinct name when a page hosts several.
Every control is a Button. The current item carries aria-current="page", and page items get full accessible names via pageLabel ("Page 7", not a bare number). Ellipses are decorative.
In link mode, everything is a real <a>. At the ends, the previous and next controls render as disabled Buttons with no href, because a link cannot be disabled and a dead link that announces itself helps no one.
Tab order is native. There are no roving-focus tricks.
References: MDN: <nav>