Only show focused toolbar for Gutenberg Block with Multiple text fields

I’m trying to create a block with multiple text fields. That’s easy enough, but when I select the block to edit it, both of the toolbars show. I’ve searched the documentation and can’t find anything.

Here’s the JSX code that mostly works. It add a heading, paragraph, and image to the block. But when one RichText element is in focus, both toolbars show, and that’s annoying.

const { registerBlockType, RichText, AlignmentToolbar, BlockControls, InspectorControls, MediaUpload } = wp.blocks;
const { Button, TextControl } = wp.components;

registerBlockType( 'skulogic/header', {
    title: 'SKULogic Header',
    icon: 'universal-access-alt',
    category: 'layout',

    attributes: {
        title: {
            type: 'array',
            source: 'children',
            selector: 'h2',
        },
        content: {
            type: 'array',
            source: 'children',
            selector: 'p',
        },
        mediaID: {
            type: 'number',
        },
        mediaURL: {
            type: 'string',
            source: 'attribute',
            selector: 'div',
            attribute: 'data-src',
        },
    },

    edit( { attributes, className, setAttributes } ) {
        const { mediaID, mediaURL, title, content } = attributes;

        const onChangeTitle = value => {
            setAttributes( { title: value } );
        };

        const onSelectImage = media => {
            setAttributes( {
                mediaURL: media.url,
                mediaID: media.id,
            } );
        };

        const onChangeContent = newContent => {
            setAttributes( { content: newContent } );
        };

        return (
            <div className={ className }>
                <RichText
                    tagName="h2"
                    placeholder={ 'Page Header' }
                    value={ title }
                    onChange={ onChangeTitle }
                />
                <RichText
                    tagName="p"
                    placeholder={ 'Page Content' }
                    value={ content }
                    onChange={ onChangeContent }
                />
                <MediaUpload
                    onSelect={ onSelectImage }
                    type="image"
                    value={ mediaID }
                    render={ ( { open } ) => (
                        <Button className={ mediaID ? 'image-button' : 'button button-large' } onClick={ open }>
                            { ! mediaID ? 'Upload Image' : <img src={ mediaURL } /> }
                        </Button>
                    )}
                />
            </div>
        );
    },
    save( { attributes, className } ) {
        const { mediaID, mediaURL, title, content } = attributes;

        const divStyle = {};
        if( mediaURL ) {
            divStyle.backgroundImage="URL("+mediaURL+')';
        }

        return (
            <div className={ className } data-src={ mediaURL } style={ divStyle }>
            <h2>{ title }</h2>
            <p>{ content }</p>
            </div>
        );
    },
} );

See attached screenshot showing the toolbar for both the <h2> and <p> elements. I want to only show the one that is in focus.

Two toolbars

1 Answer
1

<RichText> has a property, isSelected. When isSelected is true, the controls show. By default isSelected is representative of the current block being selected.

from the docs

isSelected: Boolean

Optional. Whether to show the input is selected or not in order to show the formatting controls. By default it renders the controls when the block is selected

isSelected is also a prop (I think?) that can be passed into edit({ isSelected }). isSelected by default works off of the current block being selected.

So the default is <RichText .. isSelected={ isSelected }>.

I used to have a solution for this, back in 2.2 when focus was used, but things have changed. Regardless, you can probably overwrite this by writing your own JS to see if the current <RichText> component is focus’ed or not. & That’ll toggle your toolbars.


UPDATE:

From one of the Gutenberg developers directly:

@youknowriad

in the current version you can use state and onFocus on RichText to keep track of the currently focused RichText, but in the next version, it should be done automatically


UPDATE 2:

Someone experienced your exact issue, shows code provided solution: https://github.com/WordPress/gutenberg/issues/6740#issuecomment-388829359

Leave a Comment