Pagination
Chassis React Pagination supports both a smart data-driven mode (pass total pages and current page) and manual markup with PaginationItem.
Smart pagination
Pass pages, activePage, and onActivePageChange to let <Pagination> render the full control automatically — Prev/Next buttons, page numbers, and ellipsis for lg ranges. The Prev/Next controls default to English accessible names ("Previous"/"Next"); override them with previousLabel/nextLabel for other locales — see Internationalization for why these labels aren't locale-driven automatically.
import { useState } from 'react'
import { Pagination } from '@chassis-ui/react'
export const Example = () => {
const [page, setPage] = useState(1)
return <Pagination pages={10} activePage={page} onActivePageChange={setPage} aria-label="Demo" />
}Max visible pages
Use maxVisiblePages to control how many page buttons appear before collapsing to ellipsis (default is 5).
import { useState } from 'react'
import { Pagination } from '@chassis-ui/react'
export const Example = () => {
const [page, setPage] = useState(5)
return (
<Pagination
pages={20}
activePage={page}
onActivePageChange={setPage}
maxVisiblePages={7}
aria-label="Demo"
/>
)
}Partial controls
Set showPageNumbers={false} for a Prev/Next-only paginator, or showPrevNext={false} for a page-numbers-only one. Both default to true.
import { useState } from 'react'
import { Pagination } from '@chassis-ui/react'
export const Example = () => {
const [page, setPage] = useState(1)
// const [numbersPage, setNumbersPage] = useState(1)
return (
<div className="d-flex justify-content-between flex-wrap gap-md">
<Pagination
pages={5}
activePage={page}
onActivePageChange={setPage}
showPrevNext={false}
aria-label="Numbers only"
/>
<Pagination
pages={5}
activePage={page}
onActivePageChange={setPage}
showPageNumbers={false}
aria-label="Directions only"
/>
</div>
)
}Manual markup
For sets that smart mode's contiguous-range-plus-ellipsis algorithm can't produce — like a fixed list of bookmarked pages — compose the pagination using <PaginationItem> directly.
import { useState } from 'react'
import { Pagination, PaginationItem, usePagination } from '@chassis-ui/react'
// Smart mode always shows a contiguous range around the active page. Manual mode is for sets
// smart mode can't produce — like jumping between a fixed list of bookmarked pages. Prev/Next
// step through the array by index rather than by ±1, since the page numbers themselves aren't
// contiguous.
const bookmarkedPages = [1, 5, 12, 47]
export const Example = () => {
const [index, setIndex] = useState(0)
const prevDisabled = index <= 0
const nextDisabled = index >= bookmarkedPages.length - 1
const { prevRef, nextRef, handlePrevClick, handleNextClick } = usePagination({
prevDisabled,
nextDisabled,
onPrev: () => setIndex((i) => i - 1),
onNext: () => setIndex((i) => i + 1)
})
return (
<Pagination aria-label="Bookmarked pages">
<PaginationItem
ref={prevRef}
disabled={prevDisabled}
onClick={handlePrevClick}
aria-label="Previous"
>
«
</PaginationItem>
{bookmarkedPages.map((p, i) => (
<PaginationItem key={p} active={i === index} onClick={() => setIndex(i)}>
{p}
</PaginationItem>
))}
<PaginationItem
ref={nextRef}
disabled={nextDisabled}
onClick={handleNextClick}
aria-label="Next"
>
»
</PaginationItem>
</Pagination>
)
}Real links
Smart mode always renders buttons. Pass href to PaginationItem for real anchors instead — e.g. server-rendered pages where each link is a full page load to a URL like ?page=2.
import { Pagination, PaginationItem } from '@chassis-ui/react'
// Smart mode always renders buttons wired to `onActivePageChange`. Pass `href` directly to
// `PaginationItem` for real anchors instead — e.g. server-rendered pages where each link is a
// full page load to `?page=N`. (Hrefs point to `#` here so the docs page itself doesn't
// navigate; swap in your real page URLs.)
export const Example = () => {
return (
<Pagination aria-label="Page navigation example">
<PaginationItem href="#" aria-label="Previous" disabled>
«
</PaginationItem>
<PaginationItem href="#" active>
1
</PaginationItem>
<PaginationItem href="#">2</PaginationItem>
<PaginationItem href="#">3</PaginationItem>
<PaginationItem href="#" aria-label="Next">
»
</PaginationItem>
</Pagination>
)
}Loading state
Disable every item while the paginated data is fetching, so the control visibly reflects the loading state instead of accepting clicks that only queue up once the fetch resolves.
import { Pagination, PaginationItem } from '@chassis-ui/react'
// Freeze every item as `disabled` while the paginated data is fetching, so the paginator
// visibly reflects the loading state instead of accepting clicks that only queue up once the
// fetch resolves.
export const Example = () => {
return (
<Pagination aria-label="Page navigation example" aria-busy="true">
<PaginationItem aria-label="Previous" disabled>
«
</PaginationItem>
<PaginationItem active disabled>
1
</PaginationItem>
<PaginationItem disabled>2</PaginationItem>
<PaginationItem disabled>3</PaginationItem>
<PaginationItem aria-label="Next" disabled>
»
</PaginationItem>
</Pagination>
)
}Sizing
Set size to sm or lg to scale the page links and Prev/Next controls together.
import { useState } from 'react'
import { Pagination } from '@chassis-ui/react'
export const Example = () => {
const [lgPage, setLargePage] = useState(2)
const [smPage, setSmallPage] = useState(2)
return (
<>
<Pagination
size="lg"
pages={3}
activePage={lgPage}
onActivePageChange={setLargePage}
aria-label="Large pagination example"
/>
<Pagination
size="sm"
pages={3}
activePage={smPage}
onActivePageChange={setSmallPage}
aria-label="Small pagination example"
/>
</>
)
}Alignment
Set align to center or end to position the pagination list within its container; the default is start-aligned.
import { useState } from 'react'
import { Pagination } from '@chassis-ui/react'
export const Example = () => {
const [centerPage, setCenterPage] = useState(2)
const [endPage, setEndPage] = useState(2)
return (
<>
<Pagination
align="center"
pages={3}
activePage={centerPage}
onActivePageChange={setCenterPage}
aria-label="Centered pagination"
/>
<Pagination
align="end"
pages={3}
activePage={endPage}
onActivePageChange={setEndPage}
aria-label="Right-aligned pagination"
/>
</>
)
}API
Pagination
| Prop | Type | Default |
|---|---|---|
activePage? | number | 1 |
Current active page (1-indexed). Used with pages for data-driven mode. | ||
align? | "start" | "center" | "end" | — |
| Set the alignment of pagination components. | ||
aria-label? | string | Pagination |
Accessible label for the pagination <nav> landmark. Override for non-English locales,
or when multiple paginators appear on the same page. | ||
className? | string | — |
| A string of all className you want applied to the base component. | ||
maxVisiblePages? | number | 5 |
| Maximum number of visible page buttons (default: 5). Flanking pages are collapsed to ellipsis. | ||
nextIcon? | IconValue | — |
The "next page" control's icon in smart pagination mode: an icon name, or an element of your
own icon set. Defaults to IconProvider's next icon. | ||
nextLabel? | string | Next |
| Accessible label for the "next page" control, used in smart pagination mode. Override for non-English locales. | ||
onActivePageChange? | ((page: number) => void) | — |
| Callback fired when the active page changes. | ||
pages? | number | — |
Total number of pages. When provided alongside activePage and onActivePageChange,
the component renders a fully-controlled smart paginator with Prev/Next and ellipsis. | ||
previousIcon? | IconValue | — |
The "previous page" control's icon in smart pagination mode: an icon name, or an element of
your own icon set. Defaults to IconProvider's previous icon. | ||
previousLabel? | string | Previous |
| Accessible label for the "previous page" control, used in smart pagination mode. Override for non-English locales. | ||
showPageNumbers? | boolean | true |
Show the numbered page buttons in smart pagination mode. Set false alongside
showPrevNext to build a Prev/Next-only paginator. | ||
showPrevNext? | boolean | true |
Show the Prev/Next controls in smart pagination mode. Set false alongside
showPageNumbers to build a page-numbers-only paginator. | ||
size? | "sm" | "lg" | — |
| Size the component sm or lg. | ||
PaginationItem
| Prop | Type | Default |
|---|---|---|
active? | boolean | — |
| Toggle the active state for the component. | ||
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
disabled? | boolean | — |
| Toggle the disabled state for the component. | ||
href? | string | — |
The href attribute. When provided the item renders as an <a> tag; otherwise as a <button>. | ||
ref? | any | — |