30 lines
1.9 KiB
JavaScript
30 lines
1.9 KiB
JavaScript
'use client';
|
|
import { useEffect, useState } from 'react';
|
|
import { X, ChevronLeft, ChevronRight } from 'lucide-react';
|
|
|
|
export default function MediaGallery({ images, title }) {
|
|
const [active, setActive] = useState(null);
|
|
useEffect(() => {
|
|
if (active === null) return;
|
|
const onKey = (event) => {
|
|
if (event.key === 'Escape') setActive(null);
|
|
if (event.key === 'ArrowLeft') setActive((active + 1) % images.length);
|
|
if (event.key === 'ArrowRight') setActive((active - 1 + images.length) % images.length);
|
|
};
|
|
document.body.style.overflow = 'hidden';
|
|
window.addEventListener('keydown', onKey);
|
|
return () => { document.body.style.overflow = ''; window.removeEventListener('keydown', onKey); };
|
|
}, [active, images.length]);
|
|
if (!images.length) return null;
|
|
return <>
|
|
<div className="media-gallery">{images.map((image, index) => <button key={image.id} type="button" onClick={() => setActive(index)} aria-label={`نمایش تصویر ${index + 1} از ${title}`}><img src={image.url} alt={image.alt || `${title}، تصویر ${index + 1}`} loading={index ? 'lazy' : 'eager'}/></button>)}</div>
|
|
{active !== null && <div className="lightbox" role="dialog" aria-modal="true" aria-label={`گالری ${title}`} onClick={(event) => { if (event.target === event.currentTarget) setActive(null); }}>
|
|
<button className="lightbox-close" onClick={() => setActive(null)} aria-label="بستن گالری"><X/></button>
|
|
{images.length > 1 && <button className="lightbox-prev" onClick={() => setActive((active - 1 + images.length) % images.length)} aria-label="تصویر قبلی"><ChevronRight/></button>}
|
|
<img src={images[active].url} alt={images[active].alt || title}/>
|
|
{images.length > 1 && <button className="lightbox-next" onClick={() => setActive((active + 1) % images.length)} aria-label="تصویر بعدی"><ChevronLeft/></button>}
|
|
<span>{active + 1} / {images.length}</span>
|
|
</div>}
|
|
</>;
|
|
}
|