"use client"; import { useState, useEffect } from "react"; import { createPortal } from "react-dom"; import { X, ChevronLeft, ChevronRight } from "lucide-react"; import { AnimatePresence, motion } from "framer-motion"; import Image from "next/image"; import { cn } from "@/lib/cn"; interface PerformanceGalleryProps { images: string[]; /** 当无真实图时,用此颜色生成占位 */ themeColor?: string; /** 占位标签(如 "定妆照"、"表演中") */ placeholderLabels?: string[]; } const DEFAULT_LABELS = ["定妆照", "表演中", "幕后花絮", "舞台 1", "舞台 2", "未公开"]; export default function PerformanceGallery({ images, themeColor = "#8b5cf6", placeholderLabels = DEFAULT_LABELS, }: PerformanceGalleryProps) { const [lightboxIndex, setLightboxIndex] = useState(null); const [mounted, setMounted] = useState(false); useEffect(() => setMounted(true), []); // ESC 关闭 useEffect(() => { if (lightboxIndex == null) return; const handler = (e: KeyboardEvent) => { if (e.key === "Escape") setLightboxIndex(null); if (e.key === "ArrowLeft") setLightboxIndex((i) => (i! > 0 ? i! - 1 : images.length - 1)); if (e.key === "ArrowRight") setLightboxIndex((i) => (i! < images.length - 1 ? i! + 1 : 0)); }; window.addEventListener("keydown", handler); const prev = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { window.removeEventListener("keydown", handler); document.body.style.overflow = prev; }; }, [lightboxIndex, images.length]); return ( <>
{images.map((src, i) => ( ))}

点击图片打开大图查看

{/* Lightbox */} {mounted && createPortal( {lightboxIndex !== null && ( {/* 左右切换 */} {images.length > 1 && ( <> )} {/* 图片本体 */} {images[lightboxIndex] ? ( {`表演图 ) : (

{placeholderLabels[lightboxIndex] || `Image ${lightboxIndex + 1}`}

)}
{/* 索引 */}
{lightboxIndex + 1} / {images.length}
)}
, document.body, )} ); }