0

I'm building my first Gutenberg block and the problem that I have is that the block control toolbar doesn't show. I've spend hours comparing my code with other Gutenberg blocks, but couldn't find what is wrong in my code. I would highly appreciate if someone could look at my code and advice.

Here is my code:

import { registerBlockType } from '@wordpress/blocks';
import { 
    RichText,
    InspectorControls,
    ColorPalette,
    MediaUpload
        } from '@wordpress/block-editor';
import { 
    PanelBody,
    IconButton } from '@wordpress/components';
 
registerBlockType( 'luxworx-blocks/author-block', {
    apiVersion: 2,
    title: 'Luxworx: Author Block',
    icon: 'universal-access-alt',
    category: 'design',
    example: {},
    attributes: {
        title: {
            type: 'string',
            source: 'html',
            selector: 'h2'
        },
        body: {
            type: 'string',
            source: 'html',
            selector: 'p'
        },
        textColor: {
            type: 'string',
            default: 'black'
        },
        bgColor: {
            type: 'string',
            default: 'white'
        },
        authorImage: {
            type: 'string',
            default: null
        }
    },

    edit( {attributes, setAttributes}) {

        // Custom functions
        function updateTitle (newTitle) {
            setAttributes( { title: newTitle}) 
        }
        function updateBody (newBody) {
            setAttributes( { body: newBody}) 
        }
        function onTextColorChange (newColor) {
            setAttributes( {textColor: newColor})
        }
        function onBgColorChange (newColor2) {
            setAttributes( {bgColor: newColor2})
        }
        function onSelectImage(newImage) {
            setAttributes( {authorImage: newImage.sizes.full.url })
        }
 
        return (
            <InspectorControls key="lx-authors-block-setting" style={ { marginBottom:'40px'} }>
                <PanelBody title={ 'Color setting' }>
                    <p><strong>Select text color:</strong></p>
                    <ColorPalette value={ attributes.textColor }
                                    onChange={ onTextColorChange } />
                    <p><strong>Select block bacground color:</strong></p>
                    <ColorPalette value={ attributes.bgColor }
                                    onChange={ onBgColorChange } />
                </PanelBody>
                <PanelBody title={ 'Author image'}>
                    <p><strong>Select author image:</strong></p>
                    <MediaUpload
                        onSelect={ onSelectImage }
                        type="image"
                        value={ attributes.authorImage }
                        render={ ( { open } ) => (
                            <IconButton
                                onClick={ open }
                                icon="upload"
                                className="editor-media-placeholder__button button is-default">
                                Author Image
                            </IconButton>
                        ) } />
                        
                </PanelBody>
            </InspectorControls>,
            <div className="lx-authors-block wp-block" key="container" style={{ backgroundColor: attributes.bgColor}}>
                <img src={ attributes.authorImage} className="lx-authors-image" />
                <div className="lx-author-info">
                    <RichText   
                                placeholder="Authors name"
                                tagName="h2"
                                value={attributes.title}
                                onChange={updateTitle}
                                style={ {color: attributes.textColor }} />
                    
                    <RichText  
                                placeholder="Authors bio"
                                tagName="p"
                                value={attributes.body}
                                onChange={updateBody}
                                style={ {color:attributes.textColor}} />
                </div>
            </div> 
        );
    },
    save( {attributes}) {
        
        return (
            <div className="lx-authors-block wp-block" style={{ backgroundColor: attributes.bgColor }}>
                <img src={ attributes.authorImage} className="lx-authors-image" />
                <div className="lx-author-info">
                    <h2 style={ { color: attributes.textColor }}>{attributes.title}</h2>
                    <RichText.Content tagName="p"
                                    value={attributes.body}
                                    style={ {color:attributes.textColor}}
                                    />
                </div>
            </div>
        );
    },
} );
1
  • 2
    You should not manually use wp-block that's an editor class that the editor is responsible for, not you. Use the useBlockProps etc hooks or remove those editor based classes to avoid a set of problems you're unaware of.
    – Tom J Nowell
    Commented Jul 24, 2021 at 18:14

2 Answers 2

3

Your edit function is just missing a [ and ], i.e. you forgot to actually return an array, like so:

return ([ // add that [
    <InspectorControls key="lx-authors-block-setting" style={ { marginBottom:'40px'} }>
        ...
    </InspectorControls>,
    <div className="lx-authors-block wp-block" key="container" style={{ backgroundColor: attributes.bgColor}}>
        ...
    </div>
]); // and add that ]

Or you could instead wrap the elements in a fragment (<> and </>) or div if you want:

return (
    <>
        <InspectorControls key="lx-authors-block-setting" style={ { marginBottom:'40px'} }>
            ...
        </InspectorControls>
        <div className="lx-authors-block wp-block" key="container" style={{ backgroundColor: attributes.bgColor}}>
            ...
        </div>
    </>
);

Update

In response to your answer, and as said by @TomJNowell, it's true that you should not manually add the wp-block class to your div (but I didn't notice you added it there, hence I didn't mention it in my original answer) and instead, because your block type is using the block API version 2 (note the apiVersion: 2, in your code), you should use useBlockProps to ensure the block wrapper is recognized properly and added with the proper classes like the wp-block.

However, the block editor handbook stated that:

If the element wrapper needs any extra custom HTML attributes, these need to be passed as an argument to the useBlockProps hook.

Therefore, instead of doing { ...useBlockProps() } className="lx-authors-block":

<div { ...useBlockProps() } className="lx-authors-block" key="editable" style={{ backgroundColor: attributes.bgColor}}>

You should actually pass the className as an argument to the useBlockProps hook:

<div { ...useBlockProps( {
    className: 'lx-authors-block',
    key: 'editable',
    style: { backgroundColor: attributes.bgColor },
} ) }>

Otherwise, the div will not actually going to have the wp-block class and among other issues, the div will appear full-width in the editor:

Preview image

So make sure that you use the correct syntax and your return code should look like so:

return ([
    <InspectorControls key="lx-authors-block-setting" style={ { marginBottom:'40px'} }>
        ...
    </InspectorControls>,
    <div { ...useBlockProps( {
        className: 'lx-authors-block',
        key: 'editable',
        style: { backgroundColor: attributes.bgColor },
    } ) }>
        ...
    </div>
]);

Which then would give you the correct outcome like so (note the block width and it's also focusable, e.g. when you click on the white background at the top-right corner):

Preview image

0

I have found a problem. My div wrapper was missing { ...useBlockProps() } So it should be:

 <div { ...useBlockProps() } className="lx-authors-block" key="editable" style={{ backgroundColor: attributes.bgColor}}>

...

1
  • I've just revised my answer. I hope it helps you more.
    – Sally CJ
    Commented Aug 4, 2021 at 18:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.