Astroで色々なアイコンをサクッと使う

Astro Iconを使うと便利で簡単。

SVGでアイコンを書いてくれる。

インストール

npm i astro-icon

Iconのサンプル

アイコンを使って以下のような表示のメニューを作ってみる。

シンプルにアイコンを描画したい場合はIconコンポーネントを使う。

Menu.astro

---
import MenuItem from './MenuItem.astro'

const items = [
  { name: 'HOME', path: '/' },
  { name: 'Profile', path: '/profile' },
  { name: 'About', path: '/about' },
]
---
<div>
  <ul>
    {items.map((item) => (
      <MenuItem label={item.name} link={item.path} />
    ))}
  </ul>
</div>

MenuItem.astro

---
import { Icon } from 'astro-icon'

export interface Props {
  label: string
  link: string
}

const { label, link } = Astro.props
---
<li class="flex">
  <Icon name="teenyicons:right-small-solid" class="w-6 h-6 text-blue-800 opacity-50" />
  <a class="text-blue-500" href={link}>{label}</a>
</li>

テキスト色の指定でアイコンの色を変えることもできる。
ここではスタイリングにTailwindCSSを使っているが、もちろん素のCSSでもスタイリングできる。

描画されるSVGタグ

このとき生成されるMenuItemのHTMLは以下のようになる。

<li class="flex">
  <svg viewBox="0 0 15 15" class="w-6 text-blue-800 opacity-50" astro-icon="teenyicons:right-small-solid"><path fill="currentColor" d="M10.207 7.5 6 3.293v8.414L10.207 7.5z"/></svg>
  <a class="text-blue-500" href="/about">About</a>
</li>

Spriteのサンプル

同じアイコンを何回も使うときはIconではなくSpriteを使うとリソースに少しやさしい。

Iconは都度SVGを描画するが、Spriteは一度描画したSVGを使いまわす。

Menu.astro

---
import MenuItem from './MenuItem.astro'
import { Sprite } from 'astro-icon'

const items = [
  { name: 'HOME', path: '/' },
  { name: 'Profile', path: '/profile' },
  { name: 'About', path: '/about' },
]
---
<div>
  <Sprite.Provider>
    <ul>
      {items.map((item) => (
        <MenuItem label={item.name} link={item.path} />
      ))}
    </ul>
  </Sprite.Provider>  
</div>

Spriteを使うところをSprite.Providerで囲む。
コンポーネントがまたがっていても大丈夫。

MenuItem.astro

---
import { Sprite } from 'astro-icon'

export interface Props {
  label: string
  link: string
}

const { label, link } = Astro.props
---
<li class="flex">
  <Sprite name="teenyicons:right-small-solid" class="w-6 h-6 text-blue-800 opacity-50" />
  <a class="text-blue-500" href={link}>{label}</a>
</li>

描画されるSVGタグ

MenuItemではSVGのuseタグが使われる。

<li class="flex">
  <svg class="w-6 h-6 text-blue-800 opacity-50" astro-icon="teenyicons:right-small-solid">
    <use xlink:href="#astroicon:teenyicons:right-small-solid"></use>
  </svg>
  <a class="text-blue-500" href="/about">About</a>
</li>

Menuの末尾(Sprite.Providerの閉じタグを置いた場所)にSVGのsymbolタグが入る。

<ul>...</ul>
<svg style="position: absolute; width: 0; height: 0; overflow: hidden;" aria-hidden="true" astro-icon-spritesheet>
    <symbol viewBox="0 0 15 15" id="astroicon:teenyicons:right-small-solid"><path fill="currentColor" d="M10.207 7.5 6 3.293v8.414L10.207 7.5z"/></symbol>
</svg>  

Astro Iconで利用できるアイコン

Iconify

Iconifyで探せるすべてのアイコンをIconコンポーネントのnameで指定するだけで使うことができる。

登録されているすべてのアイコンセットの中から横断的に探すことが可能。

特定のアイコンセットの中から探すなら、アイコンセットをクリックしたあと、その中のフォームでインクリメンタルに探せる。

てかIconifyがめっちゃ便利だな。

ローカルのアイコン

READMEにある通り、ローカルのアイコンを使うこともできる。

README読めばいいのでここでは割愛。