Material-UI α版
こちらの記事引き続き、React.js向けのマテリアルデザインMaterial-UIについて、αブランチ(v1.0-alphe 14)の機能をみていきます。
現在v0.18ではCSSはLESSによって構築されていますが、v1.0からはCSS in JSの仕組みが提供されるようです。別途CSS-Moduleを入れたりWebpackに設定する必要もないので簡単に利用できそうです。
α版のインストールにはnpmで@nextを指定します。
$ npm install --save material-ui@next
CSSinJS in Material-UI
Material-UIのCSSinJSではcreateStyleSheet
とwithStyles
という2つのAPIを利用します。createStyleSheet
でDOMに適用するスタイルを生成し、withStyles
でスタイルを適用したDOMを生成するという手順です。
createStyleSheet
createStyleSheetは第1引数に名前、第2引数にスタイルのオブジェクト、またはスタイルのオブジェクトを返す関数を指定します。第1引数は単にデバッグ目的に利用されるだけのようです。第2引数に渡す関数の引数theme
についてはあとで説明します。
import { createStyleSheet } from 'material-ui/styles';
let myStyleSheet = createStyleSheet("myStyle", (theme) => {
root : {
color: '#CCC',
width: '500px',
},
});
withStyle
withStyleの第1引数には先ほど生成したスタイルを指定します。返り値は高階コンポーネント(higher-order component)です。高階コンポーネントの正しい意味はよくわかりませんが、高階コンポーネントにReactコンポーネント(DOM)を渡してあげると、先ほどのスタイルが適用される新たなDOMが生成されます。
スタイルが適用されるコンポーネントにはprops
を通してclasses
プロパティが渡されます。classNameにclassesのプロパティを指定することで、その要素にスタイルが適用されます。
import { withStyles } from 'material-ui/styles';
// いつものReactコンポーネント(ただしpropsにclassesが渡される)
const MyApp = (props) = (
<div className={props.classes.root}> //渡されたclassesを適用
Hello World
</div>
)
// スタイルを適用したコンポーネント
let StyledMyApp = withStyles(myStyleSheet)(MyApp);
// スタイル付きコンポーネントは<MuiThemeProvider>の子要素にする
ReactDOM.render(<MuiThemeProvider><StyledMyApp /></MuiThemeProvider>,
document.querySelector('#app'));
themeProvider
アプリケーション全体でデザインを統一するためにテーマ(theme)の概念があるようです。themeはcreateMuiTheme
で作成して、MuiThemeProvider
の属性値として渡すことで適用できます。
前述のcteateStyleSheet
の第2引数の関数に渡されるtheme
はMuiThemeProvider
に適用されたものになります。themeオブジェクトのプロパティはたくさんあるのでこちらを参照してください。色はこちらを参照。
使い方は例えばこんな感じ。
import { purple, green, red } from 'material-ui/styles/colors';
// 独自テーマを作って
const theme = createMuiTheme({
status: {
danger: 'orange',
},
});
// 適用する
ReactDOM.render(<MuiThemeProvider theme={theme}> ...
ただ、実際にはあまりテーマを作成することはなく、テーマはそのまま利用し、自作コンポーネントにそのテーマから値(色とかフォントとか)を適用する、というのがメインになるかなと思います。たとえばこんな感じで。
let myStyleSheet = createStyleSheet("myStyle", (theme) => {
root : {
backgroundColor: theme.palette.primary[200],
color: theme.palette.getContrastText(theme.palette.primary[200]),
padding: `${theme.spacing.unit}px`, //余白もテーマで統一できる
},
});
上の例のとおり、paletteに対してgetContrastTextを使うと、背景色に適したテキスト色が選択されます。これで色環とかもう考えなくても良いですね。
やってみた
適当にテーマをいじったりしてみました。いくらフレームワークがしっかりしていても、マテリアルデザインに則らずに適当に値を指定してしまったので、全然イケてないですね。。
Material-UIを利用することで、見た目に関する色々な機能が(ほぼ)オールインワンで提供されるので、僕のような初学者にはオススメかと思います。