前回はReactだけの知識で完結するようWordPress(Gutenberg)コアで用意されているコンポーネントの使用をさけてました。
今回はGutenbergに用意されたコンポーネントを使っていきます。
かなりの量があるのでごく一部を紹介します。
StoryBookが便利です。
https://wordpress.github.io/gutenberg/?path=/story/docs-introduction--page
最低限のコンポーネントを使っていきます。
npm install --save-dev @types/wordpress__components
一旦ひな形を綺麗さっぱり余計なものを削除します。
props.ts
export default interface KurageExampleBlockProps
{
}
index.ts
の一部
const blockConf: BlockConfiguration<KurageExampleBlockProps> =
{
attributes: {},
title: metadata.title,
category: metadata.category,
edit: Edit,
save,
};
style.cscc
.wp-block-create-block-kurage-worker {
padding: .4em;
}
background-colorとcolorをバッサリ削除。
editor.scss
.wp-block-create-block-kurage-worker {
border: 1px dotted #f00;
}
Button
save.tsx
を編集します。
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
import React from 'react';
import { BlockEditProps } from '@wordpress/blocks';
import KurageExampleBlockProps from './props';
import { Button } from '@wordpress/components';
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
return (
<div {...useBlockProps()}>
<Button>Kurage</Button>
<Button variant="primary">Primary</Button>
<Button variant="link">Link</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="tertiary">Tertiary</Button>
<Button variant="primary" disabled>Disabled</Button>
</div>
);
}
ボタンの見た目を変えるにはvariant
を使います。
それぞれprimary
, secondary
, tertiary
, link
を指定します。
disabled
を指定するとクリック出来ないボタンが出来ます。
TextControl, TextAreaControl
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [name, setName] = useState('');
return (
<div {...useBlockProps()}>
<TextControl value={name} label="Your name" help="3文字以上で入力してください。" onChange={value => setName(value)} />
</div>
);
}
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [name, setName] = useState('');
return (
<div {...useBlockProps()}>
<TextareaControl
value={name}
label="苦情内容"
help="100字程度で入力してください。"
rows={3}
onChange={value => setName(value)} />
</div>
);
}
CheckboxControl, ToggleControl, RadioControl
CheckBoxControl
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [agree, setAgree] = useState(false);
return (
<div {...useBlockProps()}>
<CheckboxControl
label="同意しますか?"
checked={agree}
onChange={value => setAgree(value)}
/>
</div>
);
}
indeterminate
をtrue
にすると不確定
になるらしいですが、現段階では型定義にこのプロパティが含まれていないようです。
なので定義を生やしてます(あるいは@ts-ignoreで無視する)。
// 無理やり生やす
declare module '@wordpress/components'
{
namespace CheckboxControl
{
interface Props
{
indeterminate: boolean;
}
}
}
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [agree, setAgree] = useState(false);
return (
<div {...useBlockProps()}>
<CheckboxControl
label="同意しますか?"
indeterminate={true}
checked={agree}
onChange={value => setAgree(value)}
/>
</div>
);
}
ToggleControl
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [agree, setAgree] = useState(false);
return (
<div {...useBlockProps()}>
<ToggleControl
label="同意しますか?"
checked={agree}
onChange={value => setAgree(value)}
/>
</div>
);
}
RadioControl
const radioOptions: RadioControl.Option<string>[] = [
{ label: '勇者', value: 'yusha' },
{ label: '魔法使い', value: 'wizard' },
{ label: '戦士', value: 'warrior' },
{ label: '遊び人', value: 'neet' }
];
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [job, setJob] = useState<string|undefined>();
return (
<div {...useBlockProps()}>
<RadioControl
label="職業は何ですか?"
selected={job}
options={radioOptions}
onChange={value => setJob(value as string)}
/>
</div>
);
}
SelectControl, ComboBoxControl
SelectControl
リストの中から一つ選びます。
const items: SelectControl.Option[] = [
{ label: 'A', value: 'a' },
{ label: 'B', value: 'b', disabled: true },
{ label: 'C', value: 'c' },
{ label: 'D', value: 'd' },
];
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [alfabet, setAlfabet] = useState<string|undefined>('a');
return (
<div {...useBlockProps()}>
<p>{alfabet}</p>
<SelectControl
label="アルファベットを選んでください"
options={items}
onChange={value => setAlfabet(value as string)}
/>
</div>
);
}
options
でSelectControl.Option
型の配列を渡します。
disabled
をtrue
にすると選択出来ません。
複数行の選択
をするにはmultiple
をtrue
にします。
onChange
から受け取る項目が複数になる点に注意してください。
const items: SelectControl.Option[] = [
{ label: 'A', value: 'a' },
{ label: 'B', value: 'b', disabled: true },
{ label: 'C', value: 'c' },
{ label: 'D', value: 'd' },
];
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [alfabets, setAlfabets] = useState<string[]|undefined>(['a', 'c']);
return (
<div {...useBlockProps()}>
<p>{alfabets?.join(',')}</p>
<SelectControl
label="アルファベットを選んでください"
value={alfabets}
multiple={true}
options={items}
onChange={value => setAlfabets(value as string[])}
/>
</div>
);
}
あれれ?
現在(2023/02/21)、表示がおかしくなる。
調べてみたらselect
のサイズが30px
に設定してある。
応急処置のコードを追加してみる
.wp-block-create-block-kurage-worker {
padding: .4em;
}
select[multiple]
{
height: auto !important;
}
まだ不安定そう。
ComboboxControl
シングル選択のSelectControl
をさらに検索できるようにした感じ。
const items: any = [
{ label: 'Apple', value: 'apple' },
{ label: 'Armond', value: 'armond' },
{ label: 'BlueBerry', value: 'blueberry' },
{ label: 'Banana', value: 'banana' },
{ label: 'Melon', value: 'melon'}
];
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [alfabet, setAlfabet] = useState<string>('apple');
return (
<div {...useBlockProps()}>
<p>{alfabet}</p>
<ComboboxControl
label="アルファベットを選んでください"
value={alfabet}
options={items}
onChange={value => setAlfabet(value as string)}
/>
</div>
);
}
b
を入力するとBlueBerry
とBanana
が候補に上がる。
RangeControl
範囲を指定。
例えば0から100までの範囲の入力を求めるなら、
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [power, setPower] = useState(0);
return (
<div {...useBlockProps()}>
<RangeControl
min={0}
max={100}
label="今のやる気は何パーセントですか?"
value={power}
onChange={value => setPower(value || 0)} />
</div>
);
}
min
は最小値、max
は最大値。
そのほかにも、
step
を3
にすると3ずつカウントする(3,6,9,...)こともできる。
withInputField
をfalse
に指定すると右側のテキストを削除出来る、
はずなんだが、型定義に定義されてないようで・・・。
ColorPicker, ColorPallet
ColorPallet
カラーパレットはカラーのリストの中から選べるコンポーネントです。
const colors: ColorPalette.Color[] = [
{ name: 'Blue', color: '#0fe' },
{ name: 'Yellow', color: 'yellow' },
{ name: 'Red', color: '#f00' },
]
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [color, setColor] = useState('green');
return (
<div {...useBlockProps()}>
<ColorPalette
colors={colors}
value={color}
onChange={value => setColor(value as string)}
/>
</div>
);
}
ColorPicker
お絵描きツールなどでよくあるグラデーションなどから色を選ぶやつです。
いろいろおかしいところがあり、ちょっと現段階で使うにはりすくありかなー?
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [color, setColor] = useState<any>();
console.log(color)
return (
<div {...useBlockProps()}>
<p>{color?.hex}</p>
<Placeholder label='3パターンのColorPicker'>
<ColorPicker
color={color}
onChangeComplete={value => setColor(value)}
/>
<ColorPicker
color={color}
onChangeComplete={value => setColor(value)}
/>
<ColorPicker
color={color}
onChangeComplete={value => setColor(value)}
/>
</Placeholder>
</div>
);
}
PlaceHolder
の説明はいったん飛ばします。
セレクトボックスからHex
, HSL
, RGB
をそれぞれ選択しています。
VStack/HStack
コンポーネント等を一列に整列させて表示する。
VStack
は垂直に、HStack
は水平にならぶ。
ただ現在(2023/02/21)実装されてない模様。
一応つかってみる。
import { useBlockProps } from '@wordpress/block-editor';
import React from 'react';
import { BlockEditProps } from '@wordpress/blocks';
import { Button } from '@wordpress/components';
import KurageExampleBlockProps from './props';
import './editor.scss';
import {
__experimentalVStack as VStack,
__experimentalHStack as HStack
} from '@wordpress/components';
declare module '@wordpress/components'
{
const __experimentalVStack: any;
const __experimentalHStack: any;
}
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
return (
<div {...useBlockProps()}>
<p>垂直</p>
<VStack>
<Button variant="primary">AAAAAAA</Button>
<Button variant="primary">BBBBBBB</Button>
<Button variant="primary">CCCCCCC</Button>
<Button variant="primary">DDDDDDD</Button>
</VStack>
<p>水平</p>
<HStack>
<Button variant="primary">AAAAAAA</Button>
<Button variant="primary">BBBBBBB</Button>
<Button variant="primary">CCCCCCC</Button>
<Button variant="primary">DDDDDDD</Button>
</HStack>
</div>
);
}
Placeholder
複数のコンポーネントをひとまとめに纏めときたい時とかに使う。
VStackの代わりに使ってます。
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
return (
<div {...useBlockProps()}>
<Placeholder label='Hello Kurage' icon="wordpress" instructions="ここに入力してね!">
<TextControl value="えーーーーーーー" label="message" onChange={e => {}}/>
<TextControl value="えーーーーーーー" label="message" onChange={e => {}}/>
<TextControl value="えーーーーーーー" label="message" onChange={e => {}}/>
<TextControl value="えーーーーーーー" label="message" onChange={e => {}}/>
<Button variant="primary">Click me</Button>
</Placeholder>
</div>
);
}
<Placeholder label='Hello Kurage' icon="wordpress" instructions="ここに入力してね!" isColumnLayout={true}>
isColumnLayout
をtrue
にすると横に全快! 一列に並んでくれる。
Spinner
読み込み中とか、Loading... で表示するやつ。
<Spinner />
Modal
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
const [isOpen, setIsOpen] = useState(false);
const cancel = () => {
setIsOpen(false);
}
const ok = () => {
// ここで何らかの処理
setIsOpen(false);
}
return (
<div {...useBlockProps()}>
<Button variant="primary" onClick={() => setIsOpen(true)}>Open Modal!</Button>
{ isOpen && (
<Modal title="Hello Modal" onRequestClose={() => setIsOpen(false)}>
<p>ここにいろいろ表示する</p>
<ButtonGroup>
<Button variant="primary" onClick={cancel}>Cancel</Button>
<Button variant="primary" onClick={ok}>OK</Button>
</ButtonGroup>
</Modal>
)}
</div>
);
}
モーダルのバツボタンを押すとonRequestClose
イベントが発生します。
このイベントを拾ってモーダルを非表示にするようにしますが、内部のボタンからでも出来ます。
他にこれと同じようなことをするConfirmDialog
があるようですが今のところ(2023/02/21)非推奨。
Notice
お知らせ。
例えばワードプレス本体にてプラグインをインストールした時とかに「プラグインをインストールしました。」などとメッセージを表示してくれるやつのコンポーネント版的なやつ。
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
return (
<div {...useBlockProps()}>
<Notice>頭上に注意してください!</Notice>
</div>
);
}
Snackbar, SnackbarList
動作がおかしいのでパスします。
Icon
import { wordpress, alignLeft, arrowRight, backup } from '@wordpress/icons';
export default (props: BlockEditProps<KurageExampleBlockProps>) =>
{
return (
<div {...useBlockProps()}>
<Icon icon={wordpress} />
<Icon icon={alignLeft} />
<Icon icon={arrowRight} />
<Icon icon={backup} />
</div>
);
}
アイコン一覧はこちら。
WordPressのブロック開発メモ その4ー1 アイコン一覧
次回はツールバーとサイドバーについてです。