工具栏按钮用于自定义 Gutenberg 区块内特定富文本组件。

huangapple go评论69阅读模式
英文:

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 中,registerFormatTypeformatTypes 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={[&#39;core/italic&#39;]}

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 : () =&gt; {

    const [isRichText1Focus,setIsRichText1Focus] = useState(false)
    const [isRichText2Focus,setIsRichText2Focus] = useState(false)

    return (
        
        &lt;&gt;
        
            {isRichText1Focus &amp;&amp; (

                &lt;BlockControls&gt;
                    &lt;ToolbarGroup&gt;
                        &lt;ToolbarButton
                            icon=&quot;test&quot;
                            title=&quot;Title&quot;
                            onClick={ () =&gt; {
                                //Change a block attribute 
                            } }
                        /&gt;
                    &lt;/ToolbarGroup&gt;
                &lt;/BlockControls&gt;

            )}

            {isRichText2Focus &amp;&amp; (

                &lt;BlockControls&gt;
                    &lt;ToolbarGroup&gt;
                        &lt;ToolbarButton
                            icon=&quot;test 2&quot;
                            title=&quot;Title 2&quot;
                            onClick={ () =&gt; {
                                //Change another block attribute 
                            } }
                        /&gt;
                    &lt;/ToolbarGroup&gt;
                &lt;/BlockControls&gt;

            )}

            &lt;div className=&#39;blockName&#39;&gt;

                &lt;RichText
                    onBlur={() =&gt; {
                        setIsRichText1Focus(false)
                    }}
                    ...//other params
                    unstableOnFocus={() =&gt; {
                        setIsRichText1Focus(true)
                    }}
                /&gt;

                &lt;RichText
                    onBlur={() =&gt; {
                        setIsRichText2Focus(false)
                    }}
                    ...//other params
                    unstableOnFocus={() =&gt; {
                        setIsRichText2Focus(true)
                    }}
                /&gt;

            &lt;/div&gt;
        &lt;/&gt;

    ]) 

}

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(&#39;editor.BlockEdit&#39;, ...)),可能会帮助您看到解决问题的不同方法。

英文:

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(&#39;editor.BlockEdit&#39;, ...) it may help you see a different way to approach the problem.

huangapple
  • 本文由 发表于 2023年3月12日 19:01:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712655.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定