From 3b3e054ba498af0813330f545a0ec329846653ee Mon Sep 17 00:00:00 2001 From: Adam Wood <1017872+adamwoodnz@users.noreply.github.com> Date: Wed, 11 Dec 2024 09:53:09 +1300 Subject: [PATCH] Sidebar container: fix scrolling glitch when main is shorter than the adjacent sidebar When the sidebar becomes fixed, the height of the main element collapses causing the sidebar to become unfixed again. To avoid this we add an observer to set a min height on the main element, matching the unfixed sidebar height. Fixes https://github.com/WordPress/wporg-mu-plugins/issues/611 --- .../blocks/sidebar-container/src/view.js | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/mu-plugins/blocks/sidebar-container/src/view.js b/mu-plugins/blocks/sidebar-container/src/view.js index aa7567f5..7b797b8e 100644 --- a/mu-plugins/blocks/sidebar-container/src/view.js +++ b/mu-plugins/blocks/sidebar-container/src/view.js @@ -1,3 +1,5 @@ +/* global ResizeObserver */ + let containers; let main; let footer; @@ -100,6 +102,28 @@ function init() { const scrollHandler = createScrollHandler( container ); scrollHandlers.push( scrollHandler ); window.addEventListener( 'scroll', scrollHandler ); + + // When the sidebar container adjacent to the main element (usually the chapter list) + // is taller than the main element, a glitch occurs when scrolling past the point where + // the sidebar becomes fixed, because the main element height depends on the sidebar container + // height. To avoid this, we observe the height of this container when it is not fixed, and + // set the min-height of the main element to match the container height. + const isSibling = container.previousElementSibling === main || container.nextElementSibling === main; + if ( 'ResizeObserver' in window && isSibling ) { + const resizeObserver = new ResizeObserver( ( entries ) => { + for ( const entry of entries ) { + if ( ! container.classList.contains( 'is-fixed-sidebar' ) ) { + const containerHeight = entry.contentRect.height; + + if ( containerHeight ) { + main.style.setProperty( 'min-height', `${ containerHeight }px` ); + } + } + } + } ); + + resizeObserver.observe( container ); + } } ); }