カスタムブロック作成 アコーディオンブロックを開発

準備

プラグインディレクトリでコマンド実行

$ npx @wordpress/create-block dojo-block
$ cd todo-list
$ npm start

ダッシュボードでプラグインを有効化する

プラグイン作成

edit.jsを編集、<details>タグを追加

export default function Edit() {
	return (
		<details>
			<summary>システム要件</summary>
			<p>
				オペレーティングシステムを実行するコンピューターが必要です。コンピューターにはメモリーがあり、できれば何らかの長期保存用の記憶装置があること。入力機器と何らかの出力機器を推奨。
			</p>
		</details>
	);

	// return (
	// 	<p {...useBlockProps()}>
	// 		{__("Dojo Block – hello from the editor!", "dojo-block")}
	// 	</p>
	// );
}

ブロックとして認識されないため、インライン装飾が有効化していない。

ブロックとして認識されるためには{…useBlockProps()}が必要

export default function Edit() {
	return (
		<details {...useBlockProps()}>
			<summary>システム要件</summary>
			<p>
				オペレーティングシステムを実行するコンピューターが必要です。コンピューターにはメモリーがあり、できれば何らかの長期保存用の記憶装置があること。入力機器と何らかの出力機器を推奨。
			</p>
		</details>
	);
}

ブロックとして認識され、基本機能は完成

ただし、クリックすると閉じてしまうため、編集できない。

エディター側のみ<details>と<summary>タグを<div>に書き換える。フロントは<details>と<summary>のまま。

export default function Edit() {
	return (
		<div {...useBlockProps()}>
			<div>システム要件</div>
			<p>
				オペレーティングシステムを実行するコンピューターが必要です。コンピューターにはメモリーがあり、できれば何らかの長期保存用の記憶装置があること。入力機器と何らかの出力機器を推奨。
			</p>
		</div>
	);
}

CSSクラスを当てる

export default function Edit() {
	return (
		<div {...useBlockProps()}>
			<div className="wp-block-create-block-dojo-block__title">
				システム要件
			</div>
			<p className="wp-block-create-block-dojo-block__content">
				オペレーティングシステムを実行するコンピューターが必要です。コンピューターにはメモリーがあり、できれば何らかの長期保存用の記憶装置があること。入力機器と何らかの出力機器を推奨。
			</p>
		</div>
	);
}

style.scssを編集

edit.jsを編集、RichTextをインポート

import { __ } from "@wordpress/i18n";
import { RichText, useBlockProps } from "@wordpress/block-editor";
import "./editor.scss";

export default function Edit() {
	return (
		<div {...useBlockProps()}>
			<RichText className="wp-block-create-block-dojo-block__title" />
			<RichText className="wp-block-create-block-dojo-block__content" />
		</div>
	);
}

<div>を<p>でレンダリング、プレースホルダーを追加

export default function Edit() {
	return (
		<div {...useBlockProps()}>
			<RichText
				className="wp-block-create-block-dojo-block__title"
				placeholder="ここにタイトル"
			/>
			<RichText
				className="wp-block-create-block-dojo-block__content"
				placeholder="ここにコンテンツ"
				tagName="p"
			/>
		</div>
	);
}

block.jsonを編集、テキスト保存する

	"supports": {
		"html": false
	},
	"attributes": {
		"title": {
			"type": "string",
			"default": "タイトル"
		},
		"content": {
			"type": "string",
			"default": "コンテンツ"
		}
	},
	"textdomain": "dojo-block",

attributesを追加、初期値を設定

export default function Edit({ attributes }) {
	const { title, content } = attributes;
	return (
		<div {...useBlockProps()}>
			<RichText
				className="wp-block-create-block-dojo-block__title"
				placeholder="ここにタイトル"
				value={title}
			/>
			<RichText
				className="wp-block-create-block-dojo-block__content"
				placeholder="ここにコンテンツ"
				tagName="p"
				value={content}
			/>
		</div>
	);
}

コンテンツを監視し変化があった時にデフォルト値を更新する

import { __ } from "@wordpress/i18n";
import { RichText, useBlockProps } from "@wordpress/block-editor";
import "./editor.scss";

export default function Edit({ attributes, setAttributes }) {
	const { title, content } = attributes;
	return (
		<div {...useBlockProps()}>
			<RichText
				className="wp-block-create-block-dojo-block__title"
				placeholder="ここにタイトル"
				value={title}
				onChange={(value) => {
					setAttributes({ title: value });
				}}
			/>
			<RichText
				className="wp-block-create-block-dojo-block__content"
				placeholder="ここにコンテンツ"
				tagName="p"
				value={content}
				onChange={(value) => {
					setAttributes({ content: value });
				}}
			/>
		</div>
	);
}

更新ボタンが活性化する

save.jsに保存処理を書く

import { RichText, useBlockProps } from "@wordpress/block-editor";

export default function save({ attributes }) {
	const { title, content } = attributes;
	return (
		<details {...useBlockProps.save()}>
			<RichText.Content
				className="wp-block-create-block-dojo-block__title"
				tagName="summary"
				value={title}
			/>
			<RichText.Content
				className="wp-block-create-block-dojo-block__content"
				tagName="p"
				value={content}
			/>
		</details>
	);
}

開いているときは、アイコンを横線のみにする

.wp-block-create-block-dojo-block {
	background-color: #ccc;
	border-radius: 8px;
	padding: 0.5em;

	&[open] .wp-block-create-block-dojo-block__title::after {
		display: none;
	}
}

ブロックサポートを有効化

block.jsonを編集、コードエディタのコメントを削除

	"supports": {
		"html": false,
		"color": {
			"background": true,
			"text": true
		}
	},
	"attributes": {
		"title": {
			"type": "string",
			"default": "タイトル",
			"selector": "wp-block-create-block-dojo-block__title",
			"source": "html"
		},
		"content": {
			"type": "string",
			"default": "コンテンツ",
			"selector": "wp-block-create-block-dojo-block__content",
			"source": "html"
		}
	},