From c978a788c8315e37357c93c1b605a2831fc77485 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 9 May 2026 05:03:38 +0900 Subject: [PATCH] refac --- src/lib/components/common/Textarea.svelte | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/lib/components/common/Textarea.svelte b/src/lib/components/common/Textarea.svelte index 148c3a46ee..82d67dd37b 100644 --- a/src/lib/components/common/Textarea.svelte +++ b/src/lib/components/common/Textarea.svelte @@ -35,6 +35,19 @@ const resize = () => { if (textareaElement) { + // Find all ancestors that currently have an active scroll offset. + // This is extremely fast because reading `scrollTop` on a clean layout doesn't trigger reflow, + // and it makes the fix 100% robust without relying on hardcoded CSS classes. + let activeScrollParents = []; + let p = textareaElement.parentNode; + while (p && p !== document.body) { + if (p instanceof HTMLElement && p.scrollTop > 0) { + activeScrollParents.push({ el: p, top: p.scrollTop }); + } + p = p.parentNode; + } + const windowScrollY = window.scrollY; + textareaElement.style.height = ''; let height = textareaElement.scrollHeight; @@ -46,6 +59,15 @@ } textareaElement.style.height = `${height}px`; + + // Only restore scroll for elements that were actually scrolled. + // This prevents layout thrashing that happens if we blindly set `.scrollTop` on every parent. + activeScrollParents.forEach((p) => { + if (p.el.scrollTop !== p.top) p.el.scrollTop = p.top; + }); + if (window.scrollY !== windowScrollY) { + window.scrollTo(window.scrollX, windowScrollY); + } } };