From bbe30e358e73c7567c1245ce4965061ccab99645 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Tue, 19 Dec 2023 18:55:59 +0100 Subject: [PATCH] Add `useScrollUponInsertion` hook --- .../src/components/block-list/block.native.js | 17 ++++++- .../use-scroll-upon-insertion.native.js | 51 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 packages/block-editor/src/components/block-list/use-scroll-upon-insertion.native.js diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 027ed12a7483ae..f58251ee665832 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -7,7 +7,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useCallback, useMemo, useState } from '@wordpress/element'; +import { useCallback, useMemo, useState, useRef } from '@wordpress/element'; import { GlobalStylesContext, getMergedGlobalStyles, @@ -40,6 +40,7 @@ import BlockInvalidWarning from './block-invalid-warning'; import BlockOutline from './block-outline'; import { store as blockEditorStore } from '../../store'; import { useLayout } from './layout'; +import useScrollUponInsertion from './use-scroll-upon-insertion'; import { useSettings } from '../use-settings'; const EMPTY_ARRAY = []; @@ -103,6 +104,18 @@ function BlockWrapper( { ]; const accessible = ! ( isSelected || isDescendentBlockSelected ); + const ref = useRef(); + const [ isLayoutCalculated, setIsLayoutCalculated ] = useState(); + useScrollUponInsertion( { + clientId, + isSelected, + isLayoutCalculated, + elementRef: ref, + } ); + const onLayout = useCallback( () => { + setIsLayoutCalculated( true ); + }, [] ); + return ( { + const isAlreadyInserted = useRef( false ); + const { scrollRef } = useBlockListContext(); + const wasBlockJustInserted = useSelect( + ( select ) => + !! select( blockEditorStore ).wasBlockJustInserted( + clientId, + 'inserter_menu' + ), + [ clientId ] + ); + useEffect( () => { + const blockJustInserted = + ! isAlreadyInserted.current && wasBlockJustInserted; + if ( + ! isSelected || + ! scrollRef || + ! blockJustInserted || + ! isLayoutCalculated + ) { + return; + } + scrollRef.scrollToElement( elementRef ); + isAlreadyInserted.current = wasBlockJustInserted; + }, [ + isSelected, + scrollRef, + wasBlockJustInserted, + elementRef, + isLayoutCalculated, + ] ); +}; + +export default useScrollUponInsertion;