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