SakaniUI

Pagination

Page navigation for lists and tables. Fully controlled: it renders the state you pass it.

It doesn't hold state

page and onPageChange are both required. The component never moves on its own, which is what lets the same page number live in a URL query param or a data-fetching hook rather than being trapped in here.

How it pages

The first and last page are always there. Between them, page numbers come in fixed blocks and the highlight moves across them, so the numbers only change when you step past the edge of the block, never on every click. It stays the same width the whole way through, and an ellipsis always hides at least two pages.

Siblings

Higher values show a bigger block of pages at the cost of width. Below, the same page in a 24-page set with one sibling and then two.

In a table footer

Pair it with a count so people know the size of what they're paging through, not just where they are in it.

Showing 1–20 of 482

Props

PropTypeDefaultDescription
totalnumberTotal number of pages, not total rows. Divide by your page size first.
pagenumberCurrent page, 1-based.
onPageChange(page: number) => voidFires with the requested page.
siblingsnumber1Sets how many page numbers sit between the ellipses, in blocks of siblings × 2 + 1. The control is always siblings × 2 + 5 slots wide.

Why it works this way

Why

  • Long ranges collapse with ellipses, and the numbers between come in fixed blocks, so the highlight moves instead of the layout jumping.

Don't

  • Don't use it for an infinite feed. Load more, or scroll, fits that better.