Skip to content

Instantly share code, notes, and snippets.

@josippapez
Created March 2, 2024 11:36
Show Gist options
  • Select an option

  • Save josippapez/6f35275b104a44892e4dbafc752dbfbd to your computer and use it in GitHub Desktop.

Select an option

Save josippapez/6f35275b104a44892e4dbafc752dbfbd to your computer and use it in GitHub Desktop.
Pagination
"use client";
import { cltm } from "@57hours-frontend/utils";
import { FC, useEffect, useState } from "react";
interface PaginateProps {
pageCount: number;
onPageChange: (selectedItem: { selected: number }) => void;
previousLabel: string | JSX.Element;
nextLabel: string | JSX.Element;
pageRangeDisplayed: number;
marginPagesDisplayed: number;
breakLabel: string | JSX.Element;
forcePage: number;
disableInitialCallback: boolean;
containerClassName?: string;
pageClassName?: string;
pageLinkClassName?: string;
activeClassName?: string;
previousClassName?: string;
nextClassName?: string;
disabledClassName?: string;
breakClassName?: string;
}
export const Paginate: FC<PaginateProps> = ({
pageCount,
onPageChange,
previousLabel,
nextLabel,
pageRangeDisplayed,
marginPagesDisplayed,
breakLabel,
forcePage,
disableInitialCallback,
containerClassName,
pageClassName,
pageLinkClassName,
activeClassName,
previousClassName,
nextClassName,
disabledClassName,
breakClassName,
}) => {
const [currentPage, setCurrentPage] = useState(forcePage);
useEffect(() => {
if (!disableInitialCallback) {
onPageChange({ selected: forcePage });
}
}, [disableInitialCallback, onPageChange, forcePage]);
const handlePageClick = (pageNumber: number) => {
setCurrentPage(pageNumber);
onPageChange({ selected: pageNumber });
};
if (pageCount === 0 || pageCount === 1 || !pageCount) return null;
const pageNumbers = [...Array(pageCount).keys()];
return (
<div className={containerClassName}>
<button
onClick={() => handlePageClick(currentPage - 1)}
disabled={currentPage === 0}
className={cltm(
previousClassName,
currentPage === 0 && disabledClassName
)}
>
{previousLabel}
</button>
{pageNumbers.map((number, index) => {
if (
index < marginPagesDisplayed ||
index > pageCount - 1 - marginPagesDisplayed ||
(index >= currentPage - pageRangeDisplayed &&
index <= currentPage + pageRangeDisplayed)
) {
return (
<button
key={number}
onClick={() => handlePageClick(number)}
className={cltm(
pageClassName,
number === currentPage && activeClassName
)}
>
<span className={pageLinkClassName}>{number + 1}</span>
</button>
);
} else if (
index === marginPagesDisplayed &&
currentPage >= pageRangeDisplayed + marginPagesDisplayed
) {
return (
<button
key={number}
onClick={() =>
handlePageClick(currentPage - pageRangeDisplayed - 1)
}
className={breakClassName}
>
{breakLabel}
</button>
);
} else if (
index === pageCount - 1 - marginPagesDisplayed &&
currentPage < pageCount - 1 - pageRangeDisplayed
) {
return (
<button
key={number}
onClick={() =>
handlePageClick(currentPage + pageRangeDisplayed + 1)
}
className={breakClassName}
>
{breakLabel}
</button>
);
} else {
return null;
}
})}
<button
onClick={() => handlePageClick(currentPage + 1)}
disabled={currentPage === pageCount - 1}
className={cltm(
nextClassName,
currentPage === pageCount - 1 && disabledClassName
)}
>
{nextLabel}
</button>
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment