Pagination
The Pagination component provides composable building blocks for page navigation. It renders semantic <nav> with aria-label="pagination" and uses anchor elements that work with any routing library. Pair with the usePagination helper to generate consistent page ranges with ellipsis.
Import
import { Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis, usePagination,} from '@nim-ui/components';Basic Usage
Basic Pagination
View Code
<Pagination> <PaginationContent> <PaginationItem> <PaginationPrevious href="?page=1" /> </PaginationItem> <PaginationItem> <PaginationLink href="?page=1">1</PaginationLink> </PaginationItem> <PaginationItem> <PaginationLink href="?page=2" isActive>2</PaginationLink> </PaginationItem> <PaginationItem> <PaginationLink href="?page=3">3</PaginationLink> </PaginationItem> <PaginationItem> <PaginationEllipsis /> </PaginationItem> <PaginationItem> <PaginationNext href="?page=3" /> </PaginationItem> </PaginationContent></Pagination>With usePagination Helper
The usePagination helper computes a page range with ellipsis markers based on the current page, total pages, and a sibling count:
import { usePagination } from '@nim-ui/components';
function MyPagination({ currentPage, totalPages, onPageChange }) { const pages = usePagination({ totalPages, currentPage, siblingCount: 1, });
return ( <Pagination> <PaginationContent> <PaginationItem> <PaginationPrevious onClick={() => onPageChange(Math.max(1, currentPage - 1))} /> </PaginationItem> {pages.map((page, i) => ( <PaginationItem key={i}> {page === 'ellipsis' ? ( <PaginationEllipsis /> ) : ( <PaginationLink isActive={page === currentPage} onClick={() => onPageChange(page)} > {page} </PaginationLink> )} </PaginationItem> ))} <PaginationItem> <PaginationNext onClick={() => onPageChange(Math.min(totalPages, currentPage + 1)) } /> </PaginationItem> </PaginationContent> </Pagination> );}Example output
usePagination({ totalPages: 20, currentPage: 10, siblingCount: 1 })// => [1, 'ellipsis', 9, 10, 11, 'ellipsis', 20]
usePagination({ totalPages: 5, currentPage: 3 })// => [1, 2, 3, 4, 5]
usePagination({ totalPages: 20, currentPage: 2 })// => [1, 2, 3, 'ellipsis', 20]Props
PaginationLink
| Name | Type | Default | Description |
|---|---|---|---|
isActive | boolean | false | Mark this page as the current/active page (sets aria-current="page") |
size | 'sm' | 'md' | 'lg' | 'md' | Size variant for the link button |
href | string | - | URL for the pagination link |
className | string | - | Additional CSS classes |
usePagination
| Name | Type | Default | Description |
|---|---|---|---|
totalPages * | number | - | Total number of pages |
currentPage * | number | - | Current active page (1-indexed) |
siblingCount | number | 1 | Number of sibling pages to show on each side of the current page |
showEdges | boolean | true | Always show the first and last page |
Accessibility
- Root is a
<nav>landmark witharia-label="pagination" - Active page has
aria-current="page" - Previous/Next buttons have descriptive
aria-labels - Ellipsis is
aria-hidden="true"with a screen-reader-only “More pages” text - Focus-visible rings use the primary token for consistent keyboard feedback