Skip to content

Commit 12ca95c

Browse files
committed
refactor to fix event handling & propagation issues
1 parent b5470a6 commit 12ca95c

File tree

2 files changed

+40
-44
lines changed

2 files changed

+40
-44
lines changed

src/components/docImageClient.tsx

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,13 @@ export function DocImageClient({
2121
className,
2222
...props
2323
}: DocImageClientProps) {
24-
const handleContextMenu = (e: React.MouseEvent) => {
25-
e.preventDefault(); // Prevent default context menu
26-
// Allow right-click to open in new tab
27-
const link = document.createElement('a');
28-
link.href = imgPath;
29-
link.target = '_blank';
30-
link.rel = 'noreferrer';
31-
link.click();
32-
};
33-
34-
const handleClick = (e: React.MouseEvent) => {
35-
// If Ctrl/Cmd+click, open in new tab instead of lightbox
36-
if (e.ctrlKey || e.metaKey) {
37-
e.preventDefault();
38-
e.stopPropagation();
39-
window.open(imgPath, '_blank', 'noreferrer');
40-
}
41-
};
42-
4324
// Check if dimensions are valid (not NaN) for Next.js Image
4425
const isValidDimensions = !isNaN(width) && !isNaN(height) && width > 0 && height > 0;
4526

4627
// For external images or invalid dimensions, fall back to regular img tag
4728
if (src.startsWith('http') || !isValidDimensions) {
4829
return (
49-
<div onContextMenu={handleContextMenu} onClick={handleClick}>
30+
<a href={imgPath} target="_blank" rel="noreferrer">
5031
{/* eslint-disable-next-line @next/next/no-img-element */}
5132
<img
5233
src={src}
@@ -59,27 +40,25 @@ export function DocImageClient({
5940
className={className}
6041
{...props}
6142
/>
62-
</div>
43+
</a>
6344
);
6445
}
6546

6647
return (
67-
<div onContextMenu={handleContextMenu} onClick={handleClick}>
68-
<ImageLightbox src={src} alt={alt ?? ''} width={width} height={height}>
69-
<Image
70-
src={src}
71-
width={width}
72-
height={height}
73-
style={{
74-
width: '100%',
75-
height: 'auto',
76-
...style,
77-
}}
78-
className={className}
79-
alt={alt ?? ''}
80-
{...props}
81-
/>
82-
</ImageLightbox>
83-
</div>
48+
<ImageLightbox src={src} alt={alt ?? ''} width={width} height={height} imgPath={imgPath}>
49+
<Image
50+
src={src}
51+
width={width}
52+
height={height}
53+
style={{
54+
width: '100%',
55+
height: 'auto',
56+
...style,
57+
}}
58+
className={className}
59+
alt={alt ?? ''}
60+
{...props}
61+
/>
62+
</ImageLightbox>
8463
);
8564
}

src/components/imageLightbox.tsx

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,37 @@ interface ImageLightboxProps {
99
alt: string;
1010
children: React.ReactNode;
1111
height: number;
12+
imgPath: string;
1213
src: string;
1314
width: number;
1415
}
1516

16-
export function ImageLightbox({src, alt, width, height, children}: ImageLightboxProps) {
17+
export function ImageLightbox({src, alt, width, height, imgPath, children}: ImageLightboxProps) {
1718
const [open, setOpen] = useState(false);
1819

20+
const handleClick = (e: React.MouseEvent) => {
21+
// If Ctrl/Cmd+click, let the link handle it naturally (opens in new tab)
22+
if (e.ctrlKey || e.metaKey) {
23+
// Allow default link behavior
24+
return;
25+
}
26+
// Normal click - prevent link navigation and open lightbox
27+
e.preventDefault();
28+
setOpen(true);
29+
};
30+
1931
return (
2032
<Dialog.Root open={open} onOpenChange={setOpen}>
21-
<Dialog.Trigger asChild>
22-
<button className="cursor-pointer border-none bg-transparent p-0 block w-full">
23-
{children}
24-
</button>
25-
</Dialog.Trigger>
33+
{/* Custom trigger that handles modifier keys properly */}
34+
<a
35+
href={imgPath}
36+
target="_blank"
37+
rel="noreferrer"
38+
className="cursor-pointer border-none bg-transparent p-0 block w-full no-underline"
39+
onClick={handleClick}
40+
>
41+
{children}
42+
</a>
2643

2744
<Dialog.Portal>
2845
<Dialog.Overlay className="image-lightbox-overlay fixed inset-0 bg-black/80 backdrop-blur-sm z-50" />

0 commit comments

Comments
 (0)