React + Material-UIを使用してMaterial Designのコンポーネントを作成する

ishigaki

こんにちは、Gaji-Labo アシスタントエンジニアの石垣です。

最近案件などで Material-UI という React 用UIコンポーネントライブラリを触る機会が多くなり、知見が溜まってきたので今回は Material-UI の基本的な使い方についてまとめたいと思います。

Material-UI とは?

Material UI公式ドキュメントのキャプチャ画像

Material-UI は、 Google の Material Design をベースに作られた React 用UIコンポーネントライブラリです。

Material-UI を使うことで手軽に Material Design を取り入れたコンポーネントを作成することができるようになります。

また、それぞれのコンポーネントが Material Design に基づいてデザインされているのみでなく、色定義や間隔、タイポグラフィなど細かい面に至るまで Material Design をベースに変数によって定義されており、またそれを拡張することもできるため、サイト全体の幅広い領域で統一性を図ることが出来るのも大きな特徴です。

詳しくはこちらの公式ドキュメントをご覧ください。使用できるコンポーネントの詳細なドキュメントが用意されています。

Material-UI を使用してコンポーネントを作成する方法

まずは Material-UI を導入します。

$ yarn add @material-ui/core

@material-ui/core を導入することで、Material-UI のほとんどの機能を使用することが出来ます。

他には、 core には用意されていない特殊なコンポーネント群を追加導入する @material-ui/lab や、 Material Design にあるアイコン群を導入できる @material-ui/icons 等があります。

今回は Button コンポーネントを拡張したコンポーネントを TypeScript で作成するのを例にご紹介します。

コンポーネントを使用するには、使用したいコンポーネントを import してJSX内に置きます。

import * as React from "react";
import { Button, ButtonProps } from "@material-ui/core/";

type Props = React.ButtonHTMLAttributes<ButtonProps>;

export const ExampleButton: React.FC<Props> = () => {
  return (
    <Button variant="contained" color="primary">
      LABEL
    </Button>
  );
};

コンポーネントにはそれぞれスタイルの設定に必要な Props があらかじめ用意されており (Button の場合 variant, color など) 、それを変更することである程度の設定を行うことができます。

コンポーネントごとの Props の一覧も公式ドキュメントに記載されています。

作成した ExampleButton コンポーネント

スタイルや機能を Props を超えた範囲で拡張しない場合、そのまま置くだけで使用することができます。

TypeScript で記述する場合、コンポーネントごとに FooProps のような名称で型定義が用意されているため、それを同時に import して参照できます。

スタイルの拡張

Props で設定できる範囲を超えてスタイルを変更したい場合は、大きく分けて 2つの方法があります。

createMuiTheme を使用する方法

Material-UI には theme として各コンポーネントの規定のスタイルや、色変数 primary の定義などがあらかじめ定められています。

createMuiTheme 関数を使用することで、テーマの変数定義やコンポーネントのスタイルを変更することができます。

関数を任意の変数 (theme) に代入し、 ThemeProvider コンポーネントの theme props で呼ぶことで ThemeProvider で囲われた範囲のコンポーネントにテーマが適用されます。

import * as React from "react";
import { createMuiTheme, ThemeProvider } from "@material-ui/core/styles";
import { Button, ButtonProps } from "@material-ui/core/";

type Props = React.ButtonHTMLAttributes<ButtonProps>;

export const ExampleButton: React.FC<Props> = () => {
  const theme = createMuiTheme({
    overrides: {
      MuiButton: {
        root: {
          fontSize: "20px",
          lineHeight: 1.5,
          padding: "20px",
        },
        containedPrimary: {
          backgroundColor: "#ff9999",
        },
      },
    },
  });
  return (
    <ThemeProvider theme={theme}>
      <Button variant="contained" color="primary">
        label
      </Button>
    </ThemeProvider>
  );
};

コンポーネントの上書きは override プロパティ内で行います。override プロパティ内では scss のように入れ子でセレクタが書くことができ、 Material-UI コンポーネントの持つ Class 名をセレクタに指定することでそのスタイルを変更します。

名称の通りこの関数は全体のテーマを設定するものなのですが、こちらのやり方は以降で紹介する makeStyles と異なり、コンポーネントのスタイルを直接変更します。

デフォルトで Button コンポーネント (.MuiButton-containedPrimary) が持っているスタイル
createMuiTheme で上書きした Button コンポーネント (.MuiButton-containedPrimary) のスタイル

そのため CSSセレクタの詳細度を上げないので、現状はこのやり方を使ってコンポーネントのスタイルを変更するようにしています。

makeStyles を使用する方法

こちらのやり方では makeStyles 関数を使い、コンポーネントにスタイルを追加して上書きします。

使用する時はスタイルを上書きしたいコンポーネントに {classes.foo} の形で className を渡します。

import * as React from "react";
import { makeStyles } from "@material-ui/core/styles";
import { Button, ButtonProps } from "@material-ui/core/";

type Props = React.ButtonHTMLAttributes<ButtonProps>;

const useStyles = makeStyles({
  button: {
    padding: "20px",
    fontSize: "20px",
    lineHeight: 1.5,
    backgroundColor: "#ff9999",
  },
});

export const ExampleButton: React.FC = () => {
  const classes = useStyles();
  return (
    <Button variant="contained" color="primary" className={classes.button}>
      label
    </Button>
  );
};

こちらのやり方では styled-component に近い記法で記述することもできます。

makeStyles で上書きした Button コンポーネントのスタイル

makeStyles を使用すると makeStyles-button-6(数字はレンダリング毎に変わる) のような class が生成され、上書きされるので詳細度が createMuiTheme より深くなります。

スコープが生まれるので、特定のページでコンポーネントを上書きしたい時や、より堅牢なスタイルにしたい時にこれを使うと良さそうと感じました。

以上の2つのやり方を使い分けることによって、コンポーネントのスタイルを変更することができます。

まとめ

今回の記事では Material-UI を使用してコンポーネントを作成し、スタイルを変更する方法をまとめました。

今回はコンポーネントを作成するまでにとどまりましたが、今後より知見を溜めてもっと詳細な使い方やカスタマイズについても書いていきたいと思っています。

Material-UI に興味を持っている方の参考にしていただけると幸いです。

Gaji-Laboでは、JavaScriptフレームワーク経験が豊富なパートナーさんを募集しています

Gaji-Laboでは、開発チームの一員としてプロジェクトに一緒に取り組んでくれる業務委託のパートナーさんを募集しています。

現在は特にJavaScriptフレームワーク実践と業務経験が豊富なWebフロントエンドエンジニアを必要としています。React + TypeScript、Vue.js、Next.js、Nuxt.js など、あなたの得意なフレームワークを教えて下さい!

パートナー契約へのお問い合わせもお仕事へのお問い合わせも、どちらもいつでも大歓迎です。まずはオンラインでのリモート面談からはじめましょう。ぜひお気軽にお問い合わせください!

お問い合わせしてみる!


ishigaki

投稿者 石垣 祥太郎

アシスタントエンジニアとしてHTML/CSS/JavaScriptの実装やRailsの組み込み、スタイルガイドの構築などを担当しています。 業務の中でさまざまな学びを吸収しながら、文書構造やアクセシビリティに目を向けたマークアップの学習やJavaScriptの学習などを行っています。チームに貢献できるエンジニアとなるために日々奮闘中です。