2

I've got a custom Gutenberg block that is using two custom components. Each of the components has a toggle in the Inspector Controls panel. This is just a simplified scenario, in reality, there will be more than just two components.

// My GB block
import PreTitle from '../components/PreTitle';
import Title from '../components/Title';

const { registerBlockType } = wp.blocks;

const blockConfig = {
    title: 'My Block',
    category: 'my-blocks',
    attributes: {
        // Some attributes
    },

    edit: ( props ) => {
        return (
            <div className={`controls`}>
                <PreTitle { ...props } />
                <Title { ...props } />
            </div>
        );
    },
    save: ({attributes: { preTitleContent, TitleContent }}) => {

        return(
            <div className={`controls`}>
                <PreTitle.Content { ...props } />
                <Title.Content { ...props } />
            </div>
        );
    }
};

export const headings = registerBlockType(
    `cv-wp-lib-gutenberg-blocks/headings`,
    blockConfig
);

My Title component:

const Title = ( props ) => {
    // ... some code
    return (
        <>
            <InspectorControls>
                <PanelBody>
                    <ToggleControl
                        label={ __(`Toggle title`, `cv-wp-lib-gutenberg-blocks`) }
                        checked={ showTitle }
                        onChange={ onChangeToggleField }
                    />
                </PanelBody>
            </InspectorControls>

            // ... some JSX
        </>
    );
};

My PreTitle component:

const PreTitle = ( props ) => {
    // ... some code
    return (
        <>
            <InspectorControls>
                <PanelBody>
                    <ToggleControl
                        label={ __(`Toggle preTitle`, `cv-wp-lib-gutenberg-blocks`) }
                        checked={ showPreTitle }
                        onChange={ onChangeToggleField }
                    />
                </PanelBody>
            </InspectorControls>

            // ... some JSX
        </>
    );
};

Question: Is there a way for the components sharing the same panel?

1 Answer 1

1

You have two options:

  1. You write only one InspectorControls and put it in your main component/block and remove the InpertorControls from your Title and PreTitle js files. Don't forget to change the onChange function name 'onChangeToggleField' cause they both share the same function name. Whatever props you change now, should be now passed to Title and PreTitle
// My GB block
import PreTitle from '../components/PreTitle';
import Title from '../components/Title';

const { registerBlockType } = wp.blocks;

const blockConfig = {
    title: 'My Block',
    category: 'my-blocks',
    attributes: {
        // Some attributes
    },

    edit: ( props ) => {
        return (
           <>
            <InspectorControls>
                <PanelBody>
                    <ToggleControl
                        label={ __(`Toggle title`, `cv-wp-lib-gutenberg-blocks`) }
                        checked={ showTitle }
                        onChange={ onChangeToggleFieldTitle }
                    />
                    <ToggleControl
                        label={ __(`Toggle preTitle`, `cv-wp-lib-gutenberg- 
                          blocks`) }
                        checked={ showPreTitle }
                        onChange={ onChangeToggleFieldPreTitle }
                    />
                </PanelBody>
            </InspectorControls>
            <div className={`controls`}>
                <PreTitle { ...props } />
                <Title { ...props } />
            </div>
           </>
        );
    },
    save: ({attributes: { preTitleContent, TitleContent }}) => {

        return(
            <div className={`controls`}>
                <PreTitle.Content { ...props } />
                <Title.Content { ...props } />
            </div>
        );
    }
};

export const headings = registerBlockType(
    `cv-wp-lib-gutenberg-blocks/headings`,
    blockConfig
);
  1. You write an extra component (for example MyGbBlockInspector.js and import it in your block.
// My GB block
import PreTitle from '../components/PreTitle';
import Title from '../components/Title';
import MyGbBlockInspector from '../components/MyGbBlockInspector';

I prefer option 2, although the problem is, that Title and PreTitle are now not global anymore and can't be simply used in other Blocks without rewriting their InspectorControls functions.

3
  • 1
    Thanks for the answer, that is pretty much where I got to too. I was hoping there is some secret undocumented prop for PanelBody where I could pass some sort of reference id and it would unify the content of the preTitle PanelBody and the title PanelBody into one. :)
    – crs1138
    Commented Jun 26, 2020 at 10:08
  • 1
    As far as I know there is not, but if you find something in the source code, don't forget to recomment here, I'd like to know it too :)
    – BonisTech
    Commented Jun 26, 2020 at 13:08
  • 1
    I can confirm there is nothing in place now to do that.
    – Welcher
    Commented Jun 28, 2020 at 1:17

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.