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

  • このエントリーをはてなブックマークに追加
  • LINEで送る
この記事は 2019年4月11日 に書かれたものです

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

- Sponsored Link -

テーマ機能で色指定

サンプルコード

結論から言うと以下のように、テーマを適用したい箇所を<MuiThemeProvider>で囲み、具体的なテーマの設定は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'
};

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

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

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

/**
 * 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

<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行目がテーマを反映した物です。

※ブラウザの機能で拡大しています。

参考ページ

コメント

コメント欄は休止中です。お問い合わせはこちらからどうぞ。ご質問はTwitterにリプを投げてください。

このブログを応援する

お寄せいただいたお気持ちは全額サーバ代や次の記事を執筆するための原資として活用させていただいております。この記事が参考になった場合などぜひご検討ください。

PayPal(ペイパル)
PayPalで300円支払う
※金額は任意で変更できます。
※100円でも泣いて喜びますw
※住所の入力欄が現れた場合は「no needed」を選択ください
これまでのご協力者さま
- Sponsored Link -

同じカテゴリの記事

旧コメント欄(表示のみ)

※こちらのコメント欄は以前稼働していたものです。現在は新たに書き込むことはできません。ご感想やご質問は記事の下にあるコメント欄をご利用ください。
  1. second より:

    初めまして。
    こちらのサイトを参考にMterial-UIを学んでいます。

    Reactを独学で学んでおり、周りに先生がおらずいつも悪戦苦闘しております。

    そこで質問なのですが、
    このページの一番上のサンプルコードで、
    左が紫で右が青の時計のアイコンが表示されるはずが、
    両方とも青のアイコンになってしまいます。

    何が原因として考えられるでしょうか?

  2. 勝部 麻季人 より:

    ご覧いただきありがとうございます。
    周りに詳しい人いないと苦労しますよね。私も身近にほしいですw

    ご質問いただいた件ですが、どうもこの記事を書いた1年前から仕様が変更になったようです。こちらでも動かしてみましたが同様の現象が確認できました。後日手が空いたら更新したいと思います(すぐに調べられず申し訳ないです)