Block Controls: Toolbars and Inspector Edit

To simplify block customization and ensure a consistent experience for users, there are a number of built-in UI patterns to help generate the editor preview. Like with the RichText component covered in the previous chapter, the wp.editor global includes a few other common components to render editing interfaces. In this chapter, we’ll explore toolbars and the block inspector.

Toolbar Toolbar

Screenshot of the rich text toolbar applied to a paragraph block inside the block editor

When the user selects a block, a number of control buttons may be shown in a toolbar above the selected block. Some of these block-level controls are included automatically if the editor is able to transform the block to another type, or if the focused element is a RichText component.

You can also customize the toolbar to include controls specific to your block type. If the return value of your block type’s edit function includes a BlockControls element, those controls will be shown in the selected block’s toolbar.

( function( blocks, editor, element ) {
    var el = element.createElement;
    var RichText = editor.RichText;
    var AlignmentToolbar = editor.AlignmentToolbar;
    var BlockControls = editor.BlockControls;

    blocks.registerBlockType( 'gutenberg-examples/example-04-controls', {
        title: 'Example: Controls',
        icon: 'universal-access-alt',
        category: 'layout',

        attributes: {
            content: {
                type: 'array',
                source: 'children',
                selector: 'p',
            },
            alignment: {
                type: 'string',
                default: 'none',
            },
        },

        edit: function( props ) {
            var content = props.attributes.content;
            var alignment = props.attributes.alignment;

            function onChangeContent( newContent ) {
                props.setAttributes( { content: newContent } );
            }

            function onChangeAlignment( newAlignment ) {
                props.setAttributes( { alignment: newAlignment === undefined ? 'none' : newAlignment } );
            }

            return [
                el(
                    BlockControls,
                    { key: 'controls' },
                    el(
                        AlignmentToolbar,
                        {
                            value: alignment,
                            onChange: onChangeAlignment,
                        }
                    )
                ),
                el(
                    RichText,
                    {
                        key: 'richtext',
                        tagName: 'p',
                        style: { textAlign: alignment },
                        className: props.className,
                        onChange: onChangeContent,
                        value: content,
                    }
                ),
            ];
        },

        save: function( props ) {
            return el( RichText.Content, {
                tagName: 'p',
                className: 'gutenberg-examples-align-' + props.attributes.alignment,
                value: props.attributes.content,
            } );
        },
    } );
}(
    window.wp.blocks,
    window.wp.editor,
    window.wp.element
) );
const { registerBlockType } = wp.blocks;

const {
    RichText,
    AlignmentToolbar,
    BlockControls,
} = wp.editor;

registerBlockType( 'gutenberg-examples/example-04-controls-esnext', {
    title: 'Example: Controls (esnext)',
    icon: 'universal-access-alt',
    category: 'layout',
    attributes: {
        content: {
            type: 'array',
            source: 'children',
            selector: 'p',
        },
        alignment: {
            type: 'string',
            default: 'none',
        },
    },
    edit: ( props ) => {
        const {
            attributes: {
                content,
                alignment,
            },
            className,
        } = props;

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

        const onChangeAlignment = ( newAlignment ) => {
            props.setAttributes( { alignment: newAlignment === undefined ? 'none' : newAlignment } );
        };

        return (
            <div>
                {
                    <BlockControls>
                        <AlignmentToolbar
                            value={ alignment }
                            onChange={ onChangeAlignment }
                        />
                    </BlockControls>
                }
                <RichText
                    className={ className }
                    style={ { textAlign: alignment } }
                    tagName="p"
                    onChange={ onChangeContent }
                    value={ content }
                />
            </div>
        );
    },
    save: ( props ) => {
        return (
            <RichText.Content
                className={ `gutenberg-examples-align-${ props.attributes.alignment }` }
                tagName="p"
                value={ props.attributes.content }
            />
        );
    },
} );

Note that BlockControls is only visible when the block is currently selected and in visual editing mode. BlockControls are not shown when editing a block in HTML editing mode.

Top ↑

Inspector Inspector

Screenshot of the inspector panel focused on the settings for a paragraph block

The inspector is used to display less-often-used settings or settings that require more screen space. The inspector should be used for block-level settings only.

If you have settings that affects only selected content inside a block (example: the “bold” setting for selected text inside a paragraph): do not place it inside the inspector. The inspector is displayed even when editing a block in HTML mode, so it should only contain block-level settings.

The inspector region is shown in place of the post settings sidebar when a block is selected.

Similar to rendering a toolbar, if you include an InspectorControls element in the return value of your block type’s edit function, those controls will be shown in the inspector region.