pagination ui component for react
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The rc-pagination component provides extensive customization capabilities including custom renderers, icons, size options, and advanced display controls for sophisticated pagination implementations.
import Pagination from 'rc-pagination';
import type { PaginationProps } from 'rc-pagination';The itemRender prop allows complete customization of pagination elements including page numbers, navigation buttons, and jump controls.
/**
* Custom item renderer function
* @param page - Page number or current page for navigation items
* @param type - Type of pagination item being rendered
* @param element - Default element that would be rendered
* @returns Custom rendered element or null to hide the item
*/
type ItemRender = (
page: number,
type: 'page' | 'prev' | 'next' | 'jump-prev' | 'jump-next',
element: React.ReactNode,
) => React.ReactNode;The sizeChangerRender prop enables complete customization of the page size selector component.
The sizeChangerRender function receives an info object with the following properties:
/**
* Size changer render function parameters
*/
interface SizeChangerRenderInfo {
disabled: boolean; // Whether the size changer is disabled
size: number; // Current page size
onSizeChange: (value: string | number) => void; // Handler for size changes
'aria-label': string; // ARIA label for accessibility
className: string; // CSS class name
options: { // Available size options
label: string; // Display label for the option
value: string | number; // Value for the option
}[];
}
/**
* Size changer render function type (exported from rc-pagination)
*/
export type SizeChangerRender = (info: SizeChangerRenderInfo) => React.ReactNode;interface IconProps {
prevIcon?: React.ComponentType | React.ReactNode;
nextIcon?: React.ComponentType | React.ReactNode;
jumpPrevIcon?: React.ComponentType | React.ReactNode;
jumpNextIcon?: React.ComponentType | React.ReactNode;
}Each icon prop can accept:
import React from 'react';
import Pagination from 'rc-pagination';
function CustomPageItems() {
const itemRender = (page, type, element) => {
switch (type) {
case 'page':
return (
<a
className="custom-page-item"
style={{
padding: '8px 12px',
margin: '0 2px',
border: '1px solid #d9d9d9',
borderRadius: '4px',
textDecoration: 'none',
color: '#333',
}}
>
{page}
</a>
);
case 'prev':
return (
<a className="custom-prev">
← Previous
</a>
);
case 'next':
return (
<a className="custom-next">
Next →
</a>
);
case 'jump-prev':
return (
<a className="custom-jump-prev" title="Previous 5 pages">
⋯
</a>
);
case 'jump-next':
return (
<a className="custom-jump-next" title="Next 5 pages">
⋯
</a>
);
default:
return element;
}
};
return (
<Pagination
current={5}
total={500}
itemRender={itemRender}
onChange={(page) => console.log('Page:', page)}
/>
);
}import React from 'react';
import Pagination from 'rc-pagination';
function CustomSizeChanger() {
const sizeChangerRender = (info) => {
const { disabled, size, onSizeChange, options } = info;
return (
<div className="custom-size-changer">
<span>Show: </span>
<select
value={size}
disabled={disabled}
onChange={(e) => onSizeChange(e.target.value)}
style={{
padding: '4px 8px',
border: '1px solid #d9d9d9',
borderRadius: '4px',
marginLeft: '4px',
}}
>
{options.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
<span> entries</span>
</div>
);
};
return (
<Pagination
current={1}
total={1000}
showSizeChanger
sizeChangerRender={sizeChangerRender}
pageSizeOptions={[10, 25, 50, 100]}
onChange={(page, pageSize) => {
console.log(`Page: ${page}, Size: ${pageSize}`);
}}
/>
);
}import React from 'react';
import Pagination from 'rc-pagination';
const ChevronLeft = () => (
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
</svg>
);
const ChevronRight = () => (
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
</svg>
);
const DoubleChevronLeft = () => (
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path d="M22.41 7.41L21 6l-6 6 6 6 1.41-1.41L17.83 12z"/>
</svg>
);
const DoubleChevronRight = () => (
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path d="M3 6L1.59 7.41 6.17 12l-4.58 4.59L3 18l6-6z"/>
</svg>
);
function CustomIconPagination() {
return (
<Pagination
current={5}
total={500}
prevIcon={<ChevronLeft />}
nextIcon={<ChevronRight />}
jumpPrevIcon={<DoubleChevronLeft />}
jumpNextIcon={<DoubleChevronRight />}
onChange={(page) => console.log('Page:', page)}
/>
);
}import React from 'react';
import Pagination from 'rc-pagination';
// Icon component that receives pagination props
const DynamicPrevIcon = (props) => {
const isFirstPage = props.current === 1;
return (
<span style={{ opacity: isFirstPage ? 0.5 : 1 }}>
◀ Back
</span>
);
};
const DynamicNextIcon = (props) => {
const isLastPage = props.current === 50; // Assuming 50 total pages
return (
<span style={{ opacity: isLastPage ? 0.5 : 1 }}>
Forward ▶
</span>
);
};
function DynamicIconPagination() {
return (
<Pagination
current={1}
total={500}
prevIcon={DynamicPrevIcon}
nextIcon={DynamicNextIcon}
onChange={(page) => console.log('Page:', page)}
/>
);
}import React, { useState } from 'react';
import Pagination from 'rc-pagination';
function AdvancedSizeOptions() {
const [pageSize, setPageSize] = useState(25);
// Custom size options with labels
const customSizeOptions = [5, 10, 25, 50, 100, 200];
const buildOptionText = (value) => {
if (value === 200) return '200 (All)';
return `${value} per page`;
};
return (
<Pagination
current={1}
total={1500}
pageSize={pageSize}
pageSizeOptions={customSizeOptions}
buildOptionText={buildOptionText}
showSizeChanger
totalBoundaryShowSizeChanger={20} // Show size changer when total > 20
onChange={(page, size) => {
console.log(`Page: ${page}, Size: ${size}`);
setPageSize(size);
}}
onShowSizeChange={(current, size) => {
console.log(`Size changed to ${size} on page ${current}`);
}}
/>
);
}import React from 'react';
import Pagination from 'rc-pagination';
function ConditionalSizeChanger() {
const totalItems = 1000;
const showSizeChangerThreshold = 50;
return (
<Pagination
current={1}
total={totalItems}
pageSize={10}
// Show size changer only when total exceeds threshold
showSizeChanger={totalItems > showSizeChangerThreshold}
// Alternative: use built-in boundary
totalBoundaryShowSizeChanger={showSizeChangerThreshold}
pageSizeOptions={[10, 20, 50, 100]}
onChange={(page, pageSize) => {
console.log(`Page: ${page}, Size: ${pageSize}`);
}}
/>
);
}import React from 'react';
import Pagination from 'rc-pagination';
function CustomQuickJumper() {
return (
<Pagination
current={5}
total={1000}
// Enable quick jumper with custom go button
showQuickJumper={{
goButton: 'Jump'
}}
onChange={(page) => {
console.log('Jumped to page:', page);
}}
/>
);
}import React from 'react';
import Pagination from 'rc-pagination';
function AdvancedQuickJumper() {
return (
<Pagination
current={10}
total={2000}
pageSize={20}
showQuickJumper={{
goButton: (
<button
type="button"
style={{
marginLeft: '8px',
padding: '4px 12px',
border: '1px solid #1890ff',
borderRadius: '4px',
background: '#1890ff',
color: 'white',
cursor: 'pointer',
}}
>
Go →
</button>
)
}}
onChange={(page) => {
console.log('Navigated to page:', page);
}}
/>
);
}import React from 'react';
import Pagination from 'rc-pagination';
import './custom-pagination.css'; // Your custom styles
function StyledPagination() {
return (
<Pagination
current={1}
total={500}
// Custom CSS classes
className="my-pagination"
prefixCls="custom-pagination"
selectPrefixCls="custom-select"
// Apply styles
style={{
marginTop: '20px',
textAlign: 'center',
padding: '16px',
borderRadius: '8px',
backgroundColor: '#f5f5f5',
}}
onChange={(page) => console.log('Page:', page)}
/>
);
}import React from 'react';
import Pagination from 'rc-pagination';
function AlignmentExamples() {
return (
<div>
{/* Left aligned (default) */}
<Pagination
current={1}
total={100}
align="start"
onChange={() => {}}
/>
{/* Center aligned */}
<Pagination
current={1}
total={100}
align="center"
onChange={() => {}}
/>
{/* Right aligned */}
<Pagination
current={1}
total={100}
align="end"
onChange={() => {}}
/>
</div>
);
}import React from 'react';
import Pagination from 'rc-pagination';
function CompactPagination() {
return (
<Pagination
current={10}
total={1000}
// Show fewer page items for compact display
showLessItems={true}
// Hide some elements for minimal UI
showPrevNextJumpers={false}
showTitle={false}
// Custom compact styling
style={{ fontSize: '12px' }}
onChange={(page) => console.log('Page:', page)}
/>
);
}import React, { useState, useEffect } from 'react';
import Pagination from 'rc-pagination';
function MobileOptimizedPagination() {
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const checkMobile = () => {
setIsMobile(window.innerWidth < 768);
};
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
return (
<Pagination
current={5}
total={500}
// Switch to simple mode on mobile
simple={isMobile}
// Hide advanced features on mobile
showSizeChanger={!isMobile}
showQuickJumper={!isMobile}
showLessItems={isMobile}
onChange={(page, pageSize) => {
console.log(`Page: ${page}, Size: ${pageSize}`);
}}
/>
);
}import React from 'react';
import Pagination from 'rc-pagination';
function AccessiblePagination() {
return (
<Pagination
current={3}
total={500}
// ARIA attributes
role="navigation"
aria-label="Data table pagination"
// Show titles for screen readers
showTitle={true}
// Custom item renderer with enhanced accessibility
itemRender={(page, type, element) => {
const ariaLabels = {
'page': `Go to page ${page}`,
'prev': 'Go to previous page',
'next': 'Go to next page',
'jump-prev': 'Go to previous 5 pages',
'jump-next': 'Go to next 5 pages',
};
return React.cloneElement(element, {
'aria-label': ariaLabels[type],
title: ariaLabels[type],
});
}}
onChange={(page) => {
// Announce page change to screen readers
const announcement = `Page ${page} selected`;
const ariaLive = document.createElement('div');
ariaLive.setAttribute('aria-live', 'polite');
ariaLive.setAttribute('aria-atomic', 'true');
ariaLive.style.position = 'absolute';
ariaLive.style.left = '-10000px';
ariaLive.textContent = announcement;
document.body.appendChild(ariaLive);
setTimeout(() => {
document.body.removeChild(ariaLive);
}, 1000);
}}
/>
);
}import React, { useState } from 'react';
import Pagination from 'rc-pagination';
function FullyCustomizedPagination() {
const [current, setCurrent] = useState(1);
const [pageSize, setPageSize] = useState(20);
const itemRender = (page, type, element) => {
const baseStyle = {
padding: '8px 12px',
margin: '0 4px',
border: '1px solid #d9d9d9',
borderRadius: '6px',
background: 'white',
cursor: 'pointer',
textDecoration: 'none',
color: '#333',
display: 'inline-flex',
alignItems: 'center',
fontSize: '14px',
};
const activeStyle = {
...baseStyle,
background: '#1890ff',
color: 'white',
borderColor: '#1890ff',
};
switch (type) {
case 'page':
return (
<a style={current === page ? activeStyle : baseStyle}>
{page}
</a>
);
case 'prev':
return (
<a style={baseStyle}>
← Prev
</a>
);
case 'next':
return (
<a style={baseStyle}>
Next →
</a>
);
default:
return element;
}
};
const sizeChangerRender = (info) => (
<div style={{ marginLeft: '16px', display: 'flex', alignItems: 'center', gap: '8px' }}>
<span>Show:</span>
<select
value={info.size}
onChange={(e) => info.onSizeChange(e.target.value)}
style={{
padding: '4px 8px',
border: '1px solid #d9d9d9',
borderRadius: '4px',
}}
>
{info.options.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
);
return (
<div style={{ padding: '20px' }}>
<Pagination
current={current}
total={1000}
pageSize={pageSize}
// Custom renderers
itemRender={itemRender}
sizeChangerRender={sizeChangerRender}
// Display options
showSizeChanger
showQuickJumper={{ goButton: 'Jump' }}
showTotal={(total, range) => (
<div style={{ marginRight: '16px', color: '#666' }}>
Showing {range[0]}-{range[1]} of {total} items
</div>
)}
// Layout
align="center"
style={{
padding: '16px',
background: '#fafafa',
borderRadius: '8px',
border: '1px solid #f0f0f0',
}}
// Events
onChange={(page, size) => {
setCurrent(page);
setPageSize(size);
console.log(`Navigate to page ${page} with ${size} items per page`);
}}
/>
</div>
);
}This comprehensive customization example demonstrates how to combine multiple advanced features for a fully tailored pagination experience.
Install with Tessl CLI
npx tessl i tessl/npm-rc-pagination