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
コンポーネントなどがありますが、これらはまた次回試してみたいと思います。