Support optional captions
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
<span class="for-screen-reader">Zoom background image</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -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 %>
|
||||
<img src="" class="lightbox__image" data-lightbox-target="zoomedImage" />
|
||||
|
||||
<figure class="lightbox__figure">
|
||||
<img src="" class="lightbox__image" data-lightbox-target="zoomedImage" />
|
||||
<figcaption class="lightbox__caption" data-lightbox-target="caption"></figcaption>
|
||||
</figure>
|
||||
|
||||
<div class="lightbox__btn">
|
||||
<button class="btn fill-white" title="Close (esc)" data-action="dialog#close keydown.esc->dialog#close:stop" data-controller="hotkey">
|
||||
|
||||
Reference in New Issue
Block a user