この記事は「Snow Monkey / unitone Advent Calendar 2025」の12月◯日の記事です。まだまだ枠が空きまくっているのでぜひご参加ください!参加賞もあります!
WordPress のブロックエディターの UI の拡張(設定パネルを追加したり、ツールバーにボタンを追加したり)では、基本的に SlotFill を使います。ですが、UI を拡張したい場所に Slot(差し込みポイント)が存在しない場合はどうしたら良いのでしょうか?という問題に createPortal を使うことで対応できたので、そのことについて書きたいと思います。
SlotFill とは何か
SlotFill は「Slot」と「Fill」という2つの仕組みで構成されます。
- Slot:エディター内にあらかじめ用意された挿入ポイント(WordPress 的に言えばアクションフック的な感じ)
- Fill:
Slotに注入されるコンテンツ(Button、ToggleControl、TextControlなど)
よく利用される Slot の例としては下記のようなものがあります。
InspectorControls(ブロックの設定パネル)BlockControls(ブロックツールバー)PluginDocumentSettingPanel(ドキュメントの設定パネル)
下記はブロックツールバーにボタンを追加する例。
<BlockControls>
<ToolbarButton
icon={ shuffle }
label={ __( 'Shuffle child blocks', 'unitone' ) }
onClick={ shuffleInnerBlocks }
/>
</BlockControls>
SlotFill はあくまで「WordPress があらかじめ用意している差し込みポイント」にしかコンポーネントを追加できません。そのため、コンポーネントを表示したい場所に Slot が用意されていない場合は、別の方法でコンポーネントを追加する必要があります。
createPortal とは何か
React.createPortal は、React コンポーネントの描画先を 任意の DOM 要素 に移すための仕組みです。下記のようなコードで、child を targetElement の中(最後)に追加できます。
createPortal(child, targetElement)
SlotFill が使えない場所にボタンを配置する
下記は、unitone でワイヤーフレームジェネレーターの起動ボタンをブロックエディター自体のツールバー(ブロックのツールバーではない)に追加している例です(いろいろ省略して必要な部分だけ記述しています)。
import { createPortal } from '@wordpress/element';
const PluginSidebarWireFrameGenerator = () => {
// ↓ここにボタンを追加したい
const toolbar = document.querySelector( '.editor-header__toolbar' );
...
return (
<>
{ toolbar &&
createPortal(
<WireFrameGeneratorButton { ...{ isOpen, setIsOpen } } />,
toolbar
) }
{ isOpen && (
<WireframeGeneratorModal .../>
) }
</>
);
};
registerPlugin( 'unitone-wireframe-generator', {
render: PluginSidebarWireFrameGenerator,
} );

コメントを残す