93 lines
No EOL
2.1 KiB
TypeScript
93 lines
No EOL
2.1 KiB
TypeScript
'use client'
|
|
|
|
import styles from './styles.module.scss'
|
|
import Image, { StaticImageData } from 'next/image'
|
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
|
import { AutoScroll } from '@/components/Gallery/AutoScroll'
|
|
import { Fullscreen } from '@/components/Gallery/Fullscreen'
|
|
|
|
type ImageType = {
|
|
src: string,
|
|
width: number,
|
|
height: number
|
|
} | StaticImageData
|
|
|
|
export type GalleryItem = {
|
|
id: string;
|
|
thumbnail: ImageType ;
|
|
image: ImageType;
|
|
alt: string;
|
|
}
|
|
|
|
type GalleryItemProps = {
|
|
thumbnail: ImageType,
|
|
alt: string,
|
|
onClick?: () => void
|
|
}
|
|
|
|
type GalleryProps = {
|
|
items: GalleryItem[];
|
|
}
|
|
|
|
const GalleryItem = ({ thumbnail, alt, onClick }: GalleryItemProps) => {
|
|
return (
|
|
<Image
|
|
onClick={onClick}
|
|
className={styles.item}
|
|
src={thumbnail.src}
|
|
height={thumbnail.height}
|
|
width={thumbnail.width}
|
|
alt={alt}
|
|
unoptimized={true}
|
|
/>
|
|
)
|
|
}
|
|
|
|
export const Gallery = ({ items }: GalleryProps) => {
|
|
const [displayFullscreen, setDisplayFullscreen] = useState(false)
|
|
const [idx, setIdx] = useState(0)
|
|
const [isScrolling, setIsScrolling] = useState(true)
|
|
const displayImage = useCallback((n: number) => {
|
|
setIdx(n);
|
|
setDisplayFullscreen(true);
|
|
setIsScrolling(false)
|
|
}, [setDisplayFullscreen, setIdx, setIsScrolling]);
|
|
|
|
const next = useCallback(() => {
|
|
setIdx((idx + 1) % items.length)
|
|
}, [idx, setIdx, items])
|
|
|
|
|
|
if(items.length == 0) {
|
|
return null;
|
|
}
|
|
|
|
const { image, alt } = items[idx]
|
|
return (
|
|
<>
|
|
<AutoScroll
|
|
isScrolling={isScrolling}
|
|
onTouch={() => setIsScrolling(false)}
|
|
>
|
|
<div className={styles.container}>
|
|
{items.map((item, index) =>
|
|
<GalleryItem
|
|
onClick={() => displayImage(index)}
|
|
key={item.id}
|
|
thumbnail={item.thumbnail}
|
|
alt={item.alt}
|
|
/>)}
|
|
</div>
|
|
</AutoScroll>
|
|
|
|
<Fullscreen
|
|
display={displayFullscreen}
|
|
image={image}
|
|
closeClicked={() => setDisplayFullscreen(false)}
|
|
nextClicked={next}
|
|
/>
|
|
|
|
</>
|
|
|
|
)
|
|
} |