![[WP]BorderBoxControl でボーダー周りの設定を実装する](https://digipress.info/_wp/wp-content/uploads/2022/09/migrate-borderboxcontrol.png)
WordPress のブロックエディターにカスタムブロックを追加し、そのブロックでボーダー周り(枠線の太さ、色、線の種類)のカスタマイズを実装したい場合、WordPress 6.0 より実装された BorderBoxControl コンポーネントのみで一括で設定が可能になりました。
従来のように RangeControl や ColorPalette などそれぞれ別のコンポーネントを組み合わせる必要がなくなっただけでなく、視認性にも優れているためとても便利になっています。
このコンポーネントは、現時点では実験段階での実装として位置づけられているため、今後仕様が大きく変わる可能性があります。
BorderBoxControl
BorderBoxControl コンポーネントを利用するには、まず @wordpress/components からインポートします。
import { __experimentalBorderBoxControl as BorderBoxControl } from '@wordpress/components'
基本的な BorderBoxControl コンポーネントの使い方はこのような形です。
import { __experimentalBorderBoxControl as BorderBoxControl } from '@wordpress/components'
const edit = props => {
const {
setAttributes,
attributes,
} = props
const { borderValue } = attributes
// プリセットカラー
const presetColors = [
{
color: '#3c434a',
name: 'Gray 70'
},
{
color: '#101517',
name: 'Gray 100'
},
{
color: '#72aee6',
name: 'Blue 20'
},
{
color: '#3582c4',
name: 'Blue 40'
},
{
color: '#0a4b78',
name: 'Blue 70'
},
]
// デフォルトの枠線
const defaultBorder = {
color: '#72aee6',
style: 'dashed',
width: '1px'
}
return (
<InspectorControls>
<BorderBoxControl
colors={ presetColors } // プリセットカラー
defaultBorder={ defaultBorder } // デフォルトの枠線
disableCustomColors // 枠線の色のユーザーカスタマイズを無効(プリセットのみにする)
enableAlpha // 枠線のカラーの不透明度の変更を有効
enableStyle // 枠線のスタイル(solid, dotted, dashed)のカスタマイズを有効
popoverPlacement="right-start" // ポップアップ(色、枠線のスタイル)の表示位置
label="Borders" // 先頭に表示するラベル
onChange={ value => setAttributes( { borderValue: value } ) } // 保存処理
value={ borderValue }
/>
</InspectorControls>
...
}
ブロックのエディター側(edit.js)で利用する前提にて、 onChange には setAttributes で保存を行い、格納する変数(attributes 内)が borderValue であった場合のサンプルです。


BorderBoxControl コンポーネントを試すにはこちら。
プリセットカラーについて
ここで問題になるのが、BorderBoxControl は colors プロパティにプリセットのカラーパターンを渡しておかないと、枠線のカラーを変更する際、プリセットが何もなく、毎回ユーザーがカラーパレットで1から配色を決めないといけなくなります。
しかし、プリセットのカラーパターンをブロック(プラグイン)内で独自に用意してしまうと、WordPress 側で用意されているデフォルトのカラーパターン、または利用しているブロックテーマの theme.json で定義されているカラーパターンとは異なるため、カラーパレットなど他の配色用のコンポーネントとの統一性がなくなり、かえってユーザビリティを低下させてしまいます。
そこで、colors プロパティには、テーマ(theme.json)側でカラーパターンが用意されている場合はそれを利用し、ない場合は WordPress のデフォルトのカラーパターンを渡すようにします。
import { useSetting } from '@wordpress/block-editor'
const edit = props => {
...
// テーマのカラーパターン
const themeColors = useSetting( 'color.palette.theme' )
// WordPress のデフォルトカラーパターン
const defaultColors = useSetting( 'color.palette.default' )
...
return (
<InspectorControls>
<BorderBoxControl
colors={ themeColors || defaultColors } // テーマのカラーパターンがなければデフォルトのカラーパターンを渡す
...
/>
</InspectorControls>
<div { ...blockProps }>
...
</div>
)
}
useSetting( 'color.palette.theme' ) でテーマでプリセットされているカラーパターンを取得し、useSetting( 'color.palette.default' ) とすると WordPress のデフォルトのカラーパターンが取得できます。
戻り値のパース
BorderBoxControl からの戻り値( サンプルのborderValue に入る値)は Object型 で返されますが、ボーダーを一括で指定した場合と個別に指定した場合では構造(ネスト状態)が異なるため、実際の style 属性のスタイルとして適用するためには、少々面倒な変換処理をする必要があります。
一括指定した場合は、ボーダーのカラー、スタイル、太さの3つのデータが入ったオブジェクトが返されます。
{
color: "#2fc4cf",
style: "solid",
width: "1px"
}
個別指定した場合は、4辺(上下左右)ごとに分けられたボーダーのカラー、スタイル、太さのデータが返されます。
{
bottom: {
color: "#2fc4cf",
style: "solid",
width: "1px"
},
left: {
color: "#2fc4cf",
style: "dotted",
width: "3px"
},
right: {
color: "#2fc4cf",
style: "dashed",
width: "2px"
},
top: {
color: "#2fc4cf",
style: "double",
width: "4px"
}
}
React コンポーネントで style を渡すには、オブジェクトがネストした上記のままでは渡せないため、1つ(1階層)のオブジェクトにマージする必要があります。
さらに、HTML の style 属性に合うように、一括指定の場合は border-{prop}、個別指定の場合は border-{position}-{prop} というキー名に変更する必要があります。
これを実現するために、以下の関数を用意して解析し、そのまま渡せばいい状態に変換します。
const parseBorderStyle = borders => {
if ( typeof borders === 'object' ) {
const style = Object.keys( borders ).map( ( key ) => {
if ( typeof borders[ key ] === 'object' ) {
// 個別指定の場合はさらにループ
return Object.assign( {}, ...Object.keys( borders[ key ] ).map( ( key2 ) => {
return { [`border-${ key }-${ key2 }`]: `${ borders[ key ][ key2 ] }` }
} ) )
} else {
// 一括指定の場合は Object 型にして返す
return { [`border-${ key }`]: `${ borders[ key ] }` }
}
} )
return Object.assign( {}, ...style )
}
}
BorderBoxControl から受け取ったボーダーのデータをこの関数でパースすることで、以下のように変換されます。
{
"border-color": "#2fc4cf",
"border-style": "dashed",
"border-width": "1px"
}
{
"border-top-color": "#9fe5e5",
"border-top-style": "solid",
"border-top-width": "4px",
"border-right-color": "#2fc4cf",
"border-right-style": "solid",
"border-right-width": "4px",
"border-bottom-color": "#2fc4cf",
"border-bottom-style": "solid",
"border-bottom-width": "4px",
"border-left-color": "#2fc4cf",
"border-left-style": "solid",
"border-left-width": "4px"
}
あとは parseBorderStyle 関数で変換した値(Object)を style にそのまま渡せばOKです。
import { useBlockProps } from '@wordpress/block-editor'
...
const edit = props => {
...
const parseBorderStyle = borders => {
...
}
const blockProps = useBlockProps( {
style: parseBorderStyle( borderValues ),
} )
return (
<InspectorControls>
...
</InspectorControls>
<div { ...blockProps }>
...
</div>
)
}
その他、ブロックや特定の要素の余白(パディング、マージン)の設定に便利な BoxControl コンポーネント、角丸の度合いの設定に利用できる BorderRadiusControl コンポーネントなどがありますが、これらはまた次回試してみたいと思います。
