![[WP] BorderRadiusControl で角丸(border-radius)を制御する](https://digipress.info/_wp/wp-content/uploads/2023/01/border-radius-control.png)
WordPress のブロックエディタ(Gutenberg)のブロック開発時に、任意のブロックや要素に角丸具合(border-radius
)をコントロールするオプションを持たせる場合、大抵はRangeControl
をコントローラとして利用することが多いと思います。

ただ、border-radius
で角丸を指定する際、一括ではなく4角(左上、右上、右下、左下)ごとで指定したい場合や単位(px, % など)も選択可能にする場合、新たに様々なコンポーネントを組み合わせて独自のコントローラを作成したり属性が増えるなど、少々手間がかかります。
そこで便利なのが、標準コンポーネントである BorderRadiusControl
を利用した角丸の制御です。
BorderRadiusControl
は現時点ではまだ実験段階のコンポーネントなので、正式に実装される際には仕様が変更される可能性があります。
BorderRadiusControl を利用する
BorderRadiusControl
を利用するには、まず実験段階のコンポーネントとして宣言します。
import { __experimentalBorderRadiusControl as BorderRadiusControl } from '@wordpress/block-editor';
あとは、例えば InspectorControls
内に BorderRadiusControl
を配置するのみです。
<BorderRadiusControl values={ borderRadiusValues } onChange={ borderRadiusValues => setAttributes( { borderRadiusValues } ) } />


border-radius の単位について
border-radius
の単位は、デフォルトでは px, em, rem が提供されていますが、使用中テーマの theme.json にて settings – spacing – units に指定があればそちらを優先します。
{ "$schema": "https://schemas.wp.org/trunk/theme.json", "version": 2, "settings": { ... "spacing": { "units": [ "px", "em", "rem", "vh", "vw", "%" ], ... }, ... }
型について
BorderRadiusControl
で扱われる値の型は、以下のような Object 型で返ってきます。
{ value: "32px" }
{ bottomLeft: "20px" bottomRight: "4px" topLeft: "4px" topRight: "20px" }
このため、実際に対象ブロックの style 属性のデータとして useBlockProps
などを介して style プロパティに渡す値にするには、この返り値をborderRadius: $n
, borderTopLeftRadius: $n
のようなフォーマットのオブジェクト型に変換する必要があります。
例えば、以下のような処理を用いた関数を用意して BorderRadiusControl
からの返り値を style プロパティに適切なフォーマットに変換します。
if ( Object.keys( borderRadiusValues ).length == 1 ) { // 一括指定の場合 return Object.fromEntries( Object.entries( borderRadiusValues ) .map( radius => { if ( radius[0] == 'value' ) { return [ 'borderRadius', radius[1] ] } } ) ) } else { // コーナーごと(topLeft, topRight, bottomRight, bottomLeft)の場合 return Object.fromEntries( Object.entries( borderRadiusValues ) .filter( radius => radius[0] != 'value' ) .map( radius => { return [ `border${ radius[0].charAt(0).toUpperCase() + radius[0].slice(1) }Radius`, radius[1] ] } ) ) }