The documentation for InnerBlock has a prop renderAppender which can be used to add a custom button. In the example:
// Fully custom
<InnerBlocks
renderAppender={ () => (
<button className="bespoke-appender" type="button">Some Special Appender</button>
) }
/>
the custom button does nothing on click. How can open the Block Picker Menu on click of the custom button?
The documentation for InnerBlock has a prop renderAppender which can be used to add a custom button. In the example:
// Fully custom
<InnerBlocks
renderAppender={ () => (
<button className="bespoke-appender" type="button">Some Special Appender</button>
) }
/>
the custom button does nothing on click. How can open the Block Picker Menu on click of the custom button?
Share Improve this question asked May 30, 2020 at 13:01 Siddharth ThevarilSiddharth Thevaril 5676 silver badges22 bronze badges 2 |2 Answers
Reset to default 2So I'm answering the following: How to open the block picker menu via a custom button. I.e. Without using InnerBlocks.ButtonBlockAppender
. :)
How can I open the Block Picker Menu on click of the custom button?
There's no (as of writing) "standard" function (like alert()
) that you can simply call which then opens the block picker menu; however, you can wrap your button in a Inserter
component (wp.blockEditor.Inserter
) and call it's onToggle
method/function on clicking your button.
Here's a simplified example based on ButtonBlockAppender
(the base component that's used by InnerBlocks.ButtonBlockAppender
) for the Gutenberg plugin version 8.2.1.
// WordPress dependencies.
import { Inserter, InnerBlocks } from '@wordpress/block-editor';
import { IconButton } from '@wordpress/components';
import { registerBlockType } from '@wordpress/blocks';
function MyButtonBlockAppender( { rootClientId } ) {
return (
<Inserter
rootClientId={ rootClientId }
renderToggle={ ( { onToggle, disabled } ) => (
<IconButton
className="my-button-block-appender"
onClick={ onToggle }
disabled={ disabled }
label="Add a Block"
icon="plus"
/>
) }
isAppender
/>
);
}
registerBlockType( 'my-plugin/my-block', {
title: 'My Block',
category: 'common',
edit( { className, clientId } ) {
return (
<div className={ className }>
Click the button to add your 1st image/paragraph.
<InnerBlocks
allowedBlocks={ [ 'core/image', 'core/paragraph' ] }
renderAppender={ () => (
<MyButtonBlockAppender rootClientId={ clientId } />
) }
/>
</div>
);
},
save() {
return (
<div>
<InnerBlocks.Content />
</div>
);
},
} );
So as I said, that's a simplified example. You can just copy the original ButtonBlockAppender
component and modify it to tailor your requirements.
Happy coding!
Custom renderAppenders
require that you create all of the functionality of inserting blocks yourself. This is one I created a little while ago to only allow a single block to be inserted, you could modify the code as needed for your purposes.
/**
* WordPress Imports
*/
const { createBlock } = wp.blocks;
const { Button } = wpponents;
const { withSelect, withDispatch } = wp.data;
const { compose } = wppose;
const { __ } = wp.i18n;
/**
* Custom Appender meant to be used when there is only one type of block that can be inserted to an InnerBlocks instance.
*
* @param buttonText
* @param onClick
* @param clientId
* @param allowedBlock
* @param innerBlocks
* @param {Object} props
*/
const SingleBlockTypeAppender = ( { buttonText = __( 'Add Item' ), onClick, clientId, allowedBlock, innerBlocks, ...props } ) => {
return(
<Button onClick={ onClick } { ...props} >
{buttonText}
</Button>
);
};
export default compose( [
withSelect( ( select, ownProps ) => {
return {
innerBlocks: select( 'core/block-editor' ).getBlock( ownProps.clientId ).innerBlocks
};
} ),
withDispatch( ( dispatch, ownProps ) => {
return {
onClick() {
const newBlock = createBlock( ownProps.allowedBlock );
dispatch( 'core/block-editor' ).insertBlock( newBlock, ownProps.innerBlocks.length, ownProps.clientId );
}
};
} )
] )( SingleBlockTypeAppender );
You can then use it like this:
<InnerBlocks
renderAppender={
() =>
<SingleBlockTypeAppender
isDefault
isLarge
buttonText="Add Block"
allowedBlock="block/slug"
clientId={ this.props.clientId }
/>
}
/>
Hope this helps!
onClick={ ( event ) => console.log( event ) }
- just call the appropriate function or whatever is needed on click. – Sally CJ Commented May 30, 2020 at 18:09