Edited at

Material-UI v1.x (beta) を導入する

More than 1 year has passed since last update.


はじめに

Reactで開発するときに手軽に使えるReactコンポーネントセットの中で特に人気の高いMaterial-UIの開発がv1.xのbetaになっており、いよいよ正式にリリースされようとしています。

そこで、beta版を導入してv1.xを先取りしてみます。

また、React本体も無事にライセンス問題が解決してv16のリリースがされたばかりなので、v16を前提とします。


やること


  • Material-UIを使った開発環境構築

  • 簡単なButtonサンプル

  • JSSを使ってスタイルを適用する


補足

server-side renderingを行う場合については触れていませんが、設計として考慮されていて、実現のためにはNext.jsを使うのが良さそうです。


前提条件


  • Reactの基本的な理解

  • npm, yarnで構築する開発環境の理解


開発環境の構築1 - create-react-appで土台を作る

既に開発環境が構築済みの場合、この項は飛ばしてください。

スムーズに開発環境を構築したいので、create-react-appを使います。

まだコマンドが登録されていない場合はインストールしましょう。

# create-react-appコマンドをインストール

yarn global add create-react-app

プロジェクトを作っていきます。

create-react-app my-mui-project

cd my-mui-project

無事に動作するか確認します。

yarn start

開発用サーバーが立ち上がり、localhost:3000にブラウザからアクセスしてWelcome to Reactと表示されていれば成功です。

Screenshot from 2017-10-02 23-23-29.png


開発環境の構築2 - Material-UIの追加

Material-UIをプロジェクトに追加します。

SvgIconを使いたい場合は、v1.xから別のパッケージに分離されたので、そちらも追加します。

# beta版を試すには@nextを指定

yarn add material-ui@next -S

# SVGIconを使う場合はこちらも
yarn add material-ui-icons -S

この時点でのpackage.jsonの中身

create-react-appのおかげで、とてもすっきりしています。


package.json

{

"name": "my-mui-project",
"version": "0.1.0",
"private": true,
"dependencies": {
"material-ui": "1.0.0-beta.13",
"material-ui-icons": "^1.0.0-beta.14",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-scripts": "1.0.14"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}


開発中版 v0.x を既に使っている場合

v1.x系を次のようにパッケージ追加して共存させることができるので、順次移行作業を進めることができます。

# 既存のプロジェクトにv1.xを追加

yarn add material-ui-next@npm:material-ui@next -S

v1.x系に置き換えたい部分では以下のようにimportを書きます。

js

import FlatButton from 'material-ui/FlatButton'; // v0.x

import Button from 'material-ui-next/Button'; // v1.x


Robotoフォントの追加

Material-UIはRobotoフォントを使用するようにデザインされていますが、RobotoフォントはMaterial-UIを追加しただけでは追加されません。

Robotoフォントの追加方法はいくつかありますが、一番簡単なやり方はCDNのリンクを<head></head>内に追加することです。

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">


コンポーネントを使ってみる

さっそくApp.jsを書き換えて、コンポーネントを使ってみましょう。

UIコンポーネントの基本ということで、いろいろなボタンを追加してみました。


App.js

import React, { Component } from 'react';

import Button from 'material-ui/Button';
import IconButton from 'material-ui/IconButton';
import AddIcon from 'material-ui-icons/Add';
import ModeEditIcon from 'material-ui-icons/ModeEdit';
import AddShoppingCartIcon from 'material-ui-icons/AddShoppingCart';
import DeleteIcon from 'material-ui-icons/Delete';

class App extends Component {
handleClick = ()=> {
alert("Clicked!");
}

render() {
return (
<div>
<div>
{/* クリックイベントの処理はこんな感じ */}
<Button onClick={this.handleClick}>Default</Button>
<Button color="primary">Primary</Button>
<Button color="secondary"><DeleteIcon />削除</Button>
</div>
<div>
<Button variant="raised">Default</Button>
<Button variant="raised" color="primary">Primary</Button>
<Button variant="raised" color="secondary"><DeleteIcon />削除</Button>
</div>
<div>
<Button variant="fab" color="primary" aria-label="add">
<AddIcon />
</Button>
<Button variant="fab" color="secondary" aria-label="edit">
<ModeEditIcon />
</Button>
</div>
<div>
<IconButton aria-label="Delete">
<DeleteIcon />
</IconButton>
<IconButton color="primary" aria-label="Add to shopping cart">
<AddShoppingCartIcon />
</IconButton>
</div>
</div>
);
}
}

export default App;


見た目はこんな感じになりました。

Screenshot from 2017-10-03 01-54-28.png

[補足]

v0.xのときはButtonFlatButton, RaisedButtonなどのコンポーネントに分割されていたのですが、同じButtonコンポーネントにraisedなどの属性を付ける形になりました。


コンポーネントのスタイリング

いまの形は基本形で、CSSによるスタイルが全くありません。

スタイルの適用はCSS modules, styled-componentsなどでも良いのですが、Material-UI v1.xからはJSSを内部のスタイル適用方法として採用しています。

ここでは公式に合わせてコンポーネント利用側でもJSSを使ってスタイルを追加していきましょう。

スタイル追加の手順は以下の通りです。



  1. withStylesのimport

    import { withStyles } from 'material-ui/styles';
    



  2. スタイルを定義する

    const styles = { /*スタイル*/ };
    



  3. コンポーネントをwithStylesでラップする

    class MyComponent extends React.Component { ... }  

    export default withStyles(styles)(MyComponent);



  4. 定義したスタイルがprops.classesとして渡されるので、classNameに適用する


ちょっとしたスタイルの適用後は以下。


App.js

import React, { Component } from 'react';

import Button from 'material-ui/Button';
import IconButton from 'material-ui/IconButton';
import AddIcon from 'material-ui-icons/Add';
import ModeEditIcon from 'material-ui-icons/ModeEdit';
import AddShoppingCartIcon from 'material-ui-icons/AddShoppingCart';
import DeleteIcon from 'material-ui-icons/Delete';

import { withStyles } from 'material-ui/styles'; //追加

const styles = {
box: {
margin: 10,
padding: 10,
border: "solid 1px gray",
},
button: {
margin: 10,
},
buttonWithHover: {
margin: 10,
// hoverも記述できる
'&:hover': {
backgroundColor: '#ff0000',
}
},
};

class App extends Component {
handleClick = ()=> {
alert("Clicked!");
}

render() {
// 長くなるので参照
const classes = this.props.classes;
return (
<div>
<div className={classes.box}>
{/* クリックイベントの処理はこんな感じ */}
<Button onClick={this.handleClick} className={classes.button}>Default</Button>
<Button color="primary" className={classes.buttonWithHover}>Primary</Button>
<Button color="accent"><DeleteIcon />削除</Button>
</div>
<div className={classes.box}>
<Button raised className={classes.button}>Default</Button>
<Button raised color="primary" className={classes.button}>Primary</Button>
<Button raised color="accent" className={classes.button}><DeleteIcon />削除</Button>
</div>
<div className={classes.box}>
<Button fab color="primary" aria-label="add" className={classes.button}>
<AddIcon />
</Button>
<Button fab color="accent" aria-label="edit" className={classes.button}>
<ModeEditIcon />
</Button>
</div>
<div className={classes.box}>
<IconButton aria-label="Delete" className={classes.button}>
<DeleteIcon />
</IconButton>
<IconButton color="primary" aria-label="Add to shopping cart" className={classes.button}>
<AddShoppingCartIcon />
</IconButton>
</div>
</div>
);
}
}

export default withStyles(styles)(App);


スタイルを適用して見た目を整えてあげると、こんな感じになりました。

Screenshot from 2017-10-03 01-53-35.png


まとめ

非常に簡単に、よくある見た目のWebコンポーネントを使うことができます。