UNPKG

@adaptui/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

71 lines (69 loc) 2.99 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, { useMemo } from "react"; import { useControlledState, useStorePublisher } from "ariakit-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] = useControlledState(defaultPage, currentPageProp, 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 = useMemo(() => [...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], [boundaryCount, count, endPages, siblingsEnd, siblingsStart, startPages]); 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]); var isAtLastPage = currentPage >= count; var isAtFirstPage = currentPage <= 1; var state = useMemo(() => ({ pages, currentPage, isAtLastPage, isAtFirstPage, nextPage, prevPage, movePage, firstPage, lastPage }), [pages, currentPage, isAtLastPage, isAtFirstPage, nextPage, prevPage, movePage, firstPage, lastPage]); return useStorePublisher(state); }; function range(start, end) { var length = end - start + 1; return Array.from({ length }, (_, i) => start + i); } //# sourceMappingURL=pagination-state.js.map