Skip to content

Commit c880bd7

Browse files
committed
feat: enhance pagination controls with filter key handling and stability improvements
1 parent 3da9123 commit c880bd7

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

src/components/PaginatedNavigation.tsx

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,27 @@ type PaginationControlsProps = {
1414
currentPage: number;
1515
totalPages: number;
1616
onPageChange: (page: number) => void;
17+
// Optional key whose change can shrink/grow pages immediately (e.g. active filter)
18+
filterKey?: string;
1719
};
1820

1921
export const PaginatedNavigation = ({
2022
currentPage,
2123
totalPages,
2224
onPageChange,
25+
filterKey,
2326
}: PaginationControlsProps) => {
2427
const { chainId } = useUserStore();
2528

2629
const lastValidTotalPagesRef = useRef(1);
2730
const lastChainIdRef = useRef<number | null>(null);
2831
const chainChangeFrameRef = useRef(0);
2932

33+
const lastFilterKeyRef = useRef<string | undefined>(undefined);
34+
const filterChangeFrameRef = useRef(0);
35+
3036
const chainHasChanged = chainId !== lastChainIdRef.current;
37+
const filterHasChanged = filterKey !== lastFilterKeyRef.current;
3138

3239
if (chainHasChanged) {
3340
lastChainIdRef.current = chainId ?? null;
@@ -36,66 +43,72 @@ export const PaginatedNavigation = ({
3643
chainChangeFrameRef.current++;
3744
}
3845

46+
if (filterHasChanged) {
47+
lastFilterKeyRef.current = filterKey;
48+
filterChangeFrameRef.current = 0;
49+
} else {
50+
filterChangeFrameRef.current++;
51+
}
52+
3953
let stableTotalPages = lastValidTotalPagesRef.current;
4054

4155
const isRecentChainChange = chainChangeFrameRef.current <= 5;
42-
43-
if (chainHasChanged || isRecentChainChange) {
56+
const isRecentFilterChange = filterChangeFrameRef.current <= 5;
57+
58+
if (
59+
chainHasChanged ||
60+
filterHasChanged ||
61+
isRecentChainChange ||
62+
isRecentFilterChange
63+
) {
4464
stableTotalPages = Math.max(totalPages, 1);
4565
} else if (totalPages > 0 && totalPages >= lastValidTotalPagesRef.current) {
4666
stableTotalPages = totalPages;
4767
}
68+
// Reset page if it no longer exists after filter change
69+
if (filterHasChanged && currentPage > stableTotalPages) {
70+
onPageChange(1);
71+
}
4872

4973
lastValidTotalPagesRef.current = stableTotalPages;
5074

51-
// Don't render pagination if no pages or invalid state
5275
if (!stableTotalPages || stableTotalPages <= 0 || currentPage <= 0) {
5376
return null;
5477
}
5578

5679
const generatePages = () => {
5780
const pages: (number | 'ellipsis')[] = [];
5881

59-
// Mobile-first approach: show fewer pages on small screens
6082
const isMobile = typeof window !== 'undefined' && window.innerWidth < 640;
6183
const maxVisiblePages = isMobile ? 3 : 7;
6284

6385
if (stableTotalPages <= maxVisiblePages) {
64-
// Show all pages if within limit
6586
for (let i = 1; i <= stableTotalPages; i++) {
6687
pages.push(i);
6788
}
6889
} else if (isMobile) {
69-
// Mobile: simplified pagination - only show current and neighbors
7090
if (currentPage === 1) {
71-
// At start: 1 2 ... last
7291
pages.push(1, 2, 'ellipsis', stableTotalPages);
7392
} else if (currentPage === stableTotalPages) {
74-
// At end: 1 ... (last-1) last
7593
pages.push(1, 'ellipsis', stableTotalPages - 1, stableTotalPages);
7694
} else {
77-
// Middle: 1 ... current ... last
7895
pages.push(1, 'ellipsis', currentPage, 'ellipsis', stableTotalPages);
7996
}
8097
} else {
81-
// Desktop: full pagination logic
8298
pages.push(1);
8399

84100
if (currentPage <= 3) {
85-
// Near beginning: 1 2 3 4 ... last
86101
for (let i = 2; i <= 4; i++) {
87102
pages.push(i);
88103
}
89104
pages.push('ellipsis');
90105
pages.push(stableTotalPages);
91106
} else if (currentPage >= stableTotalPages - 2) {
92-
// Near end: 1 ... (last-3) (last-2) (last-1) last
93107
pages.push('ellipsis');
94108
for (let i = stableTotalPages - 3; i <= stableTotalPages; i++) {
95109
pages.push(i);
96110
}
97111
} else {
98-
// In middle: 1 ... (current-1) current (current+1) ... last
99112
pages.push('ellipsis');
100113
for (let i = currentPage - 1; i <= currentPage + 1; i++) {
101114
pages.push(i);

0 commit comments

Comments
 (0)