From 0e24bfc8c5db1726841964fb7f12c8cc47e0d373 Mon Sep 17 00:00:00 2001 From: Steve Ross Date: Fri, 6 Feb 2026 21:42:37 +0000 Subject: [PATCH] add simple lightbox --- web/app/themes/badegg/resources/css/app.scss | 9 +- .../css/components/_BadEggLightbox.scss | 92 +++++++++++++++++++ web/app/themes/badegg/resources/js/app.js | 5 +- .../badegg/resources/js/lib/BadEggLightbox.js | 81 ++++++++++++++++ 4 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 web/app/themes/badegg/resources/css/components/_BadEggLightbox.scss create mode 100644 web/app/themes/badegg/resources/js/lib/BadEggLightbox.js diff --git a/web/app/themes/badegg/resources/css/app.scss b/web/app/themes/badegg/resources/css/app.scss index 5227b5e8..fe4d6373 100644 --- a/web/app/themes/badegg/resources/css/app.scss +++ b/web/app/themes/badegg/resources/css/app.scss @@ -9,15 +9,16 @@ @use "plugins/contact-form-7"; @use "plugins/mce"; -// Sections -@use "sections/header"; -@use "sections/footer"; - // Components @use "components/block"; @use "components/forms"; @use "components/button"; @use "components/card"; +@use "components/BadEggLightbox"; + +// Sections +@use "sections/header"; +@use "sections/footer"; // Page Styles @use "views/page"; diff --git a/web/app/themes/badegg/resources/css/components/_BadEggLightbox.scss b/web/app/themes/badegg/resources/css/components/_BadEggLightbox.scss new file mode 100644 index 00000000..75a116a2 --- /dev/null +++ b/web/app/themes/badegg/resources/css/components/_BadEggLightbox.scss @@ -0,0 +1,92 @@ +#badegg-lightbox { + &-overlay, + &-image, + &-close { + transition: all 300ms ease; + opacity: 0; + } + + &-modal { + position: fixed; + inset: 0; + z-index: 9999; + padding: 3em; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + &-overlay { + position: absolute; + inset: 0; + background: rgba(white, 0.5); + + .open & { + opacity: 1; + backdrop-filter: blur(1em); + } + } + + &-image { + position: relative; + z-index: 2; + object-fit: contain; + max-width: 100%; + max-height: 100%; + width: auto; + height: auto; + transform: scale(0.8); + + .open & { + transform: none; + opacity: 1; + } + } + + &-close { + position: absolute; + z-index: 3; + top: 1em; + right: 1em; + display: block; + appearance: none; + border: none; + background: transparent; + border: 2px solid black; + border-radius: 50%; + width: 2em; + height: 2em; + cursor: pointer; + transform: scale(0.01) rotate(-360deg); + + .open & { + opacity: 1; + transform: none; + } + + &:hover, + &:focus { + transform: scale(1.2) rotate(90deg); + } + + .admin-bar & { + top: calc(1em + 32px); + + @media (max-width: 782px) { + top: calc(1em + 46px); + } + } + + svg { + display: block; + width: 100%; + stroke: black; + stroke-width: 5; + } + + &:focus { + outline: 2px dashed red; + } + } +} diff --git a/web/app/themes/badegg/resources/js/app.js b/web/app/themes/badegg/resources/js/app.js index 676f0f5d..3039c602 100644 --- a/web/app/themes/badegg/resources/js/app.js +++ b/web/app/themes/badegg/resources/js/app.js @@ -5,7 +5,8 @@ import.meta.glob([ import Header from '../views/sections/header/header.js'; import LazyLoad from './lib/Lazy.js'; +import BadEggLightbox from './lib/BadEggLightbox'; -LazyLoad(); Header(); - +LazyLoad(); +BadEggLightbox(); diff --git a/web/app/themes/badegg/resources/js/lib/BadEggLightbox.js b/web/app/themes/badegg/resources/js/lib/BadEggLightbox.js new file mode 100644 index 00000000..f59d8453 --- /dev/null +++ b/web/app/themes/badegg/resources/js/lib/BadEggLightbox.js @@ -0,0 +1,81 @@ +export default function BadEggLightbox() +{ + const lightboxes = document.querySelectorAll(".badegg-lightbox"); + + if(!lightboxes) return; + + lightboxes.forEach(lightbox => { + const fullSize = lightbox.getAttribute('href'); + const thumbnail = lightbox.querySelector("img"); + + lightbox.addEventListener("click", (e) => { + e.preventDefault(); + // console.log(e); + + modal(fullSize, thumbnail); + }); + + }); +} + +function modal(src = '', img = '') +{ + if(!src || !img) { + alert('Error: No image defined'); + return; + } + + const title = img.getAttribute("title") || ''; + const alt = img.getAttribute("alt") || ''; + + const body = document.querySelector("body"); + + let template = ` + ${alt} + +
+ `; + + let modal = document.createElement("div"); + + modal.setAttribute("id", "badegg-lightbox-modal"); + modal.setAttribute("aria-modal", "true"); + modal.innerHTML = template; + + body.appendChild(modal); + + setTimeout(() => modal.classList.add("open"), 100); + + document.getElementById("badegg-lightbox-image").focus(); + + modalDeleteListener(); +} + +function modalDeleteListener() +{ + const modal = document.getElementById("badegg-lightbox-modal"); + + if(!modal) return; + + const modalClose = document.getElementById("badegg-lightbox-close"); + const modalOverlay = document.getElementById("badegg-lightbox-overlay"); + + modalClose.addEventListener("click", (e) => { + modal.remove(); + }); + + modalOverlay.addEventListener("click", (e) => { + modal.remove(); + }); + + document.addEventListener("keydown", (e) => { + if(e.key === 'Escape') { + modal.remove(); + } + }); +}