MUI v5 Theme ~基本の使い方からカスタマイズまで~

73480 ワード

Vite + React + TypeScript 環境で MUI v5 を使用しています。
今回は MUI v5 の Theme についてTips的にまとめてみました。

  • テーマをアプリケーション全体に適用する
  • Light モードと Dark モードを切り替える
  • テーマの色を変更する
  • テーマを一部のコンポーネントに適用する
  • 適用されているテーマの一部を変更したテーマを作成し、一部のコンポーネントに適用する
  • テーマに欧文フォント・日本語フォントを追加する
  • テーマに独自のカラーキーワードを追加し、ボタンで使用する

Themeの基本

デフォルトテーマ

MUI には Light モード用のデフォルトテーマと Dark モード用のデフォルトテーマが用意されています。
それぞれのテーマに設定されている値などは 公式: Default Theme で確認できます。

テーマをアプリケーション全体に適用する global theme

デフォルトテーマは特に何も設定しなくても、アプリケーション全体に適用されています。
試しに、テーマを設定しない状態でもデフォルトテーマが適用されていることを確認してみます。

下記のサンプルは、ボタンにテーマカラーを設定しているだけのSamppleComponent.tsx を
App.tsx から表示しているだけの何でもないコードです。

CssBaseline は MUI が用意しているリセットCSSです。
リセットCSSとは・・・
ブラウザにはデフォルトCSSとよばれるがあります。このデフォルトスタイルはブラウザごとにバグや微妙な差があり、この差を調整してくれるのがリセットCSSです。
詳しくはコチラを参照:Vite+React+Emotionに、リセットCSSを導入する。
MUI が用意しているリセットCSSは App.tsx などのルートコンポーネントに配置しておきます。

App.tsx
import CssBaseline from '@mui/material/CssBaseline'
import { SampleComponent } from './SampleComponent'

export function App() {
  return (
    <>
      <CssBaseline />
      <SampleComponent />
    </>
  )
}
SamppleComponent.tsx
import { Stack, Button } from "@mui/material"

export function SampleComponent()  {
  return (
    <Stack direction="row" spacing={2} sx={{m:2, p:2}}>
      <Button variant="contained" color="primary">primary</Button>
      <Button variant="contained" color="secondary">secondary</Button>
      <Button variant="contained" color="warning">warning</Button>
      <Button variant="contained" color="info">info</Button>
      <Button variant="contained" color="success">success</Button>
    </Stack>
  )
}

ボタンにテーマカラーが設定されています。

明示的にアプリケーション全体にテーマを適用する

明示的にアプリケーション全体にテーマを適用するには、
まずルートコンポーネントで、createTheme でテーマを作成します。
次に ThemeProvider に作成したテーマを指定し、子コンポーネントをラップします。
CssBaseline も ThemeProvider でラップすることがポイントです。
(CssBaseline をラップしないと Body 要素にテーマが適用されません)

App.tsx
import CssBaseline from '@mui/material/CssBaseline'
import { ThemeProvider, createTheme } from '@mui/material/styles'
import { SampleComponent } from './SampleComponent'

export function App() {
+  const theme = createTheme()
  return (
+    <ThemeProvider theme={theme}>
+      <CssBaseline />
      <SampleComponent />
+    </ThemeProvider>
  )
}

Light モードと Dark モードを切り替える

明示的にアプリケーション全体に適用したテーマの動作確認も兼ねて、
アプリケーション全体で、Lightモードテーマ と Darkモードテーマを切り替えます。

作成するテーマのパレットにmode: 'dark'を指定します。
Liteテーマの場合はmode:lightを指定します。
Body 要素にテーマが適用されるよう CssBaseline を ThemeProvider でラップします。

App.tsx
import CssBaseline from '@mui/material/CssBaseline'
import { ThemeProvider, createTheme } from '@mui/material/styles'
import { SampleComponent } from './SampleComponent'


export function App() {
-  const theme = createTheme()
+  const theme = createTheme({
+    palette: {
+      mode: 'dark'
+    }
+  })
  
  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <SampleComponent />
    </ThemeProvider>
  )
}

Darkテーマ が 適用されました。

▶ OSの設定でテーマが切り替わるようにする

OSの設定でテーマが切り替わるようにするサンプルコードです。
useMediaQueryで OS の 表示モードの設定を取得します。

App.tsx
import CssBaseline from '@mui/material/CssBaseline'
import { ThemeProvider, createTheme } from '@mui/material/styles'
+ import useMediaQuery from '@mui/material/useMediaQuery'
import { SampleComponent } from './SampleComponent'

export function App() {
+  const isDarkMode = useMediaQuery('(prefers-color-scheme: dark)')

  const theme = createTheme({
    palette: {
+      mode: isDarkMode ? 'dark' : 'light'
    }
  })

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <SampleComponent />
    </ThemeProvider>
  )
}

windows11 で Light/Dark モードを切り替えるには 「設定 > 個人設定 > 色 > モードを選ぶ」で変更します。

テーマの色を変更する

次に テーマ の primary の色を変更してみます。
最初に紹介したデフォルトテーマの定義内容を見れば、primary の色を変更する方法はわかると思います。
primary の main色、light色、dark色を上書きします。
下記のサイトを使うと main色から light色、dark色を自動で見つけてくれるので便利です。