1
- import React , { ComponentProps } from "react"
1
+ import React , { ComponentProps , useEffect , useRef , useState } from "react"
2
2
import { images } from "../../../utils/conf-images"
3
3
import Zoom from "react-medium-image-zoom"
4
4
import "react-medium-image-zoom/dist/styles.css"
@@ -15,63 +15,87 @@ function chunk<T>(arr: T[], len: number): T[][] {
15
15
return chunks
16
16
}
17
17
18
- function Img ( { src, alt = "gallery" } : ComponentProps < "img" > ) {
18
+ function Img ( {
19
+ src,
20
+ alt = "gallery" ,
21
+ isLast,
22
+ newLimit,
23
+ } : ComponentProps < "img" > & {
24
+ isLast ?: boolean
25
+ newLimit : ( ) => any
26
+ } ) {
27
+ /**
28
+ * Select the Card component with useRef
29
+ */
30
+ const cardRef = useRef < HTMLImageElement > ( null )
31
+
32
+ /**
33
+ * Implement Intersection Observer to check if the last Card in the array is visible on the screen, then set a new limit
34
+ */
35
+ useEffect ( ( ) => {
36
+ if ( ! cardRef ?. current ) return
37
+
38
+ const observer = new IntersectionObserver ( ( [ entry ] ) => {
39
+ if ( isLast && entry . isIntersecting ) {
40
+ newLimit ( )
41
+ observer . unobserve ( entry . target )
42
+ }
43
+ } )
44
+
45
+ observer . observe ( cardRef . current )
46
+ } , [ isLast ] )
47
+
19
48
return (
20
49
< Zoom >
21
50
< img
22
51
alt = { alt }
23
52
className = "object-cover aspect-video w-full hover:opacity-75 rounded-md"
24
53
src = { src }
54
+ ref = { cardRef }
25
55
/>
26
56
</ Zoom >
27
57
)
28
58
}
29
59
30
60
const GalleryConf = ( ) => {
61
+ const [ page , setPage ] = useState ( 1 )
62
+
63
+ const currentImages = chunk ( images , 6 ) . slice ( 0 , page )
64
+ const lastSrc = currentImages . at ( - 1 ) ! . at ( - 1 )
31
65
return (
32
66
< div className = "py-20" >
33
- < div className = "container px-3 py-6 mx-auto" >
34
- { chunk ( images , 6 ) . map ( ( c , i ) => (
35
- < div key = { i } className = "flex max-lg:flex-col flex-wrap" >
36
- < div className = "flex flex-wrap lg:w-1/2" >
37
- { c [ 0 ] && (
38
- < div className = "md:p-2 p-1 lg:w-1/2" >
39
- < Img src = { c [ 0 ] } />
40
- </ div >
41
- ) }
42
- { c [ 1 ] && (
43
- < div className = "md:p-2 p-1 lg:w-1/2" >
44
- < Img src = { c [ 1 ] } />
45
- </ div >
46
- ) }
47
- { c [ 2 ] && (
48
- < div className = "md:p-2 p-1 lg:w-full" >
49
- < Img src = { c [ 2 ] } />
50
- </ div >
51
- ) }
67
+ { currentImages . map ( ( c , i ) => {
68
+ function getCard ( index : number ) {
69
+ return (
70
+ c [ index ] && (
71
+ < Img
72
+ src = { c [ index ] }
73
+ isLast = { c [ index ] === lastSrc }
74
+ newLimit = { ( ) => setPage ( page + 1 ) }
75
+ />
76
+ )
77
+ )
78
+ }
79
+
80
+ return (
81
+ < div key = { i } className = "grid lg:grid-cols-2 gap-2" >
82
+ < div >
83
+ < div className = "grid grid-cols-2 gap-2" >
84
+ { getCard ( 0 ) }
85
+ { getCard ( 1 ) }
86
+ </ div >
87
+ { getCard ( 2 ) }
52
88
</ div >
53
- < div className = "lg:w-1/2" >
54
- { c [ 3 ] && (
55
- < div className = "md:p-2 p-1 w-full" >
56
- < Img src = { c [ 3 ] } />
57
- </ div >
58
- ) }
59
- < div className = "flex" >
60
- { c [ 4 ] && (
61
- < div className = "md:p-2 p-1 lg:w-1/2" >
62
- < Img src = { c [ 4 ] } />
63
- </ div >
64
- ) }
65
- { c [ 5 ] && (
66
- < div className = "md:p-2 p-1 lg:w-1/2" >
67
- < Img src = { c [ 5 ] } />
68
- </ div >
69
- ) }
89
+ < div >
90
+ { getCard ( 3 ) }
91
+ < div className = "grid grid-cols-2 gap-2" >
92
+ { getCard ( 4 ) }
93
+ { getCard ( 5 ) }
70
94
</ div >
71
95
</ div >
72
96
</ div >
73
- ) ) }
74
- </ div >
97
+ )
98
+ } ) }
75
99
</ div >
76
100
)
77
101
}
0 commit comments