@mantine/hooks
Version:
A collection of 50+ hooks for state and UI management
80 lines (79 loc) • 2.77 kB
JavaScript
"use client";
import { useUncontrolled } from "../use-uncontrolled/use-uncontrolled.mjs";
import { useCallback, useMemo } from "react";
//#region packages/@mantine/hooks/src/use-pagination/use-pagination.ts
function range(start, end) {
const length = end - start + 1;
return Array.from({ length }, (_, index) => index + start);
}
const DOTS = "dots";
function usePagination({ total, siblings = 1, boundaries = 1, page, initialPage, onChange, startValue = 1 }) {
const _startValue = Math.max(Math.trunc(startValue), 1);
const _endValue = Math.max(Math.trunc(total), _startValue);
const _total = _endValue - _startValue + 1;
const _initialPage = initialPage ?? _startValue;
const [activePage, setActivePage] = useUncontrolled({
value: page,
onChange,
defaultValue: _initialPage,
finalValue: _initialPage
});
const setPage = useCallback((pageNumber) => {
if (pageNumber < _startValue) setActivePage(_startValue);
else if (pageNumber > _endValue) setActivePage(_endValue);
else setActivePage(pageNumber);
}, [
_startValue,
_endValue,
setActivePage
]);
const next = useCallback(() => setPage(activePage + 1), [activePage, setPage]);
const previous = useCallback(() => setPage(activePage - 1), [activePage, setPage]);
const first = useCallback(() => setPage(_startValue), [setPage, _startValue]);
const last = useCallback(() => setPage(_endValue), [_endValue, setPage]);
return {
range: useMemo(() => {
if (siblings * 2 + 3 + boundaries * 2 >= _total) return range(_startValue, _endValue);
const leftSiblingIndex = Math.max(activePage - siblings, _startValue + boundaries - 1);
const rightSiblingIndex = Math.min(activePage + siblings, _endValue - boundaries);
const shouldShowLeftDots = leftSiblingIndex > _startValue + boundaries + 1;
const shouldShowRightDots = rightSiblingIndex < _endValue - boundaries;
if (!shouldShowLeftDots && shouldShowRightDots) return [
...range(_startValue, _startValue + (siblings * 2 + boundaries + 2) - 1),
DOTS,
...range(_endValue - (boundaries - 1), _endValue)
];
if (shouldShowLeftDots && !shouldShowRightDots) {
const rightItemCount = boundaries + 1 + 2 * siblings;
return [
...range(_startValue, _startValue + boundaries - 1),
DOTS,
...range(_endValue - rightItemCount, _endValue)
];
}
return [
...range(_startValue, _startValue + boundaries - 1),
DOTS,
...range(leftSiblingIndex, rightSiblingIndex),
DOTS,
...range(_endValue - boundaries + 1, _endValue)
];
}, [
_total,
siblings,
activePage,
_startValue,
_endValue,
boundaries
]),
active: activePage,
setPage,
next,
previous,
first,
last
};
}
//#endregion
export { usePagination };
//# sourceMappingURL=use-pagination.mjs.map