Interactivity APIの練習として、WordPressをライトモードとダークモードに切り替えるボタンブロックを作成します。
コンテンツ
ダークモードの切り替えはcolor-schemeを使用する
ブラウザには画面表示をダークモードに切り替える機能があり、通常はブラウザの設定に従ってWebサイトを表示する。
ダークモードの切り替え方法
- ブラウザの開発者ツールを開く
- 右上の︙(DevToolsのカスタマイズと管理)>その他のツール>レンダリング
- 追加表示された「レンダリング」タブの中から、「CSSメディア特性 prefers-color-scheme をエミュレートする」を探す
- いずれかを選択する。デフォルトでは「エミュレートなし」が選択されている
- エミュレートなし
- prefers-color-scheme: dark(→オペレーティングシステムのダーク配色を使用して要素をレンダリング)
- prefers-color-scheme: light(→オペレーティングシステムのライト配色を使用して要素をレンダリング)
配色設定を定義する場合
OSデフォルトの配色を使用せずにカスタマイズしたい場合、color-scheme
を :root
要素で設定する。下記は明るいパターンと暗いパターンを定義し、prefers-color-scheme
メディアクエリーを用いて各パターンの要素に配色を設定している。
:root { color-scheme: light dark; }
@media (prefers-color-scheme: light) {
.element {
color: black;
background-color: white;
}
}
@media (prefers-color-scheme: dark) {
.element {
color: white;
background-color: black;
}
}
ブロックの雛形を生成する
npx @wordpress/create-block@latest dark-light-mode --template @block-developer-cookbook/dark-light-mode
ブロック構成
- dark-light-mode
- build/
- block.json
- index.asset.php
- index.js
- render.php
- style-index.css
- view.asset.php
- view.js
- src/
- block.json
- edit.js
- index.js
- render.php
- style.scss
- view.js
- package.json
- simple-dark-mode.php
- node_modules/
- and more …
- build/
TT4 Dark Themeをダウンロードする。
ブロックを登録する
dark-light-mode.php
namespace BlockDevelopersCookbook;
/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/reference/functions/register_block_type/
*/
function create_block_dark_light_mode_block_init() {
register_block_type( __DIR__ . '/build' );
}
add_action('wp_head', __NAMESPACE__ . '\add_color_scheme_styles');
color-schemeプロパティを:rootに設定する
dark-light-mode.php
function add_color_scheme_styles() {
?>
<style>
:root {
color-scheme: light dark;
}
</style>
<?php
}
add_action('wp_head', __NAMESPACE__ . '\add_color_scheme_styles');
その結果、<head>内の<style>に:root { color-scheme: light dark; }が出力される。ブラウザを再読込すると、ユーザー設定に基づいてダークモードへ切り替えられるようになる。
ブロックの初期設定
このブロックはInteractivity APIを用いて、stateの管理とcolor-schemeの更新を行うため、block.jsonに書きを記述してInteractivity APIを有効化する
block.json
{
"supports": {
"interactive": true
},
"viewScriptModule": "file:./view.js"
}
Interactivity APIを有効化しているのは、supports.interactiveの部分。
viewScriptModuleプロパティはInteractivity APIを用いるJavaScriptがどこにあるかを示している。この場合、Interactivity APIは、view.jsで使用されていることを意味している。また、view.jsはESモジュールとして構築する必要がある。
viewScriptModuleで設定したファイルがモジュールとして構築されることを@wordpress/scripts
packageに指示しなければならないため、package.jsonのbuildとstartを書き換える。
package.json
"build": "wp-scripts build --experimental-modules",
"start": "wp-scripts start --experimental-modules"
Interactivity APIの設定をする
Interactivity APIではstoreを作成します。storeには「dark-light-mode」という識別名をつけます。
view.js
/**
* WordPress dependencies
*/
import { store } from '@wordpress/interactivity';
store( 'dark-light-mode', {
state: {},
actions: {},
callbacks: {},
} );
storeは3つのプロパティを持ちます。
- state:storeからデータを取得する
- actions:イベントのコールバック関数を格納する(ボタンクリックなど)
- callbacks:ユーザーの行動をトリガーとしないコールバック関数を格納する(コンポーネントのロードなど)
定義したstoreをブロックと紐づけるには、render.phpにdata-wp-interactiveディレクティブを記述します。data-wp-interactiveディレクティブには、view.jsで定義したstoreの名前を渡します。
2点目のdata-wp-bind–aria-pressedは、data-wp-bindディレクティブを使用して、aria-pressed属をdarkMode変数に接続するためにものです。
3点目のdata-wp-on–clickは、data-wp-onディレクティブを使用して、ボタンのクリックイベントをコールバック関数のtoggleModeに紐づけるためのものです。
render.php
/**
* Render template for the Dark Light Mode Block.
*
* @package block-developers-cookbook
*/
namespace BlockDevelopersCookbook;
?>
<div <?php echo wp_kses_data(get_block_wrapper_attributes()); ?>>
<button
data-wp-interactive="dark-light-mode"
data-wp-bind--aria-pressed="state.darkMode"
data-wp-on--click="actions.toggleMode"
class="toggle"
type="button">
<span class="toggle__display" hidden></span>
</button>
</div>
view.jsにtoggleMode関数を定義します。
/**
* WordPress dependencies
*/
import { store } from '@wordpress/interactivity';
const { state } = store( 'dark-light-mode', {
state: {},
actions: {
/**
* Toggles between dark and light mode.
*
* @return {void}
*/
toggleMode() {
state.darkMode = ! state.darkMode;
},
},
callbacks: {},
} );
render.phpにstateのdarkMode変数を監視するdata-wp-watch=”callbacks.updateColorScheme”を定義します。
data-wp-watch="callbacks.updateColorScheme"
コールバック関数のupdateColorSchemeを定義します。
view.js
callbacks: {
/**
* Updates the root element's color scheme CSS property
* when the dark mode state changes.
* Skips if darkMode state is not yet initialized.
*
* @return {void}
*/
updateColorScheme() {
// Dark mode will be undefined if there is not cookie or user meta.
if ( 'undefined' === typeof state.darkMode ) {
return;
}
const root = document.querySelector( ':root' );
root.style.setProperty(
'color-scheme',
state.darkMode ? 'dark' : 'light'
);
},
},
ブロックが最初にレンダリングするときにのみdarkMode変数を初期化するdata-wp-init=”callbacks.initToggle”を定義します。
render.php
data-wp-init="callbacks.initToggle"
view.js
initToggle() {
state.darkMode =
window.matchMedia &&
window.matchMedia( '(prefers-color-scheme: dark)' ).matches;
},
参考:https://blockdevelopercookbook.com/recipes/creating-a-dark-light-mode-block/