import React, { Fragment, useEffect, useState } from "react"; import { Button } from ":/components/Button"; import { Input } from ":/components/Forms/Input"; import { useCunningham } from ":/components/Provider"; export interface PaginationProps { /** Current page */ page: number; /** Called when page need to change */ onPageChange: (page: number) => void; /** Total number of pages */ pagesCount?: number; /** Total number of items per page */ // eslint-disable-next-line react/no-unused-prop-types pageSize: number; /** Display the goto input */ displayGoto?: boolean; } export const usePagination = ({ defaultPage = 1, defaultPagesCount, pageSize = 10, }: { /** Default current page */ defaultPage?: number; /** Default total number of pages */ defaultPagesCount?: number; /** Total number of items per page */ pageSize?: number; }) => { const [page, setPage] = useState(defaultPage); const [pagesCount, setPagesCount] = useState(defaultPagesCount); return { page, setPage, onPageChange: setPage, pagesCount, setPagesCount, pageSize, }; }; export const Pagination = ({ page, onPageChange, pagesCount = 0, displayGoto = true, }: PaginationProps) => { const { t } = useCunningham(); const [gotoValue, setGotoValue] = useState(""); useEffect(() => { setGotoValue(page + ""); }, [page]); if (pagesCount <= 1) { return null; } // Create the default list of all the page numbers we intend to show const pageList = [ 1, // If there is just one page between first page and currentPage - 2, // we can display this page number instead of "..." page - 2 === 3 ? page - 3 : -1, page - 2, page - 1, page, page + 1, page + 2, // If there is just one page between maxPage and currentPage + 2, // we can display this page number instead of "..." page + 3 === pagesCount - 1 ? page + 3 : -1, pagesCount, ] // Filter out page numbers below 1 (when currentPage is 1 or 2) .filter((_page) => _page > 0) // Filter out page numbers above the max (they do not have anything to display) .filter((_page) => _page <= pagesCount) // Drop duplicates (this is trivial as our pageList is sorted) .filter((_page, index, list) => _page !== list[index - 1]); const onPreviousClick = () => { onPageChange(Math.max(page - 1, 0)); }; const onNextClick = () => { onPageChange(Math.min(page + 1, pagesCount)); }; const gotoPage = () => { let value = +gotoValue; if (value < 0 || !value) { value = 1; } if (value > pagesCount) { value = pagesCount; } onPageChange(value); }; const canPrevious = page > 1; const canNext = page < pagesCount; return (
) : ( )} ))}
{displayGoto && (
{ e.preventDefault(); gotoPage(); }} > setGotoValue(e.target.value)} min={1} max={pagesCount} onBlur={() => gotoPage()} onFocus={(e) => e.target.select()} />
)}
); };