/** * ArtworkViewer * * Fullscreen image modal. Opens on image click or keyboard F. * Controls: ESC to close, click outside to close. */ import React, { useEffect, useRef } from 'react'; export default function ArtworkViewer({ isOpen, onClose, artwork, presentLg, presentXl }) { const dialogRef = useRef(null); // Resolve best quality source const imgSrc = presentXl?.url || presentLg?.url || artwork?.thumbs?.xl?.url || artwork?.thumbs?.lg?.url || artwork?.thumb || null; // ESC to close useEffect(() => { if (!isOpen) return; function onKey(e) { if (e.key === 'Escape') onClose(); } window.addEventListener('keydown', onKey); return () => window.removeEventListener('keydown', onKey); }, [isOpen, onClose]); // Lock scroll while open useEffect(() => { if (isOpen) { document.body.style.overflow = 'hidden'; // Focus the dialog for accessibility requestAnimationFrame(() => dialogRef.current?.focus()); } else { document.body.style.overflow = ''; } return () => { document.body.style.overflow = ''; }; }, [isOpen]); if (!isOpen || !imgSrc) return null; return (