Skip to content

Commit dc8498b

Browse files
Create paginator component
1 parent 16df602 commit dc8498b

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { Button, IconButton, HStack } from "@chakra-ui/react";
2+
import { ArrowBackIcon, ArrowForwardIcon } from "@chakra-ui/icons";
3+
4+
export type PaginatorProps = {
5+
page: number;
6+
totalPages: number;
7+
adjacent: number;
8+
onPageChange: (x: number) => void;
9+
};
10+
11+
export const Paginator = (pp: PaginatorProps) => {
12+
const { page, totalPages, adjacent, onPageChange } = pp;
13+
const next = () => {
14+
if (page === totalPages) return;
15+
onPageChange(page + 1);
16+
};
17+
18+
const prev = () => {
19+
if (page === 1) return;
20+
onPageChange(page - 1);
21+
};
22+
23+
const renderButton = (p: number) => {
24+
if (p < 0) {
25+
return (
26+
<Button colorScheme="blue" variant="" isDisabled>
27+
...
28+
</Button>
29+
);
30+
}
31+
32+
return (
33+
<Button
34+
colorScheme="blue"
35+
key={p}
36+
variant={p === page ? "solid" : "ghost"}
37+
isDisabled={p === page}
38+
onClick={() => onPageChange(p)}
39+
>
40+
{p}
41+
</Button>
42+
);
43+
};
44+
45+
let from: number = Math.max(page - adjacent, 1);
46+
let to: number = Math.min(page + adjacent, totalPages);
47+
const btns: number[] = from !== 1 ? [1] : [];
48+
if (from > 2) {
49+
btns.push(-1);
50+
}
51+
for (let i = from; i <= to; i++) btns.push(i);
52+
if (to < totalPages - 1) {
53+
btns.push(-1);
54+
}
55+
if (to < totalPages) {
56+
btns.push(totalPages);
57+
}
58+
59+
return (
60+
<div>
61+
<HStack
62+
spacing="4px"
63+
width="fit-content"
64+
backgroundColor="white"
65+
borderRadius="10"
66+
boxShadow="base"
67+
transition="box-shadow 0.2s"
68+
_hover={{
69+
boxShadow: "md",
70+
}}
71+
>
72+
<IconButton
73+
colorScheme="blue"
74+
variant="ghost"
75+
aria-label="Previous Page"
76+
icon={<ArrowBackIcon />}
77+
onClick={prev}
78+
isDisabled={page === 1}
79+
/>
80+
{btns.map((page) => renderButton(page))}
81+
<IconButton
82+
colorScheme="blue"
83+
variant="ghost"
84+
aria-label="Next Page"
85+
icon={<ArrowForwardIcon />}
86+
onClick={next}
87+
isDisabled={page === totalPages}
88+
/>
89+
</HStack>
90+
</div>
91+
);
92+
};

0 commit comments

Comments
 (0)