Material-UIでコンポーネントの色を変更する方法まとめ[React+Typescript]

# はじめに
フロントまだまだよくわからないけれど、React+Typescript+Material-uiを使って、かっこいいWebアプリを作ろうとしてつまずいている初心者がMaterial-UIでコンポーネントの色を変えようとして四苦八苦したので、そのまとめです。
公式のドキュメントやサンプルコードを参考に色を変える方法として以下の３つでまとめました。

- Material-uiのPaletteを使う方法
    - Paletteの色を変えたい
- style属性を使う方法
- className属性を使う方法

今回は以下のSimple App Barの色を変更していきます。
公式のサンプルコードは[こちら](https://material-ui.com/components/app-bar/)です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/5373c5de-9f62-bf1d-9d04-36452ecb8c5b.png)

# 変更していくコードの概要
今回は説明の都合上、以下のコマンドを実行して、そのままApp.tsxを変更していきます。

```
npx create-react-app learn-material-ui --typescript
// material-uiのパッケージのインストール
yarn add @material-ui/core
yarn add @material-ui/icons
```

バージョンなどは以下です。

```
node.js:v10.16.0
"@material-ui/core": "^4.9.5",
"@material-ui/icons": "^4.9.1"
```

App.tsxを[公式のサンプルコード](https://material-ui.com/components/app-bar/)を参考に以下のように書き換えます。
これで実行すると上で紹介したスクリーンショットのようになります。

``` react
import React from "react";
import "./App.css";
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
import IconButton from "@material-ui/core/IconButton";
import MenuIcon from "@material-ui/icons/Menu";

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      flexGrow: 1,
      color: "#388e3c",
      backgroundColor: "#81c784"
    },
    menuButton: {
      marginRight: theme.spacing(2)
    },
    title: {
      flexGrow: 1,
      textAlign: "center"
    }
  })
);

function App() {
  const classes = useStyles();
  return (
    <div className={classes.root}>
      <AppBar position="static">
        <Toolbar>
          <IconButton
            edge="start"
            className={classes.menuButton}
            color="inherit"
            aria-label="menu"
          >
            <MenuIcon />
          </IconButton>
          <Typography variant="h6" className={classes.title}>
            News
          </Typography>
          <Button color="inherit">Login</Button>
        </Toolbar>
      </AppBar>
    </div>
  );
}

export default App;

```

# Material-uiのPaletteを使う方法
一番単純な`AppBar`の`color`を利用する方法を紹介します。
コードの変更箇所は単純で以下のように`AppBar`タグに`color`を追加するだけです。

```react
<AppBar position="static" color="secondary">
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/5cc6ad4d-4d72-599f-ec2d-27442b734f26.png)


[公式のドキュメント](https://material-ui.com/api/app-bar/)によると、`AppBar`の`color`は以下の要素に対応しているそうです。

- `default`
- `inherit`
- `primary`
- `secondary`
- `transparent`

「いやいや、この要素どれがなんなのかさっぱりわからないよ……」となったので、自分なりに調べてみたり実行したりした結果が以下です。
ちなみにブラウザの検証の`Elements`で`AppBar`の中を見ると、cssの中身が分かります。

- `default`:モノクロ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/96cf88b7-23fa-d5b0-76eb-08b4e61bd954.png)

- `inherit`:親要素の`color`を`inherit`（サンプルコードでは親要素の`div`に設定していた`color: "#388e3c"`が継承されました）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/369a1b45-d350-963b-de68-876b373abb8a.png)


- `primary`:デフォルトで設定されている。material-uiが用意している[Default Theme](https://material-ui.com/customization/default-theme/?expand-path=$.palette)の`palette`の`primary`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/36917e5c-9b65-9952-5837-29c7c9a18985.png)


- `secondary`:material-uiが用意している[Default Theme](https://material-ui.com/customization/default-theme/?expand-path=$.palette)の`palette`の`secondary`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/4c320ce5-fada-e830-4fa8-487b3097ebfc.png)

- `transparent`:`color`は`inherit`で、`background-color`は`transparent`（透過）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/a137ea2e-b040-dd60-b9a8-9bba17d30d0d.png)


このなかの`primary`と`secondary`はmaterial-uiで色に統一感を持たせるための[Palette](https://material-ui.com/customization/palette/#palette)というものの１つです。
様々なコンポーネントで利用されていて、コンポーネントごとに利用できるものが異なります。
デフォルトでは以下のような色が設定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/cab783d8-7316-4ed3-3eb6-6eb466d7d0ed.png)

この色を変更する方法を次に紹介します。

## Paletteの色を変えたい
アプリのイメージカラーで統一したいといったときに`createMuiTheme`と`ThemeProvider`を利用します。
[公式ページ](https://material-ui.com/customization/palette/#customization)を参考にしつつ、コードを以下のように変更してみました。

```react
import React from "react";
import "./App.css";
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
import IconButton from "@material-ui/core/IconButton";
import MenuIcon from "@material-ui/icons/Menu";
import { createMuiTheme } from "@material-ui/core/styles";
import { teal } from "@material-ui/core/colors";
import { ThemeProvider } from "@material-ui/styles";

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      flexGrow: 1,
      color: "#388e3c",
      backgroundColor: "#81c784"
    },
    menuButton: {
      marginRight: theme.spacing(2)
    },
    title: {
      flexGrow: 1,
      textAlign: "center"
    }
  })
);

// 追記
const theme = createMuiTheme({
  palette: {
    primary: {
      main: teal[500]
    },
    secondary: {
      main: "#00bcd4"
    }
  }
});

function App() {
  const classes = useStyles();
  return (
    <ThemeProvider theme={theme}> // 追記
      <div className={classes.root}>
        <AppBar position="static" color="primary">
          <Toolbar>
            <IconButton
              edge="start"
              className={classes.menuButton}
              color="inherit"
              aria-label="menu"
            >
              <MenuIcon />
            </IconButton>
            <Typography variant="h6" className={classes.title}>
              News
            </Typography>
            <Button color="inherit">Login</Button>
          </Toolbar>
        </AppBar>
      </div>
      <div className={classes.root}>
        <AppBar position="static" color="secondary">
          <Toolbar>
            <IconButton
              edge="start"
              className={classes.menuButton}
              color="inherit"
              aria-label="menu"
            >
              <MenuIcon />
            </IconButton>
            <Typography variant="h6" className={classes.title}>
              News
            </Typography>
            <Button color="inherit">Login</Button>
          </Toolbar>
        </AppBar>
      </div>
    </ThemeProvider> // 追記
  );
}

export default App;
```
すると以下のように色を変更したAppBarを２つ表示することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/e8c0cd57-61e2-2ae2-f539-fd7b702eecae.png)

ちなみに`@material-ui/core/colors`で、Materialデザインの色を利用することができます。
色の一覧は[このページ](https://material-ui.com/customization/color/)を参照してみてください。


# style属性を使う方法
以下のように`AppBar`タグを変更します。

```
<AppBar position="static" style={{ color: "#e0f2f1", backgroundColor: "#004d40" }}>
```

すると、以下のように色を変更することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/17d8871c-dfdf-284b-1e23-c59ee3ca9e87.png)

# className属性を使う方法
まず、以下のように`useStyles`を書き換えます。

```react
const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      flexGrow: 1,
      color: "#388e3c",
      backgroundColor: "#81c784"
    },
    bar: {
      color: "#e0f2f1",
      backgroundColor: "#004d40"
    },
    menuButton: {
      marginRight: theme.spacing(2)
    },
    title: {
      flexGrow: 1,
      textAlign: "center"
    }
  })
);
```

次に`AppBar`タグを以下のように変更します。

```react
<AppBar position="static" className={classes.bar}>
```

すると、以下のようにstyle属性を使う方法と同じく書き換えることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174954/b0ae3cae-449f-128f-49a2-bf1f1f4c2ee6.png)


# おわりに
Material-UIでコンポーネントの色を変える方法をまとめました。
Material-UI、とても便利なので使いこなしていきたいですね…！
また、わかったことなどありましたら、まとめていきたいと思います。