Pagination

Moves through paginated content. Square controls; the current page fills with ink.

Leaf

The catalog

Use it for

  • Paged lists and tables where the user needs to jump to a specific page.
  • siblings to widen the window around the current page.

Not for

  • Feeds that load more on scroll.
  • Fewer than three pages; a previous and next pair is enough.

Three ways in. They share one source, so the pixels match whichever you pick.

1. Import the package

npm install @noorddev/vlak-react

// once, next to your app's root
import "@noorddev/vlak-react/css";

import { Pagination } from "@noorddev/vlak-react";

Precompiled React and one stylesheet. No compiler to configure. Per-component imports work too: @noorddev/vlak-react/components/pagination.

2. Vendor the source

npx @noorddev/vlak-cli add pagination

The StyleX leaf lands in components/vlak/, for your own compiler to own. See StyleX.

3. Through shadcn

npx shadcn add https://vlak.dev/r/pagination.json

The same registry item, installed by shadcn's CLI.

CSS only

<link rel="stylesheet" href="node_modules/@noorddev/vlak/css/vlak.css" />

No React. Link vlak.css and use the markup and classes below.

import { useState } from "react";
import { Pagination } from "@noorddev/vlak-react";

const [page, setPage] = useState(1);

<Pagination page={page} count={12} onPageChange={setPage} siblings={1} />

Pagination

PropTypeDefaultDescription
pagerequirednumberCurrent 1-based page.
countrequirednumber
onPageChange(page: number) => void
siblingsnumber1Pages kept visible around the current one.

Also accepts HTMLAttributes<HTMLElement>.

KeysDoes
TabMoves between the page buttons
Enter, SpaceGoes to that page
<div class="rs-pages"><span class="rs-page"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter"><path d="M10.5 3.75 L5.5 8.25 L10.5 12.75" vector-effect="non-scaling-stroke"/></svg></span><span class="rs-page rs-page-on">1</span><span class="rs-page">2</span><span class="rs-page"><svg viewBox="0 0 16 16" width="12" height="12" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter"><path d="M5.5 3.75 L10.5 8.25 L5.5 12.75" vector-effect="non-scaling-stroke"/></svg></span></div>
.rs-pages.rs-page.rs-page-on.rs-page-gap.rs-pages-icon