优化图片备注弹窗样式并修复越界显示

This commit is contained in:
Your Name 2026-02-08 12:18:17 +08:00
parent ec16c316cc
commit bb1c0998c3

View File

@ -407,25 +407,6 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
return { top, left }; return { top, left };
}; };
const getNotePanelPosition = () => {
if (!containerRef.current || typeof window === "undefined") {
return { top: 0, left: 0 };
}
const rect = containerRef.current.getBoundingClientRect();
const panelWidth = 300;
const spacing = 12;
const maxTop = Math.max(12, window.innerHeight - 360);
let left = rect.right + spacing;
if (left + panelWidth > window.innerWidth - 12) {
left = Math.max(12, rect.left - panelWidth - spacing);
}
const top = Math.min(Math.max(12, rect.top + 8), maxTop);
return { top, left };
};
const displayTitle = getImageNodeTitle(data, node.id); const displayTitle = getImageNodeTitle(data, node.id);
const handleSaveTitle = useCallback(() => { const handleSaveTitle = useCallback(() => {
@ -1814,66 +1795,37 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
document.body document.body
)} )}
{/* 图片备注面板 */} {/* 图片备注对话框 */}
{notePanelOpen && typeof document !== "undefined" && createPortal( <Dialog open={notePanelOpen} onOpenChange={setNotePanelOpen}>
<div <DialogContent className="sm:max-w-[560px] max-h-[85vh] overflow-y-auto">
className="fixed z-[10001] w-[300px] rounded-xl border border-amber-200 bg-amber-50/95 shadow-2xl backdrop-blur" <DialogHeader>
style={{ <DialogTitle className="flex items-center gap-2">
top: getNotePanelPosition().top, <StickyNote className="h-5 w-5" />
left: getNotePanelPosition().left, 图片备注
}} </DialogTitle>
onMouseDown={(e) => e.stopPropagation()} </DialogHeader>
onPointerDown={(e) => e.stopPropagation()} <div className="space-y-3 py-1">
onClick={(e) => e.stopPropagation()}
>
<div className="flex items-center justify-between px-4 py-3 border-b border-amber-200/80">
<div className="flex items-center gap-2 text-amber-800">
<StickyNote className="h-4 w-4" />
<span className="text-sm font-medium">图片备注</span>
</div>
<Button
variant="ghost"
size="icon"
className="h-7 w-7 text-amber-700 hover:text-amber-900 hover:bg-amber-100"
onClick={() => setNotePanelOpen(false)}
>
<X className="h-4 w-4" />
</Button>
</div>
<div className="px-4 py-3">
<Textarea <Textarea
value={draftNote} value={draftNote}
onChange={(e) => setDraftNote(e.target.value)} onChange={(e) => setDraftNote(e.target.value)}
placeholder="记录这张图的想法、待办或交付要求..." placeholder="记录这张图的想法、待办或交付要求..."
rows={6} rows={8}
className="resize-y bg-white/80 border-amber-200 focus-visible:ring-amber-300" className="resize-y min-h-[180px]"
/> />
<p className="mt-2 text-[11px] text-amber-700/80"> <p className="text-xs text-muted-foreground">
备注仅在你点开时显示,不会直接覆盖在画面上。 备注仅在你点开时显示,不会直接覆盖在画面上。
</p> </p>
</div> </div>
<DialogFooter>
<div className="flex items-center justify-between gap-2 px-4 py-3 border-t border-amber-200/80"> <Button variant="outline" onClick={() => setNotePanelOpen(false)}>
<Button
variant="ghost"
size="sm"
className="text-amber-700 hover:text-amber-900 hover:bg-amber-100"
onClick={() => setNotePanelOpen(false)}
>
取消 取消
</Button> </Button>
<Button <Button onClick={handleSaveNote}>
size="sm"
className="bg-amber-600 text-white hover:bg-amber-700"
onClick={handleSaveNote}
>
保存备注 保存备注
</Button> </Button>
</div> </DialogFooter>
</div>, </DialogContent>
document.body </Dialog>
)}
{/* 文字编辑面板(显示在图片节点旁边) */} {/* 文字编辑面板(显示在图片节点旁边) */}
{isSelected && textEditPanelOpen && data.src && typeof document !== "undefined" && createPortal( {isSelected && textEditPanelOpen && data.src && typeof document !== "undefined" && createPortal(