mirror of
https://github.com/stefanpejcic/openpanel
synced 2025-06-26 18:28:26 +00:00
64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
import { useMemo } from "react";
|
|
|
|
export const DOTS = "...";
|
|
|
|
const range = (start: number, end: number) => {
|
|
const length = end - start + 1;
|
|
return Array.from({ length }, (_, idx) => idx + start);
|
|
};
|
|
|
|
type UsePaginationProps = {
|
|
totalPages: number;
|
|
currentPage: number;
|
|
siblingCount?: number;
|
|
};
|
|
|
|
export const usePagination = ({
|
|
totalPages,
|
|
siblingCount = 1,
|
|
currentPage,
|
|
}: UsePaginationProps) => {
|
|
const paginationRange = useMemo(() => {
|
|
const totalPageNumbers = siblingCount + 5;
|
|
|
|
if (totalPageNumbers >= totalPages) {
|
|
return range(1, totalPages);
|
|
}
|
|
|
|
const leftSiblingIndex = Math.max(currentPage - siblingCount, 1);
|
|
const rightSiblingIndex = Math.min(
|
|
currentPage + siblingCount,
|
|
totalPages,
|
|
);
|
|
|
|
const shouldShowLeftDots = leftSiblingIndex > 2;
|
|
const shouldShowRightDots = rightSiblingIndex < totalPages - 2;
|
|
|
|
const firstPageIndex = 1;
|
|
const lastPageIndex = totalPages;
|
|
|
|
if (!shouldShowLeftDots && shouldShowRightDots) {
|
|
const leftItemCount = 3 + 2 * siblingCount;
|
|
const leftRange = range(1, leftItemCount);
|
|
|
|
return [...leftRange, DOTS, totalPages];
|
|
}
|
|
|
|
if (shouldShowLeftDots && !shouldShowRightDots) {
|
|
const rightItemCount = 3 + 2 * siblingCount;
|
|
const rightRange = range(
|
|
totalPages - rightItemCount + 1,
|
|
totalPages,
|
|
);
|
|
return [firstPageIndex, DOTS, ...rightRange];
|
|
}
|
|
|
|
if (shouldShowLeftDots && shouldShowRightDots) {
|
|
const middleRange = range(leftSiblingIndex, rightSiblingIndex);
|
|
return [firstPageIndex, DOTS, ...middleRange, DOTS, lastPageIndex];
|
|
}
|
|
}, [siblingCount, currentPage]);
|
|
|
|
return paginationRange;
|
|
};
|