ブロックの作成⑦ラベルタブ付きボックスの作成【useInnerBlocksPropsでネスト構造とする】
ラベルタブ付きボックス用のブロックを自作していきます。次のようなボックスです。
以下の機能を盛り込みます。
- ラベル部と本文入力欄の2つのパートからなるボックスとする
- ラベル部には任意のテキストを入力し、左・中央・右の配置調整ができる
- 本文入力欄では、任意のブロックを配置して好きなコンテンツを作成できる
- 以下の配色を可能とする
・ボックス全体の枠線
・ラベル部の文字色と背景色
・本文入力欄の背景色
ラベルタブ付きボックスの基本構造
ラベル部にはRichTextコンポーネント、本文入力欄にはuseInnerBlocksPropsを使うことでネスト構造を作成することができます。
この場合のedit.jsとsave.jsの基本構成は以下の通りです。
edit.js
<div {...useBlockProps( )} > <RichText /> <div {...useInnerBlocksProps( )} ></div> </div>
save.js
<div {...useBlockProps.save( )} > <RichText.Content /> <div {...useInnerBlocksProps.save( )} ></div> </div>
RichTextコンポーネントの使い方については、以下の記事を参照ください。
useInnerBlocksPropsについて
useInnerBlocksPropsは、ワードプレスversion5.9から使えるようになった、比較的新しいフックです。
version5.9以前は、ネスト構造を作成するために<innerBlocks />コンポーネントを使用する必要がありましたが、HTML階層が深くなってしまい使い勝手が今いちでした。
useInnerBlocksPropsは、version5.8の頃でも__experomentalUserInnerBlocksPropsをuseInnerBlocksPropsとしてインポートする、という裏技で使えましたが、version5.9で正式リリースされたものです。これにしたがい、__experimentalUseInnerBlocksPropsは廃止になりました。
ラベルタブ付きブロックの骨格を作成
まずは、文字の配置や配色設定は抜きにして、ブロックの骨格となる基本構造を作成していきます。
- ラベル部と本文入力欄の2つのパートからなるボックスとする
- ラベル部には任意のテキストを入力できるようにする
- 本文入力欄では、任意のブロックを配置して好きなコンテンツを作成できる
手順概要
- create-blockでブロック雛形を作成(label-tab-boxという名前で作成する)
- プラグインlabel-tab-blockを有効化
- srcフォルダ内の各ファイルを書き換えてbuildする
①ブロック雛形の作成方法については、次の記事を参照ください。
手順①②については進めたものとして、以下では手順③の各ファイルの記述内容について紹介していきます。
各ファイルの記述内容
出来上がった雛形をベースにして、以下の内容に変更します。
block.json
雛形からの変更内容は以下の通りです。
- category,icon,descriptionを適宜変更
- supportsにclassName, align, alignwide, spacing の記述を追加
- RichText(ラベル部)の中味となるattributes.boxTitleを追加
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "create-block/label-tab-box",
"version": "0.1.0",
"title": "Label Tab Box",
"category": "design",
"icon": "media-document",
"description": "ラベルタブ付ボックス",
"supports": {
"html": false,
"className": false,
"align": true,
"alignWide": true,
"spacing": {
"padding":true
},
"anchor": true
},
"attributes": {
"boxTitle": {
"type":"string",
"source": "html",
"selector": ".my-label-tab-box__title"
}
},
"textdomain": "label-tab-box",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
supportsに追記した内容については、以下の記事を参照ください。
またsupportsでcolorの設定をしなかった理由については、後述します。
edit.js
基本構成をもう一度書いておきます。
<div {...useBlockProps( )} > <RichText /> <div {...useInnerBlocksProps( )} ></div> </div>
雛形からの変更内容は以下の通りです。
- useInnerBlocksProps,RichTextをインポート
- 上記基本構成を記述
- 各要素のクラス名を以下のように指定
・ブロックのコンテナ(useBlockProps):my-label-tab-box
・ラベル部(RichText):my-label-tab-box__title
・本体(useInnerBlocksProps):my-label-tab-box__body - RichTextの各属性を指定。onChangeでattributes.boxTitleを書き換える記述もする。
import { __ } from '@wordpress/i18n';
import {
useBlockProps,
useInnerBlocksProps,
RichText
} from '@wordpress/block-editor';
import './editor.scss';
export default function Edit({attributes, setAttributes}) {
const blockProps = useBlockProps({
className: 'my-label-tab-box',
});
const innerBlocksProps = useInnerBlocksProps({
className: 'my-label-tab-box__body',
});
return (
<div { ...blockProps }>
<RichText
tagName = 'div'
className = 'my-label-tab-box__title'
value = { attributes.boxTitle }
placeholder = 'ここにタイトルを入力'
onChange = { ( newTitle ) => {
setAttributes({ boxTitle: newTitle });
}}
/>
<div {...innerBlocksProps}>
</div>
</div>
);
}
save.js
基本構成をもう一度書いておきます。
<div {...useBlockProps.save( )} > <RichText.Content /> <div {...useInnerBlocksProps.save( )} ></div> </div>
この基本構成をベースに、edit.jsと同様にコンポーネントのインポートやクラス名の付与、およびRichTextへの属性記述を行います。
import { __ } from '@wordpress/i18n';
import {
useBlockProps,
useInnerBlocksProps,
RichText
} from '@wordpress/block-editor';
export default function save({attributes}) {
const blockProps = useBlockProps.save({
className: 'my-label-tab-box'
});
const innerBlocksProps = useInnerBlocksProps.save({
className: 'my-label-tab-box__body',
});
return (
<div { ...blockProps }>
<RichText.Content {...blockProps}
tagName = 'div'
className = 'my-label-tab-box__title'
value = { attributes.boxTitle }
/>
<div {...innerBlocksProps}>
</div>
</div>
);
}
各scssファイル
stylscssの記述は現段階では不要なので削除します。
editor.scssは雛形記述のままとします(念のため以下の通りです)。
.wp-block-create-block-label-tab-box {
border: 1px dotted #f00;
}
ここまでで出来上がったラベルタブ付きブロック
ここまで出来上がったブロックを確認します。
ブロックカテゴリーの”デザイン”に”Label Tab Block”という名前で表示されます。ブロックエディターの本文内に挿入配置して、ブロックの外観を確認します。
ブロックの各設定部(ツールバー・設定サイドバー)には、block.jsonのsupportsの設定が反映されています。
ラベル入力部へのテキスト入力と本文入力欄へ任意のブロックを配置(例として段落とリストブロックを配置)してみます。
プレビューして、フロント側の表示(web表示)とそのときのHTML構造を確認すると次の通りです。
目論見どおりにブロックが出来上がっているのが確認できました。各部要素につけたクラス名も問題ありません。
ラベルテキストの配置・各部配色の設定を追加する
ブロックの基本構造が出来上がったので、ラベル部のテキスト配置や枠線・配色の設定機能をブロックに追加していきましょう。
- ラベル部のテキストの左・中央・右の配置調整ができる
- 以下の配色を可能とする
・ボックス全体の枠線
・ラベル部の文字色と背景色
・本文入力欄の背景色
ラベル部のテキスト配置は、<BlockControls>コンポーネントを介して<AlignmentToolbar />を設置し、ブロック内ツールバーで設定できるようにします。
また枠線色と各部の配色は、<InspectorControls>を介して<colorPalette />を設置し、設定サイドバーで設定できるようにします。
block.jsonのsupportsで色の設定をしない理由
記事:ブロックの作成⑥自作ブロックに色・フォント設定機能を簡単に実装【block.jsonのsupportsを活用】 で紹介したように、block.jsonのsupportsにcolor設定をすれば、わざわざ<ColorPalette />を使わなくても文字色や背景色の設定ができますが、今回は使用しません。
supportsでの設定が反映されるのは、useBlockPropsを配置するブロック全体のコンテナ要素であって、今回のように配色対象がコンテナ要素の中で各要素に分かれている場合には適用できないのです。
仮にsupportsにcolor設定の記述をして背景色を橙色に設定した場合、ブロック全体に適用されることになります。仮に本文入力欄の各ブロック(段落とリストブロック)を白背景としても、ブロック間の余白には橙色が残ることになります。
各コンポーネントを追記
それでは各コンポーネントを配置して設定を追加します。詳細の手順はすでに紹介した記事を参考にしていただくとして、ここではコードの結果のみ紹介します。
block.json
追加記述は以下の通りです。
- attributesに各設定用の記述をする
・boxTitle_alignment:ラベル部テキストの配置(デフォルト値はnone)
・boxBorderColor:ボックス全体の枠線色(デフォルト値は#333)
・boxTitle_bgColor:ラベル部の背景色(デフォルト値は#eee)
・boxTitle_color:ラベル部の文字色(デフォルト値は#333)
・boxBody_bgColor:本文入力欄の背景色(デフォルト値は#fff)
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "create-block/label-tab-box",
"version": "0.1.0",
"title": "Label Tab Box",
"category": "design",
"icon": "media-document",
"description": "ラベルタブ付ボックス",
"supports": {
"html": false,
"className": false,
"align": true,
"alignWide": true,
"spacing": {
"padding":true
},
"anchor": true
},
"attributes": {
"boxTitle": {
"type":"string",
"source": "html",
"selector": ".my-label-tab-box__title"
},
"boxTitle_alignment": {
"type": "string",
"default": "none"
},
"boxBorderColor": {
"type": "string",
"default": "#333"
},
"boxTitle_bgColor": {
"type": "string",
"default": "#eee"
},
"boxTitle_color": {
"type": "string",
"default": "#333"
},
"boxBody_bgColor": {
"type": "string",
"default": "#fff"
}
},
"textdomain": "label-tab-box",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
edit.js
追加記述は以下の通りです。
- 各コンポーネントのインポート
- 各要素の属性にstyle記述をする
style: { (CSS変数): (各attibutes変数) }の形式で記述 - 各コンポーネントの追加記述
・<BlockControls>の中に<AlignmentToolbar />を配置し、attributes.boxTitle_alignmentをonChnageで更新
・<InspectorControls>の中に<Panel><panelBody>を介して<ColorPalette/>を配置(枠線色・ラベル背景色・ラベル文字色・本文背景色の4種類)。各ColorPalette内には対応するattributesの変数をonChangeで更新する記述をする
import { __ } from '@wordpress/i18n';
import {
useBlockProps,
useInnerBlocksProps,
RichText,
BlockControls,
AlignmentToolbar,
InspectorControls,
ColorPalette
} from '@wordpress/block-editor';
import {
Panel,
PanelBody
} from '@wordpress/components'
import './editor.scss';
export default function Edit({attributes, setAttributes}) {
const blockProps = useBlockProps({
className: 'my-label-tab-box',
style: {
'--box_bordercolor': attributes.boxBorderColor
}
});
const innerBlocksProps = useInnerBlocksProps({
className: 'my-label-tab-box__body',
style: {
'--boxbody_bgcolor': attributes.boxBody_bgColor
}
});
return (
<>
<div { ...blockProps }>
<RichText
tagName = 'div'
className = 'my-label-tab-box__title'
value = { attributes.boxTitle }
placeholder = 'ここにタイトルを入力'
style = {{
textAlign: attributes.boxTitle_alignment || null,
'--boxtitle_bgcolor': attributes.boxTitle_bgColor,
'--boxtitle_color': attributes.boxTitle_color
}}
onChange = { ( newTitle ) => {
setAttributes({ boxTitle: newTitle });
}}
/>
<div {...innerBlocksProps}>
</div>
</div>
<BlockControls>
<AlignmentToolbar
value = {attributes.boxTitle_alignment }
onChange = {( newAlignment ) => {
setAttributes({ boxTitle_alignment: newAlignment })
}}
/>
</BlockControls>
<InspectorControls>
<Panel header="色の設定">
<PanelBody title="枠線色">
<ColorPalette
onChange = {( newBorderColor ) => {
setAttributes({ boxBorderColor: newBorderColor });
}}
/>
</PanelBody>
<PanelBody title="ラベル背景色">
<ColorPalette
onChange = {( newTitleBgColor ) => {
setAttributes({ boxTitle_bgColor: newTitleBgColor });
}}
/>
</PanelBody>
<PanelBody title="ラベル文字色">
<ColorPalette
onChange = {( newTitleColor ) => {
setAttributes({ boxTitle_color: newTitleColor });
}}
/>
</PanelBody>
<PanelBody title="本文背景色">
<ColorPalette
onChange = {( newBodyBgColor ) => {
setAttributes({ boxBody_bgColor: newBodyBgColor });
}}
/>
</PanelBody>
</Panel>
</InspectorControls>
</>
);
}
save.js
edit.js同様、各要素の属性にstyle記述を追加します。
import { __ } from '@wordpress/i18n';
import {
useBlockProps,
useInnerBlocksProps,
RichText
} from '@wordpress/block-editor';
export default function save({attributes}) {
const blockProps = useBlockProps.save({
className: 'my-label-tab-box',
style: {
'--box_bordercolor': attributes.boxBorderColor
}
});
const innerBlocksProps = useInnerBlocksProps.save({
className: 'my-label-tab-box__body',
style: {
'--boxbody_bgcolor': attributes.boxBody_bgColor
}
});
return (
<div { ...blockProps }>
<RichText.Content {...blockProps}
tagName = 'div'
className = 'my-label-tab-box__title'
value = { attributes.boxTitle }
style = {{
textAlign: attributes.boxTitle_alignment || null,
'--boxtitle_bgcolor': attributes.boxTitle_bgColor ,
'--boxtitle_color': attributes.boxTitle_color
}}
/>
<div {...innerBlocksProps}>
</div>
</div>
);
}
style.scss
edit.jsおよびsave.jsで記述したCSS変数を使って、配色のスタイルを記述します。
paddingは好みで設定してください。
.my-label-tab-box {
border: 1px solid var(--box_bordercolor, #333);
}
.my-label-tab-box__title {
background-color: var(--boxtitle_bgcolor, #eee);
color: var(--boxtitle_color, #333);
padding: 0.5em 1em;
}
.my-label-tab-box__body {
background-color: var(--boxbody_bgcolor, #fff);
padding: 0.5em 1em;
}
editor.scss
style.scssでスタイルを記述したので、editor.scssの記述は空としておきます。
完成形のラベルタブ付きボックスを確認
完成形となったラベルタブ付きボックスを確認します。
基本形にはなかった各設定(ラベル部テキストの配置、各部の配色設定)が追加されているのがわかります。
試しにラベル部のテキストを中央寄せ、各部の配色を設定してみると目論見どおり表示されます。
配色の自由度が高いので、結構いろいろ使えると思います。
まとめ
今回はuseInnerBlocksPropsを使って、他のブロックを挿入できるネスト構造のブロックとして、ラベルタブ付きボックスを作成してみました。
他のコンポーネントも導入することで次の機能を持たせることができています。
- ラベル部と本文入力欄の2つのパートからなるボックスとする
- ラベル部には任意のテキストを入力し、左・中央・右の配置調整ができる
- 本文入力欄では、任意のブロックを配置して好きなコンテンツを作成できる
- 以下の配色を可能とする
・ボックス全体の枠線
・ラベル部の文字色と背景色
・本文入力欄の背景色
さらにblock.jsonにstylesを記述してブロックスタイルも追加すれば、ラベル部の表示形式をタブ状にしたり、枠線を点線にするなども機能として追加することができます。
自作ブロックへのブロックスタイルの追加方法は、こちらの記事内で紹介しているので参考にしてみてください。