From b9cbab256e898ee96481d72119067b8111781d5f Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 9 Feb 2026 16:23:32 -0800 Subject: [PATCH 1/4] add resizeobserving + layout to monaco-react components --- frontend/app/monaco/monaco-react.tsx | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/frontend/app/monaco/monaco-react.tsx b/frontend/app/monaco/monaco-react.tsx index aee722e314..f133a6a8ac 100644 --- a/frontend/app/monaco/monaco-react.tsx +++ b/frontend/app/monaco/monaco-react.tsx @@ -5,6 +5,7 @@ import { loadMonaco } from "@/app/monaco/monaco-env"; import type * as MonacoTypes from "monaco-editor"; import * as monaco from "monaco-editor"; import { useEffect, useRef } from "react"; +import { debounce } from "throttle-debounce"; function createModel(value: string, path: string, language?: string) { const uri = monaco.Uri.parse(`wave://editor/${encodeURIComponent(path)}`); @@ -72,6 +73,20 @@ export function MonacoCodeEditor({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + useEffect(() => { + const editor = editorRef.current; + const el = divRef.current; + if (!editor || !el) return; + + const debouncedLayout = debounce(100, () => { + editor.layout(); + }); + const resizeObserver = new ResizeObserver(debouncedLayout); + resizeObserver.observe(el); + + return () => resizeObserver.disconnect(); + }, []); + // Keep model value in sync with props useEffect(() => { const editor = editorRef.current; @@ -145,6 +160,20 @@ export function MonacoDiffViewer({ original, modified, language, path, options } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + useEffect(() => { + const diff = diffRef.current; + const el = divRef.current; + if (!diff || !el) return; + + const debouncedLayout = debounce(100, () => { + diff.layout(); + }); + const resizeObserver = new ResizeObserver(debouncedLayout); + resizeObserver.observe(el); + + return () => resizeObserver.disconnect(); + }, []); + // Update models on prop change useEffect(() => { const diff = diffRef.current; From bc1bed0639e9a9fd9a731548f82369737312ca21 Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 9 Feb 2026 16:32:00 -0800 Subject: [PATCH 2/4] remove now redundant waveconfig layout call --- frontend/app/view/waveconfig/waveconfig.tsx | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/frontend/app/view/waveconfig/waveconfig.tsx b/frontend/app/view/waveconfig/waveconfig.tsx index 9c5e873bc9..702779e1c4 100644 --- a/frontend/app/view/waveconfig/waveconfig.tsx +++ b/frontend/app/view/waveconfig/waveconfig.tsx @@ -11,7 +11,6 @@ import { cn } from "@/util/util"; import { useAtom, useAtomValue } from "jotai"; import type * as MonacoTypes from "monaco-editor"; import { memo, useCallback, useEffect, useRef } from "react"; -import { debounce } from "throttle-debounce"; interface ConfigSidebarProps { model: WaveConfigViewModel; @@ -147,20 +146,6 @@ const WaveConfigView = memo(({ blockId, model }: ViewComponentProps window.removeEventListener("keydown", handleKeyDown); }, [hasChanges, isSaving, model]); - useEffect(() => { - if (!editorContainerRef.current) { - return; - } - const debouncedLayout = debounce(100, () => { - if (model.editorRef.current) { - model.editorRef.current.layout(); - } - }); - const resizeObserver = new ResizeObserver(debouncedLayout); - resizeObserver.observe(editorContainerRef.current); - return () => resizeObserver.disconnect(); - }, [model]); - const saveTooltip = `Save (${model.saveShortcut})`; return ( @@ -279,7 +264,8 @@ const WaveConfigView = memo(({ blockId, model }: ViewComponentProps Loading... - ) : selectedFile.visualComponent && (!selectedFile.hasJsonView || activeTab === "visual") ? ( + ) : selectedFile.visualComponent && + (!selectedFile.hasJsonView || activeTab === "visual") ? ( (() => { const VisualComponent = selectedFile.visualComponent; return ; From 9633ee0fba4a74afbe9fb3e76dbf892aad602bc0 Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 9 Feb 2026 17:05:07 -0800 Subject: [PATCH 3/4] added cancel --- frontend/app/monaco/monaco-react.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/app/monaco/monaco-react.tsx b/frontend/app/monaco/monaco-react.tsx index f133a6a8ac..864bf3dd4f 100644 --- a/frontend/app/monaco/monaco-react.tsx +++ b/frontend/app/monaco/monaco-react.tsx @@ -84,7 +84,10 @@ export function MonacoCodeEditor({ const resizeObserver = new ResizeObserver(debouncedLayout); resizeObserver.observe(el); - return () => resizeObserver.disconnect(); + return () => { + resizeObserver.disconnect(); + debouncedLayout.cancel(); + }; }, []); // Keep model value in sync with props @@ -171,7 +174,10 @@ export function MonacoDiffViewer({ original, modified, language, path, options } const resizeObserver = new ResizeObserver(debouncedLayout); resizeObserver.observe(el); - return () => resizeObserver.disconnect(); + return () => { + resizeObserver.disconnect(); + debouncedLayout.cancel(); + }; }, []); // Update models on prop change From c3e768bd78b1ee35604311110ef69c1eee835f7e Mon Sep 17 00:00:00 2001 From: sawka Date: Mon, 9 Feb 2026 17:05:55 -0800 Subject: [PATCH 4/4] remove unused ref --- frontend/app/view/waveconfig/waveconfig.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/app/view/waveconfig/waveconfig.tsx b/frontend/app/view/waveconfig/waveconfig.tsx index 702779e1c4..4e515466f4 100644 --- a/frontend/app/view/waveconfig/waveconfig.tsx +++ b/frontend/app/view/waveconfig/waveconfig.tsx @@ -10,7 +10,7 @@ import { adaptFromReactOrNativeKeyEvent, checkKeyPressed, keydownWrapper } from import { cn } from "@/util/util"; import { useAtom, useAtomValue } from "jotai"; import type * as MonacoTypes from "monaco-editor"; -import { memo, useCallback, useEffect, useRef } from "react"; +import { memo, useCallback, useEffect } from "react"; interface ConfigSidebarProps { model: WaveConfigViewModel; @@ -96,7 +96,6 @@ const WaveConfigView = memo(({ blockId, model }: ViewComponentProps(null); const handleContentChange = useCallback( (newContent: string) => { @@ -156,7 +155,7 @@ const WaveConfigView = memo(({ blockId, model }: ViewComponentProps -
+
{selectedFile && ( <>