1
- import { FC , useCallback , useEffect , useMemo , useState } from 'react'
1
+ import { FC , useEffect , useMemo , useState } from 'react'
2
2
3
3
import { useWindowSize , WindowSize } from '~/libs/shared'
4
4
import { Button , IconOutline } from '~/libs/ui'
@@ -19,98 +19,39 @@ const Pagination: FC<PaginationProps> = (props: PaginationProps) => {
19
19
const MAX_PAGE_DISPLAY = 5
20
20
const MAX_PAGE_MOBILE_DISPLAY = 3
21
21
const { width : screenWidth } : WindowSize = useWindowSize ( )
22
+ const isMobile = useMemo ( ( ) => screenWidth < 767 , [ screenWidth ] )
22
23
23
24
const [ displayPages , setDisplayPages ] = useState < number [ ] > ( [ ] )
24
- const mobiledisplayPages = useMemo ( ( ) => {
25
- if ( displayPages . length <= MAX_PAGE_MOBILE_DISPLAY ) {
26
- return displayPages
27
- }
28
-
29
- const LEFT = MAX_PAGE_MOBILE_DISPLAY % 2 === 0 ? MAX_PAGE_MOBILE_DISPLAY / 2 : ( MAX_PAGE_MOBILE_DISPLAY + 1 ) / 2
30
- const RIGHT = MAX_PAGE_MOBILE_DISPLAY - LEFT
31
- const index = displayPages . indexOf ( props . page )
32
- let start = Math . max ( 0 , index - LEFT )
33
- let end = Math . min ( index + RIGHT , displayPages . length )
34
- if ( end - start < MAX_PAGE_MOBILE_DISPLAY ) {
35
- start = Math . min ( Math . max ( 0 , end - MAX_PAGE_MOBILE_DISPLAY ) , start )
36
- }
37
-
38
- if ( end - start < MAX_PAGE_MOBILE_DISPLAY ) {
39
- end = Math . min ( Math . max ( start + MAX_PAGE_MOBILE_DISPLAY , end ) , displayPages . length )
40
- }
41
-
42
- return displayPages . slice ( start , end )
43
- } , [ displayPages , props . page , screenWidth ] ) // eslint-disable-line react-hooks/exhaustive-deps, max-len -- unneccessary dependency: screenWidth
44
-
45
- const createDisplayPages = useCallback ( ( reset : boolean ) => {
46
- // eslint-disable-next-line complexity
47
- setDisplayPages ( oldDisplayPages => {
48
- let expectedDisplayPages = oldDisplayPages
49
- if ( expectedDisplayPages . includes ( props . page ) && ! reset ) {
50
- return [ ...expectedDisplayPages ]
51
- }
52
-
53
- if ( reset ) {
54
- expectedDisplayPages = [ ]
55
- }
56
-
57
- // Initial
58
- if ( expectedDisplayPages . length === 0 ) {
59
- const pages = [ ]
60
- for (
61
- let i = props . page - MAX_PAGE_DISPLAY + 1 ;
62
- i <= props . page + MAX_PAGE_DISPLAY ;
63
- i ++
64
- ) {
65
- if ( i >= 1 && i <= totalPages && pages . length < MAX_PAGE_DISPLAY ) {
66
- pages . push ( i )
67
- }
68
- }
69
-
70
- return pages
71
- }
72
25
73
- // Go next
74
- if ( props . page > expectedDisplayPages [ expectedDisplayPages . length - 1 ] ) {
75
- const pages = [ ]
76
- for (
77
- let i = props . page - MAX_PAGE_DISPLAY + 1 ;
78
- i <= props . page ;
79
- i ++
80
- ) {
81
- if ( i >= 1 ) {
82
- pages . push ( i )
83
- }
26
+ useEffect ( ( ) => {
27
+ let pages : number [ ] = [ ]
28
+ if ( props . page ) {
29
+ pages = [ props . page ]
30
+ const maxDisplayPage = isMobile
31
+ ? MAX_PAGE_MOBILE_DISPLAY
32
+ : MAX_PAGE_DISPLAY
33
+ let haveAvailablePage = true
34
+ let i = 1
35
+ while ( haveAvailablePage && pages . length < maxDisplayPage ) {
36
+ const prevPage = props . page - i
37
+ haveAvailablePage = false
38
+ if ( prevPage > 0 ) {
39
+ pages = [ prevPage , ...pages ]
40
+ haveAvailablePage = true
84
41
}
85
42
86
- return pages
87
- }
88
-
89
- // Go previous
90
- if ( props . page < expectedDisplayPages [ 0 ] && props . page >= 1 ) {
91
- const pages = [ ]
92
- for (
93
- let i = props . page ;
94
- i < props . page + MAX_PAGE_DISPLAY ;
95
- i ++
96
- ) {
97
- pages . push ( i )
43
+ const nextPage = props . page + i
44
+ if ( nextPage <= totalPages ) {
45
+ pages = [ ...pages , nextPage ]
46
+ haveAvailablePage = true
98
47
}
99
48
100
- return pages
49
+ i += 1
101
50
}
51
+ }
102
52
103
- return [ ...expectedDisplayPages ]
104
- } )
105
- } , [ props . page , totalPages ] )
106
-
107
- useEffect ( ( ) => {
108
- createDisplayPages ( true )
109
- } , [ totalPages ] ) // eslint-disable-line react-hooks/exhaustive-deps
110
-
111
- useEffect ( ( ) => {
112
- createDisplayPages ( false )
113
- } , [ props . page ] ) // eslint-disable-line react-hooks/exhaustive-deps
53
+ setDisplayPages ( pages )
54
+ } , [ totalPages , props . page , isMobile ] ) // eslint-disable-line react-hooks/exhaustive-deps
114
55
115
56
const createHandlePageClick = ( p : number ) => ( ) => {
116
57
if ( p === 0 || p > totalPages || p === props . page ) {
@@ -148,7 +89,7 @@ const Pagination: FC<PaginationProps> = (props: PaginationProps) => {
148
89
className = { styles . previous }
149
90
/>
150
91
< div className = { styles . pageNumbers } >
151
- { ( screenWidth < 767 ? mobiledisplayPages : displayPages ) . map ( i => (
92
+ { displayPages . map ( i => (
152
93
< Button
153
94
key = { `page-${ i } ` }
154
95
secondary
0 commit comments