Skip to content

Commit 8de071b

Browse files
Merge pull request #328 from harjibbolar26/add-basic-pagination-component
Fix: Add Basic Pagination Component
2 parents 5eedf64 + af77fa2 commit 8de071b

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import React from 'react';
2+
3+
interface PaginationProps {
4+
currentPage: number;
5+
totalPages: number;
6+
onPageChange: (page: number) => void;
7+
}
8+
9+
export const Pagination: React.FC<PaginationProps> = ({
10+
currentPage,
11+
totalPages,
12+
onPageChange,
13+
}) => {
14+
const handlePrevious = () => {
15+
if (currentPage > 1) {
16+
onPageChange(currentPage - 1);
17+
}
18+
};
19+
20+
const handleNext = () => {
21+
if (currentPage < totalPages) {
22+
onPageChange(currentPage + 1);
23+
}
24+
};
25+
26+
const getPageNumbers = () => {
27+
const pages: (number | string)[] = [];
28+
const maxVisible = 7;
29+
30+
if (totalPages <= maxVisible) {
31+
for (let i = 1; i <= totalPages; i++) {
32+
pages.push(i);
33+
}
34+
} else {
35+
if (currentPage <= 4) {
36+
for (let i = 1; i <= 5; i++) {
37+
pages.push(i);
38+
}
39+
pages.push('...');
40+
pages.push(totalPages);
41+
} else if (currentPage >= totalPages - 3) {
42+
pages.push(1);
43+
pages.push('...');
44+
for (let i = totalPages - 4; i <= totalPages; i++) {
45+
pages.push(i);
46+
}
47+
} else {
48+
pages.push(1);
49+
pages.push('...');
50+
for (let i = currentPage - 1; i <= currentPage + 1; i++) {
51+
pages.push(i);
52+
}
53+
pages.push('...');
54+
pages.push(totalPages);
55+
}
56+
}
57+
58+
return pages;
59+
};
60+
61+
if (totalPages <= 1) {
62+
return null;
63+
}
64+
65+
return (
66+
<div className="flex items-center justify-center gap-2">
67+
<button
68+
onClick={handlePrevious}
69+
disabled={currentPage === 1}
70+
className="px-4 py-2 rounded-md border border-gray-300 bg-white text-gray-700 font-medium hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-white transition-colors"
71+
aria-label="Previous page"
72+
>
73+
Prev
74+
</button>
75+
76+
<div className="flex items-center gap-1">
77+
{getPageNumbers().map((page, index) => {
78+
if (page === '...') {
79+
return (
80+
<span
81+
key={`ellipsis-${index}`}
82+
className="px-3 py-2 text-gray-500"
83+
>
84+
...
85+
</span>
86+
);
87+
}
88+
89+
const pageNum = page as number;
90+
const isActive = pageNum === currentPage;
91+
92+
return (
93+
<button
94+
key={pageNum}
95+
onClick={() => onPageChange(pageNum)}
96+
className={`min-w-[40px] px-3 py-2 rounded-md font-medium transition-colors ${
97+
isActive
98+
? 'bg-blue-600 text-white hover:bg-blue-700'
99+
: 'border border-gray-300 bg-white text-gray-700 hover:bg-gray-50'
100+
}`}
101+
aria-label={`Page ${pageNum}`}
102+
aria-current={isActive ? 'page' : undefined}
103+
>
104+
{pageNum}
105+
</button>
106+
);
107+
})}
108+
</div>
109+
110+
<button
111+
onClick={handleNext}
112+
disabled={currentPage === totalPages}
113+
className="px-4 py-2 rounded-md border border-gray-300 bg-white text-gray-700 font-medium hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-white transition-colors"
114+
aria-label="Next page"
115+
>
116+
Next
117+
</button>
118+
</div>
119+
);
120+
};
121+
122+
export default Pagination;

0 commit comments

Comments
 (0)