UNPKG

react-use-pagination

Version:
138 lines (133 loc) 4.16 kB
// src/getPaginationMeta.ts var getPreviousEnabled = (currentPage) => currentPage > 0; var getNextEnabled = (currentPage, totalPages) => currentPage + 1 < totalPages; var getTotalPages = (totalItems, pageSize) => Math.ceil(totalItems / pageSize); var getStartIndex = (pageSize, currentPage) => pageSize * currentPage; var getEndIndex = (pageSize, currentPage, totalItems) => { const lastPageEndIndex = pageSize * (currentPage + 1); if (lastPageEndIndex > totalItems) { return totalItems - 1; } return lastPageEndIndex - 1; }; var limitPageBounds = (totalItems, pageSize) => (page) => Math.min(Math.max(page, 0), getTotalPages(totalItems, pageSize) - 1); var getPaginationMeta = ({ totalItems, pageSize, currentPage }) => { const totalPages = getTotalPages(totalItems, pageSize); return { totalPages, startIndex: getStartIndex(pageSize, currentPage), endIndex: getEndIndex(pageSize, currentPage, totalItems), previousEnabled: getPreviousEnabled(currentPage), nextEnabled: getNextEnabled(currentPage, totalPages) }; }; // src/usePagination.ts import { useCallback, useEffect, useMemo, useRef, useReducer } from "react"; // src/paginationStateReducer.ts var getCurrentPageReducer = (rootState) => function currentPageReducer(state, action) { switch (action.type) { case "SET_PAGE": return limitPageBounds(rootState.totalItems, rootState.pageSize)(action.page); case "NEXT_PAGE": return limitPageBounds(rootState.totalItems, rootState.pageSize)(state + 1); case "PREVIOUS_PAGE": return limitPageBounds(rootState.totalItems, rootState.pageSize)(state - 1); case "SET_PAGESIZE": return limitPageBounds(rootState.totalItems, action.pageSize)(action.nextPage ?? state); case "SET_TOTALITEMS": return limitPageBounds(action.totalItems, rootState.pageSize)(action.nextPage ?? state); default: return state; } }; function totalItemsReducer(state, action) { switch (action.type) { case "SET_TOTALITEMS": return action.totalItems; default: return state; } } function pageSizeReducer(state, action) { switch (action.type) { case "SET_PAGESIZE": return action.pageSize; default: return state; } } function paginationStateReducer(state, action) { return { currentPage: getCurrentPageReducer(state)(state.currentPage, action), totalItems: totalItemsReducer(state.totalItems, action), pageSize: pageSizeReducer(state.pageSize, action) }; } // src/usePagination.ts function usePagination({ totalItems = 0, initialPage = 0, initialPageSize = 0 } = {}) { const initialState = { totalItems, pageSize: initialPageSize, currentPage: initialPage }; const [paginationState, dispatch] = useReducer(paginationStateReducer, initialState); const totalItemsRef = useRef(totalItems); totalItemsRef.current = totalItems; useEffect(() => { return () => { if (typeof totalItemsRef.current !== "number" || totalItems === totalItemsRef.current) { return; } dispatch({ type: "SET_TOTALITEMS", totalItems: totalItemsRef.current }); }; }, [totalItems]); return { ...paginationState, ...useMemo(() => getPaginationMeta(paginationState), [paginationState]), setPage: useCallback((page) => { dispatch({ type: "SET_PAGE", page }); }, []), setNextPage: useCallback(() => { dispatch({ type: "NEXT_PAGE" }); }, []), setPreviousPage: useCallback(() => { dispatch({ type: "PREVIOUS_PAGE" }); }, []), setPageSize: useCallback((pageSize, nextPage = 0) => { dispatch({ type: "SET_PAGESIZE", pageSize, nextPage }); }, []) }; } // src/Pagination.tsx function Pagination({ children, totalItems = 0, initialPage = 0, initialPageSize }) { return children(usePagination({ totalItems, initialPage, initialPageSize })); } Pagination.displayName = "Pagination"; export { Pagination, getEndIndex, getNextEnabled, getPaginationMeta, getPreviousEnabled, getStartIndex, getTotalPages, limitPageBounds, usePagination }; //# sourceMappingURL=react-use-pagination.mjs.map