fix(chat): 修复图片放大与工具详情浮层被覆盖及定位错乱
图片放大(ImageLightbox)与工具详情(ToolDetailModal)渲染在虚拟化消息行内,行元素的 transform 成为 fixed 后代的包含块,导致遮罩只覆盖行区域、工具栏定位偏移、其他内容叠在其上。 改用 createPortal 渲染到 document.body,并将 z-index 提升到 z-[10000] 超过下拉浮层 z-[9999],恢复视口级覆盖与右上角按钮定位。
This commit is contained in:
parent
e2841ce791
commit
f711948902
@ -1,4 +1,5 @@
|
|||||||
import { useState, useEffect, memo } from 'react';
|
import { useState, useEffect, memo } from 'react';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
import {
|
import {
|
||||||
CheckCircle,
|
CheckCircle,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
@ -319,9 +320,14 @@ function ImageLightbox({
|
|||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
// 必须 portal 到 body:本组件渲染在虚拟化消息行内,行元素带
|
||||||
|
// transform(translateY),transformed 祖先会成为 fixed 后代的包含块,
|
||||||
|
// 导致遮罩只覆盖该行区域、工具栏定位到行盒而非视口、其他行内容叠在
|
||||||
|
// 遮罩之上。portal 后 fixed/z-index 相对视口全局生效。
|
||||||
|
// z-[10000]:高于下拉选择器(z-[9999])等全局浮层。
|
||||||
|
return createPortal(
|
||||||
<div
|
<div
|
||||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black/85 backdrop-blur-sm animate-fade-in"
|
className="fixed inset-0 z-[10000] flex items-center justify-center bg-black/85 backdrop-blur-sm animate-fade-in"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
{/* 顶部工具栏 */}
|
{/* 顶部工具栏 */}
|
||||||
@ -349,7 +355,8 @@ function ImageLightbox({
|
|||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
alt="图片预览"
|
alt="图片预览"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>,
|
||||||
|
document.body,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
import { X, Terminal, Clock, Maximize2 } from 'lucide-react';
|
import { X, Terminal, Clock, Maximize2 } from 'lucide-react';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import remarkGfm from 'remark-gfm';
|
import remarkGfm from 'remark-gfm';
|
||||||
@ -65,9 +66,12 @@ export function ToolDetailModal({
|
|||||||
? 'var(--accent-amber)'
|
? 'var(--accent-amber)'
|
||||||
: 'var(--text-muted)';
|
: 'var(--text-muted)';
|
||||||
|
|
||||||
return (
|
// portal 到 body:在虚拟化消息行内打开时,行元素的 transform 会成为
|
||||||
|
// fixed 后代的包含块,遮罩/定位全部失效(同 ImageLightbox)。
|
||||||
|
// z-[10000]:高于下拉选择器(z-[9999])等全局浮层。
|
||||||
|
return createPortal(
|
||||||
<div
|
<div
|
||||||
className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm animate-fade-in"
|
className="fixed inset-0 z-[10000] flex items-center justify-center bg-black/80 backdrop-blur-sm animate-fade-in"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
>
|
>
|
||||||
{/* Modal container */}
|
{/* Modal container */}
|
||||||
@ -145,6 +149,7 @@ export function ToolDetailModal({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>,
|
||||||
|
document.body,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user