API
@k8ordo/color-schemeがexportするコンポーネントとフック、値、型の一覧です。入口は@k8ordo/color-schemeの1つだけです。
このページの内容
ColorSchemeProvider
import元 @k8ordo/color-scheme
ルートレイアウトの<body>の中で、ページ全体を包むプロバイダです。最初の描画の前に<html>へdarkクラスを付けるインラインスクリプトを描き、そのあともクラスを合わせ続けます。
ColorSchemeProvider(props: ColorSchemeProviderProps): ReactNode引数
defaultPreferenceColorSchemePreference = 'system'- 何も選んでいない訪問者に出す配色です。
'system'ならOSの設定に従い、'light'か'dark'なら訪問者が選ぶまでその配色にします。省略すると'system'です。 noncestring | undefined- インラインスクリプトに付けるnonceです。
@k8ordo/serverではnonce()を渡します。ハッシュで許可するときは渡しません。 childrenReactNode- ページ全体です。スクリプトはこれより前に描かれます。
注意
'use client'のモジュールからexportしているので、Server Componentのルートレイアウトからそのまま描けます。<html>にはsuppressHydrationWarningを付けます。スクリプトが付けたclassはサーバーのHTMLに無いので、開発時のReactが食い違いとして報告するからです。- アプリに1つだけ置きます。プロバイダはそれぞれがスクリプトを描いてクラスを書くので、2つあると食い違うことがあります。
- サーバーは保存された選択もOSの設定も読めないので、既定値で描きます。既定値が
'system'なら、サーバーが描く配色は'light'です。
layout.tsxexport default function RootLayout({
children,
}: {
children: ReactNode;
}) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ColorSchemeProvider>{children}</ColorSchemeProvider>
</body>
</html>
);
}useColorScheme
import元 @k8ordo/color-scheme
いま画面に出ている配色と、訪問者の選択、選択を変える関数を返します。Client Componentの中で使います。
useColorScheme(): UseColorScheme戻り値
UseColorScheme — schemeとpreference、setPreferenceをまとめたオブジェクトです。
フィールド
scheme'light' | 'dark'- 画面に出ている配色です。訪問者の選択か、プロバイダの既定値か、OSの設定のどれかから決まります。
preference'light' | 'dark' | 'system'- 訪問者が選んだものです。何も選んでいないときは
'system'です。 setPreference(preference: ColorSchemePreference) => void- 選んだものを保存します。
'system'を渡すと保存していた選択を消し、プロバイダの既定値に戻ります。
注意
- プロバイダの外で呼ぶと、
useColorScheme needs <ColorSchemeProvider> above itで始まるエラーを投げます。既定値を黙って返すことはありません。 - プロバイダが決めた値を読むだけで、
<html>のクラスにもlocalStorageにも触れません。 - サーバーでの描画とハイドレーションの描画では、サーバーの推測を返します。保存された選択とOSの設定は、その直後の描画から読みます。
scheme-toggle.tsxconst { scheme, setPreference } = useColorScheme();
<button
onClick={() => {
setPreference(scheme === 'dark' ? 'light' : 'dark');
}}
type="button"
>
Toggle
</button>トグルと3択の作り方は「切り替えのボタンを作る」を見てください。
colorSchemeState
import元 @k8ordo/color-scheme
設定の保存先を表す、@k8ordo/stateのdefineLocalStateの定義そのものです。localStorageのk8ordo-state:color-schemeに、preferenceを1つだけ持つ行として保存します。
const colorSchemeState = defineLocalState(
'color-scheme',
z.object({ preference: z.optional(z.enum(['light', 'dark'])) }),
);フィールド
kind'local'- 状態の置き場所の種類です。localStorageなので
'local'です。 key'color-scheme'@k8ordo/stateの中での名前です。ストアはこの名前ごとに1つ作られます。schemaZodMiniObject- 定義に渡したスキーマです。
storageKey'k8ordo-state:color-scheme'- localStorageのキーです。
k8ordo-state:にkeyをつなげたものです。 inlineRead() => string- インラインスクリプトに書くためのJavaScriptの式を返します。式は保存された行のオブジェクトに評価され、読めないときは
nullになります。
注意
useAppState(colorSchemeState)を使うと、フックを通さずに保存されたpreferenceを読めます。返るのは'light' | 'dark' | undefinedで、解決したschemeではありません。- 選択を変えるときは
setPreferenceを使います。同じタブでlocalStorage.setItemを直接呼んでも、プロバイダは再読み込みまで気づきません。 - アプリで
defineLocalState('color-scheme', …)をもう1つ定義しないでください。ストアは名前で共有されるので、2つの定義が同じ行を取り合います。
stored-preference.tsxconst [{ preference }] = useAppState(colorSchemeState);
// 'light' | 'dark' | undefinedcolorSchemeScriptHash
import元 @k8ordo/color-scheme
プロバイダが描くインラインスクリプトのSHA-256を、CSPのソースの形('sha256-…')で返します。nonceを使わずにスクリプトを許可するポリシーに入れます。
colorSchemeScriptHash(
defaultPreference?: ColorSchemePreference,
): Promise<string>引数
defaultPreferenceColorSchemePreference = 'system'- プロバイダに渡している
defaultPreferenceです。既定値はスクリプトの文字列に入るので、この値でハッシュが変わります。
戻り値
Promise<string> — 'sha256-…'のように、前後の引用符まで含んだCSPのソースです。
注意
- ハッシュの値をポリシーに書き写さず、ポリシーを書く場所で毎回呼びます。スクリプトの文字列はインストールした版のもので、更新で変わることがあるからです。
@k8ordo/serverのように応答ごとのnonceを付けられるなら、ハッシュは要りません。
vite.config.tsframework({
csp: {
'script-src': ["'self'", await colorSchemeScriptHash()],
},
});ColorScheme
import元 @k8ordo/color-scheme
画面に出せる配色です。schemeの型です。
type ColorScheme = 'light' | 'dark';ColorSchemePreference
import元 @k8ordo/color-scheme
配色か'system'です。訪問者の選択としての'system'は「何も選んでいない」で、プロバイダの既定値に従います。既定値としての'system'は、OSの設定に従います。
type ColorSchemePreference = ColorScheme | 'system';ColorSchemeProviderProps
import元 @k8ordo/color-scheme
ColorSchemeProviderのpropsの型です。プロバイダを包むコンポーネントを自分で作るときに使います。
type ColorSchemeProviderProps = {
readonly defaultPreference?: ColorSchemePreference;
readonly nonce?: string;
readonly children: ReactNode;
};UseColorScheme
import元 @k8ordo/color-scheme
useColorScheme()の戻り値の型です。フックの値をpropsで受け取るコンポーネントに使います。
type UseColorScheme = {
readonly scheme: ColorScheme;
readonly preference: ColorSchemePreference;
readonly setPreference: (preference: ColorSchemePreference) => void;
};