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 のみでしたが、色、フォント、影なども定義可能です。