The Pagination component provides navigation controls for moving between pages of content. It automatically handles the display of page numbers with ellipsis for large page counts.
Basic Usage
import { Pagination } from 'reshaped';
function App() {
return (
<Pagination
total={10}
defaultPage={1}
previousAriaLabel="Previous page"
nextAriaLabel="Next page"
/>
);
}
Controlled Mode
Control the current page externally:
import { Pagination } from 'reshaped';
import { useState } from 'react';
function App() {
const [currentPage, setCurrentPage] = useState(1);
return (
<Pagination
total={20}
page={currentPage}
onChange={({ page }) => setCurrentPage(page)}
previousAriaLabel="Previous page"
nextAriaLabel="Next page"
/>
);
}
With Page Labels
Provide custom aria labels for each page:
<Pagination
total={10}
defaultPage={1}
pageAriaLabel={({ page }) => `Go to page ${page}`}
previousAriaLabel="Go to previous page"
nextAriaLabel="Go to next page"
/>
Navigation Patterns
function DataTable() {
const [page, setPage] = useState(1);
const itemsPerPage = 10;
const totalItems = 250;
const totalPages = Math.ceil(totalItems / itemsPerPage);
const startIndex = (page - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const currentItems = items.slice(startIndex, endIndex);
return (
<>
<Table data={currentItems} />
<Pagination
total={totalPages}
page={page}
onChange={({ page }) => setPage(page)}
previousAriaLabel="Previous page"
nextAriaLabel="Next page"
/>
</>
);
}
With URL Synchronization
import { useSearchParams } from 'react-router-dom';
function SearchResults() {
const [searchParams, setSearchParams] = useSearchParams();
const currentPage = parseInt(searchParams.get('page') || '1');
const handlePageChange = ({ page }) => {
setSearchParams({ page: page.toString() });
};
return (
<>
<Results page={currentPage} />
<Pagination
total={50}
page={currentPage}
onChange={handlePageChange}
previousAriaLabel="Previous page"
nextAriaLabel="Next page"
/>
</>
);
}
Infinite Scroll Alternative
function PaginatedContent() {
const [page, setPage] = useState(1);
return (
<View gap={4}>
<Content page={page} />
<View align="center">
<Pagination
total={100}
page={page}
onChange={({ page }) => {
setPage(page);
window.scrollTo({ top: 0, behavior: 'smooth' });
}}
previousAriaLabel="Previous page"
nextAriaLabel="Next page"
/>
</View>
</View>
);
}
Page Display Logic
The Pagination component automatically handles the display of page numbers:
- Shows ellipsis (…) when there are many pages
- Always shows the first and last pages
- Shows pages around the current selection
- Adapts the display based on the total number of pages
{/* Few pages: 1 2 3 4 5 */}
<Pagination total={5} page={3} />
{/* Many pages: 1 ... 5 6 7 ... 20 */}
<Pagination total={20} page={6} />
{/* Near start: 1 2 3 4 ... 20 */}
<Pagination total={20} page={2} />
{/* Near end: 1 ... 17 18 19 20 */}
<Pagination total={20} page={19} />
Props
Total number of pages available
Currently selected page number, starts with 1 (controlled mode)
Default selected page number, starts with 1 (uncontrolled mode)
onChange
(args: { page: number }) => void
Callback when the current page changes
pageAriaLabel
(args: { page: number }) => string
Function to dynamically get an aria-label for each page button
aria-label attribute for the previous page button
aria-label attribute for the next page button
Additional CSS class name
Additional HTML attributes