Files
AboutMe/components/zoomable-image.tsx
T
2026-08-19 18:05:20 +08:00

66 lines
1.6 KiB
TypeScript

"use client";
import Image from "next/image";
import {
Dialog,
DialogClose,
DialogContent,
DialogTitle,
DialogTrigger
} from "@/components/ui/dialog";
type ZoomableImageProps = {
src: string;
alt: string;
width: number;
height: number;
className?: string;
};
/** 点击图片放大预览,再点任意区域关闭 */
export const ZoomableImage = ({
src,
alt,
width,
height,
className
}: ZoomableImageProps) => {
const imageSrc = src || "/placeholder.svg";
const previewLabel = alt || "图片预览";
return (
<Dialog>
<DialogTrigger
className={`block w-full cursor-zoom-in border-0 bg-transparent p-0 ${className ?? ""}`}
aria-label={alt ? `放大查看:${alt}` : "放大查看图片"}
>
<Image
src={imageSrc}
alt={alt}
width={width}
height={height}
className="h-auto w-full"
/>
</DialogTrigger>
<DialogContent
showCloseButton={false}
overlayClassName="cursor-zoom-out bg-background/90 backdrop-blur-sm"
className="w-full max-w-none border-0 bg-transparent p-0 px-2 shadow-none ring-0 md:w-auto md:px-0"
>
<DialogTitle className="sr-only">{previewLabel}</DialogTitle>
{/* 点击预览图本身也会关闭 */}
<DialogClose className="block w-full cursor-zoom-out border-0 bg-transparent p-0 md:w-[80vw]">
<Image
src={imageSrc}
alt={alt}
width={width * 2}
height={height * 2}
className="h-auto max-h-svh w-full object-contain"
/>
</DialogClose>
</DialogContent>
</Dialog>
);
};