SlopUI.Icons.Set (SlopUI v0.1.0)

Copy Markdown View Source

Compile-time icon sets.

use SlopUI.Icons, sets: [...] defines an icon/1 function component in the calling module whose SVGs are read from disk at compile time and embedded in the module, so nothing is fetched at runtime and unknown names fail the build.

defmodule MyAppWeb.Icons do
  use SlopUI.Icons,
    sets: [
      phosphor: [weight: :regular, icons: ~w(house users bell)],
      hero: [style: :outline, icons: ~w(arrow-path)],
      app: [dir: "assets/icons", icons: :all]
    ]
end

<MyAppWeb.Icons.icon name="phosphor-house" />
<MyAppWeb.Icons.icon name="hero-arrow-path" class="sl-icon-lg" />
<MyAppWeb.Icons.icon name="app-logo" aria-label="Acme" />

Each set is keyed by its prefix. Names are prefix-file-name (the file's basename without .svg), so sets never collide.

Set options

  • :dir – folder of .svg files. Required unless a preset applies.
  • :icons – list of names to embed, or :all for every file in the folder. Required. A name that does not exist raises at compile time with the closest matches.
  • :prefix – overrides the prefix (defaults to the key). false uses the bare file names.
  • :preset:phosphor or :heroicons. Inferred from the key when the key is :phosphor, :hero or :heroicons.

Phosphor

Add the icons to your deps (git checkout, nothing compiled):

{:phosphor, github: "phosphor-icons/core", sparse: "assets", depth: 1,
 app: false, compile: false}

Options: :weight:regular (default), :thin, :light, :bold, :fill or :duotone; :dep – the dep name if you called it something other than :phosphor.

Heroicons

{:heroicons, github: "tailwindlabs/heroicons", sparse: "optimized", depth: 1,
 app: false, compile: false}

Options: :style:outline (default), :solid, :mini (20px) or :micro (16px); :dep.

Normalisation

The root <svg> keeps its viewBox and any fill/stroke attributes; width, height, xmlns, class and id are dropped so the icon is sized by CSS (1em by default, see .sl-icon). Hard-coded black fills and strokes become currentColor. Everything inside the root element is kept as-is, so multi-layer icons (Phosphor duotone) work.

Accessibility

Icons are aria-hidden by default. Pass aria-label for a meaningful icon and it becomes role="img" instead.