DigiPress

Highly Flexible WordPress Theme

メニュー

[WP] BorderRadiusControl で角丸(border-radius)を制御する

[WP] BorderRadiusControl で角丸(border-radius)を制御する

WordPress のブロックエディタ(Gutenberg)のブロック開発時に、任意のブロックや要素に角丸具合(border-radius)をコントロールするオプションを持たせる場合、大抵はRangeControl をコントローラとして利用することが多いと思います。

RangeControl

ただ、border-radius で角丸を指定する際、一括ではなく4角(左上、右上、右下、左下)ごとで指定したい場合や単位(px, % など)も選択可能にする場合、新たに様々なコンポーネントを組み合わせて独自のコントローラを作成したり属性が増えるなど、少々手間がかかります。

そこで便利なのが、標準コンポーネントである BorderRadiusControl を利用した角丸の制御です。

BorderRadiusControl は現時点ではまだ実験段階のコンポーネントなので、正式に実装される際には仕様が変更される可能性があります。

BorderRadiusControl を利用する

BorderRadiusControl を利用するには、まず実験段階のコンポーネントとして宣言します。

JSX
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 に指定があればそちらを優先します。

theme.jsonunits
{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 2,
	"settings": {
		...
		"spacing": {
			"units": [ "px", "em", "rem", "vh", "vw", "%" ],
			...
		},
	...
}

BorderRadiusControl (GitHub)

型について

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]
			]
		} )
	)
}
Share / Subscribe
Facebook Likes
Tweets
Hatena Bookmarks
Pinterest
Pocket
Feedly
Send to LINE