Add image lightbox: click any image to view full-screen
Deploy to LXC / deploy (push) Successful in 20s

Reusable ImageLightbox component with dark overlay, close on
click/Escape, zoom-in cursor on thumbnails. Applied to both
device and component detail pages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-09 16:52:19 +07:00
parent 99371648be
commit 2695de25a3
3 changed files with 48 additions and 2 deletions
+10 -1
View File
@@ -4,6 +4,9 @@
import { formatDate, timeAgo } from '$lib/utils/date.js';
import ImageUpload from '$lib/components/ui/ImageUpload.svelte';
import DocumentUpload from '$lib/components/ui/DocumentUpload.svelte';
import ImageLightbox from '$lib/components/ui/ImageLightbox.svelte';
let lightboxSrc = $state<string | null>(null);
let { data, form } = $props();
const c = $derived(data.component);
@@ -100,7 +103,9 @@
<div class="grid gap-2 sm:grid-cols-3">
{#each data.images as img}
<div class="group relative overflow-hidden rounded-md">
<img src={img.filePath} alt={img.caption ?? c.title} class="h-32 w-full object-cover" />
<button type="button" onclick={() => (lightboxSrc = img.filePath)} class="w-full">
<img src={img.filePath} alt={img.caption ?? c.title} class="h-32 w-full cursor-zoom-in object-cover" />
</button>
<form method="POST" action="?/deleteImage" use:enhance
class="absolute top-1 right-1 hidden group-hover:block">
<input type="hidden" name="imageId" value={img.id} />
@@ -348,3 +353,7 @@
</div>
</div>
</div>
{#if lightboxSrc}
<ImageLightbox src={lightboxSrc} alt={c.title} onclose={() => (lightboxSrc = null)} />
{/if}
+10 -1
View File
@@ -3,6 +3,9 @@
import { DEVICE_CONDITIONS, DEVICE_LOG_TYPES } from '$lib/constants.js';
import ImageUpload from '$lib/components/ui/ImageUpload.svelte';
import DocumentUpload from '$lib/components/ui/DocumentUpload.svelte';
import ImageLightbox from '$lib/components/ui/ImageLightbox.svelte';
let lightboxSrc = $state<string | null>(null);
import { formatDate, timeAgo } from '$lib/utils/date.js';
let { data, form } = $props();
@@ -160,7 +163,9 @@
<div class="grid gap-2 sm:grid-cols-3">
{#each data.images as img}
<div class="group relative overflow-hidden rounded-md">
<img src={img.filePath} alt={img.caption ?? data.device.title} class="h-32 w-full object-cover" />
<button type="button" onclick={() => (lightboxSrc = img.filePath)} class="w-full">
<img src={img.filePath} alt={img.caption ?? data.device.title} class="h-32 w-full cursor-zoom-in object-cover" />
</button>
<form method="POST" action="?/deleteImage" use:enhance
class="absolute top-1 right-1 hidden group-hover:block">
<input type="hidden" name="imageId" value={img.id} />
@@ -707,3 +712,7 @@
</div>
</div>
</div>
{#if lightboxSrc}
<ImageLightbox src={lightboxSrc} alt={data.device.title} onclose={() => (lightboxSrc = null)} />
{/if}