Material-UIの使い方(UIフレームワークで手軽に構築)

Material-UIは、React用のUIコンポーネントフレームワークです。マテリアルデザインの手法に基づいた豊富なコンポーネントを提供しています。ここでは、React & TypeScriptプロジェクトにMaterial-UIを導入して、基本的な利用方法を確認します。

前準備

インストール

create-react-app でReactプロジェクトを生成します。

npx create-react-app my-app --template typescript
cd my-app/

Material-UIのコンポーネントを利用できるようにパッケージをインストールします。

yarn add @material-ui/core @material-ui/icons

大部分のコンポーネントは、@material-ui/core をインストールすることで利用できます。
(破壊的変更が加えられる可能性があるコンポーネントは @material-ui/lab に格納されています。)

SVGアイコンを使うため、@material-ui/icons もインストールしています。

バージョン

今回インストールされたバージョンは以下の通りです。

$ yarn info react | grep version:
  version: '17.0.1',
$ 
$ 
$ yarn info @material-ui/core | grep version:
  version: '4.11.0',

補足ですが、2021年にv5のリリースを予定しているようです。
[RFC] Material-UI v5 🚀 · Issue #20012 · mui-org/material-ui

コンポーネントとSVGアイコンを利用

Material-UIで提供されている コンポーネントSVGアイコン を利用する方法を確認します。

index.tsx を以下のようにしてアプリを起動します。

import React from 'react';
import ReactDOM from 'react-dom';
import { Box, Button } from '@material-ui/core';
import FavoriteIcon from '@material-ui/icons/Favorite';

ReactDOM.render(
  <React.StrictMode>
    <Box component="span" m={1}>
      <Button variant="contained" startIcon={<FavoriteIcon />}>
        Default
      </Button>
    </Box>
    <Box component="span" m={1}>
      <Button variant="contained" color="primary" startIcon={<FavoriteIcon />}>
        Primary
      </Button>
    </Box>
    <Box component="span" m={1}>
      <Button variant="contained" color="secondary" startIcon={<FavoriteIcon />}>
        Secondary
      </Button>
    </Box>
  </React.StrictMode>,
  document.getElementById('root'),
);

import { Box, Button } from '@material-ui/core'; という形でMaterial-UIのコンポーネントを読み込んでいます。
import FavoriteIcon from '@material-ui/icons/Favorite'; という形でSVGアイコンを読み込んでいます。

763-react-material-ui_00_use_component.png

実行結果です。

利用したいSVGアイコンは下記ページから探すことができます。
https://material-ui.com/components/material-icons/

主なコンポーネント

よくあるWebページを構成するのに利用できるコンポーネントを紹介します。

763-react-material-ui_01_use_component.png

① Header部分はAppBarコンポーネントを活用できます。

② クリック時にメニューを開くUIはMenuコンポーネントを活用できます。

③ サイドバーのUIはDrawerコンポーネントを活用できます。

調整|テーマ
( ThemeProvider, createMuiTheme )

createMuiTheme でThemeを作成して、ThemeProviderコンポーネントを利用して、配下コンポーネントでもThemeを利用できるようにしておきます。

import React, { FC } from 'react';
import { ThemeProvider, createMuiTheme } from '@material-ui/core/styles';

const theme = createMuiTheme({
  (省略)
});

const App: FC = () => {
  return (
    <ThemeProvider theme={theme}>
      (省略)
    </ThemeProvider>
  );
};

export default App;

ブランドカラー調整
( palette )

paletteプロパティでWebサイトのブランドカラーを調整できます。

import { createMuiTheme } from '@material-ui/core/styles';
import red from '@material-ui/core/colors/red';
import grey from '@material-ui/core/colors/grey';

const theme = createMuiTheme({
  palette: {
    primary: red,
    secondary: grey,
  },
});

export default theme;

下記ページでどのように変化するか確認できます。
https://material-ui.com/customization/color/#playground

フォント調整
( typography )

typographyプロパティで利用フォントを指定できます。

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

const theme = createMuiTheme({
  typography: {
    fontFamily: [
      'Helvetica Neue',
      'Arial',
      'Hiragino Kaku Gothic ProN',
      'Hiragino Sans',
      'sans-serif',
    ].join(),
  },
});

export default theme;

Roboto などWebフォントを利用したい場合は、以下のように取り込む指定を入れておく必要があります。

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />

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

大枠のレイアウト調整、コンポーネントとコンポーネント間のレイアウト調整方法などを確認します。

各コンポーネントの利用方法は必要になったタイミングで確認すればいいと思いますが、レイアウト調整部分は一通り確認しておくと良いと思います。

CssBaseline

CssBaselineは各ブラウザーの差異を平均化させる normalize.css のような役割を果たしてくれるようです。

import React, { FC } from 'react';
import { ThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import theme from 'theme';

import MyApp from 'components/MyApp';

const App: FC = () => {
  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <MyApp />
    </ThemeProvider>
  );
};

export default App;

Container
( 中央寄せ )

Containerはコンテンツを中央寄せしたいときに活用できます。

import React, { FC } from 'react';
import { ThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';
import Container from '@material-ui/core/Container';
import theme from 'theme';

import MediaCard from 'components/MediaCard';

const App: FC = () => {
  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <Container maxWidth="sm">
        <MediaCard />
      </Container>
    </ThemeProvider>
  );
};

export default App;

上記のようなコードを記述した場合、以下のように Containerコンポーネント で囲んだ要素が中央寄せされていました。

763-react-material-ui_10_container.png

Grid

GridはGridレイアウトを実装したいときに活用できます。

調整|スタイル

Box
( コンポーネントをラップして調整 )

Boxは他のコンポーネントをラップしてスタイル調整するのに活用できます。

利用するときは、下記ページを参考にすると良さそうです。

makeStylesを利用

makeStyles を利用してスタイルを割り当てることができます。

下記のようなスタイル指定も可能です。

  • ネストによるスタイル指定
  • props経由で動的にスタイル指定
  • 画面幅に応じたスタイル変更
import React, { FC } from 'react';
import { makeStyles, Theme } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';

type Props = {
  color: string;
};

const useStyles = makeStyles<Theme, Props>((theme) => ({
  root: {
    // ネスト(入れ子)によるスタイル指定
    '& p': {
      // props経由で動的にスタイル指定
      color: (props) => props.color,
    },
  },
  button: {
    margin: '10px 30px',
    padding: theme.spacing(2),
    background: 'linear-gradient(rgba(0,0,0,0),rgba(0,0,0,0.1))',

    // mediumサイズ以上の画面幅のときのスタイル指定
    [theme.breakpoints.up('md')]: {
      background: 'linear-gradient(#e66465, #9198e5)',
    },
  },
}));

const Child: FC<Props> = (props) => {
  const classes = useStyles(props);

  return (
    <div className={classes.root}>
      <Button className={classes.button}>Click</Button>
      <p>Hello World.</p>
    </div>
  );
};

const Parent: FC = () => {
  return <Child color="#d32f2f" />;
};

export default Parent;
763-react-material-ui_20_style.gif

実行結果です。

styled componentsを利用

makeStyles を利用する場合、cssのプロパティをJavascriptのObject形式で指定する必要があります。

cssのまま記述したい場合 styled components を活用するという方法もあります。styled components の利用方法は、下記ページで取り上げられていました。

Style Library Interoperability - Material-UI|Styled Components

参考・関連