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