サイドバーに「テキストと背景のカラー設定」を作成する「my-first-block」

サイドバーに「テキストと背景のカラー設定」を作成する「my-first-block」

ここでは2つの方法を書いている。
1つは簡単に追加できるがコントロール名がデフォルトの設定のままで変更できない。しかし、これで問題ないと思う。十分使えるから。
もう一つはチェット複雑になるが、コントール設定で自由に名前を設定できる方法である。

簡単にサイドバーにカラーコントロールを追加する方法

最初は非常に簡単にサイドバーに色のコントロールを追加表示する方法になる。これはWordPressのデフォルト設定のテキストになるので変更することはできない。
もし変更する場合は、この後の記事に記述しているので参考にしてください。

ユーザーがブロックのテキストの色と背景色コントロールを簡単にサイドバーに追加するには、block.json の supports プロパティに以下のように color プロパティを追加します(13行目)。

この例では color プロパティの値に空のオブジェクトを指定していますが、この設定でもデフォルトで text と background が true なのでテキストと背景の色のコントロールが表示されます。

以下のように13行目に「”color”: {}」を追加するだけ。

{
  "$schema": "https://schemas.wp.org/trunk/block.json",
  "apiVersion": 3,
  "name": "create-block/multi-columns",
  "version": "0.1.0",
  "title": "Multi Columns",
  "category": "design",
  "icon": "columns",
  "description": "Example block scaffolded with Create Block tool.",
  "example": {},
  "supports": {
    "html": true,
    "color": {}
  },
  "attributes": {
    "content": {
      "type": "string",
      "source": "html",
      "selector": "p"
    }
  },
  "textdomain": "multi-columns",
  "editorScript": "file:./index.js",
  "editorStyle": "file:./index.css",
  "style": "file:./style-index.css",
  "viewScript": "file:./view.js"
}

このように、block.jsonに「”color”: {}」を追加するだけで、以下のようにインスペクターパネルに [色]のコントロールが表示され、しかもテキストも背景も実際に設定できるようになる。
ただ、右サイドのコントロールで表示されているテキストはデフォルト設定のままで変更できない。

color プロパティでは値に空のオブジェクトを指定することができますが、プロパティにより指定する値の形式は異なります。
例えば、spacing プロパティの場合、以下のようにどの間隔(margin や padding)を有効にするかを個別に指定する必要があります。

つまり、この説明はプロパティの種類により空でも良い場合と、空ではダメな場合もあるということ。

グラデーションをカラーピッカーに追加する

また、以下では color に “gradients”: true (14行目)を追加して色の背景色でグラデーションを有効にしています。

ここでは、ついでに「パディング」「マージン」「blockGap:ブロックの間隔」の設定も追加している。
これだけで機能するようになる。

{
  "$schema": "https://schemas.wp.org/trunk/block.json",
  "apiVersion": 3,
  "name": "create-block/multi-columns",
  "version": "0.1.0",
  "title": "Multi Columns",
  "category": "design",
  "icon": "columns",
  "description": "Example block scaffolded with Create Block tool.",
  "example": {},
  "supports": {
    "html": true,
    "color": {
      "gradients": true
    },
    "spacing": {
      "margin": true,
      "padding": true,
      "blockGap": true
    }
  },
  "attributes": {
    "content": {
      "type": "string",
      "source": "html",
      "selector": "p"
    }
  },
  "textdomain": "multi-columns",
  "editorScript": "file:./index.js",
  "editorStyle": "file:./index.css",
  "style": "file:./style-index.css",
  "viewScript": "file:./view.js"
}

上記を保存すると、サイズ(spacing)のコントロールが追加されます。また、背景色を選択すると color に gradients を追加したので「グラデーション」のタブが追加されます。

チョット面倒になるが、同じくカラーのコントロール追加方法、コントロール設定で希望のテキストを入れることができるようになる方法

サイドバーでテキストと背景のカラーを設定する設定を作成。

コントロールは、ブロック設定サイドバーにも追加できます(アプリケーション用に新規サイドバーを作成することも)。

APIとしては、InspectorControlsコンポーネントがあります。

ブロックエディターハンドブックで、設定サイドバーの使い方を以下のように説明しています。

設定サイドバーは、あまり使わない設定や、大きな画面スペースが必要な設定で使用されます。設定サイドバーはブロックレベル設定でのみ使用してください。

ブロック内の選択したコンテンツでのみ有効な設定は(例:段落内の選択したテキストに対する「太字」設定)、設定サイドバーの中に置かないでください。設定サイドバーはHTMLモードでブロックを編集するときにも表示されるため、ブロックレベルの設定のみを配置する必要があります。

再び、同じ手順で進めます。

  1. edit.js」で、WordPressパッケージから必要なコンポーネントをインポートする
  2. edit.js」で、JSXコードに対応する要素を追加する
  3. block.json」で、必要な属性を定義する
  4. edit.js」で、イベントハンドラを定義する
  5. save.js」で、データを保存する

ステップ1. @wordpress/block-editorからInspectorControlsとPanelColorSettingsコンポーネントをインポートする

ブロックの特定部分をカスタマイズできるようにするには、必要なコントロールを追加します。例えば、カラーコントロールパネルを実装するには、block-editorモジュールからInspectorControlsPanelColorSettingsコンポーネントをインポートします。

import { 
	useBlockProps, 
	RichText, 
	AlignmentControl, 
	BlockControls,
	InspectorControls,
	PanelColorSettings
} from '@wordpress/block-editor';

ステップ2. JSXコードに対応する要素を追加する

次に、Edit関数が返すJSXに、対応する要素を追加します。

※ JSXとは、JavaScriptにHTMLのような構文を拡張したもので、ReactでUIを記述する際に使われ、HTMLのような記述でコンポーネントを定義できる。

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();

	const { content, align, backgroundColor, textColor } = attributes;

	const onChangeContent = ( newContent ) => {
		setAttributes( { content: newContent } )
	}
	const onChangeAlign = ( newAlign ) => {
		setAttributes( { 
			align: newAlign === undefined ? 'none' : newAlign, 
		} )
	}
	return (
		<>
			<InspectorControls>
				<PanelColorSettings 
					title={ __( 'Color settings', 'ka-example-block' ) }
					initialOpen={ false }
					colorSettings={ [
						{
						  value: textColor,
						  onChange: onChangeTextColor,
						  label: __( 'Text color', 'ka-example-block' )
						},
						{
						  value: backgroundColor,
						  onChange: onChangeBackgroundColor,
						  label: __( 'Background color', 'ka-example-block' )
						}
					] }
				/>
			</InspectorControls>
			<BlockControls>
				<AlignmentControl
					value={ align }
					onChange={ onChangeAlign }
				/>
			</BlockControls>
			<RichText 
				{ ...blockProps }
				tagName="p"
				onChange={ onChangeContent }
				allowedFormats={ [ 'core/bold', 'core/italic' ] }
				value={ content }
				placeholder={ __( 'テキストを書く...' ) }
				style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
			/>
		</>
	);
}

ステップ3. block.jsonに必要な属性を定義する

ここで、block.jsonファイルにbackgroundColortextColor属性を定義します。

"attributes": {
	"content": {
		"type": "string",
		"source": "html",
		"selector": "p"
	},
	"align": {
		"type": "string",
		"default": "none"
	},
	"backgroundColor": {
		"type": "string"
	},	 
	"textColor": {
		"type": "string"
	}
},

ステップ4. イベントハンドラを定義する

次に、入力に応じてbackgroundColortextColorを更新する2つの関数を定義します。

const onChangeBackgroundColor = ( newBackgroundColor ) => {
	setAttributes( { backgroundColor: newBackgroundColor } )
}

const onChangeTextColor = ( newTextColor ) => {
	setAttributes( { textColor: newTextColor } )
}

ステップ5. データを保存する

最後にsave.jsファイルを開き、スクリプトを以下のように変更します。

変更前:

export default function save( { attributes } ) {
	const { content, align } = attributes;
	const blockProps = useBlockProps.save( {
		className: `has-text-align-${ align }`
	} );

	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ content } 
			style={ { textAlign: align } }
		/>
	);
}

変更後:

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	const { content, align, backgroundColor, textColor } = attributes;

	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ content } 
			style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
		/>
	);
}

ファイルを保存して、エディターでブロックを確認します。ブロックに予期せぬ、または無効なコンテンツが含まれていることを知らせるエラーメッセージが表示される場合があります。

ファイルを保存して、エディターでブロックを確認します。ブロックに予期せぬ、または無効なコンテンツが含まれていることを知らせるエラーメッセージが表示される場合があります。

予期せぬ、または無効なコンテンツのエラーメッセージ
予期せぬ、または無効なコンテンツのエラーメッセージ

このエラーは、save.jsファイルが変更され、データベースに保存されたコードがエディターで使用されているコードと一致しない時に発生します。

これを修正するには、ページを更新し、ブロックのインスタンスを一度削除して、再度投稿に追加してください。

変更を加え、投稿を保存して、フロントエンドで表示します。ブロックエディターで行った変更が、サイトにも反映されているはずです。

このように色を変えることも出来たし、テキストの揃えも機能している。

ここまでの成功したblock.jsonファイル

これをコピーして使う場合は4行目と14行目にある「”name”: “ka-example-block/ka-example-block”」「”textdomain”: “ka-example-block”」を使用しているブロック名に変える必要があることに注意!

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "ka-example-block/ka-example-block",
	"version": "0.1.0",
	"title": "Kinsta Academy Block",
	"category": "widgets",
	"icon": "superhero-alt",
	"description": "An example block for Kinsta ",
	"example": {},
	"supports": {
		"html": false
	},
	"textdomain": "ka-example-block",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css",
	"viewScript": "file:./view.js",
	"keywords": [ 
		"kinsta", 
		"academy", 
		"superhero" 
	],
	"attributes": {
		"content": {
			"type": "string",
			"source": "html",
			"selector": "p"
		},
		"align": {
			"type": "string",
			"default": "none"
		},
		"backgroundColor": {
			"type": "string"
		},	 
		"textColor": {
			"type": "string"
		}
	}
}

ここまでの成功したedit.jsファイル

コードが薄くなく、全てまともな色で表示されていると正常に表示されるハズである。

import { __ } from '@wordpress/i18n';

// import { useBlockProps } from '@wordpress/block-editor'; //最初の記述
import { 
	useBlockProps, 
	RichText, 
	AlignmentControl, 
	BlockControls,
	InspectorControls,
	PanelColorSettings
} from '@wordpress/block-editor';

import './editor.scss';

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();

	const { content, align, backgroundColor, textColor } = attributes;

	const onChangeContent = ( newContent ) => {
		setAttributes( { content: newContent } )
	}

	const onChangeAlign = ( newAlign ) => {
		setAttributes( { 
			align: newAlign === undefined ? 'none' : newAlign, 
		} )
	}

	const onChangeBackgroundColor = ( newBackgroundColor ) => {
		setAttributes( { backgroundColor: newBackgroundColor } )
	}

	const onChangeTextColor = ( newTextColor ) => {
		setAttributes( { textColor: newTextColor } )
	}
	
	return (
		<>
			<InspectorControls>
				<PanelColorSettings 
					title={ __( 'Color settings', 'ka-example-block' ) }
					initialOpen={ false }
					colorSettings={ [
						{
						  value: textColor,
						  onChange: onChangeTextColor,
						  label: __( 'Text color', 'ka-example-block' )
						},
						{
						  value: backgroundColor,
						  onChange: onChangeBackgroundColor,
						  label: __( 'Background color', 'ka-example-block' )
						}
					] }
				/>
			</InspectorControls>
			<BlockControls>
				<AlignmentControl
					value={ align }
					onChange={ onChangeAlign }
				/>
			</BlockControls>
			<RichText 
				{ ...blockProps }
				tagName="p"
				onChange={ onChangeContent }
				allowedFormats={ [ 'core/bold', 'core/italic' ] }
				value={ content }
				placeholder={ __( 'Write your text...' ) }
				style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
			/>
		</>
	);
}

ここまでの成功したsave.jsファイル

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

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	const { content, align, backgroundColor, textColor } = attributes;

	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ content } 
			style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
		/>
	);
}