// retoor <retoor@molodetz.nl>
import { Component } from "./Component.js";
import { assetUrl } from "../assetVersion.js";
const LB_CSS_ID = "lightbox-css";
export class AppLightbox extends Component {
connectedCallback() {
if (this._built) {
return;
}
this._built = true;
this._ensureCss();
this.lastFocus = null;
this.bodyOverflow = "";
this.build();
this.bind();
}
_ensureCss() {
if (document.getElementById(LB_CSS_ID)) return;
const link = document.createElement("link");
link.id = LB_CSS_ID;
link.rel = "stylesheet";
link.href = assetUrl("/static/css/lightbox.css");
document.head.appendChild(link);
}
build() {
const overlay = document.createElement("div");
overlay.className = "lightbox-overlay";
overlay.setAttribute("role", "dialog");
overlay.setAttribute("aria-modal", "true");
overlay.setAttribute("aria-label", "Image viewer");
overlay.innerHTML =
'<button type="button" class="lightbox-close" aria-label="Close">&times;</button>' +
'<img class="lightbox-image" src="" alt="">';
this.appendChild(overlay);
this.overlay = overlay;
this.image = overlay.querySelector(".lightbox-image");
this.closeBtn = overlay.querySelector(".lightbox-close");
}
bind() {
this.overlay.addEventListener("click", (e) => {
if (e.target !== this.image) this.close();
});
this.closeBtn.addEventListener("click", () => this.close());
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" && this.overlay.classList.contains("visible")) {
e.preventDefault();
this.close();
}
});
this.overlay.addEventListener("keydown", (e) => {
if (e.key === "Tab" && this.overlay.classList.contains("visible")) {
e.preventDefault();
this.closeBtn.focus();
}
});
document.addEventListener("click", (e) => {
const thumb = e.target.closest("img[data-lightbox]");
if (!thumb || thumb.closest("a")) return;
e.preventDefault();
this.open(thumb.dataset.full || thumb.currentSrc || thumb.src, { alt: thumb.alt });
});
}
open(src, options) {
const opts = options || {};
if (!src) return;
this.image.src = src;
this.image.alt = opts.alt || "Enlarged image";
this.lastFocus = document.activeElement;
this.bodyOverflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
this.overlay.classList.add("visible");
setTimeout(() => this.closeBtn.focus(), 20);
}
close() {
this.overlay.classList.remove("visible");
this.image.src = "";
document.body.style.overflow = this.bodyOverflow;
if (this.lastFocus && this.lastFocus.focus) this.lastFocus.focus();
}
}
customElements.define("dp-lightbox", AppLightbox);