1 | import { useMemo } from 'react' |
||
2 | |||
3 | import { IPagination } from './types' |
||
4 | |||
5 | const DOTS = 0 |
||
6 | |||
7 | const range = (start: number, end: number) => { |
||
8 | const length = end - start + 1 |
||
9 | return Array.from({ length }, (_, idx) => idx + start) |
||
10 | } |
||
11 | |||
12 | const usePagination = ({ |
||
13 | totalPages, |
||
14 | siblingCount = 1, |
||
15 | currentPage, |
||
16 | }: IPagination) => { |
||
17 | const paginationRange = useMemo(() => { |
||
18 | const totalPageNumbers = siblingCount + 5 |
||
19 | |||
20 | if (totalPageNumbers >= totalPages) { |
||
21 | return range(1, totalPages) |
||
22 | } |
||
23 | |||
24 | const leftSiblingIndex = Math.max(currentPage - siblingCount, 1) |
||
25 | const rightSiblingIndex = Math.min(currentPage + siblingCount, totalPages) |
||
26 | |||
27 | const showLeftDots = leftSiblingIndex > 2 |
||
28 | const showRightDots = rightSiblingIndex < totalPages - 2 |
||
29 | |||
30 | const firstPageIndex = 1 |
||
31 | const lastPageIndex = totalPages |
||
32 | |||
33 | if (!showLeftDots && showRightDots) { |
||
34 | const leftItemCount = 3 + 2 * siblingCount |
||
35 | const leftRange = range(1, leftItemCount) |
||
36 | |||
37 | return [...leftRange, DOTS, totalPages] |
||
38 | } |
||
39 | |||
40 | if (showLeftDots && !showRightDots) { |
||
41 | const rightItemCount = 3 + 2 * siblingCount |
||
42 | const rightRange = range(totalPages - rightItemCount + 1, totalPages) |
||
43 | |||
44 | return [firstPageIndex, DOTS, ...rightRange] |
||
45 | } |
||
46 | |||
47 | if (showLeftDots && showRightDots) { |
||
48 | let middleRange = range(leftSiblingIndex, rightSiblingIndex) |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
49 | return [firstPageIndex, DOTS, ...middleRange, DOTS, lastPageIndex] |
||
50 | } |
||
51 | }, [currentPage, totalPages, siblingCount]) |
||
52 | |||
53 | return paginationRange |
||
54 | } |
||
55 | |||
56 | export { usePagination, DOTS } |
||
57 |