Skip to content

Commit

Permalink
Use getScrollContainer and calculate real top position of scrollable …
Browse files Browse the repository at this point in the history
…area instead of using a hard-coded value
  • Loading branch information
andrewserong committed Jan 13, 2023
1 parent c812bba commit 308cc7d
Showing 1 changed file with 25 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* WordPress dependencies
*/
import { getScrollContainer } from '@wordpress/dom';
import { useEffect } from '@wordpress/element';

export default function useListViewScrollIntoView( {
Expand All @@ -9,6 +10,10 @@ export default function useListViewScrollIntoView( {
selectedItemRef,
} ) {
useEffect( () => {
// Skip scrolling into view if more than one block is selected.
// This is to avoid scrolling the view in a multi selection where the user
// has intentionally selected multiple blocks within the list view,
// but the initially selected block may be out of view.
if (
numBlocksSelected !== 1 ||
! selectedItemRef?.current ||
Expand All @@ -17,12 +22,28 @@ export default function useListViewScrollIntoView( {
return;
}

const scrollContainer = getScrollContainer( selectedItemRef.current );
const { ownerDocument } = selectedItemRef.current;
const { defaultView } = ownerDocument;

const windowScroll =
scrollContainer === ownerDocument.body ||
scrollContainer === ownerDocument.documentElement;

// If the there is no scroll container, of if the scroll container is the window,
// do not scroll into view, as the block is already in view.
if ( windowScroll || ! scrollContainer ) {
return;
}

const { top, height } = selectedItemRef.current.getBoundingClientRect();
const { innerHeight } = window;
const topOfScrollContainer =
scrollContainer.getBoundingClientRect().top;

const { innerHeight } = defaultView;

// If the selected block is not visible, scroll to it.
// The hard-coded value of 110 corresponds to the position at the top of the scrollable area.
if ( top < 110 || top + height > innerHeight ) {
// If the selected block is not currently visible, scroll to it.
if ( top < topOfScrollContainer || top + height > innerHeight ) {
selectedItemRef.current.scrollIntoView();
}
}, [
Expand Down

0 comments on commit 308cc7d

Please sign in to comment.