Files
20260512-skg-tk/web/components/nodes/hover-preview.tsx

58 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
/**
* 视觉类节点统一 hover 大预览:
* - 浮在缩略图正上方bottom: calc(100% + 10px),居中),跟随 ReactFlow viewport 缩放
* - 固定 280px 宽,原比例高
* - 视频自动播放muted loop图片静态
* - pointer-events-none不阻挡同行/邻近交互
* - 用法:<div className="group ..."> ... <HoverPreview ... /> </div>
*/
interface Props {
imgSrc?: string
videoSrc?: string
poster?: string
aspect: string
label?: string
caption?: string
borderClass?: string
width?: number
}
export function HoverPreview({
imgSrc, videoSrc, poster, aspect,
label, caption,
borderClass = "border-violet-300/55",
width = 280,
}: Props) {
return (
<div
className="pointer-events-none absolute opacity-0 group-hover:opacity-100 scale-95 group-hover:scale-100 transition-all duration-150 z-[60]"
style={{
bottom: "calc(100% + 10px)",
left: "50%",
transform: "translateX(-50%)",
transformOrigin: "bottom center",
}}
>
<div className={`rounded-lg overflow-hidden border-2 bg-black shadow-2xl ${borderClass}`} style={{ width }}>
<div style={{ aspectRatio: aspect }}>
{videoSrc ? (
<video src={videoSrc} poster={poster} muted loop playsInline autoPlay className="w-full h-full object-cover" />
) : imgSrc ? (
<img src={imgSrc} alt="" className="w-full h-full object-cover" />
) : (
<div className="w-full h-full bg-black/40" />
)}
</div>
{(label || caption) && (
<div className="px-2 py-1 bg-black/80 text-white text-[10.5px] flex items-center justify-between">
{label && <span>{label}</span>}
{caption && <span className="text-white/60 font-mono">{caption}</span>}
</div>
)}
</div>
</div>
)
}