Search code examples
javascriptwordpressreactjswordpress-gutenberggutenberg-blocks

Gutenberg editor scroll block into view


How can I scroll a newly inserted block into the view in the wordpress gutenberg editor?

I am creating the block with

const nextBlock = createBlock( 'core/paragraph' );
wp.data.dispatch( 'core/editor' ).insertBlock( nextBlock );
//scroll the block into the view

I have also seen that gutenberg uses the dom-scroll-into-view package like e.g. here.

Their documentation says:

var scrollIntoView = require('dom-scroll-into-view');
scrollIntoView(source,container,config);

but how can I get it working in my case, how to get the source and container DOM elements?


Solution

  • in my case, how to get the source and container DOM elements?

    It's actually quite easy.. just use document.querySelector() to get the block node and then wp.dom.getScrollContainer() to get that node's container:

    const nextBlock = wp.blocks.createBlock( 'core/paragraph' );
    wp.data.dispatch( 'core/editor' ).insertBlock( nextBlock );
    
    const source = document.querySelector( '[data-block="' + nextBlock.clientId + '"]' );
    const container = wp.dom.getScrollContainer( source );
    

    References: One Two

    And here's my code:

    /**
     * External dependencies
     */
    import scrollIntoView from 'dom-scroll-into-view';
    
    /**
     * WordPress dependencies
     */
    import { createBlock } from '@wordpress/blocks';     // wp.blocks.createBlock
    import { dispatch } from '@wordpress/data';          // wp.data.dispatch
    import { getScrollContainer } from '@wordpress/dom'; // wp.dom.getScrollContainer
    
    function getBlockDOMNode( clientId ) {
        return document.querySelector( '[data-block="' + clientId + '"]' );
    }
    
    const nextBlock = createBlock( 'core/paragraph' );
    dispatch( 'core/editor' ).insertBlock( nextBlock );
    
    const source = getBlockDOMNode( nextBlock.clientId );
    const container = source ? getScrollContainer( source ) : null;
    if ( source && container ) {
        scrollIntoView( source, container );
    }
    

    UPDATE

    For testing the imported scrollIntoView(), try this:

    function scrollBlockIntoView( block ) {
        const source = getBlockDOMNode( block.clientId );
        const container = source ? getScrollContainer( source ) : null;
        if ( source && container ) {
            console.log( source, container );
            scrollIntoView( source, container );
        }
    }
    
    window.scrollBlockIntoView = function( block ) {
        scrollBlockIntoView( block || {} );
    };
    

    And then from the browser console, run this:

    scrollBlockIntoView( wp.data.select('core/editor').getBlocks()[1] )
    

    But make sure that you have at least two blocks in the editor — e.g. a paragraph with a lengthy content and an image block.

    Tried and tested working on Chrome (Windows 10).