1- import React , { ComponentProps } from "react"
1+ import React , { ComponentProps , useEffect , useRef , useState } from "react"
22import { images } from "../../../utils/conf-images"
33import Zoom from "react-medium-image-zoom"
44import "react-medium-image-zoom/dist/styles.css"
@@ -15,63 +15,87 @@ function chunk<T>(arr: T[], len: number): T[][] {
1515 return chunks
1616}
1717
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+
1948 return (
2049 < Zoom >
2150 < img
2251 alt = { alt }
2352 className = "object-cover aspect-video w-full hover:opacity-75 rounded-md"
2453 src = { src }
54+ ref = { cardRef }
2555 />
2656 </ Zoom >
2757 )
2858}
2959
3060const 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 )
3165 return (
3266 < 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 ) }
5288 </ 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 ) }
7094 </ div >
7195 </ div >
7296 </ div >
73- ) ) }
74- </ div >
97+ )
98+ } ) }
7599 </ div >
76100 )
77101}
0 commit comments