Material UI v5 を使ってみる

2021-10-07

こぷらです。 普段から Web アプリを作成するときは、Material UI を使用してます。 このブログでも使おうと思いドキュメントを開いてみたら、先日の 9 月 16 日に version 5.0 への大規模なアップデートが行われたそうです。 早速使ってみようと思ったので、記事でまとめて紹介します。

また、既存プロジェクトでのアップデートも行ったので、その際に行ったことを備忘録代わりにまとめています。 もしこれからバージョンアップを行いたい方がいれば参考にしてみてください。

目次

Material UI とは

様々なところで紹介され尽くしていますが、かんたんに説明を。

Material UI は React ベースの UI ライブラリー。 UI ライブラリーを使用することで、細かいスタイルを定義せずに整った見た目の UI が作成できる。 UI ライブラリーは様々あるが、特に Material UI は Google が提案する Material Design に則ったシンプルで洗練されたデザインが特徴である。

インストールと使い方の基本

Node.js などのインストールはすでに完了しているものとします。 以下コマンドで関連ライブラリをインストール可能。

yarn add @mui/material @emotion/react @emotion/styled

Material UI をつかときは、ソースコード内でスタイリングされたコンポーネントを呼び出します。 例えばボタンを使いたい場合は、import Button from @mui/material/Button を呼び出します。

```shell export default function App() { return ; } ```

ボタン以外にも多数のコンポーネントがありますが、数が多すぎるので紹介はしません。 各種コンポーネントの使い方からサンプルプロジェクトの紹介まで幅広く網羅されているドキュメントがありますので、そちらを参照してください。

v4 からの移行

新規のプロジェクトであればインストールするだけで良いですが、既存のプロジェクトをアップデートする場合はそうは行きません。 特に今回のアップデートでは Style の適用方法が大きく変わっており、自分の場合は Material UI を使うすべてのファイルを修正しました。 個人的には以前よりもわかりやすい形になり満足しています。

以降では、アップデートに伴って行った修正をまとめます。

パッケージのインストール

v5 環境で v4 の要素を利用するためのパッケージがあるので、そちらをインストールします。

yarn add @mui/styles

その他アイコンや lab 機能を使っていた場合は以下もインストールします。

yarn add @mui/lab @mui/icons-material

移行スクリプトの実行

バージョンアップのためにファイルを一つ一つ確認し変更するのは非常に手間です。 そこで、公式から変換スクリプトが提供されているのでそれを活用しましょう。

ドキュメント では 3 つのスクリプトを実行するよう提案されてます。 一つづつ確認しましょう。

preset-safe

v4 から v5 へのマイグレーションには基本的にこれを使うことになります。 実行方法はこちらです、ドキュメントには各ファイルに対して 1 回だけ実行するように書かれているため、注意してください。

npx @mui/codemod v5.0.0/preset-safe <path|folder>

実行すると、既存の v4 用コードの大部分が v5 用に変更されます。 自分の環境では以下の変更が行われました。

  • @material-ui/core -> @mui/material
  • @material-ui/core/styles -> @mui/styles
  • adaptV4Theme モジュールでテーマ用オブジェクトをラップ
  • Light Mode / Dark Mode の切り替えを theme.palette.type から theme.palette.mode に変更
  • デフォルトサイズの IconButtonsize="large" に変更

かなり長いですが、こちらのページに変換の詳細が記載されています。 これを見ると、自分の環境はごく一部の変換だけですんでいるようでした。

variant-prop

<TextField/>, <FormControl/>, <Select/> 用のもので、variant props が定義されていない場合に variant="standard" を付与します。 ただし注意点として、テーマ上で TextField の variant のデフォルト値を outlined にしている場合に限り、スクリプトを実行してはいけません。

この変換が必要な理由は TextField の variant のデフォルト値が standard から outlined に変更されたためです。 そのため、Theme でデフォルト値を outlined に変えていた場合は、変化がないので実行する必要はなくなります。

npx @mui/codemod v5.0.0/variant-prop <path>

<Link/> コンポーネントの underline props が定義されていない場合に underline="hover" を付与します。 ただし注意点として、テーマ上で variant のデフォルト値を always にしている場合に限り、スクリプトを実行してはいけません。

variant-prop のときと同じで、underline のデフォルト値が hover から always に変わったために必要な変換です。 自身の環境で本当に必要なのかよく確認してから実行しましょう。

npx @mui/codemod v5.0.0/link-underline-hover <path>

ここまでで変換作業は一通り終わりです。 エラーなくできていれば、すぐにアプリケーションを起動することができるでしょう。

ただし、現状だと v4 のレガシーな作法が混ざってしまっているので、それらを解消します。

ThemeProvider のアップデート

スクリプト実行後のテーマは、以下のような形になっているはずです。

import { createTheme, adaptV4Theme } from '@mui/material/styles';
const theme = createTheme(adaptV4Theme({
    // v4 theme
}));

これは、v4 相当のテーマオブジェクトを v5 用に変換している形になっています。 そこで、adaptV4Theme を削除して v5 用のテーマを作成しましょう。

  • ダークモード使用のためのキーが theme.palette.type から theme.palette.mode に変更されたので、テーマ上も変更します。
 import { createTheme } from '@mui/material/styles';
-const theme = createTheme({palette: { type: 'dark' }}),
+const theme = createTheme({palette: { mode: 'dark' }}),
  • theme.props および theme.overrides を廃止し theme.components に統一
 import { createTheme } from '@mui/material/styles';
 const theme = createTheme({
-  props: {
-    MuiButton: {
-      disableRipple: true,
-    },
-  },
-  overrides: {
-    MuiButton: {
-      root: { padding: 0 },
-    },
-  },
+  components: {
+    MuiButton: {
+      defaultProps: {
+        disableRipple: true,
+      },
+      styleOverrides: {
+        root: { padding: 0 },
+      },
+    },
+  },
 });

テーマの変更は以上です。

makeStyles・withStyles

コンポーネントへのスタイルの適用方法も大きく変わっているため、修正が必要です。 スクリプト実行後は、makeStyles を使っていた箇所で以下のようになっているはずです。 (withStyles も同様)

-import { makeStyles } from '@material-ui/styles';
+import { makeStyles } from '@mui/styles';

これはコア機能から外されたレガシーな手法を流用するための応急措置です。 v5 の作法でスタイルを適用するには主に2つの方法があります。

sx property

1 つ目は各コンポーネントに追加された sx プロパティを使うものです。 sx プロパティに css を模したオブジェクトを渡すことで、そのコンポーネントのスタイルを上書きできます。 以下は使用例です。 ボタンの色を変更したコンポーネントを並べて表示しています。

<Button
  variant="contained"
  sx={{
    color: "white",
    backgroundColor: "red",
    "&:hover": {
      backgroundColor: "crimson"
    }
  }}
>
  Hello Styled Button
</Button>

Styled Component

2 つ目の方法は、あるコンポーネントをベースにして、独自のスタイルを適用した新しいコンポーネントを作る方法です。 ドキュメントでは Styled Component と呼ばれています。 使い方は Utility 関数の styled をインポートして、引数にベースのコンポーネントを指定します。 そして、初期化子として適用したいスタイルを与えることで、返り値に Styled Component を受け取れます。 使い心地は withStyles に似ています。 以下は使用例です。 sx プロパティと同じものを Styled Component で実装しました。

import { styled } from "@mui/material/styles";
const StyledButton = styled(Button)(({ theme }) => ({
  color: "white",
  backgroundColor: "red",
  "&:hover": {
    backgroundColor: "crimson"
  }
}));

sx プロパティを使えば、その場限りの変更を気軽に実装できます。 逆に同じ見た目を使いまわしたいときや、変更量が多いときなどは Styled Component を使うのが良いでしょう。 これらの方法に従って、makeStyles, withStyles の使用箇所を修正すればアップデート前の挙動を v5 環境で再現できるようになるはずです。 一通り修正が終わったら、不要なパッケージを削除しておきましょう。

yarn remove @mui/styles @material-ui/core

気になる追加機能

アップデートも完了したところで、v5 で追加された新機能の中から気になったものをいくつかピックアップしてみます。 コードの実装方法についてはドキュメントで詳しく紹介されているので、ここでは省略します。

Stack

<Stack>
  <Typography>item 1</Typography>
  <Typography>item 2</Typography>
  <Typography>item 3</Typography>
</Stack>

要素を縦 or 横に並べて表示する機能です。 シンプルな機能ですが、きれいに並べるのは地味に面倒な作業だったため、今後は頻繁に使うことになりそうです。

Pagination

<Pagination count={10} />

ページング機能をサポートするための機能です。 よくある次/前のページボタンと現在のページがわかるようになります。 表示範囲を自動で調整したり、見た目もいじりやすいので、自分で作るよりもはるかにいいものができそうです。

Masonry

<Masonry columns={4} spacing={1}>
  {heights.map((height, index) => (
    <MasonryItem key={index}>
      <Item sx={{ height }}>{index + 1}</Item>
    </MasonryItem>
  ))}
</Masonry>

高さの異なるアイテムを隙間なく並べるコンポーネントです。 これを使うだけでかなりおしゃれに見えそうですね。 こちらは Lab 機能のため、追加のパッケージインストールが必要です。

yarn add @mui/lab

まとめ

今回は Material UI を v4 から v5 へ更新する方法について紹介しました。 変更点が非常に多いのでそれなりに面倒な作業が必要ですが、その分使いやすく便利な機能が増えていました。 アップデートを検討している方がいれば参考にしてみてください。 それでは。


Profile picture

Written by Coppla

職業:ソフトウェアエンジニア - 会社では精密機械の制御系ソフトウェアの開発を、プライベートで Web アプリ制作の勉強をしています。趣味は旅行と美味しいものを食べること

Categories

© 2022 Coppla, Built with Gatsby