Material UIでFont Awesomeをラップする


はじめに

今回はMaterial UIを使ってFont Awesomeをラップすることがありましたのでその手順を残したいと思います。

検証環境

  • Material UI: 5.0.4
  • Font Awesome: 6.1.1

なぜMaterial UIを使ってFont Awesomeをラップするのか

Material UIは色やフォントサイズなどのテーマを定義したファイルを用意することで、個別に色やフォントサイズを指定しなくてもスタイルを適用することができます。

例えば、下記のように記述することで別ファイルに記載したprimary.mainの色を文字に指定することができます。

 <Typography  color={'primary.main'}>サンプル</Typography>

しかし、これができるのはMaterial UIが提供しているコンポーネントだけです。

Font Awesomeでアイコンに色を指定したい場合は下記のように書く必要があります。

const PrimaryMainColor = "#0C6993"
<FontAwesomeIcon icon={faHome} color={PrimaryMainColor} />

もちろんこのような手法でスタイルを指定することはできますが、Font Awesomeを含めた各パッケージごとにスタイルを指定すると管理がどんどん複雑になります。

そこでFontAwesomeもMaterial UIと同様の方法でスタイルを指定することができれば、スタイルの管理をシンプルにすることができると考えました。

コンポーネントの作成

下記の様に記述することでMaterial UIと同様の方法でスタイルを適用することができます。

下記では、Propsとしてmainlightdarkを指定できるようにしています。

また、それ以外のPropsはFontAwesomeIconを使うときと全く同じように指定することができます。

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { styled } from '@mui/system';
import * as React from 'react';
import type { FontAwesomeIconProps } from '@fortawesome/react-fontawesome';

type colorType = 'main' | 'light' | 'dark';

type Props = Omit<FontAwesomeIconProps, 'color'> & {
  color?: color;
};

const Icon = styled(FontAwesomeIcon, {
  shouldForwardProp: (prop) => prop !== 'color',
  name: 'Icon',
  overridesResolver: (
    props: { color: colorType },
    styles
  ) => [
    props.color === 'main' && styles.main,
    props.color === 'light' && styles.light,
    props.color === 'dark' && styles.dark,
  ],
})<Props>({});

export const StyledIcon: React.FC<Props> = ({
  color,
  icon,
  ...inputProps
}) => <Icon color={color} icon={icon} {...inputProps} />;

theme.tsの作成

続いて、theme.tsを編集していきます。

components配下に今回作成したSyledIconのスタイルを設定することによってMaterial UIのデザインシステムを使ってFont Awesomeのアイコンのスタイルを変更することができます。

ここではアイコンの色としてmainlightdarkに各色を指定しています。

import { createTheme } from '@mui/material';
import type { Theme, ThemeOptions } from '@mui/material';

export const theme: Theme = createTheme({
  components: {
    StyledIcon: {
      styleOverrides: {
        main: {
          color:  '#0C6993',
        },
        light: {
          color: '#5097C4',
        },
        dark: {
          color: '#01579B',
        },
      },
    },
  },
} as ThemeOptions);

アイコンを利用するコンポーネント

アイコンを利用するコンポーネントでは、下記のように記述することでFontAwesomeのアイコンをMaterialUIのコンポーネントのように利用することができます。

  <StyledIcon icon={icon} color={'main'} />

まとめ

今回は、Material UIのデザインシステムでFont Awesomeのスタイルを変更する手法をまとめてみました。

本手法を用いることでFontAwesomeのアイコンのスタイルをMaterial UIと同様に管理することができますので、ぜひ一度検討してみたはいかがでしょうか。