# `Iconex.Set`
[🔗](https://github.com/paradox460/iconex/blob/main/lib/iconex/set.ex#L1)

The behaviour every icon set implements, and the registry of known sets.

Each set is identified by an atom (`:lucide`, ...) that names its component
function (`Iconex.lucide/1`), its config key (`config :iconex, lucide: [...]`),
its data file (`priv/sets/lucide.json`) and its sprite symbol prefix
(`#lucide-house`).

## Data files

`mix iconex.download SET` fetches a set's upstream data and writes it in a
normalized form shared by every set:

    {"set": "lucide", "version": "1.47.0",
     "icons": {"house": {"viewBox": "0 0 24 24",
                         "nodes": [["path", {"d": "..."}], ...]}}}

Nodes are `[tag, attrs]` or `[tag, attrs, children]` with string attribute
values.

## Adding an icon set

  1. Write `Iconex.Set.<Name>` implementing this behaviour.
  2. Register it in `modules/0`.
  3. Add a component function named after the id in `Iconex`, wrapped in
     `if :<id> in @sets do ... end`.
  4. Add its pinned version to `@set_versions` in `mix.exs` and its data file
     to `package[:files]`.
  5. Add its license text under `licenses/`.

# `icon`

```elixir
@type icon() :: %{required(String.t()) =&gt; term()}
```

`%{"viewBox" => String.t(), "nodes" => [node]}`

# `data_url`

```elixir
@callback data_url(version :: String.t()) :: String.t()
```

The URL of the upstream data for `version`.

# `docs_url`

```elixir
@callback docs_url() :: String.t()
```

Where users can look up the set's icon names.

# `normalize`

```elixir
@callback normalize(decoded :: term()) ::
  {:ok, %{required(String.t()) =&gt; icon()}} | :error
```

Converts the decoded upstream data to `%{name => icon}`.

# `npm_package`

```elixir
@callback npm_package() :: String.t()
```

The npm package the set's data is downloaded from.

# `symbol_attrs`

```elixir
@callback symbol_attrs() :: [{String.t(), String.t()}]
```

Presentation attributes placed on every `<symbol>` of the set.

# `ids`

Known set ids.

# `module!`

The module implementing set `id`.

# `modules`

Known sets, keyed by id.

# `read`

```elixir
@spec read(Path.t()) :: {:ok, %{required(String.t()) =&gt; icon()}} | :error
```

Reads a normalized data file written by `mix iconex.download`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
