diff --git a/app/assets/stylesheets/lightbox.css b/app/assets/stylesheets/lightbox.css index a5e5cec2d..59fd0cbc0 100644 --- a/app/assets/stylesheets/lightbox.css +++ b/app/assets/stylesheets/lightbox.css @@ -1,6 +1,7 @@ @layer components { .lightbox { --dialog-duration: 350ms; + --lightbox-padding: 3vmin; background-color: transparent; block-size: 100dvh; @@ -11,7 +12,8 @@ max-height: unset; max-width: unset; overflow: hidden; - padding: var(--block-space-half) var(--inline-space); + padding: var(--lightbox-padding); + text-align: center; &::backdrop { -webkit-backdrop-filter: blur(16px); @@ -19,13 +21,6 @@ background-color: oklch(var(--lch-black) / 50%); } - img { - animation: slide-down var(--dialog-duration); - animation-fill-mode: forwards; - display: block; - margin: auto; - } - /* Closed state */ &, &::backdrop { @@ -43,7 +38,7 @@ opacity: 0; } - img { + .lightbox__figure { animation: slide-up var(--dialog-duration); } } @@ -54,10 +49,32 @@ position: absolute; } + .lightbox__figure { + align-self: stretch; + animation-fill-mode: forwards; + animation: slide-down var(--dialog-duration); + display: flex; + flex-direction: column; + gap: var(--lightbox-padding); + margin: 0 auto; + max-block-size: 100%; + + img { + object-fit: contain; + } + } + + .lightbox__caption { + color: var(--color-ink-inverted); + + &:empty { + display: none; + } + } + .lightbox__image { - grid-area: 1/1; - max-inline-size: calc(100dvw - (var(--inline-space) * 2)); - max-block-size: calc(100dvh - (var(--block-space) * 2)); + flex: 1; + min-block-size: 0; } /* Prevent body from scrolling when lightbox is open */ diff --git a/app/javascript/controllers/lightbox_controller.js b/app/javascript/controllers/lightbox_controller.js index 9032bcb02..b39566b44 100644 --- a/app/javascript/controllers/lightbox_controller.js +++ b/app/javascript/controllers/lightbox_controller.js @@ -1,7 +1,7 @@ import { Controller } from "@hotwired/stimulus" export default class extends Controller { - static targets = [ "image", "dialog", "zoomedImage" ] + static targets = [ "caption", "image", "dialog", "zoomedImage" ] connect() { this.dialogTarget.addEventListener('transitionend', this.handleTransitionEnd.bind(this)) @@ -25,10 +25,18 @@ export default class extends Controller { reset() { this.zoomedImageTarget.src = "" + this.captionTarget.innerText = "" this.dispatch('closed') } #set(target) { - this.zoomedImageTarget.src = target.href + const imageSrc = target.href + const caption = target.dataset.lightboxCaptionValue + + this.zoomedImageTarget.src = imageSrc + + if (caption) { + this.captionTarget.innerText = caption + } } } diff --git a/app/views/cards/display/perma/_background.html.erb b/app/views/cards/display/perma/_background.html.erb index d8c3203a8..c591b6238 100644 --- a/app/views/cards/display/perma/_background.html.erb +++ b/app/views/cards/display/perma/_background.html.erb @@ -4,4 +4,3 @@ Zoom background image <% end %> <% end %> - \ No newline at end of file diff --git a/app/views/layouts/_lightbox.html.erb b/app/views/layouts/_lightbox.html.erb index 085b1c10e..bd99bf3b3 100644 --- a/app/views/layouts/_lightbox.html.erb +++ b/app/views/layouts/_lightbox.html.erb @@ -1,6 +1,10 @@ <%= tag.dialog class:"lightbox", aria: { label: "Image Viewer (Press escape to close)" }, data: { controller: "dialog", dialog_target: "dialog", dialog_modal_value: "true", lightbox_target: "dialog" } do %> - + +