diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/wwwroot/js/monaco-init.js b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/wwwroot/js/monaco-init.js index 0812f523..f14ab926 100644 --- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/wwwroot/js/monaco-init.js +++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/wwwroot/js/monaco-init.js @@ -144,6 +144,25 @@ } catch (e) { return []; } } + // A single body-level node for Monaco's overflow widgets (suggest / hover / parameter hints). + // Rendering them here — outside any ancestor with a CSS transform (e.g. the theme's `.rise` + // entrance animation) — keeps the position:fixed widgets viewport-correct. Without it, the + // transformed ancestor becomes the containing block and the popup is offset far from the caret. + function overflowWidgetsNode() { + let node = document.getElementById("otopcua-monaco-overflow"); + if (!node) { + node = document.createElement("div"); + node.id = "otopcua-monaco-overflow"; + node.className = "monaco-editor"; // so the suggest/hover widget CSS applies + node.style.position = "absolute"; + node.style.top = "0"; + node.style.left = "0"; + node.style.zIndex = "2000"; + document.body.appendChild(node); + } + return node; + } + async function createEditor(id, host, options, dotNetRef) { await ensureLoaded(); if (!host) return; @@ -152,7 +171,10 @@ theme: "vs", minimap: { enabled: false }, scrollBeyondLastLine: false, automaticLayout: true, fontSize: 13, lineNumbers: "on", renderLineHighlight: "line", readOnly: !!options.readOnly, - tabSize: 4, insertSpaces: true, wordWrap: "off", fixedOverflowWidgets: true, + tabSize: 4, insertSpaces: true, wordWrap: "off", + // Render overflow widgets (suggest/hover) in a body-level node so an ancestor CSS + // transform doesn't mis-position them; requires fixedOverflowWidgets. + fixedOverflowWidgets: true, overflowWidgetsDomNode: overflowWidgetsNode(), // Auto-suggest inside string literals too, so tag-path completion surfaces while typing // inside ctx.GetTag("…") / ctx.SetVirtualTag("…") without requiring an explicit Ctrl+Space. quickSuggestions: { other: true, comments: false, strings: true }