![[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]
]
} )
)
}
