From 729f25e0688fa63f7a34e3dd11931307eeca7410 Mon Sep 17 00:00:00 2001 From: "Logan.Li" Date: Fri, 26 Jun 2026 15:04:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(k8s):=20YAML=20=E5=BC=B9=E6=A1=86=20Portal?= =?UTF-8?q?=20=E5=88=B0=20body=20=E4=BF=AE=E5=A4=8D=E5=B1=85=E4=B8=AD?= =?UTF-8?q?=E5=81=8F=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PageTransition 的 transform 会使 fixed 弹框相对页面定位而非视口, YamlViewer 尺寸较大时容易跑出可视区。统一用 ModalOverlay Portal。 --- .../kubernetes/ResourceVisualEditor.tsx | 10 +++++--- .../kubernetes/YamlImportDialog.tsx | 5 ++-- .../src/components/kubernetes/YamlViewer.tsx | 12 ++++++---- frontend/src/components/ui/modal-overlay.tsx | 24 +++++++++++++++++++ 4 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 frontend/src/components/ui/modal-overlay.tsx diff --git a/frontend/src/components/kubernetes/ResourceVisualEditor.tsx b/frontend/src/components/kubernetes/ResourceVisualEditor.tsx index 2eb3c49..5aeac79 100644 --- a/frontend/src/components/kubernetes/ResourceVisualEditor.tsx +++ b/frontend/src/components/kubernetes/ResourceVisualEditor.tsx @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback } from 'react'; import { X, Save, Loader2, Plus, Trash2, FileText, Network, Shield, Database, ChevronRight} from 'lucide-react'; import { Button } from '@/components/ui/button'; +import { ModalOverlay } from '@/components/ui/modal-overlay'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; @@ -132,8 +133,11 @@ export function ResourceVisualEditor({ clusterCode, namespace, resource, name, o const MetaIcon = meta.icon; return ( -
-
e.stopPropagation()}> + +
e.stopPropagation()} + > {/* Header */}
@@ -206,7 +210,7 @@ export function ResourceVisualEditor({ clusterCode, namespace, resource, name, o )}
-
+
); } diff --git a/frontend/src/components/kubernetes/YamlImportDialog.tsx b/frontend/src/components/kubernetes/YamlImportDialog.tsx index c21a930..60a5d84 100644 --- a/frontend/src/components/kubernetes/YamlImportDialog.tsx +++ b/frontend/src/components/kubernetes/YamlImportDialog.tsx @@ -2,6 +2,7 @@ import { useState } from 'react'; import { X, Upload, Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; +import { ModalOverlay } from '@/components/ui/modal-overlay'; import { useToast } from '@/hooks/use-toast'; import { kubernetesApi } from '@/api'; import CodeMirror from '@uiw/react-codemirror'; @@ -36,7 +37,7 @@ export function YamlImportDialog({ clusterCode, onClose, onApplied }: YamlImport }; return ( -
+
e.stopPropagation()} @@ -71,6 +72,6 @@ export function YamlImportDialog({ clusterCode, onClose, onApplied }: YamlImport
-
+ ); } \ No newline at end of file diff --git a/frontend/src/components/kubernetes/YamlViewer.tsx b/frontend/src/components/kubernetes/YamlViewer.tsx index 7ca8740..2c1a570 100644 --- a/frontend/src/components/kubernetes/YamlViewer.tsx +++ b/frontend/src/components/kubernetes/YamlViewer.tsx @@ -4,6 +4,7 @@ import { useState, useEffect, useMemo} from 'react'; import { X, Copy, Check, Save, Loader2, Sparkles} from 'lucide-react'; import { Button } from '@/components/ui/button'; +import { ModalOverlay } from '@/components/ui/modal-overlay'; import { useToast } from '@/hooks/use-toast'; import { kubernetesApi } from '@/api'; import { cleanYAML } from './k8s-yaml-utils'; @@ -186,10 +187,13 @@ export function YamlViewer({ clusterCode, namespace, resource, name, onClose, on ); } - // 弹窗模式(原有行为) + // 弹窗模式 — Portal 到 body,避免 PageTransition transform 导致偏移 // Logan.Li return ( -
-
e.stopPropagation()}> + +
e.stopPropagation()} + > {/* Header */}
@@ -260,6 +264,6 @@ export function YamlViewer({ clusterCode, namespace, resource, name, onClose, on )}
-
+
); } diff --git a/frontend/src/components/ui/modal-overlay.tsx b/frontend/src/components/ui/modal-overlay.tsx new file mode 100644 index 0000000..46de437 --- /dev/null +++ b/frontend/src/components/ui/modal-overlay.tsx @@ -0,0 +1,24 @@ +// ModalOverlay — Portal 到 body,避免父级 transform 导致 fixed 弹框偏移 // Logan.Li +import { createPortal } from 'react-dom'; + +interface ModalOverlayProps { + onClose: () => void; + children: React.ReactNode; + /** 遮罩 z-index,默认高于 Sidebar/Header */ + zIndex?: number; +} + +export function ModalOverlay({ onClose, children, zIndex = 100 }: ModalOverlayProps) { + return createPortal( +
+
+ {children} +
+
, + document.body, + ); +} \ No newline at end of file