Node.js
reactjs
material-ui

ReactでテールスピンRPGを作るっ!Day#02 Material-UIでデザインを適用する

これまでのあらすじ

神の啓示を受けて「テールスピンRPG」を作ることを決めたノアnoah_40w.pngが神の御使いロジカlogica_40w.pngの助けを借りて開発に着手!Reactのインストールが完了し、基本的なデザイン設計にとりかかることに・・・

デザインを適用する

「デザインか・・・別に嫌いではないんだけど、WEBページのデザインって案外面倒臭いよね。」

「そうケロね。見やすく操作しやすいページにするためには守るべきルールが結構あって、それを意識しながらCSS定義したり画像を用意したりする確かに手間がかかるケロね。
でも安心するケロ。ノアがそう思うってことは、世の中の多くのエンジニアが同じように思っていて、そういう人のために便利なツールがきっと用意されているに違いないケロ!」

「ん?つい最近も同じような内容の話を聞いたような気が・・・。まあいいや。じゃ検索してみるね。『react デザイン』、と。
・・・いくつかそれっぽいのがヒットしたみたい。へ〜また色々あるんだね。選ぶのが難しいや。
うん、とりあえず一番上の『Material-UI』をまず試してみよう。」

「OKケロ。じゃあ早速インストールするケロ。」

「うん。えーと、『npm install material-ui』、と・・・。」

「ちょっと待つケロ。アプリ内から利用するモジュールをインストールするときは、『--save』オプションをつけておいた方がいいケロ。そうするとインストールされるモジュールの情報がアプリディレクトリ内のpackage.jsonに記録されるので、別の環境にアプリを持って行くときに一発で必要なモジュールを全部インストールできるようになるケロ。」

「そうなんだ。ありがとう教えてくれて。」

$ npm install material-ui --save

「ね。でもう一つ、material-uiで用意されているコンポーネントを利用するときに、タップイベントを有効にするためのモジュールも必要みたいなんで一緒にインストールするね。」

$ npm install react-tap-event-plugin --save

「インストールはこれでOKかな。じゃ早速Reactのスクリプトに組み込んでいこう!」

「ケロ。まず組み込みたいコンポーネントを選ぶケロ。それに必要なファイルをimportするケロ。」

「どうしようかな・・・。じゃページの上の方から行こう。よくあるタイトルやログインボタンなんかがあるヘッダをつけられないかな。」

「それなら『AppBar』ケロね。AppBarコンポーネントをimportしておいて、renderメソッドのreturn文の中でAppBarタグを書けばいいケロ。」

「わかったちょっとやってみるね。」

import React, { Component } from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import AppBar from 'material-ui/AppBar';

class App extends Component {
  render() {
    return (
      <AppBar title="TOLDOT">
      <div>
        ReactでRPGを作るよ!
      </div>
    );
  }
}

export default App;

「・・・保存と。
あれ?エラーぽい画面が表示されてしまったよ。」

「そうケロ。このスクリプトには2箇所に問題があるケロ。」

「そ、そうなんだ。2行しか加えていないというのに。僕って・・・。」

「落ち込む必要はないケロ。これはJSXの文法に則っていないというだけで、決してノアの能力が低いというわけではないケロ。多分そうケロ。」

「ありがとうロジカ。多分・・・ね。」

「まず1つ目の問題ケロが、JSXのルールでは単独タグの場合、HTMLでいうとbrとかimgタグのような閉じタグが必要ないタイプのタグのことケロが、<br/><img/>のようにスラッシュを書く必要があるケロ。」

「ふ〜ん、HTML5では書かないってことだったけど、JSXでは必要なんだ・・・ややこしいね。」

「まあ、この分野の技術ってそういうもんケロ。そのときのルールに従うしかないケロ。
で、2つ目ケロが、return文で返すDOM要素は1つだけと決まっているケロ。今回はAppBarとdivの2つ存在しているのでこれもエラーになるケロ。」

「え!?じゃどっちかしか返せないってこと?」

「それじゃ何も作れないケロ。子要素はいくらでもあっていいので、全体をdivタグでくくるなどすればOKケロ。」

「こんな感じかな。」

return (
  <div>
    <AppBar title="TOLDOT"/>
    <div>
      ReactでRPGを作るよ!
    </div>
  </div>
);

「うん、これでいいケロね。」

「あれ?まだ何かエラーが出るよ。」

「あ、忘れてたケロ。Material-UIで定義されているコンポーネントはMuiThemeProviderコンポーネントの子要素にしないといけなかったケロ。今回使っているのはAppBarだけなので、AppBarタグだけをくくってもいいケロが、これからコンポーネントが増えていくことを考えるとページ全体をくくっておくのがいいケロね。」

「じゃあ、こんな感じかな?あ、MuiThemeProviderタグが1つのDOM要素を作ることになるので、さっき入れたdivタグは要らなくなる?」

return (
  <MuiThemeProvider>
    <div>
      <AppBar title="TOLDOT"/>
      <div>
        ReactでRPGを作るよ!
      </div>
    </div>
  </MuiThemeProvider>
);

「いや。MuiThemeProviderタグの子要素も1つのDOM要素である必要があるのでdivタグは残すケロ。」

「なるほど。あ、ようやくエラーがなくなってコンパイルが成功したようだよ。」

ss201.png

「おお!なんかそれっぽくなっているよ。テンション上がるねー。メニューボタンまでついてるよ。クリッククリック♪・・・あれ、何も起きないけど・・・。」

「左のメニューボタンはデフォルトで表示されるようになっているみたいケロ。機能を持たせるためにはそれなりのコードを書く必要があるケロ。」

「そっか。必要になるまではただの飾りということだね。」

カラーを決める

「ところでこのAppBarの色、ちょっとアプリのイメージとは色がずれているんで変えたいんだけ、どうすればいいかな?」

「色の指定は単独で行われているのではなく『テーマ』として配色などの情報が設定さているケロ。いい感じのものが用意されて入ればそこから選ぶこともできるかと思ったケロが、今のところ明るめ(デフォルト)と暗めの2種類のテーマしかないみたいケロ。
仕方ないんでオリジナルのテーマを作って色を設定するケロ。アプリのイメージは何色ケロ?」

「はっきりとしたイメージはないけど、どちらかというと軽い感じではなく重たい感じかな。世界を創る、というのが結構重いイメージがあるので。大地や自然の色合いのアースカラー、茶色系か深緑系がいいかな。茶色は地味すぎるとしたら深緑?モスグリーンとか。」

「OK。じゃイメージに近い色コードを見つけて来るケロ。それをテーマのカラーに設定するケロ。」

「わかった。えとカラーパレットのサイトはと・・・。この色、あとこれもいいかな。」

「見つかったケロね。じゃ組み込んでいくケロ。
getMuiThemeメソッドにカラー情報を渡して、テーマオブジェクトを受け取り、それをMuiThemeProviderのプロパティとして設定すればいいケロ。」

「ちょっとややこしそうだけどトライしてみるね。」

src/App.js
import React, { Component } from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import AppBar from 'material-ui/AppBar';
import getMuiTheme from 'material-ui/styles/getMuiTheme';

const muiTheme = getMuiTheme({
  palette : {
    primary1Color: '#656733', // 深いモスグリーン
    primary2Color: '#90AD66', // 淡いモスグリーン
    primary3Color: '#D5EAD8', // ペールグリーン

    accent1Color: '#B71C1C', // 濃い赤
    accent2Color: '#aaaaaa', // 薄いグレー
    accent3Color: '#EDF2C5', // ベージュ
    textColor:    '#333333', // 黒
    alternateTextColor: '#ffffff', // 白
  },
});

class App extends Component {
  render() {
    return (
      <MuiThemeProvider muiTheme={muiTheme}>
        <div>
          <AppBar title="TOLDOT"/>
          <div>
            ReactRPGを作るよ!
          </div>
        </div>
      </MuiThemeProvider>
    );
  }
}

export default App;

「やった!色が変わったよ!」

ss202.png

「イメージ通りケロか?納得いくまで調整するケロ。
どのコンポーネントのどの部分にどの色が使用されているかというのがちょっとわからないので、都度調整していけば良いケロ。」

「わかった。
ところで、JSX中の<muiThemeProvider muiTheme={muiTheme}>の書き方がちょっとわからないんだけど・・・。」

「そっか、初めて出て来たケロね。JSXの中ではブレース(波括弧)の中に自由にJavaScriptのコードを書くことができるケロ。変数名や関数呼び出しを書くことが多いケロ。
ここでは、muiThemeプロパティの値として、classの外で定義しているmuiThemeオブジェクトを渡しているケロ。ちなみにこのときプロパティの値をダブルクオートで括る必要はないケロ。」

次回予告

Material-UIのコンポーネントから何かを利用してストーリー表示にチャレンジするケロ。お楽しみに!