From 8f04b73050cd2823a272b790fa4304b02480ee41 Mon Sep 17 00:00:00 2001 From: Nathan Date: Tue, 18 Nov 2025 13:53:58 +0800 Subject: [PATCH] fix: scroll to top when swithc embeded database view --- src/components/database/DatabaseViews.tsx | 41 ++++++++++++------- .../blocks/database/DatabaseBlock.tsx | 25 ----------- 2 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/components/database/DatabaseViews.tsx b/src/components/database/DatabaseViews.tsx index 7bbf5ebf..000a4c1a 100644 --- a/src/components/database/DatabaseViews.tsx +++ b/src/components/database/DatabaseViews.tsx @@ -153,7 +153,7 @@ function DatabaseViews({ }, [isLoading, viewVisible, layout, viewId]); // Scroll restoration with RAF enforcement - // Even with keep-mounted, Board's autoScrollForElements can still interfere on first switch + // Board's autoScrollForElements interferes with scroll, so we enforce for multiple frames useEffect(() => { if (isLoading) return; if (lastScrollRef.current == null) return; @@ -168,8 +168,17 @@ function DatabaseViews({ let rafCount = 0; let rafId: number; + // Temporarily prevent scroll events during restoration + const preventScroll = (e: Event) => { + if (scrollElement.scrollTop !== targetScroll) { + e.preventDefault(); + scrollElement.scrollTop = targetScroll; + } + }; + + scrollElement.addEventListener('scroll', preventScroll, { passive: false }); + // Use RAF loop to enforce scroll position - // This handles Board's autoScrollForElements which may still interfere on first display const enforceScroll = () => { const currentScroll = scrollElement.scrollTop; const delta = Math.abs(currentScroll - targetScroll); @@ -185,16 +194,22 @@ function DatabaseViews({ } rafCount++; - // Run for 3 frames (~48ms) - shorter than before since views stay mounted - if (rafCount < 3) { + // Run for 5 frames (~80ms) to catch delayed scroll changes from Board mount + if (rafCount < 5) { rafId = requestAnimationFrame(enforceScroll); } else { logDebug('[DatabaseViews] scroll restoration completed', { final: scrollElement.scrollTop, target: targetScroll, }); + // Remove scroll listener and clean up + scrollElement.removeEventListener('scroll', preventScroll); lastScrollRef.current = null; setViewVisible(true); + // Release height lock to allow view to resize to its natural height + if (!fixedHeight) { + setLockedHeight(null); + } } }; @@ -204,6 +219,7 @@ function DatabaseViews({ if (rafId) { cancelAnimationFrame(rafId); } + scrollElement.removeEventListener('scroll', preventScroll); }; }, [isLoading, viewId]); @@ -251,20 +267,17 @@ function DatabaseViews({ className={'relative flex h-full w-full flex-1 flex-col overflow-hidden'} style={ effectiveHeight !== null - ? { height: `${effectiveHeight}px` } + ? { height: `${effectiveHeight}px`, maxHeight: `${effectiveHeight}px` } : undefined } >
{view} diff --git a/src/components/editor/components/blocks/database/DatabaseBlock.tsx b/src/components/editor/components/blocks/database/DatabaseBlock.tsx index 56414a2d..55fd927f 100644 --- a/src/components/editor/components/blocks/database/DatabaseBlock.tsx +++ b/src/components/editor/components/blocks/database/DatabaseBlock.tsx @@ -67,25 +67,6 @@ export const DatabaseBlock = memo( }; }, [doc, viewId]); - const EMBEDDED_DB_HEIGHT = 560; - - const logContainerSize = () => { - if (!containerRef.current) return; - const rect = containerRef.current.getBoundingClientRect(); - console.debug('[DatabaseBlock] container size', { - viewId, - selectedViewId, - width, - height: rect.height, - paddingStart, - paddingEnd, - }); - }; - - useEffect(() => { - logContainerSize(); - }, [selectedViewId, width, paddingStart, paddingEnd]); - return (
@@ -95,11 +76,6 @@ export const DatabaseBlock = memo( contentEditable={false} ref={containerRef} className='container-bg relative my-1 flex w-full select-none flex-col' - style={{ - minHeight: EMBEDDED_DB_HEIGHT, - height: EMBEDDED_DB_HEIGHT, - width: '100%', - }} >