UNPKG

pagination-react-js

Version:

React Pagination Hook, which is lightweight, fast and easy to use.

102 lines (98 loc) 3.75 kB
// src/package/hooks/usePagination/usePagination.ts import { useMemo, useState } from "react"; // src/package/utils/generateNumArr/generateNumArr.ts function generateNumArr(loopStart, loopMax) { const numArr = []; for (let i = loopStart; i <= loopMax; i++) { numArr.push(i); } return numArr; } // src/package/utils/getOffsetNumbers/getOffsetNumbers.ts function getOffsetNumbers({ pageNumbers, firstNumber, lastNumber, activeNumber, offset, permanentFirstNumber, permanentLastNumber }) { const pageOffsetNumbers = []; if (!firstNumber || !lastNumber) { return { pageOffsetNumbers }; } const additionalOffsetStart = firstNumber + offset * 2 + (permanentFirstNumber ? 1 : 0); const additionalOffsetEnd = lastNumber - offset * 2 - (permanentLastNumber ? 1 : 0); for (const pageNumber of pageNumbers) { if (pageNumber === activeNumber || pageNumber <= activeNumber + offset && pageNumber > activeNumber || pageNumber >= activeNumber - offset && pageNumber < activeNumber || activeNumber - offset <= firstNumber && pageNumber <= additionalOffsetStart || activeNumber + offset >= lastNumber && pageNumber >= additionalOffsetEnd) { pageOffsetNumbers.push(pageNumber); } } return { pageOffsetNumbers }; } // src/package/hooks/usePagination/usePagination.ts function usePagination({ activePage: initialActivePage, recordsPerPage: initialRecordsPerPage, totalRecordsLength, offset, navCustomPageSteps, permanentFirstNumber, permanentLastNumber }) { const [activePage, setActivePage] = useState(initialActivePage); const [recordsPerPage, setRecordsPerPage] = useState(initialRecordsPerPage); const indexOfLastRecord = (recordsPerPage > totalRecordsLength ? totalRecordsLength : activePage * recordsPerPage) - 1; const indexOfFirstRecord = recordsPerPage > indexOfLastRecord ? 0 : indexOfLastRecord - recordsPerPage + 1; if (totalRecordsLength < 0) { throw new Error("totalRecordsLength cannot be negative"); } if (recordsPerPage <= 0) { throw new Error("recordsPerPage must be greater than zero"); } if (activePage <= 0) { throw new Error("activePage must be at least 1"); } const pageNumbers = useMemo(() => generateNumArr(1, Math.ceil(totalRecordsLength / recordsPerPage)), [totalRecordsLength, recordsPerPage]); const firstPage = useMemo(() => pageNumbers[0], [pageNumbers]); const lastPage = useMemo(() => pageNumbers[pageNumbers.length - 1], [pageNumbers]); const { pageOffsetNumbers } = useMemo( () => getOffsetNumbers({ pageNumbers, firstNumber: firstPage, lastNumber: lastPage, activeNumber: activePage, offset, permanentFirstNumber, permanentLastNumber }), [pageNumbers, firstPage, lastPage, activePage, offset, permanentFirstNumber, permanentLastNumber] ); return { records: { perPage: recordsPerPage, indexOfFirst: indexOfFirstRecord, indexOfLast: indexOfLastRecord }, pagination: firstPage && lastPage ? { activePage, firstPage, lastPage, previousPage: activePage > firstPage ? activePage - 1 : null, nextPage: activePage < lastPage ? activePage + 1 : null, customPreviousPage: navCustomPageSteps?.prev && activePage - navCustomPageSteps.prev >= firstPage + 1 ? activePage - navCustomPageSteps.prev : null, customNextPage: navCustomPageSteps?.next && activePage + navCustomPageSteps.next <= lastPage - 1 ? activePage + navCustomPageSteps.next : null, pageNumbers: pageOffsetNumbers } : null, setRecordsPerPage: (recordsPerPage2) => { setRecordsPerPage(recordsPerPage2); }, setActivePage: (pageNumber) => { setActivePage(pageNumber); } }; } export { usePagination };