From 01393186e7639c8168c2f64b5593ec80b5a41474 Mon Sep 17 00:00:00 2001 From: Continue Agent Date: Thu, 18 Sep 2025 00:03:50 +0000 Subject: [PATCH 1/2] Fix auto-scroll failing when components are dynamically added to chat - Added MutationObserver to watch for dynamically added DOM elements - Changed from observing only direct children to observing all descendants - New elements and their children are automatically observed when added - This ensures auto-scroll works when components pop into the chat, not just text Generated with [Continue](https://continue.dev) Co-Authored-By: Continue --- gui/src/pages/gui/useAutoScroll.ts | 40 +++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/gui/src/pages/gui/useAutoScroll.ts b/gui/src/pages/gui/useAutoScroll.ts index 236ca9f7694..4527b3f62be 100644 --- a/gui/src/pages/gui/useAutoScroll.ts +++ b/gui/src/pages/gui/useAutoScroll.ts @@ -43,18 +43,46 @@ export const useAutoScroll = ( elem.scrollTop = elem.scrollHeight; }); - ref.current.addEventListener("scroll", handleScroll); + // MutationObserver to watch for dynamically added components + const mutationObserver = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + mutation.addedNodes.forEach((node) => { + if (node instanceof Element) { + // Observe the newly added element and all its descendants + const elementsToObserve = [node, ...node.querySelectorAll('*')]; + elementsToObserve.forEach((el) => { + resizeObserver.observe(el); + }); + } + }); + }); + }); - // Observe the container - resizeObserver.observe(ref.current); + const observeAllElements = (container: Element) => { + // Observe the container itself + resizeObserver.observe(container); + + // Observe all existing descendants (not just direct children) + const allElements = container.querySelectorAll('*'); + allElements.forEach((element) => { + resizeObserver.observe(element); + }); + }; - // Observe all immediate children - Array.from(ref.current.children).forEach((child) => { - resizeObserver.observe(child); + ref.current.addEventListener("scroll", handleScroll); + + // Observe all existing elements + observeAllElements(ref.current); + + // Start watching for new elements + mutationObserver.observe(ref.current, { + childList: true, + subtree: true, // Watch all descendants, not just direct children }); return () => { resizeObserver.disconnect(); + mutationObserver.disconnect(); ref.current?.removeEventListener("scroll", handleScroll); }; }, [ref, history.length, userHasScrolled]); From 0e70b99e65122d238728655abd1a9aaedbedf41f Mon Sep 17 00:00:00 2001 From: Patrick Erichsen Date: Wed, 1 Oct 2025 10:52:21 -0700 Subject: [PATCH 2/2] Update useAutoScroll.ts --- gui/src/pages/gui/useAutoScroll.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gui/src/pages/gui/useAutoScroll.ts b/gui/src/pages/gui/useAutoScroll.ts index 4527b3f62be..5b19d185cec 100644 --- a/gui/src/pages/gui/useAutoScroll.ts +++ b/gui/src/pages/gui/useAutoScroll.ts @@ -49,7 +49,7 @@ export const useAutoScroll = ( mutation.addedNodes.forEach((node) => { if (node instanceof Element) { // Observe the newly added element and all its descendants - const elementsToObserve = [node, ...node.querySelectorAll('*')]; + const elementsToObserve = [node, ...node.querySelectorAll("*")]; elementsToObserve.forEach((el) => { resizeObserver.observe(el); }); @@ -61,19 +61,19 @@ export const useAutoScroll = ( const observeAllElements = (container: Element) => { // Observe the container itself resizeObserver.observe(container); - + // Observe all existing descendants (not just direct children) - const allElements = container.querySelectorAll('*'); + const allElements = container.querySelectorAll("*"); allElements.forEach((element) => { resizeObserver.observe(element); }); }; ref.current.addEventListener("scroll", handleScroll); - + // Observe all existing elements observeAllElements(ref.current); - + // Start watching for new elements mutationObserver.observe(ref.current, { childList: true,