refactor(lightbox): move state to html and use a more robust global click listener
All checks were successful
Deploy Theme / deploy (push) Successful in 14s
All checks were successful
Deploy Theme / deploy (push) Successful in 14s
This commit is contained in:
34
default.hbs
34
default.hbs
@@ -2,6 +2,9 @@
|
|||||||
<html lang="{{@site.lang}}"
|
<html lang="{{@site.lang}}"
|
||||||
x-data="{
|
x-data="{
|
||||||
theme: localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'),
|
theme: localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'),
|
||||||
|
mobileMenuOpen: false,
|
||||||
|
lightboxOpen: false,
|
||||||
|
lightboxImage: '',
|
||||||
init() {
|
init() {
|
||||||
$watch('theme', val => {
|
$watch('theme', val => {
|
||||||
localStorage.setItem('theme', val);
|
localStorage.setItem('theme', val);
|
||||||
@@ -9,8 +12,19 @@
|
|||||||
});
|
});
|
||||||
document.documentElement.setAttribute('data-theme', this.theme);
|
document.documentElement.setAttribute('data-theme', this.theme);
|
||||||
document.documentElement.classList.remove('hidden');
|
document.documentElement.classList.remove('hidden');
|
||||||
|
},
|
||||||
|
handleGlobalClick(e) {
|
||||||
|
if (this.lightboxOpen && e.target.closest('#lightbox')) return;
|
||||||
|
|
||||||
|
const img = e.target.closest('img');
|
||||||
|
if (img && img.src && !img.closest('a') && img.closest('.kg-image-card, .post-content, .post-feature-image')) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.lightboxImage = img.src;
|
||||||
|
this.lightboxOpen = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}"
|
}"
|
||||||
|
@click.window="handleGlobalClick($event)"
|
||||||
:data-theme="theme"
|
:data-theme="theme"
|
||||||
class="hidden">
|
class="hidden">
|
||||||
<head>
|
<head>
|
||||||
@@ -27,14 +41,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body class="{{body_class}} font-sans antialiased" hx-boost="true">
|
<body class="{{body_class}} font-sans antialiased" hx-boost="true">
|
||||||
|
|
||||||
<div class="min-h-screen flex flex-col"
|
<div class="min-h-screen flex flex-col">
|
||||||
x-data="{ mobileMenuOpen: false, lightboxOpen: false, lightboxImage: '' }"
|
|
||||||
@click="const img = $event.target.closest('.kg-image-card img, .post-content img, .post-feature-image img');
|
|
||||||
if (img && img.src && !img.closest('a')) {
|
|
||||||
$event.preventDefault();
|
|
||||||
lightboxImage = img.src;
|
|
||||||
lightboxOpen = true;
|
|
||||||
}">
|
|
||||||
{{> header}}
|
{{> header}}
|
||||||
|
|
||||||
<main class="flex-grow">
|
<main class="flex-grow">
|
||||||
@@ -44,16 +51,7 @@
|
|||||||
{{> footer}}
|
{{> footer}}
|
||||||
|
|
||||||
{{> mobile-menu}}
|
{{> mobile-menu}}
|
||||||
|
{{> lightbox}}
|
||||||
<div id="lightbox"
|
|
||||||
x-show="lightboxOpen"
|
|
||||||
x-transition
|
|
||||||
@click="lightboxOpen = false"
|
|
||||||
class="fixed inset-0 bg-black bg-opacity-80 z-50 flex items-center justify-center"
|
|
||||||
x-cloak>
|
|
||||||
<button @click.stop="lightboxOpen = false" class="absolute top-4 right-4 text-white text-3xl">×</button>
|
|
||||||
<img :src="lightboxImage" alt="Lightbox image" class="max-w-full max-h-full" @click.stop>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ghost_foot}}
|
{{ghost_foot}}
|
||||||
|
|||||||
26
partials/lightbox.hbs
Normal file
26
partials/lightbox.hbs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<div id="lightbox"
|
||||||
|
x-show="lightboxOpen"
|
||||||
|
x-transition:enter="transition ease-out duration-300"
|
||||||
|
x-transition:enter-start="opacity-0"
|
||||||
|
x-transition:enter-end="opacity-100"
|
||||||
|
x-transition:leave="transition ease-in duration-200"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="lightboxOpen = false"
|
||||||
|
@keydown.escape.window="lightboxOpen = false"
|
||||||
|
class="fixed inset-0 bg-black/90 z-50 flex items-center justify-center p-4"
|
||||||
|
x-cloak>
|
||||||
|
|
||||||
|
<button @click.stop="lightboxOpen = false"
|
||||||
|
class="absolute top-6 right-6 text-white/70 hover:text-white transition-colors duration-200 z-50">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-10 h-10">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="relative max-w-7xl max-h-full flex items-center justify-center" @click.stop>
|
||||||
|
<img :src="lightboxImage"
|
||||||
|
alt="Lightbox image"
|
||||||
|
class="max-w-full max-h-[90vh] object-contain shadow-2xl rounded-sm">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
Reference in New Issue
Block a user