📷

ZennのメディアキットにロゴだけのSVGが追加されたので Material UI で IconButton にする

4 min read 2

Zenn のメディアキットに ロゴのアイコン部分SVGが追加されましたね。

この部分です👇

何が嬉しいかという話なのですが、たとえば自分のブログでZennへのリンクを貼るとき、Twitter や GitHub のアイコンと並べて表示したいときがあります。こういうやつです。

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
 
+      <Grid container justify="center" alignItems="center">
+        <Grid item xs={1}>
+          <IconButton target="_blank" href="https://twitter.com/">
+            <Twitter />
+          </IconButton>
+        </Grid>
+        <Grid item xs={1}>
+          <IconButton target="_blank" href="https://github.com/">
+            <GitHub />
+          </IconButton>
+        </Grid>
+      </Grid>
+    </div>
  );
}

結果👇

ここに Zenn のアイコンも追加したいときは、以下のような手順を踏みます。

  1. Zenn の SVGファイル を import できるようにする
    • React の場合: import { ReactComponent as Logo } from './logo-only.svg';
    • Next.js の場合: next.config.jsreact-svg-loader の設定を追加して import できるようにします
  2. import した SVG を、Material-UI の <SvgIcon></SvgIcon> で囲む
  3. それっぽい表示になる

Zenn の SVGファイル を import できるようにする

React と Next.js でやりかたがすこし違いますが、共通しているのは public ではなく src ファイルとして扱いますので、以下のように配置します。

React の場合

+import { ReactComponent as Zenn } from "./logo-only.svg";

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Container maxWidth="sm">
        <Grid container justify="center" alignItems="center">
          <Grid item xs={1}>
            <IconButton target="_blank" href="https://twitter.com/">
              <Twitter />
            </IconButton>
          </Grid>
          <Grid item xs={1}>
            <IconButton target="_blank" href="https://github.com/">
              <GitHub />
            </IconButton>
          </Grid>
        </Grid>
      </Container>
    </div>
  );
}

React の場合はシンプルで、上記のような import 文を書けばSVGコンポーネントとして扱えます。

Next.js の場合

next.config.js に設定を追加することで、React と同じように import できるようになります。

https://blog.kimizuka.org/entry/2021/06/05/224908?utm_source=feed

こちらが参考になると思います。importできるようになったら、あとは先述した方法と同じです。

import した SVG を、Material-UI の <SvgIcon></SvgIcon> で囲む

ではZennアイコンを表示していきましょう。Reactのケースで書いています。

+import { ReactComponent as Zenn } from "./logo-only.svg"; // React 

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <Container maxWidth="sm">
        <Grid container justify="center" alignItems="center">
          <Grid item xs={1}>
            <IconButton target="_blank" href="https://twitter.com/">
              <Twitter />
            </IconButton>
          </Grid>
          <Grid item xs={1}>
            <IconButton target="_blank" href="https://github.com/">
              <GitHub />
            </IconButton>
          </Grid>
 +          <Grid item xs={1}>
+            <IconButton target="_blank" href="https://zenn.dev/waddy">
+              <SvgIcon>
+                <Zenn />
+              </SvgIcon>
+            </IconButton>
+          </Grid>
+        </Grid>
      </Container>
    </div>
  );
}

Material-UI の <SvgIcon> で囲っているのがポイントです。結果は以下のようになります。

色なのですが、このあたりを見ていろいろ試したものの、うまく反映されませんでした。gタグにfillがあるとCSSでは変更できないみたいですね。
後述していますが、 gタグのfillをcurrentColorにするとうまくいきました、catnoseさんありがとうございました。

https://dev.to/abachi/how-to-change-svg-s-color-in-react-42g2

今回は、SVG自体の色を変更しました。他になにかいい方法があったら教えて下さい🙇‍♂️

コメントで教えてもらいました。

  • <g> タグの fill を色ではなく currentColor にする。そうすると外側からCSSで色が制御できるようになる
  • 今回はMaterial-UIが色の調整をやってくれているので、currentColorにするだけでOKです

https://zenn.dev/link/comments/ff6121baaeda53

./logo-only.svg
  <svg>
-    <g fill="#3EA8FF">
+    <g fill="currentColor">
        <path .../>
        <path .../>
    </g>
  </svg>

これでいい感じに並べることができました。

おわりに

試したコードは codesandbox に置いています。

Discussion

svgをimgタグではなくインラインで埋め込む場合、fill="currentColor"とすることで外側からCSSで色を指定できるようになります。
具体的には

<svg>
    <g fill="currentColor">
       <path .../>
       <path .../>
   </g>
 </svg>

というsvgをReactで以下のように読み込む場合、

import { ReactComponent as Logo } from "./logo.svg"

<Logo className="foo"/> 

CSSで

.foo { color: red }

とすれば、SVGのfill="currentColor"に該当する部分が赤になります。

svgをimgタグではなくインラインで埋め込む場合、fill="currentColor"とすることで外側からCSSで色を指定できるようになります

おお、知りませんでした!たしかに、fill="currentColor" とすることで Material-UI 側のカラーが反映されるようになりました。この修正を入れるよう記事も直しておきます、ありがとうございます!

ログインするとコメントできます