From 78a200c6eeaa93fbade91d17ccae3a264723b9e8 Mon Sep 17 00:00:00 2001 From: mnerv <24420859+mnerv@users.noreply.github.com> Date: Mon, 20 Apr 2026 01:34:25 +0200 Subject: [PATCH] Add image lightbox for item thumbnails and kit parts --- src/components/ItemCard.tsx | 39 +++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/components/ItemCard.tsx b/src/components/ItemCard.tsx index 09dd212..cc5ed09 100644 --- a/src/components/ItemCard.tsx +++ b/src/components/ItemCard.tsx @@ -25,6 +25,14 @@ export function ItemCard({ item, onEdit, onRemove }: Props) { const [hoverImg, setHoverImg] = useState(null) const [mousePos, setMousePos] = useState({ x: 0, y: 0 }) + const [lightboxImg, setLightboxImg] = useState(null) + + useEffect(() => { + if (!lightboxImg) return + function onKey(e: KeyboardEvent) { if (e.key === 'Escape') setLightboxImg(null) } + document.addEventListener('keydown', onKey) + return () => document.removeEventListener('keydown', onKey) + }, [lightboxImg]) // Preload part images into memCache so resolveImageSync works on hover useEffect(() => { @@ -52,7 +60,12 @@ export function ItemCard({ item, onEdit, onRemove }: Props) { > {/* Thumbnail */} {thumbnail ? ( - {item.name} + {item.name} setLightboxImg(thumbnail)} + /> ) : (
{ setHoverImg(resolveImageSync(p.image) ?? null); setMousePos({ x: e.clientX, y: e.clientY }) } : undefined} onMouseMove={p.image ? e => setMousePos({ x: e.clientX, y: e.clientY }) : undefined} onMouseLeave={p.image ? () => setHoverImg(null) : undefined} + onClick={p.image ? () => { const r = resolveImageSync(p.image); if (r) setLightboxImg(r) } : undefined} >
@@ -141,15 +155,32 @@ export function ItemCard({ item, onEdit, onRemove }: Props) { {/* Hover image preview */} {hoverImg && (
setLightboxImg(hoverImg)} > - + +
+ )} + + {/* Lightbox */} + {lightboxImg && ( +
setLightboxImg(null)} + > +
)}