ReactでMaterial UI(MUI)を使ってみよう

Material UI(MUI)はフランスの会社でReactをはじめとしたUIデザインのライブラリを提供しています。日本だとユニクロがマテリアルUIを使っているようです。

このUIデザインではGoogleのマテリアルデザインというデザイン言語(テーマ)をもとに洗練されたUIを作ることができます。

今日はReactにMaterial UIをインストールして使う方法を紹介していきます。オープンソースでコードをGitHubで見ることもできます。

Reactのプロジェクトをスタート

今回はViteを使ってReactを始めます。詳しいViteの使い方はこちらの記事を参照してください。今日はReactのプロジェクトを始めるために必要なコマンドだけ紹介していきます。

react >= 17.0.0 でreact-dom >= 17.0.0 以降のバージョンを使用することが前提です。

npm create vite@latest

#結果
Need to install the following packages:
  create-vite@4.0.0
Ok to proceed? (y) y
✔ Project name: … mui-app
✔ Select a framework: › React
✔ Select a variant: › JavaScript

Scaffolding project in /home/dan/Documents/public/mui-app...

Done. Now run:

  cd mui-app
  npm install
  npm run dev

ではcdのコマンドでReactのプロジェクトフォルダに移動して、npmを使ってライブラリをインストールします。

Material UIをインストール

では下記のコマンドでMaterial UIをインストールしていきます。

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

#結果
added 54 packages, and audited 137 packages in 15s

19 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities



#yarnの場合
yarn add @mui/material @emotion/react @emotion/styled

Material UIはデフォルトでEmotionというスタイルエンジンを使っています。詳しい使い方は後から説明します。これでJavaScriptでCSSスタイルの記述ができるようになったとだけ理解しておきましょう。

似た方法で、styled-componentsのライブラリを使ってスタイリングを記述する方法もあります。今回は省きます。

Robotoフォントのインストール

Material UIはデフォルトでRobotoフォントを使用します。

こちらもインストールしておきましょう。もしインストールではなくCDNでフォントを使用したい場合は飛ばしてください。

npm install @fontsource/roboto

#Yarnの場合
yarn add @fontsource/roboto

フォントのCSSのインポートはこのように記述しましょう。

import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';

CDNでフォントを使用したい場合

GoogleのCDNで提供されているフォントを使用したい場合は<head>タグ内に下記を記述します。

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

アイコン

次にマテリアルUIで使用するアイコンをインストールします。

npm install @mui/icons-material

#Yarnの場合
yarn add @mui/icons-material

もし、インストールではなくCDNでアイコンを表示したい場合は下記の様に<head/>タグ内にリンクを記載しましょう。

<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/icon?family=Material+Icons"
/>

Material UIを使ってみよう

では、早速テキストエディタを開いてMaterialUIのボタンを使ってみましょう。

コンポーネントのインポートはimport Button from “@mui/material/Button”;を使用してください。これで、<Button/>コンポーネントが使用できるようになりました。

import { useState } from "react";
import "./App.css";
import Button from "@mui/material/Button";

function App() {
  const [count, setCount] = useState(0);

  return (
    <div className="App">
      <Button variant="contained">Hello World</Button>

    </div>
  );
}

export default App;

実際にnpm run devのコマンドで開発用のウェブサーバーを起動するとこのようにボタンができたことが確認できます。

レスポンシブmetaタグ

Material UIはモバイルファーストのコンポーネントになります。ですのでPCでスケールアップする際にCSSのMedia Queryを使ってデザインを変えるようにしていきます。

すべてのデバイスで正しくレンダリングされるように<head>タグ内に下記の行を追加しておきましょう。

<meta name="viewport" content="initial-scale=1, width=device-width" />

例としてスライダーもコピペで使えるようになりました。

import { useState } from "react";
import "./App.css";
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import Slider from '@mui/material/Slider';
import VolumeDown from '@mui/icons-material/VolumeDown';
import VolumeUp from '@mui/icons-material/VolumeUp';

function App() {
  const [value, setValue] = useState(30);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };

  return (
    <div className="App">
      <Button variant="contained">Hello World</Button>
      <Box sx={{ width: 200 }}>
      <Stack spacing={2} direction="row" sx={{ mb: 1 }} alignItems="center">
        <VolumeDown />
        <Slider aria-label="Volume" value={value} onChange={handleChange} />
        <VolumeUp />
      </Stack>
      <Slider disabled defaultValue={30} aria-label="Disabled slider" />
    </Box>
    </div>
  );
}

export default App;

テーマカラーとスタイリング

次にCSSのカスタムの仕方を見てみます。

各コンポーネントにsxというpropsを流すことができます。これでカスタムスタイリングを設定することができます。

下記の例を見てください。

import { Box, ThemeProvider, createTheme } from '@mui/system';

const theme = createTheme({
  palette: {
    background: {
      paper: '#fff',
    },
    text: {
      primary: '#173A5E',
      secondary: '#46505A',
    },
    action: {
      active: '#001E3C',
    },
    success: {
      dark: '#009688',
    },
  },
});

export default function Example() {
  return (
    <ThemeProvider theme={theme}>
      <Box
        sx={{
          bgcolor: 'background.paper',
          boxShadow: 1,
          borderRadius: 2,
          p: 2,
          minWidth: 300,
        }}
      >
        <Box sx={{ color: 'text.secondary' }}>Sessions</Box>
        <Box sx={{ color: 'text.primary', fontSize: 34, fontWeight: 'medium' }}>
          98.3 K
        </Box>
        <Box
          sx={{
            color: 'success.dark',
            display: 'inline',
            fontWeight: 'bold',
            mx: 0.5,
            fontSize: 14,
          }}
        >
          +18.77%
        </Box>
        <Box sx={{ color: 'text.secondary', display: 'inline', fontSize: 14 }}>
          vs. last week
        </Box>
      </Box>
    </ThemeProvider>
  );
}

このようにsxにカスタムしたいCSSを指示していることが分かります。

更に、ThemeProviderを使うことでテーマカラーを変更することができます。これはオプショナルなのでカスタマイズしたいときには使う事もできます。

基本はこれくらいです。

お疲れ様でした。