英文:
Toolbar buttons for specific Richtext components inside custom Gutenberg block
问题
我有一个自定义的 Gutenberg 区块,里面包含多个 RichText 组件。我需要为不同的 RichText 组件显示特定的 ToolbarButtons,以类似于 formatTypes 的本机方法的用户体验,例如:
allowedFormats={['core/italic']}
将显示 RichText 元素的斜体控件。我不希望使用 registerFormatType
,因为这些控件会保存区块属性,而不是调整富文本格式。这让我进行了一些实验,我在这里伪代码表示了几乎可以工作的概念:
edit: () => {
const [isRichText1Focus, setIsRichText1Focus] = useState(false)
const [isRichText2Focus, setIsRichText2Focus] = useState(false)
return (
<>
{isRichText1Focus && (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon="test"
title="Title"
onClick={() => {
// 更改区块属性
}}
/>
</ToolbarGroup>
</BlockControls>
)}
{isRichText2Focus && (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon="test 2"
title="Title 2"
onClick={() => {
// 更改另一个区块属性
}}
/>
</ToolbarGroup>
</BlockControls>
)}
<div className='blockName'>
<RichText
onBlur={() => {
setIsRichText1Focus(false)
}}
...//其他参数
unstableOnFocus={() => {
setIsRichText1Focus(true)
}}
/>
<RichText
onBlur={() => {
setIsRichText2Focus(false)
}}
...//其他参数
unstableOnFocus={() => {
setIsRichText2Focus(true)
}}
/>
</div>
</>
)
}
您可以看到,我的尝试是仅在富文本区域获得焦点时显示某些区块控制按钮。但是,无法可靠地获得覆盖工具栏本身的 "onBlur",因此在 RichText 组件上的 "onBlur" 不合适。在 Gutenberg 中,registerFormatType
和 formatTypes
API 很好地处理了这个问题的可靠焦点/失焦的概念。我是否可以以某种方式使用这种方法来复制这个?或者这个方法是否太巧妙,我应该完全采用不同的方法?最好使用本机的 Toolbar,而不是创建自己的用户界面。
英文:
I have a custom Gutenberg block with multiple RichText components inside. I need to show specific ToolbarButtons for different RichText components, in a similar UX to the native approach for formatTypes, for example:
allowedFormats={['core/italic']}
Will show the italic control for the RichText element. I do not wish to registerFormatType as these controls would save block attributes rather than adjust richtext formatting. It's led me to a few experiments, where I have an almost working concept, pseudocoded here:
edit : () => {
const [isRichText1Focus,setIsRichText1Focus] = useState(false)
const [isRichText2Focus,setIsRichText2Focus] = useState(false)
return (
<>
{isRichText1Focus && (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon="test"
title="Title"
onClick={ () => {
//Change a block attribute
} }
/>
</ToolbarGroup>
</BlockControls>
)}
{isRichText2Focus && (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon="test 2"
title="Title 2"
onClick={ () => {
//Change another block attribute
} }
/>
</ToolbarGroup>
</BlockControls>
)}
<div className='blockName'>
<RichText
onBlur={() => {
setIsRichText1Focus(false)
}}
...//other params
unstableOnFocus={() => {
setIsRichText1Focus(true)
}}
/>
<RichText
onBlur={() => {
setIsRichText2Focus(false)
}}
...//other params
unstableOnFocus={() => {
setIsRichText2Focus(true)
}}
/>
</div>
</>
])
}
You can see my attempt here is to only show certain block control buttons when in focus of a RichText area. However, it isn't possible to get a reliable 'onBlur' that also covers the toolbar itself, so onBlur on the RichText component is inappropriate. There is clearly a concept within Gutenberg for a reliable focus/ blur as registerFormatType and the formatTypes API handle this well. Can I replicate this somehow with this approach? Or is this approach just too hacky, and I should take a different approach completely? Would be wonderful to use the native Toolbar rather than create my own UI alongside.
答案1
得分: 1
我会采用不同的方法,使用InnerBlocks和块变体来创建一个自定义的父块和子块。
父块类似于一个包装块,仅包含InnerBlocks
设置,以通过template
存储自定义子块变体。这使您可以指定子块的初始状态和属性。
子块包含一个RichText
组件,具有定义通过块变体更改的Toolbar
内容的块属性。这样,当选择RichText时,将呈现正确的工具栏;焦点保持在块级别,无需使用setState()
或可能导致不良setState()
调用。
由于您正在使用块控件,我建议将它们实现在块级别。如果您还了解如何将块控件添加到现有的块过滤器(例如,wp.hooks.addFilter('editor.BlockEdit', ...)
),可能会帮助您看到解决问题的不同方法。
英文:
I would take a different approach using InnerBlocks and block variations by creating a custom Parent and Child block.
The Parent block is like a wrapper block, only containing a InnerBlocks
setup, to store the custom Child block variants via a template
. This enables you to specify the initial state of the Child blocks and their attributes.
The Child block contains a RichText
component, with a block attribute that defines the Toolbar
content to change via block variations. This way, the correct toolbar is rendered when the RichText is selected; the focus remains at the block level and no need for setState()
or potential bad setState()
calls.
As you are using Block Controls, I would implement them at the block level. If you also look into how Block Controls can be added to existing block filters, eg wp.hooks.addFilter('editor.BlockEdit', ...)
it may help you see a different way to approach the problem.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论