はじめに
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と表示されていれば成功です。
開発環境の構築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のおかげで、とてもすっきりしています。
{
"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を書きます。
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コンポーネントの基本ということで、いろいろなボタンを追加してみました。
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;
[補足]
v0.xのときはButton
はFlatButton
, RaisedButton
などのコンポーネントに分割されていたのですが、同じButton
コンポーネントにraised
などの属性を付ける形になりました。
コンポーネントのスタイリング
いまの形は基本形で、CSSによるスタイルが全くありません。
スタイルの適用はCSS modules
, styled-components
などでも良いのですが、Material-UI v1.xからはJSSを内部のスタイル適用方法として採用しています。
ここでは公式に合わせてコンポーネント利用側でもJSSを使ってスタイルを追加していきましょう。
スタイル追加の手順は以下の通りです。
-
withStyles
のimportimport { withStyles } from 'material-ui/styles';
-
スタイルを定義する
const styles = { /*スタイル*/ };
-
コンポーネントを
withStyles
でラップするclass MyComponent extends React.Component { ... } export default withStyles(styles)(MyComponent);
-
定義したスタイルが
props.classes
として渡されるので、className
に適用する
ちょっとしたスタイルの適用後は以下。
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);
スタイルを適用して見た目を整えてあげると、こんな感じになりました。
まとめ
非常に簡単に、よくある見た目のWebコンポーネントを使うことができます。