Components Heroicons

Heroicons

The makers of Tailwind CSS have created a library of 316 beautiful hand-crafted SVG icons and we have made it incredibly simple for you to use them. Search the full list of these icons here.

heex
          <.icon name="hero-home-micro" class="text-gray-700 dark:text-gray-300" />
<.icon name="hero-home-mini" class="text-gray-700 dark:text-gray-300" />
<.icon name="hero-home-solid" class="text-gray-700 dark:text-gray-300" />
<.icon name="hero-home" class="text-gray-700 dark:text-gray-300" />

<.icon name="hero-academic-cap" class="text-pink-700 dark:text-pink-300" />
<.icon name="hero-adjustments-horizontal" class="text-green-700 dark:text-green-300" />

        

Heroicons are generated as a set of CSS classes. Class names start with "hero" and end with "solid", "mini", "micro" or nothing (for "outline").

Properties
elixir
            # <.icon>
  attr :name, :string, required: true
  attr :class, :any, default: nil, doc: "SVG container class"

  attr :rest, :global, doc: "Forwarded to the Heroicon function component"

        
Heroicon name checking

If configured correctly (see setup for more detail), then the Icon component will check Heroicon names at runtime.

Setup

Add the following dependency to your mix.exs:

elixir
          # mix.exs
def deps do
  [
    {:heroicons,
      github: "tailwindlabs/heroicons",
      tag: "v2.1.5",
      app: false,
      compile: false,
      sparse: "optimized"},
  ]
end

        

This will download a copy of the source SVG files directly from GitHub (into deps/heroicons/optimized).

Finally, update assets/tailwind.config.js:

javascript
          // assets/tailwind.config.js

// Add these if they're missing
const fs = require("fs");
const path = require("path");

// Add plugin:
module.exports = {
  plugins: [
    // Embeds Heroicons (https://heroicons.com) into your app.css bundle
    // See your `CoreComponents.icon/1` for more information.
    //
    plugin(function({matchComponents, theme}) {
      let iconsDir = path.join(__dirname, "../deps/heroicons/optimized")
      let values = {}
      let icons = [
        ["", "/24/outline"],
        ["-solid", "/24/solid"],
        ["-mini", "/20/solid"],
        ["-micro", "/16/solid"]
      ]
      icons.forEach(([suffix, dir]) => {
        fs.readdirSync(path.join(iconsDir, dir)).forEach(file => {
          let name = path.basename(file, ".svg") + suffix
          values[name] = {name, fullPath: path.join(iconsDir, dir, file)}
        })
      })
      matchComponents({
        "hero": ({name, fullPath}) => {
          let content = fs.readFileSync(fullPath).toString().replace(/\r?\n|\r/g, "")
          let size = theme("spacing.6")
          if (name.endsWith("-mini")) {
            size = theme("spacing.5")
          } else if (name.endsWith("-micro")) {
            size = theme("spacing.4")
          }
          return {
            [`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`,
            "-webkit-mask": `var(--hero-${name})`,
            "mask": `var(--hero-${name})`,
            "mask-repeat": "no-repeat",
            "background-color": "currentColor",
            "vertical-align": "middle",
            "display": "inline-block",
            "width": size,
            "height": size
          }
        }
      }, {values})
    })
  ],
};

        
Why use CSS instead of a Hex Package?

Generating Heroicons as a set of CSS classes brings two main benefits:

  • Unused Heroicons are automatically trimmed by the Tailwind JIT - reducing the size of your deployment
  • Heroicon classes operate client-side and can be cached by the browser
Compatibility with Phoenix Core Components

If you have generated an app with Phoenix Framework 1.7.11 (or above), then you’ll need to update to the latest version of Petal Components. This is to avoid a name clash with the :heroicons dependency.

Alternatively, if you’re using Petal Components 1.9.3 (or older), you can rename the :heroicons dependency to something else (e.g. :core_heroicons). That way you can stick with V2 of the Icon component. However, you’ll need to update tailwind.config.js to read the alternative path.

You can use the Icon component that’s generated by the Phoenix Framework. However, the Petal Components Icon component has the Heroicon name checking feature.