"use client"; import * as React from "react"; import { cn } from "./lib/utils"; export interface GalleryImage { id: string; src: string; alt?: string; } export interface GalleryGridProps extends React.HTMLAttributes { images: GalleryImage[]; columns?: 2 | 3 | 4; } /** Image gallery grid: expandable fullscreen lightbox view. */ export function GalleryGrid({ images, columns = 3, className, ...props }: GalleryGridProps) { const [active, setActive] = React.useState(null); const colClass = { 2: "grid-cols-2", 3: "grid-cols-3", 4: "grid-cols-4" }[columns]; React.useEffect(() => { if (active === null) return; const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") setActive(null); if (e.key === "ArrowRight") setActive((a) => (a === null ? null : (a + 1) % images.length)); if (e.key === "ArrowLeft") setActive((a) => (a === null ? null : (a - 1 + images.length) % images.length)); }; document.addEventListener("keydown", onKey); return () => document.removeEventListener("keydown", onKey); }, [active, images.length]); return (
{images.map((img, idx) => ( ))}
{/* Lightbox */} {active !== null && images[active] && (
setActive(null)}>
e.stopPropagation()}> {/* eslint-disable-next-line @next/next/no-img-element */} {images[active].alt
{active + 1} / {images.length}
)}
); }