対象読者
- JavaScriptとWeb開発の基礎に理解がある方
- Reactに興味/関心があり、これから学び始める方
前提環境
- macOS Sierra 10.12
- Node.js v6.6.0/npm 3.10.3
- React 15.4.0
- Material-UI 0.16.7
Material-UIの導入編
最近のエンドユーザーは優れたデザインを兼ね備えた多くのプロダクトに慣れ親しんでおり、それなりに利用されるものを作るには、アプリの機能だけでなくデザインも重要な要素です。
Yahoo! Japanは検索窓の枠を1ピクセル太くしただけで約5億円の広告収入増を達成した、というニュースが以前話題になりましたが、デザインが再訪問率やコンバージョン率に与える影響はますます大きくなっています。こういった背景から、新しいプロダクトを作る場合にはデザイナーを含めたチームを構成してプロジェクトを進めるべきですが、なんらかの制約でデザイナーを確保できず、デザインを勉強したことのないエンジニアが、UIの優れた成果物をアウトプットしなければいけない状況もあるでしょう。
Reactではサードパーティーによって開発された、さまざまなコンポーネントがMITライセンスで公開されています。これらを活用することで、ある程度しっかりした作りのアプリを比較的容易に開発できるようになります。利用目的がはっきりと決まっている場合はGitHubに公開されているコンポーネントを利用してもいいですが、ここでは最も有名なコンポーネントセットの一つである、Material-UIを利用する方法を紹介したいと思います。
冒頭でご紹介した通り、Material-UIはGoogleのデザインガイドラインに沿って開発されたコンポーネントセットであり、npmパッケージとして提供されています。画面内の部品に相当するReactコンポーネント群と、画面全体の色調を設定するテーマの二つを組み合わせてアプリを作成します。Material-UIで利用できる全てのReactコンポーネントを本稿で紹介することはできませんが、図2で紹介している通り、ボタンやカレンダー、ダイアログをはじめ、多くのコンポーネントが利用可能となっています。また、個々のコンポーネントとテーマに標準で適用されているデザイン(スタイル)は、必要に応じてカスタマイズすることもできます。
Material-UIのインストール
Reactプロジェクトのトップディレクトリで下記コマンドを実行し、パッケージをインストールします。Material-UIのコンポーネントでは、タップ系のイベントの取得にreact-tap-event-pluginを利用しています。この依存関係は将来的にはなくなると公式サイトに記載されていますが、現行バージョン(React 15.4.0)ではMaterial-UI導入時にreact-tap-event-pluginも併せてインストールする必要があります。
$ npm install --save-dev material-ui $ npm install --save-dev react-tap-event-plugin
インストールが完了すると、下図のようにMaterial-UIのパッケージが追加されます。
Material-UIを実装する
Material-UIの活用
では、Material-UIを実装する方法を解説していきます。まずはチップとアバターというコンポーネントについて紹介します。チップは角丸の長方形のオブジェクト内に複数の要素を表現できるコンポーネント、アバターは人やものを丸いアイコンで表現するためのコンポーネントです。
ここで紹介するサンプルでのチップとアバターの関係は、チップにアバターが内包されているというイメージです。下表(表1、表2)のチップとアバターのプロパティ一覧にも記載していますが、チップではonRequestDeleteにコールバックを設定することで削除アイコンを表示させ、ハンドルすることが可能です。アバターは単独で利用されるというよりもチップやリストアイテムといった他のコンポーネントと組み合わせて利用するケースのほうが多いと思います。
| # | プロパティ | 型 | 説明 |
|---|---|---|---|
| 1 | backgroundColor | string | 背景色を設定。 |
| 2 | labelColor | string | ラベルの色を設定。 |
| 3 | labelStyle | object | ラベルのスタイルを設定。 |
| 4 | onRequestDelete | function | 削除ボタンクリック時のコールバックを設定。このプロパティが設定された場合に削除ボタンが表示される。 |
| 5 | onTouchTap | function | 要素がタップされた時のコールバックを設定。 |
| 6 | style | object | スタイルを指定。親要素のスタイルをオーバーライドする場合に利用。 |
| # | プロパティ | 型 | 説明 |
|---|---|---|---|
| 1 | backgroundColor | string | 背景色を設定。アイコン画像には適用されない。 |
| 2 | children | node | 子要素を設定。 |
| 3 | icon | element | アバターにSvgIcon、またはFontIconというアイコンコンポーネントを設定。 |
| 4 | color | string | アイコンの色を設定。 |
| 5 | size | number | アバターのピクセル数を設定。 |
| 6 | src | string | アバターに画像を設定。この値が設定される場合はimg要素として描画され、それ以外の場合はdiv要素として描画される。 |
| 7 | style | object | スタイルを指定。親要素のスタイルをオーバーライドする場合に利用。 |
リスト2と図4は、チップとアバターを利用したサンプルコードとその実行結果です。削除ボタンのクリック時とそれ以外の領域のクリック時に、それぞれhandleTouchDeleteとhandleTouchTapが実行されます。
import React from 'react'; import ReactDOM from 'react-dom'; import ‘./index.css'; // (1)モジュールのインポート import MuiThemeProvider from ‘material-ui/styles/MuiThemeProvider'; import Avatar from 'material-ui/Avatar'; import Chip from 'material-ui/Chip'; import injectTapEventPlugin from 'react-tap-event-plugin'; // (2)タッチイベントに必要なコード // http://stackoverflow.com/a/34015469/988941 injectTapEventPlugin(); const styles = { chip: { margin: 5, }, wrapper: { display: 'flex', flexWrap: 'wrap', }, }; // (3)タップイベントのハンドラ function handleTouchDelete() { alert('削除ボタンが押されました'); } function handleTouchTap() { alert('チップが選択されました。'); } // (4)Material-UIのコンポーネントの宣言 class MyChipSmaple extends React.Component { render() { return ( <MuiThemeProvider> <div style={styles.wrapper}> <Chip onRequestDelete={handleTouchDelete} onTouchTap={handleTouchTap} style={styles.chip} > <Avatar size={32}>TS</Avatar> Taro Sakurai </Chip> [繰り返しのため省略] </MuiThemeProvider> ); } } ReactDOM.render( <MyChipSmaple />, document.getElementById('root') );
実行結果の通り、Material-UIを利用すると今風のUIのウィジェットを簡単に表示することができます。(1)でモジュールを読み込み、(4)で宣言したコンポーネントをReactDOM.renderメソッドで描画することでMaterial-UIを利用しています。また、宣言したコンポーネント内でチップを呼び出し、同時にイベントハンドラの設定、およびコンテンツの表示を行っています。ここで言及すべきポイントは、Material-UIで提供されるコンポーネントを利用するためにテーマを適用する必要があるということです。(4)のように、MuiThemeProviderを最上位の階層としてチップやアバターのコンポーネントを呼び出すことにより、Material-UIのデザインがウィジェットに適用されます。(2)はインストール時にも触れましたが、タップイベント系取得に必要な設定で、アプリの最初に書くおまじないのようなものです。
MuiThemeProviderについて
Material-UIで提供されるMuiThemeProviderをカスタマイズすることで、アプリ全体のデザインを変更することができます。標準で提供されているスタイルには、lightBaseTheme(デフォルト設定)とdarkBaseThemeがあります。darkBaseThemeを適用する場合は、以下のようなモジュールの読み込みとテーマ適用の設定を行います。
import darkBaseTheme from 'material-ui/styles/baseThemes/darkBaseTheme'; import getMuiTheme from 'material-ui/styles/getMuiTheme';
class MyButton extends React.Component { render() { return( <MuiThemeProvider muiTheme={getMuiTheme(darkBaseTheme)}> <RaisedButton label="MyButton" /> </MuiThemeProvider> ); } }
また、さらに細やかなスタイルの変更は、 muiThemeオブジェクトのプロパティの設定を個別にすることで実現できます。muiThemeオブジェクトには、コンポーネント間の間隔やフォント、要素のカラーといったさまざまな設定がされています。コンポーネント宣言時にカスタマイズしたテーマを適用することで、思い通りのデザインのアプリを作ることが可能です。カスタマイズ可能な項目は以下の表の通りです。
| # | プロパティ | 説明 |
|---|---|---|
| 1 | spacing | コンポーネント間の間隔を設定。 |
| 2 | fontFamily | デフォルトのフォントを設定。 |
| 3 | palette | ウィジェットやテキストの色を設定。 |
| 4 | zIndex | コンポーネントの重なりの順序を指定。 |
| 5 | isRTL | 文字が右から左に表示されるように指定。 |
| 6 | App Bar、Avatar等 | 個別のコンポーネントのスタイルを指定。 |
実装方法は、引数にJSONファイルとしてカスタマイズしたい項目をセットしてgetMuiThemeメソッドを呼び出し、戻り値のmuiThemeオブジェクトをMuiThemeProviderコンポーネント生成時のPropsとして設定します。
// カスタマイズしたい項目の設定 const muiTheme = getMuiTheme({ palette: { primary1Color: blue500, }, RaisedButton: { width: 80, }, }); // PropsとしてmuiThemeオブジェクトを設定 const Main = () => ( <MuiThemeProvider muiTheme={muiTheme}> <RaisedButton label="My Button” /> </MuiThemeProvider> );
まとめ
今回は、Reactコンポーネントセットの一つである、Material-UIを紹介しました。他にもさまざまなコンポーネントが利用可能なので、ご自身に合ったものをぜひ探してみてください。

