本文へスキップ
Material 3 Expressivev1.3.0-rc.1
ガイド

テーマ設定

テーマを作成し、トークンを上書きして、テーマのスコープを入れ子にします。

スタイルシート全体を一度だけ読み込み、Material 3トークンを適用する範囲をプロバイダーで囲みます。

import { Material3Provider } from '@language-lit/material3-expressive'
import '@language-lit/material3-expressive/styles.css'

export function App() {
  return <Material3Provider colorMode="system">...</Material3Provider>
}

プロバイダーは、完全で不変なデフォルトテーマとシステムカラーモードをデフォルトで適用します。.m3e-themeクラスを持つdivをレンダリングし、className、style、その他のdiv属性をその要素に転送します。

テーマを作成、拡張する

テーマユーティリティは部分的な上書きを受け取り、完成したテーマ全体を検証して、新しいディープフリーズ済みの値を返します。

import { Material3Provider } from '@language-lit/material3-expressive'
import { createTheme } from '@language-lit/material3-expressive/theme'

const compactTheme = createTheme({
  density: { scale: -1 },
  reference: {
    typeface: {
      brand: ['Roboto Flex', 'sans-serif'],
    },
  },
})

export function App() {
  return <Material3Provider theme={compactTheme}>...</Material3Provider>
}

./themeと./tokensのサブパスにはReactランタイムが含まれず、サーバーのデータモジュールで安全に使えます。ルートエントリはプロバイダーとフックも公開しているため、便利なReactクライアント向けAPIです。

カラースキームはテーマのreference.paletteパスを参照します。カラーロールのトーンの対応を維持する場合はパレット値を上書きし、別のパレットトーンを使う場合はロールの$refを上書きします。無効な参照やコントラストを損なうスキームは拒否されます。

ネストしたスコープ

各プロバイダーは完全なデフォルトスコープから始め、そのテーマの差分を適用します。ネストしたプロバイダーは親から独立しています。

<Material3Provider theme={brandTheme}>
  <MainContent />
  <Material3Provider theme={editorTheme} colorMode="dark">
    <Editor />
  </Material3Provider>
</Material3Provider>

ポータルで表示するオーバーレイ

Menu、Selectのポップアップリストボックス、Tooltip、Snackbarはdocument.bodyにレンダリングされるため、祖先要素のoverflowやスタッキングコンテキストの外に表示されます。これらはプロバイダー要素の外側に置かれ、継承だけではスコープが届きません。そのため、各オーバーレイはポータルのルートに、囲んでいるスコープ(.m3e-themeクラス、カラーモード属性、プロバイダーのインラインテーマ差分)を再適用します。

利用側での追加対応は不要です。ネストしたプロバイダー内で開いたオーバーレイにはそのネストしたスコープが引き継がれ、上位にプロバイダーがない場合はスコープを出力しません。そのため、アプリケーションが.m3e-themeとdata-m3e-color-modeを<html>自体に設定している場合、その設定が引き続きdocument.bodyを制御します。

<Material3Provider theme={editorTheme} colorMode="dark">
  <Editor /> {/* a Menu opened here paints editorTheme's dark scheme */}
</Material3Provider>

SSRと解決済みモード

systemModeFallbackは、useResolvedColorModeがサーバーとハイドレーション時に使う決定的なスナップショットを制御します。静的CSSはハイドレーション前から、ブラウザーのシステムカラースキームを選択します。

const mode = useResolvedColorMode() // "light" or "dark"
const theme = useMaterial3Theme()

これらのフックは別々のコンテキストを使うため、解決済みモードだけを読むコンポーネントはテーマオブジェクト全体を購読しません。

ハイドレーション前にdata-m3e-resolved-color-modeを調べるアプリケーションでは、preventColorSchemeFlashを指定して任意の静的初期化スクリプトを出力できます。リクエストのCSP nonceはnonceで渡します。このスクリプトはデフォルトでは出力されず、ドキュメントルートも変更しません。