はじめてのReact #30 「CSSフレームワークを導入する」Material-UI テーマをカスタマイズ編

前回はアイコンやテキスト情報を表示しましたが、色を直接指定することができませんでした。primaryerrorなど意味を示す物でしたよね。今回はデフォルトで定義されている色などを変更するテーマ機能を触ってみます。

テーマ機能で色指定

サンプルコード

結論から言うと以下のように、テーマを適用したい箇所をで囲み、具体的なテーマの設定はcreateMuiTheme()関数で行います。これだけ。

import React, { Component } from 'react';
import AlarmIcon from '@material-ui/icons/Alarm';             // "Alarm"アイコン
import { createMuiTheme } from '@material-ui/core/styles';    // テーマの設定を行う
import { MuiThemeProvider } from '@material-ui/core/styles';  // テーマを実際に利用する
import blue from '@material-ui/core/colors/blue';             // 「青」

//ここでテーマの設定を行う
const mytheme = createMuiTheme({
  palette: {
    primary: blue,
  },
});

class App extends Component {
  render() {
    return (
      <div>
        <AlarmIcon color="primary" />

        {/* ここからテーマ利用 */}
        <MuiThemeProvider theme={mytheme} >
          <AlarmIcon color="primary" />
        </MuiThemeProvider>
        {/* ここまで */}
      </div>
    );
  }
}

export default App;

実行結果は以下の通りです。 向かって左側のAlarmがテーマが適用されていない状態、右側がテーマが適用された物です。 ※ブラウザの機能で大きく表示しています。

細かく指定する

次のようにさらに細かく指定することができます。 primary, secondaryといった単位だとオブジェクトを指定するしかありませんが、個別に指定する場合はRGBを直接書くことができます。

import { createMuiTheme } from '@material-ui/core/styles';

const theme = createMuiTheme({
  palette: {
    primary: {
      light: '#757ce8',
      main: '#3f50b5',
      dark: '#002884',
      contrastText: '#fff',
    },
    secondary: {
      light: '#ff7961',
      main: '#f44336',
      dark: '#ba000d',
      contrastText: '#000',
    },
  },
});

カラーパレット

細かく指定する際にRGBを直接しても良いのですが、RGBの値を調べるのが面倒ですよね。そんなときには以下のような指定が可能です。

import { createMuiTheme } from '@material-ui/core/styles';
import blue from '@material-ui/core/colors/blue';

const theme = createMuiTheme({
  palette: {
    primary: {
      light: blue[300],  //添字の数字が大きくなるほど暗くなる
       main: blue[500],
       dark: blue[700],
    },
  },
});

添字(キー)は適当な数字だと動きません。 blueの中身ですが、@material-ui/core/colors/blueの中身をのぞくと、単純に以下のような連想配列になっています。あらかじめ準備されたRGBのコードを利用しているというわけです。

// node_modules/@material-ui/core/colors/blue.js
var blue = {
  50: '#e3f2fd',
  100: '#bbdefb',
  200: '#90caf9',
  300: '#64b5f6',
  400: '#42a5f5',
  500: '#2196f3',
  600: '#1e88e5',
  700: '#1976d2',
  800: '#1565c0',
  900: '#0d47a1',
  A100: '#82b1ff',
  A200: '#448aff',
  A400: '#2979ff',
  A700: '#2962ff'
};

詳しくは公式ドキュメントに色見本や簡単なサンプルが掲載されていますので参考に。 material-ui.com

テーマ設定を別ファイルに分ける

先ほどのサンプルのままでも動きはしますが、実際に利用する際には複数のファイルから共通のテーマとして呼び出したくなりますので、通常は以下のようにファイルを分割します。

/**
 * MyTheme.js
 */
import { createMuiTheme } from '@material-ui/core/styles';    // テーマの設定を行う
import blue from '@material-ui/core/colors/blue';             // 「青」

//ここでテーマの設定を行う
export default createMuiTheme({
  palette: {
    primary: blue,
  },
});
/**
 * App.js
 */
import React, { Component } from 'react';
import AlarmIcon from '@material-ui/icons/Alarm';             // "Alarm"アイコン
import { MuiThemeProvider } from '@material-ui/core/styles';  // テーマを実際に利用する
import mytheme from './MyTheme'; 

class App extends Component {
  render() {
    return (
      <div>
        <AlarmIcon color="primary" />

        {/* ここからテーマ利用 */}
        <MuiThemeProvider theme={mytheme} >
          <AlarmIcon color="primary" />
        </MuiThemeProvider>
        {/* ここまで */}
      </div>
    );
  }
}

export default App;

実行結果は分割前と変わりません。

色以外の設定

Typography

に対してフォントの種類と大きさを指定することができます。

/**
 * MyTheme.js
 */
import { createMuiTheme } from '@material-ui/core/styles';    // テーマの設定を行う
import blue from '@material-ui/core/colors/blue';             // 「青」

export default createMuiTheme({
  typography:{
    fontFamily: ['fantasy', '"Helvetica Neue"'].join(","),
    fontSize: 20,
  },
  palette: {
    primary: blue,
  },
});
/**
 * App.js
 */
import React, { Component } from 'react';
import { MuiThemeProvider } from '@material-ui/core/styles';  // テーマを実際に利用する
import { Typography } from '@material-ui/core';
import mytheme from './MyTheme';

class App extends Component {
  render() {
    return (
      <div>
        <Typography variant="body1">
          Hello Material-UI
        </Typography>
        <MuiThemeProvider theme={mytheme} >
          <Typography variant="body1">
            Hello Material-UI
          </Typography>
        </MuiThemeProvider>
      </div>
    );
  }
}

export default App;

実行結果は以下の通り。 1行目がテーマ未指定、2行目がテーマを反映した物です。 ※ブラウザの機能で拡大しています。

参考ページ