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)} + > +
)}