Gutenberg のカスタムブロックを TypeScript で書く
TypeScript初心者。
静的型付けの経験はほぼ皆無。
さすがに基本的な型は分かる。
Gutenberg は良く分かってない。
画像設定させたりテキスト入力させたりが限度。
ts のトランスパイラやカスタムブロックを WordPress へ組み込む方法については省略。
以上、ご留意。
ブロックエディタの定義ファイルは @types/wordpress__block-editor
。
edit
, save
に返すクラスコンポーネントは @wordpress/element
の Component
を継承すると楽。
React から引っ張ってきても良いけど型の設定が面倒臭い。
edit は BlockEditProps
, save は BlockSavePorps
をジェネリクスとして設定する。
BlockEditProps と BlockSaveProps は @wordpress/blocks
に定義されている。
BlockEditProps と BlockSaveProps には attributes
の interface をジェネリクスとして設定する。
設定は @wordpress/blocks の BlockConfiguration
を設定する。
ジェネリクスは上記で設定した attributes の interface。
attribues の各プロパティには @wordpress/blocks の BlockAttribute<型>
を設定する。(この辺なんか違う気がしてる)
icon
は @wordpress/blocks の BlockIcon
を設定する。
最悪 @types/wordpress__block-editor
を頑張って読めばどうにかなる。
JSX のコンポーネントなのでなんとなくで割と書ける。
分かり辛いのは動的な部分、 attributes
の扱い。
以下のサンプルは動作未確認。
import { Component } from '@wordpress/element';
import {
BlockEditProps,
BlockSaveProps,
BlockAttribute,
BlockIcon,
BlockConfiguration,
registerBlockType
} from '@wordpress/blocks';
import { PlainText } from '@wordpress/block-editor';
interface Attribute {
text: string;
}
interface AttributeEntity {
text: BlockAttribute<string>
}
const icon: BlockIcon = 'layout';
const attributes: AttributeEntity = {
text: {
type: 'string',
source: 'html',
selector: '.text',
},
}
const edit = class extends Component<BlockEditProps<Attributes>> {
render () {
const { className, attributes, setAttributes } = this.props;
return (
<div className="text">
<PlainText
onChange={(text) => setAttributes({text})}
value={attributes.text}
/>
</div>
);
}
};
const save = class extends Component<BlockSaveProps<Attributes>> {
render () {
const { attributes } = this.props;
return (
<div className="text">
{ attributes.text }
</div>
)
}
};
const config: BlockConfiguration<Attributes> = {
title: 'テキスト',
category: 'layout',
icon,
attributes,
edit,
save,
};
registerBlockType('gcb/text', config);