@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
JavaScript
/**
* 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