Reactでのアプリケーション開発を学習中の方、ユーザとサービスとの接点となる画面のUIを作成するときに苦労されていませんか?

UIを使いやすく奇麗に実装することは、アプリケーションをユーザに使ってもらう上で大切です。

この記事では画面へのUI設置を簡単に行うことができるMaterial-UIのインストール方法と、実装できるコンポーネントを一挙にご紹介します。

Material-UIとは

Googleが公開しているガイドラインである「Mterial Design」をベースに開発されたUIコンポーネントライブラリです。

Reactのアプリケーションを開発するにあたり、複雑で奇麗なUIを簡単に実装することを可能とします。

特にMaterial-UI v5からはCSSを記述するためのライブラリにemotionがデフォルトで使用されるようになりました。

これによりv4よりも動的なスタイルに強くなり、ソースコードの量が少なくなり、さらに多くの機能を他のライブラリよりも洗練された状態で使うことができます。

v5からは基本となるコンポーネントであり無料で使用することができるMUI Coreの他、ややこしい実装に向けた有料のコンポーネントであるMUI Xが提供されています。

インストール方法

Reactが17.0.0以上、React DOMが17.0.0以上であることを確認した後、プロジェクトのディレクトリ直下で以下のコマンドを実行してください。

npm install @mui/material @emotion/react @emotion/styled

これでCSS-in-JSライブラリにemotionを使用する設定でインストールすることができます。

もしもCSS-in-JSライブラリをデフォルトのemotionからstyled-componentsに変更したい場合は以下のコマンドを実行します。

npm install @mui/material @mui/styled-engine-sc styled-components

Material-UIの主なコンポーネント

VSCodeでReactの開発環境を整える!手順とおすすめ拡張機能を紹介

それでは、実装が可能なコンポーネントを解説していきます。

Layout: レイアウトのためのコンポーネント 

BoxほとんどのCSSユーティリティが必要とするラッパーコンポーネントとして使うことができます。componentプロパティを設定することにより、生成するタグをdivとspanで切り替えることができます。
Containerコンテンツを中央揃えにするコンポーネントで、最も基本となります。流動的コンテナと段階的コンテナの2種類を生成することができます。
Grid画面を格子状に分割して、組み合わせることでレイアウト全体に一貫性を持たせているレスポンシブレイアウトです。Material Designでは12列のレイアウトに基づいています。
Stackスタックはレイアウトを管理するコンポーネントです。直下の子要素が管理対象となり、垂直または水平に並べ、さらに子要素同士の間に余白や仕切りをつけます。
Image Listイメージリストはグリッド状に整頓された画像を表示することができます。基本となる全ての画像が同じ大きさで表示されるリストの他、特定の画像を強調して表現することもできます。

Inputs: 入力のためのコンポーネント 

Autocompleteオートコンプリートはオプション値を選択することのできるコンポーネントで、選択肢をテキストボックスに入力された値で絞り込むことができます。
Buttonボタンはユーザが実行できる行動を伝達するためのコンポーネントです。モーダルウィンドウの「閉じる」ボタンやフォームの「送信」ボタンが主な例と言えるでしょう。
Button GroupButtonGroupコンポーネントでは、関係しているボタンをグループ化できます。グループ化するボタンはButtonGroupコンポーネントの直下の子要素である必要があります。
Checkboxチェックボックスは選択肢の中から複数のものを選ぶことができます。
Floating Action Buttonフローティングアクションボタンとは画面の定位置に表示されるボタンです。通常は円の中にアイコンを用いたデザインが使われ、コンテンツの一番前面に浮かんだように表示されています。
Radio buttonラジオボタンは複数の選択肢の中から1つだけ選ぶことができます。
RatingRatingsはコンテンツの管理者に対してユーザの評価を送るためにあります。管理者の意見や体験したことに対して、ユーザは星の数で自分の評価をつけられます。
Selectセレクトコンポーネントはリストの中からユーザが選択した情報を収集するために使われます。ユーザはプルダウンメニューで選択肢を確認し、選択することができます。
Sliderスライダーは特定の範囲の中から値を設定するためのコンポーネントです。音量の設定をするときに提供されていることが多いと言えます。
Swetchスイッチはひとつの設定でオンオフの状態を切り替えます。
Text fieldテキストフィールドはテキストを入力および編集することのできるコンポーネントです。
Transfer List転送リストは、1つ以上のアイテムをリスト間で移動することのできるコンポーネントです。
Toggle Buttonトグルボタンは関連するオプションをグループ化できます。グループ化されたオプションは1つだけ選択することが可能なもの、複数のオプションを選択することが可能なものがあります。

Navigation: ナビゲーションに関するコンポーネント 

Bottom Navigationボタンナビゲーションではアプリの中の主だった項目の間を移動することが可能となります。
Bareadcrumbs構造化されたWebサイトをユーザが閲覧しているときに、表示されているページの階層を可視化することができます。トップページからどのようにたどり着くことができるか、ナビゲーションを可能にするリンクで構成されています。
Drawerアプリ内の主要なコンテンツへアクセスできるメニュー画面を表示します。特に画面の左右どちらかに固定された、補足コンテンツを含む画面のことをサイドシートと言います。
Linkリンクコンポーネントを使うと、テーマカラーと文字デザインのスタイルを使用して簡単にアンカー要素をカスタマイズできます。
Menuメニューを一時的に画面よりも優先して表示します。
Paginationページネーションコンポーネントを有効にすると、複数あるページの中から特定のページを選択して表示できるようになります。
Speed Dial画面上に浮いているアクションボタンを押したとき、3~6個の関連するアクションを表示できます。
Stepperステッパーは番号が付けられたステップを通じて、進行状況を伝えるコンポーネントです。ウィザードのような役目を果たします。
Tabsタブを使用すると簡単に表示したいビューを探して切り替えられます。表示したい情報が載っているタブを選択すると表示される情報が切り替わります。

Surfaces: 任意のコンポーネントを載せるためのコンポーネント

Accordionアコーディオンコンポーネントはアコーディオンメニューを実装できます。ひとつのページ上にある関係のあるコンテンツをセクションごとに表示したり非表示にしたりする機能で、大きな面でも使うこともでき、軽量であることが特徴です。
App Barその時点で表示されている画面に関しての情報をまとめて表示します。画面上部に設置されたAppBarは、多くの場合タイトルを表示したりナビゲーションバーとして、もしくは実行できる情報をまとめるために使われます。
Cardカードはひとつのコンテンツと関係する動きや情報をまとめて表示できます。関連している情報を読み込むことができる必要があります。
Paper紙のような質感をアプリケーションの背景に表現します。リサイズしたり、シャッフルしたり、複数の紙を扱っているかのように表示することができます。

Feedback: フィードバックのためのコンポーネント

Alertアラートはユーザの作業を中断することなく、注意を引く方法で重要な短いメッセージを表示します。
Backdrop特定の要素もしくはその一部を強調するために使用されます。アプリケーションの状態が変化していることをユーザに示したり、ローダーやダイアログの作成にも使われています。
Dialogs作業に対しての重要な情報を含めて通知したり重要な決定を促したりします。ダイアログはモーダルウィンドウの形でアプリケーションの表面に表示されます。
Progressプログレスインジケーターは一般的に待機時間の特定できない場合は回転するオブジェクトを表示したり、プロセスの長さを表示したりします。
Skeletonデータが読み込まれる前に仮のコンテンツ領域を確保して表示し、見ているユーザが不満を持ってしまうのを軽減します。
Snackbar一時的に画面に簡単な通知を行います。このコンポーネントはトースト通知として知られています。

Data Display: データ表示のためのコンポーネント

Avatarテーブルやダイアログメニューまであらゆる用途に使用されます。顔写真や名前、アイコンなどが設定でき、主な用途としてはアプリケーションへのログイン状態を表示するのにつかわれます。
Badgeバッジは子要素の右上に小さな通知を表示します。例えばメールやメッセージが何通来ているかを表示できます。
ChipChipsは入力、属性または何らかの実行ができることを表すコンパクトな要素です。ブログ記事につけられたタグを表示したり、特定の要素を押してタグを絞り込んで記事を表示したりすることができます。
DividerDividerはリストとレイアウトをグループ化する細い線を表示します。
IconsMaterial-UIはアイコンについて、以下の3つの方法をサポートしています。1.標準の Material Design iconsを、Reactコンポーネント(SVGアイコン)として、エクスポートする方法2.ReactラッパーのカスタムSVGアイコンとして、SVGアイコン コンポーネントを利用する方法3.Reactラッパーのカスタムフォントアイコンとして、アイコン コンポーネントを利用する方法
Material Icons公式のWebサイトからすぐに使うことができる1700以上のReact Materialアイコンが提供されています。
Listリストはテキストや画像を一覧表示するもので、垂直方向に連続して表示されます。
Tableテーブルにはデータセットを表示させることができます。Cardなどの他のコンテンツを埋め込んでカスタマイズすることができます。
TooltipTooltipはユーザが要素にカーソルを合わせたり、フォーカスしたり、タップしたりすると、その要素をクリックしたときに実行される機能が分かりやすく記載されたテキストを表示します。
TypographyTypographyを使うことでデザインとコンテンツを明確かつ効果的に表すことができます。

Utils: 各種の便利なコンポーネント

Clik Awal Listener要素がクリックされたかどうかを検出するリスナーです。表示されているドキュメントの任意の個所で発生するクリックイベントを検出します。
CSS BaselineHTMLの要素と属性のスタイルをそろえるコレクションであるnormalize.cssのような役割を果たします。
Modalモーダルウィンドウを表示するコンポーネントです。ダイアログ、ポップオーバー、ライトボックスなどの作成するための基礎的な機能を提供します。
No SSRサーバサイドレンダリングの対象から意図的にコンポーネントを外すために使用されます。
PopoverPopoverを使うことで、一部のコンテンツを別のコンテンツ上に表示させることができます。
PopperPopperも、使用することで一部のコンテンツを別のコンテンツ上に表示することができます。react-popperの代替手段です。
Portalportalコンポーネントは子要素をDOMの階層の外側にある新しいサブツリーにレンダリングします。
Textarea Autosizeテキストエリアを表示するReactのコンポーネントです。デフォルトでは自由にサイズを変更することができますが、サイズや行数を固定することも可能となっています。
TransitionsTransitionはUIを簡単に表現する手助けをします。
useMediaQueryReactのCSSメディアクエリフックです。CSSのメディアクエリとクエリが一致するかどうかに基づいてコンポーネントをレンダリングします。

カラー調整の方法

ReactNative入門 基礎知識と始め方を徹底解説

Material-UIでは、テーマを使用することでスタイルを制御できます。

テーマを自作するときにはアプリケーションのイメージに合わせて、コンポーネントの色、表面の暗さ、影のレベル、透明度などを設定してください。

このようにしてテーマを作成することで、全体として統一感のあるデザインを表現できます。

それでは、実際にテーマを作成してみましょう。

ブランドカラーの調整

ブランドカラーを変更するにはテーマを構成するための変数のひとつであるpaletteオブジェクトを設定します。

paletteオブジェクトが持っているprimary、secondary、error、warning、info、sucessの値を独自の色にオーバーライドすると、アプリケーションのカラーを変更することができます。

カラーオブジェクトを使用

簡単にカラーをカスタマイズする方法としては、Material-UIから提供されているカラーをインポートする方法があります。

import { createTheme } from '@material-ui/core/styles';
import blue from '@material-ui/core/colors/blue';

const theme = createTheme({
  palette: {
    primary: blue,
  },
});

上のソースコードではprimaryの値にblueというカラーを割り当てています。

色を直接指定

カラーオブジェクトを使用するよりも、もっと細かく色を設定したい場合は色を直接設定することも可能です。

main、light、darkのキーに設定する方法と、contrastTextに設定する方法があります。

import { createTheme } from '@material-ui/core/styles';

const theme = createTheme({
  palette: {
    primary: {
      main: '#ff4400',
    },
    secondary: {
      light: '#0066ff',
      main: '#0044ff',
      contrastText: '#ffcc00',
    },
    contrastThreshold: 3,
    tonalOffset: 0.2,
  },
});

この例では、primaryにはmainのキーに#ff4400、secondaryにはlightに#0066ff、mainに#0044ffを設定しています。

darkやlightのキーの設定を省略した場合、それぞれの値はtonalOffsetとmainの値から計算されます。

contrastTextを省略した場合はcontrastThresholdとmainの値からcontrastTextの値が計算されます。

フォントの調整

フォントを調整したい場合はテーマを構成する要素のひとつであるtypographyというオブジェクトを使用します。

フォントファミリーの設定

フォントファミリーを設定するためには、fontFamilyキーに対してフォントを指定します。

const theme = createTheme({
  typography: {
    fontFamily: [
      '-apple-system',
      'BlinkMacSystemFont',
      '"Segoe UI"',
      'Roboto',
      '"Helvetica Neue"',
      'Arial',
      'sans-serif',
      '"Apple Color Emoji"',
      '"Segoe UI Emoji"',
      '"Segoe UI Symbol"',
    ].join(','),
  },
});

フォントサイズの設定

フォントのサイズを設定することもできます。

Material-UIではtypographyオブジェクトのfontSizeプロパティに値を設定します。デフォルト値は14pxとなります。

const theme = createTheme({
  typography: {
    fontSize: 12,
  },
});

レイアウト・コンポーネント間の調整

react-scripts

CssBaseline

Material-UIはCssBaselineコンポーネントを提供しています。

これを使うことで、上品で一貫性のあるシンプルなベースラインを構築することができます。

Container

「レイアウトのためのコンポーネント」の項目でも触れたContainerコンポーネントは、コンテンツを左右(水平方向)に中央揃えをすることができるコンポーネントです。

レイアウトをする上で最も基本的な要素となります。