@@ -6,39 +6,48 @@ import KeyboardArrowRight from "@material-ui/icons/KeyboardArrowRight"
6
6
import { ChooseOne , Cond } from "components/Conditionals/ChooseOne"
7
7
import { Maybe } from "components/Conditionals/Maybe"
8
8
import { CSSProperties } from "react"
9
+ import { useSearchParams } from "react-router-dom"
9
10
import { PageButton } from "./PageButton"
10
11
import { buildPagedList , DEFAULT_RECORDS_PER_PAGE } from "./utils"
11
12
12
13
export type PaginationWidgetProps = {
13
14
prevLabel : string
14
15
nextLabel : string
15
- onPrevClick : ( ) => void
16
- onNextClick : ( ) => void
17
- onPageClick ?: ( page : number ) => void
16
+ onPageChange : ( offset : number , limit : number ) => void
18
17
numRecordsPerPage ?: number
19
18
numRecords ?: number
20
- activePage ?: number
21
19
containerStyle ?: CSSProperties
22
20
}
23
21
24
22
export const PaginationWidget = ( {
25
23
prevLabel,
26
24
nextLabel,
27
- onPrevClick,
28
- onNextClick,
29
- onPageClick,
25
+ onPageChange,
30
26
numRecords,
31
27
numRecordsPerPage = DEFAULT_RECORDS_PER_PAGE ,
32
- activePage = 1 ,
33
28
containerStyle,
34
29
} : PaginationWidgetProps ) : JSX . Element | null => {
35
- const numPages = numRecords ? Math . ceil ( numRecords / numRecordsPerPage ) : 0
36
- const firstPageActive = activePage === 1 && numPages !== 0
37
- const lastPageActive = activePage === numPages && numPages !== 0
38
30
const theme = useTheme ( )
39
31
const isMobile = useMediaQuery ( theme . breakpoints . down ( "sm" ) )
40
32
const styles = useStyles ( )
41
33
34
+ const [ searchParams , setSearchParams ] = useSearchParams ( )
35
+ const currentPage = searchParams . get ( "page" )
36
+ ? Number ( searchParams . get ( "page" ) )
37
+ : 1
38
+
39
+ const numPages = numRecords ? Math . ceil ( numRecords / numRecordsPerPage ) : 0
40
+ const firstPageActive = currentPage === 1 && numPages !== 0
41
+ const lastPageActive = currentPage === numPages && numPages !== 0
42
+
43
+ const changePage = ( newPage : number ) => {
44
+ // change the page in the url
45
+ setSearchParams ( { page : newPage . toString ( ) } )
46
+ // fetch new page of records
47
+ const offset = ( newPage - 1 ) * numRecordsPerPage
48
+ onPageChange ( offset , numRecordsPerPage )
49
+ }
50
+
42
51
// No need to display any pagination if we know the number of pages is 1
43
52
if ( numPages === 1 || numRecords === 0 ) {
44
53
return null
@@ -50,7 +59,7 @@ export const PaginationWidget = ({
50
59
className = { styles . prevLabelStyles }
51
60
aria-label = "Previous page"
52
61
disabled = { firstPageActive }
53
- onClick = { onPrevClick }
62
+ onClick = { ( ) => changePage ( currentPage - 1 ) }
54
63
>
55
64
< KeyboardArrowLeft />
56
65
< div > { prevLabel } </ div >
@@ -59,26 +68,22 @@ export const PaginationWidget = ({
59
68
< ChooseOne >
60
69
< Cond condition = { isMobile } >
61
70
< PageButton
62
- activePage = { activePage }
63
- page = { activePage }
71
+ activePage = { currentPage }
72
+ page = { currentPage }
64
73
numPages = { numPages }
65
74
/>
66
75
</ Cond >
67
76
< Cond >
68
- { buildPagedList ( numPages , activePage ) . map ( ( page ) =>
77
+ { buildPagedList ( numPages , currentPage ) . map ( ( page ) =>
69
78
typeof page !== "number" ? (
70
- < PageButton
71
- key = { `Page${ page } ` }
72
- placeholder = "..."
73
- disabled
74
- />
79
+ < PageButton key = { `Page${ page } ` } placeholder = "..." disabled />
75
80
) : (
76
81
< PageButton
77
82
key = { `Page${ page } ` }
78
- activePage = { activePage }
83
+ activePage = { currentPage }
79
84
page = { page }
80
85
numPages = { numPages }
81
- onPageClick = { onPageClick }
86
+ onPageClick = { ( ) => changePage ( page ) }
82
87
/>
83
88
) ,
84
89
) }
@@ -88,7 +93,7 @@ export const PaginationWidget = ({
88
93
< Button
89
94
aria-label = "Next page"
90
95
disabled = { lastPageActive }
91
- onClick = { onNextClick }
96
+ onClick = { ( ) => changePage ( currentPage + 1 ) }
92
97
>
93
98
< div > { nextLabel } </ div >
94
99
< KeyboardArrowRight />
@@ -109,5 +114,4 @@ const useStyles = makeStyles((theme) => ({
109
114
prevLabelStyles : {
110
115
marginRight : `${ theme . spacing ( 0.5 ) } px` ,
111
116
} ,
112
-
113
117
} ) )
0 commit comments