UNPKG

@renderlesskit/react

Version:

Collection of headless components/hooks that are accessible, composable, customizable from low level to build your own UI & Design System powered by Reakit

72 lines (70 loc) 2.71 kB
/** * Thanks to [Material UI](https://material-ui.com/) * Based on the logic from [usePagination Hook](https://github.com/mui-org/material-ui/blob/master/packages/material-ui-lab/src/Pagination/usePagination.js) */ import React from "react"; import { useControllableState } from "../utils"; export var usePaginationState = function usePaginationState() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var { defaultPage = 1, page: currentPageProp, onChange, count = 1, boundaryCount = 1, siblingCount = 1 } = props; var [currentPage, setCurrentPage] = useControllableState({ value: currentPageProp, defaultValue: defaultPage, onChange }); var startPages = range(1, Math.min(boundaryCount, count)); var endPages = range(Math.max(count - boundaryCount + 1, boundaryCount + 1), count); var siblingsStart = Math.max(Math.min( // Natural start currentPage - siblingCount, // Lower boundary when page is high count - boundaryCount - siblingCount * 2 - 1), // Greater than startPages boundaryCount + 2); var siblingsEnd = Math.min(Math.max( // Natural end currentPage + siblingCount, // Upper boundary when page is low boundaryCount + siblingCount * 2 + 2), // Less than endPages endPages[0] - 2); // Page to render // e.g. pages = [1, 'start-ellipsis', 4, 5, 6, 'end-ellipsis', 10] var pages = [...startPages, // Start ellipsis ...(siblingsStart > boundaryCount + 2 ? ["start-ellipsis"] : boundaryCount + 1 < count - boundaryCount ? [boundaryCount + 1] : []), // Sibling pages ...range(siblingsStart, siblingsEnd), // End ellipsis ...(siblingsEnd < count - boundaryCount - 1 ? ["end-ellipsis"] : count - boundaryCount > boundaryCount ? [count - boundaryCount] : []), ...endPages]; var nextPage = React.useCallback(() => { setCurrentPage(prevPage => prevPage + 1); }, [setCurrentPage]); var prevPage = React.useCallback(() => { setCurrentPage(prevPage => prevPage - 1); }, [setCurrentPage]); var firstPage = React.useCallback(() => { setCurrentPage(1); }, [setCurrentPage]); var lastPage = React.useCallback(() => { setCurrentPage(count); }, [count, setCurrentPage]); var movePage = React.useCallback(page => { if (page >= 1 && page <= count) setCurrentPage(page); }, [count, setCurrentPage]); return { pages, currentPage, isAtLastPage: currentPage >= count, isAtFirstPage: currentPage <= 1, nextPage, prevPage, movePage, firstPage, lastPage }; }; function range(start, end) { var length = end - start + 1; return Array.from({ length }, (_, i) => start + i); } //# sourceMappingURL=PaginationState.js.map