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.
1 Answer
<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