【React】【Material-UI】テーマ機能で Material-UI コンポーネントのデフォルト値や CSS を定義する

 Material-UI は React のデザインフレームワークです。HTML 組み込みのタグの代わりに Material-UI の定義するコンポーネントを用いることで簡単にリッチな画面を構成できます。
Material-UI: A popular React UI framework
 便利なフレームワークなのですが後付けでデフォルトの状態から CSS を変えたりするのは面倒です。というのも HTML のクラス付けルールが複雑な上、 React コード上からは隠蔽されているためです。次のデモは Material-UI のリファレンスにあるデモとその実行結果の HTML です。
 Accordion React component – Material-UI


 見た目はシンプルですが、HTML 上は class がぎっちり埋まっている上、動的に変化することもあります。これに都度 CSS を当てるセレクタを取得するのは手間です。手っ取り早い解決方法は次の様にコンポーネントに対して style を渡すことです。Material-UI の中でいい感じに変換してくれます。

<Accordion style={{background:'aliceblue'}}>

 また、Material-UI コンポーネントに渡す props にいい感じの制御があったならば、自らの手で CSS を定義するよりそちらを選んだほうが賢明です。 input 要素に対応する次のデモのコンポーネントはこれの代表です。

 props に渡す方法を紹介しましたが、これには定義こそ簡単であっても次の様にコード量が増える点でまだ不満があります。variant, style の二つの重複が邪魔者です。

<TextField id="outlined-1" label="Outlined1" variant="outlined" style={styles.input} />
<TextField id="outlined-2" label="Outlined2" variant="outlined" style={styles.input} />
<TextField id="outlined-3" label="Outlined3" variant="outlined" style={styles.input} />

 デフォルト値を含んだ Material-UI コンポーネントをラッピングしたコンポーネントを作る方法が解決方法の一つですが props のデフォルト値のためだけにそれを行うのは少々贅沢です。テーマ機能でこれを解決できます。

Theming – Material-UI
テーマ – Material-UI

 テーマ は Material-UI コンポーネントの様々な部分をデフォルト値として書き換え、追記する仕組みです。使い方は次のコードの通り、テーマを定義して ThemeProvider に渡し、 ThemeProvider 以下で Material-UI コンポーネントを呼び出すのみです。

// thema.js
// テーマを定義するファイル
// 凝っていく程、巨大になるので分割がおすすめ
import { createMuiTheme } from '@material-ui/core/styles';

export const theme = createMuiTheme({
  // テーマの内容
});

// app.jsx
// React を使う大本のファイル
import React from 'react';
import ReactDOM from 'react-dom';
import { AppFrame } from './AppFrame';
import { AppContent } from './AppContent';
import { theme } from './styles/thema';
import { ThemeProvider } from '@material-ui/core/styles';

/**
 * ルートコンポーネント
 * @constructor
 */
function App() {
  // ThemeProvider 以下で使われた Material-UI コンポーネントのデフォルト値が変わります
  return (
    <ThemeProvider theme={theme}>
      <AppFrame>
        <AppContent />
      </AppFrame>
    </ThemeProvider>
  );
}
ReactDOM.render(<App />, document.getElementById('app'));

 これを使うと次のデモの様なことができます。

// demo.tsx
import React from "react";
import TextField from "@material-ui/core/TextField";

export default function BasicTextFields() {
  // 素のままの Material-UI コンポーネント呼び出し
  return (
    <form>
      <TextField id="standard-basic" label="Standard" />
      <TextField id="filled-basic" label="Filled" />
      <TextField id="outlined-basic" label="Outlined" />
    </form>
  );
}
// index.tsx
import React from "react";
import ReactDOM from "react-dom";
import Demo from "./demo";
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
// テーマ定義
const theme = createMuiTheme({
  overrides: { // CSS の上書き
    MuiTextField: {
      root: {
        width: "100%"
      }
    }
  },
  props: { // props のデフォルト値の上書き
    MuiTextField: {
      variant: "outlined"
    }
  }
});

ReactDOM.render(
  <ThemeProvider theme={theme}>
    <Demo />
  </ThemeProvider>,
  document.querySelector("#root")
);

 Material-UI のためだけに知るべきことは多いですがテーマ機能を使うことで様々な要素を一気に定義できます。例では CSS と props のみでしたが、色、フォント、影なども定義可能です。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG