React+TypeScript で作る SVG のためのシンプルな Icon コンポーネント


はじめに

こんにちは kimizuy です。

今回は React と TypeScript で複数の SVG を一括で管理するためのシンプルな Icon コンポーネントをご紹介します。

アイコンを専用のコンポーネントで管理することで、サイズやスタイルのインターフェイスも統一できアイコンの新規追加も簡単になります。

tldr

コード例を以下に示します(リポジトリ)。

// src/icon.tsx
import { ReactComponent as Empty } from './icon/mood-empty.svg'
import { ReactComponent as Happy } from './icon/mood-happy.svg'
import { ReactComponent as Sad } from './icon/mood-sad.svg'

const icons = { Empty, Happy, Sad }

type Name = keyof typeof icons

type Props = {
  name: Name
  size?: number
  className?: string
}

const DEFAULT_SIZE = 24

export function Icon({ name, size = DEFAULT_SIZE, className }: Props) {
  const SvgComponent = icons[name]

  return (
    <SvgComponent
      style={{ height: `${size}px`, width: `${size}px` }}
      className={className}
    />
  )
}

簡単にまとめると icons に SVG コンポーネントを列挙し、Icon コンポーネントの中でブラケット記法を利用して呼び出します。新規のアイコンは icons に追加していくだけです。

const icons = { Empty, Happy, Sad }

Name 型はオブジェクトのキーを取得して、ユニオン型を作成しています。これで型の恩恵を受けることができ、アイコンの名前を間違える心配もありません。

type Name = keyof typeof icons

style props でアイコンのサイズを指定することで .svg ファイル側にある width height 属性を上書きすることができます。

    <SvgComponent
      style={{ width: `${size}px`, height: `${size}px` }}
      className={className}
    />

使い方

Icon コンポーネントは以下のように利用します。

// src/App.tsx
import './App.css'
import { Icon } from './icon'

function App() {
  return (
    <div className="App">
      <div className="Icons-wrapper">
        <div>
          <Icon name="Empty" />
        </div>
        <div>
          <Icon name="Happy" className="Icon-orange" />
        </div>
        <div>
          <Icon name="Sad" size={100} />
        </div>
      </div>
    </div>
  )
}

export default App

補足

今回の記事は create-react-app を使ってデモを作成しました。create-react-app プロジェクトはビルトインで SVG が使えます。環境によって SVG コンポーネントのインポート方法が異なる場合は適宜読み替えてください。

Adding SVGs

import { ReactComponent as Empty } from './icon/mood-empty.svg'

おわりに

今回はシンプルな Icon コンポーネントについてご紹介しました。個人的にミニマルな感じで書くことができて気に入っています。

以上、お読みいただきありがとうございました。

今すぐの転職でなくてもOKです!まずはお話しませんか?

現在弊社では一緒にお仕事をしてくださるエンジニアさんやデザイナーさんを積極募集しています。まずはカジュアルな面談で、お互いに大事にしていることをお話できたらうれしいです。詳しい応募要項は以下からチェックしてください。

パートナー契約へのお問い合わせもお仕事へのお問い合わせも、どちらもいつでも大歓迎です。まずはオンラインでの面談でお話しましょう。ぜひお気軽にお問い合わせください!

話をしてみたい!

投稿者 Gaji-Labo Staff

Gaji-Laboの社内デジタル環境でいろいろなお手伝いをしているがじ専務&じら常務。みんなのシリーズ記事をまとめたり、卒業したスタッフの過去記事を記録したり、Twitterをやったりしています。