Customizable React Pagination Component (Typescript)
https://github.com/canerdemirci/cnr-react-pagination
https://www.npmjs.com/package/cnr-react-pagination
I have written a pagination component in React and published on npm. I aimed to make pagination easier and more useful. The component can navigate to the first page, previous page, next page, last page, and a specific page by number. There are page buttons based on the given range. When a page is selected, the page buttons will be rearranged if necessary. There is also a dropdown menu for selecting pages. The component's style and its icons and button range are customizable.
Here is a sample usage of the pagination component in React:
import Pagination from 'cnr-react-pagination'
import 'cnr-react-pagination/dist/index.css'
const dataLengthPerPage = 8;
const data = [
{
"name": "Adeel Solangi",
"language": "Sindhi",
"id": "V59OF92YF627HFY0",
"bio": "Donec lobortis eleifend condimentum. Cras dictum dolor lacinia lectus vehicula rutrum. Maecenas quis nisi nunc. Nam tristique feugiat est vitae mollis. Maecenas quis nisi nunc.",
"version": 6.1
},
// You can add more
];
const [currentPage, setCurrentPage] = useState(1);
const [shownData, setShownData] = useState(data.slice(0, dataLengthPerPage));
useEffect(() => {
setShownData(data.slice((currentPage - 1) * dataLengthPerPage, currentPage * dataLengthPerPage));
}, [currentPage])
return (
<div className="App">
<table className="dataTable">
<thead>
<tr>
<th>Number</th>
<th>Name</th>
<th>Language</th>
<th>ID</th>
<th>BIO</th>
<th>Version</th>
</tr>
</thead>
<tbody>
{shownData.map((d, i) =>
<tr key={i}>
<td>{i+((currentPage-1)*dataLengthPerPage)+1}</td>
<td>{d.name}</td>
<td>{d.language}</td>
<td>{d.id}</td>
<td>{d.bio}</td>
<td>{d.version}</td>
</tr>)}
</tbody>
</table>
<br />
<Pagination
dataLength={data.length}
dataLengthPerPage={dataLengthPerPage}
btn_range={10}
onChange={(page) => {setCurrentPage(page)}}
firstBtnIcon={<ImFirst />}
lastBtnIcon={<ImLast />}
prevBtnIcon={<ImPrevious2 />}
nextBtnIcon={<ImNext2 />}
pageButtonClassName='pagination_4_pageBtn'
pageButtonSelectedClassName='pagination_4_pageBtn_selected'
infoSectionClassName='pagination_4_infosection'
/>
<br />
<Pagination
dataLength={data.length}
dataLengthPerPage={dataLengthPerPage}
onChange={(page) => {setCurrentPage(page)}}
/>
The component's page button arrangement function:
This function rearranges the page buttons when the current page number changes. Its logic is explained in the comments.
function arrangeButtonArray(): number[] {
/*
** We want this arrangment. Selected page is in parentheses.
** (Default range limit is 7)
** 1, 2, 3, 4, 5, 6, 7 or 16, 17, 18, 19, 20, 21, 22 => If clicked in range limit array remains same.
** 1, 2, 3, 4, 5, 6, 7 => (7) => 6, (7), 8, 9, 10, 11, 12
** 6, 7, 8, 9, 10, 11, 12 => (6) => 1, 2, 3, 4, 5, (6), 7
*/
let newArr: number[] = [];
// If there are as many pages as range limit.
if (lastPage <= btn_range) {
return newArr = Array.from({ length: lastPage }, (_, i) => i + 1);
}
// * FIRST
// If selected page is 1.
if (currentPage === 1) {
newArr = Array.from({ length: btn_range }, (_, i) => i + 1);
}
// * LAST
// If selected page is last page.
else if (currentPage === lastPage) {
newArr = Array.from({ length: btn_range }, (_, i) => i === 0 ? lastPage : lastPage - i).reverse();
}
// * PREVIOUS - 6, 7, 8, 9, 10, 11, 12 => (6) => 1, 2, 3, 4, 5, (6), 7
// If selected page is in button array and is first and not 1.
else if (currentPage <= buttonArray[0] && currentPage !== 1) {
let start = Math.max(currentPage - btn_range + 2, 1);
let end = start + btn_range;
for (let i = start; i < end; i++) {
newArr.push(i);
}
// * NEXT - 1, 2, 3, 4, 5, 6, 7 => (7) => 6, (7), 8, 9, 10, 11, 12
// If selected page is in button array and is last and not last page.
} else if (currentPage >= buttonArray[buttonArray.length - 1] && currentPage !== lastPage) {
let start = currentPage - 1;
let end = start + btn_range;
if (end > lastPage) {
end = lastPage + 1;
start = lastPage - btn_range + 1;
}
for (let i = start; i < end; i++) {
newArr.push(i);
}
}
// If selected page is in button array.
else {
return [...buttonArray];
}
return newArr;
}
and its using in rendering:
const [buttonArray, setButtonArray] = useState<number[]>(Array.from({ length: btn_range }, (_, i) => i + 1));
useEffect(() => {
setButtonArray(arrangeButtonArray());
}, [currentPage]);
{/* Page Buttons */}
{buttonArray.map(i => <PageButton
key={i}
pageNumber={i}
isSelected={currentPage === i}
onClick={() => onChangePage(i)}
className={pageButtonClassName}
selectedClassName={pageButtonSelectedClassName}
/>)}
You can use the component on your react, next projects: https://www.npmjs.com/package/cnr-react-pagination
You can see the source code of the component and an example project in my GitHub repository: https://github.com/canerdemirci/cnr-react-pagination
Subscribe to my newsletter
Read articles from caner demirci directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
caner demirci
caner demirci
Programming is fun. It is nice to spend time with it and not realize how time passes, learning new things... I hope one day I will make awesome things with it.