2024-05-17 11:03:00 -07:00
|
|
|
import { useEffect, useState } from "react";
|
|
|
|
|
import clsx from "clsx";
|
2024-04-07 21:52:59 +03:00
|
|
|
|
|
|
|
|
type HTMLImageElementProps = React.ComponentProps<"img">;
|
|
|
|
|
|
|
|
|
|
function ZoomableImage(props: HTMLImageElementProps) {
|
2024-05-17 11:03:00 -07:00
|
|
|
const [modalOpen, setModalOpen] = useState(false);
|
|
|
|
|
const [zoom, setZoom] = useState(false);
|
|
|
|
|
|
|
|
|
|
const openModal = () => {
|
|
|
|
|
setZoom(false);
|
|
|
|
|
setModalOpen(true);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const closeModal = () => {
|
|
|
|
|
setModalOpen(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
function handleEscKey(e: KeyboardEvent) {
|
|
|
|
|
if (modalOpen && e.key === "Escape") {
|
|
|
|
|
closeModal();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
document.addEventListener("keydown", handleEscKey);
|
|
|
|
|
return () => {
|
|
|
|
|
document.removeEventListener("keydown", handleEscKey);
|
|
|
|
|
};
|
|
|
|
|
}, [modalOpen]);
|
|
|
|
|
|
2024-04-07 21:52:59 +03:00
|
|
|
return (
|
2024-05-17 11:03:00 -07:00
|
|
|
<div>
|
2024-05-17 21:52:33 +03:00
|
|
|
<img
|
|
|
|
|
{...props}
|
|
|
|
|
onClick={openModal}
|
2024-06-03 10:56:26 -07:00
|
|
|
className={clsx("cursor-pointer object-contain", props.className)}
|
2024-05-17 21:52:33 +03:00
|
|
|
/>
|
2024-05-17 11:03:00 -07:00
|
|
|
{modalOpen && (
|
|
|
|
|
<div
|
|
|
|
|
className={clsx(
|
|
|
|
|
"fixed inset-0 z-50 flex justify-center bg-black bg-opacity-75 overflow-auto p-16",
|
|
|
|
|
{
|
|
|
|
|
"items-center": !zoom,
|
|
|
|
|
"items-baseline": zoom,
|
|
|
|
|
},
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
<span
|
|
|
|
|
className="absolute top-4 right-4 text-white text-4xl cursor-pointer"
|
|
|
|
|
onClick={closeModal}
|
|
|
|
|
>
|
|
|
|
|
×
|
|
|
|
|
</span>
|
|
|
|
|
<img
|
|
|
|
|
{...props}
|
|
|
|
|
onClick={() => setZoom(!zoom)}
|
|
|
|
|
className={clsx({
|
|
|
|
|
"min-h-full object-contain h-full w-full m-0 cursor-zoom-in max-h-full max-w-full":
|
|
|
|
|
!zoom,
|
|
|
|
|
"min-h-full object-contain m-0 cursor-zoom-out max-w-none max-h-none mr-auto ml-auto":
|
|
|
|
|
zoom,
|
|
|
|
|
})}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
2024-04-07 21:52:59 +03:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export { ZoomableImage };
|