執筆エクスペリエンス

背景

WYSIWYG エディターとしての Gutenberg の基本理念の1つに「編集時の見た目をできる限り公開時の見た目に近づけること」があります。ブロックを作成する場合もこの理念を念頭に置いてください。

プレースホルダー

ブロックが挿入され、まだデータが入力されていない状態を「プレースホルダー」と呼びます。組み込みの Placeholder コンポーネントは標準的な見た目を提供します。プレースホルダーの例は画像ブロックや埋め込みブロックで見られます。

プレースホルダーを使用するには <Placeholder> コンポーネントの子要素となるように <TextControl> コンポーネントをラップします。自分のコードでも試してみてください。更新後は次のようになるはずです。

import { Placeholder, TextControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export default function Edit( { attributes, className, setAttributes } ) {
    return (
        <div className={ className }>
            <Placeholder
                label="Gutenpride Block"
                instructions="Add your message"
            >
                <TextControl
                    value={ attributes.message }
                    onChange={ ( val ) => setAttributes( { message: val } ) }
                />
            </Placeholder>
        </div>
    );
}

isSelected 三項演算子

単純なテキストメッセージであればプレースホルダーで良さそうに見えますが、期待したとおりではないかもしれません。しかし、埋め込みブロックのように入力した瞬間にブロックを置き換えるのであればプレースホルダーは有用です。

三項演算子を使用すると、値のあるなしで表示するコンテンツを変えることができます。三項演算子は次のような構文のインライン if-else 文です。

clause ? doIfTrue : doIfFalse;

この構文をブロック内で使用してパラメータのあるなしで何を表示するか制御できます。単純なコードでは message がセットされていればそれを、セットされていなければフォーム要素を表示できます。

    return (
        <div>
            { attributes.message ?
                <div>Message: { attributes.message }</div> :
                <div>
                    <p>No Message.</p>
                    <TextControl
                        value={ attributes.message }
                        onChange={ ( val ) => setAttributes( { message: val } ) }
                    />
                </div>
            }
    );

しかし上のコードには問題があります。attributes.message だけをチェックしているためテキストフィールドに何か一文字でも入力した瞬間メッセージが値にセットされ、テキストフィールドが消えてしまいます。追加の isSelected パラメータとペアにする必要があります。

isSelected パラメーターは edit 関数に渡され、エディター内でブロックが選択され編集中の場合 true にセットされます。それ以外の部分を編集中の場合は false にセットされます。

このパラメータで次のようなロジックを使うことができます。

attributes.message && ! isSelected;

メッセージがあり、かつ ! isSelected の場合、すなわちブロックは編集中でなくフォーカスはどこかブロックの外にある場合、テキストフィールドでなくメッセージが表示されます。

まとめると edit 関数は次のようになります。

import { Placeholder, TextControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

export default function Edit( {
    attributes,
    className,
    isSelected,
    setAttributes,
} ) {
    return (
        <div className={ className }>
            { attributes.message && ! isSelected ? (
                <div>{ attributes.message }</div>
            ) : (
                <Placeholder
                    label="Gutenpride Block"
                    instructions="Add your message"
                >
                    <TextControl
                        value={ attributes.message }
                        onChange={ ( val ) =>
                            setAttributes( { message: val } )
                        }
                    />
                </Placeholder>
            ) }
        </div>
    );
}

すべての変更を保存しリビルド、リロードすると、編集していない場合にはメッセージが表示され、ブロック內部をクリックするとテキストフィールドが表示されます。

もっと良いソリューション

プレースホルダーと入力コントロールとの間の切り替えは、画像やビデオのようなビジュアルな要素で動作しますが、ブロック内のテキストの例ではもっとうまく実装できます。

よりシンプルで上手いソリューションでは editor.css を編集して、入力中に適切にスタイリングされたテキストを含めることができます。

editor.css を以下のように更新します。

.wp-block-create-block-gutenpride input[type='text'] {
    font-family: Gilbert;
    font-size: 64px;
}

edit 関数は以下のようにシンプルになります。

import { TextControl } from '@wordpress/components';

export default function Edit( { attributes, className, setAttributes } ) {
    return (
        <TextControl
            className={ className }
            value={ attributes.message }
            onChange={ ( val ) => setAttributes( { message: val } ) }
        />
    );
}

次のセクション: 最後の仕上げ

原文

最終更新日: