Klick aufs Artikelbild oeffnet es bildschirmfuellend; Schliessen per Knopf, Klick auf den Hintergrund oder Escape. Neue Lightbox-Komponente (Portal an <body>), im bestehenden Farbschema. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
33 lines
1.2 KiB
JavaScript
33 lines
1.2 KiB
JavaScript
import { useEffect } from "react";
|
||
import { createPortal } from "react-dom";
|
||
import Icon from "./Icon";
|
||
|
||
/**
|
||
* Bildschirmfüllende Bildansicht. Schließt per Schließen-Knopf, Klick auf den
|
||
* Hintergrund oder Escape. Wird per Portal an den <body> gehängt, damit es über
|
||
* allem liegt und nicht von Containern (overflow) abgeschnitten wird.
|
||
*/
|
||
export default function Lightbox({ src, alt, onClose }) {
|
||
useEffect(() => {
|
||
function onKey(e) { if (e.key === "Escape") onClose(); }
|
||
document.addEventListener("keydown", onKey);
|
||
const vorher = document.body.style.overflow;
|
||
document.body.style.overflow = "hidden";
|
||
return () => {
|
||
document.removeEventListener("keydown", onKey);
|
||
document.body.style.overflow = vorher;
|
||
};
|
||
}, [onClose]);
|
||
|
||
return createPortal(
|
||
<div className="lightbox" onClick={onClose} role="dialog" aria-modal="true">
|
||
<button className="lightbox-close" onClick={onClose} title="Schließen" aria-label="Schließen">
|
||
<Icon name="close" size={20} />
|
||
</button>
|
||
{/* Klick aufs Bild soll nicht schließen – nur der Hintergrund. */}
|
||
<img className="lightbox-img" src={src} alt={alt || ""} onClick={(e) => e.stopPropagation()} />
|
||
</div>,
|
||
document.body,
|
||
);
|
||
}
|