Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .ex_icon.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,13 @@
module_path: "output/lucide.ex",
module_name: MyAppWeb.Components.Lucide,
attrs: ["stroke"]
],
simple_icons: [
icons: ["helix", "mastodon"],
provider: ExIcon.SimpleIcons,
version: "16.15.0",
module_path: "output/simple_icons.ex",
module_name: MyAppWeb.Components.SimpleIcons,
attrs: []
]
]
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

## Unreleased

## [0.3.0] - 2026-04-10

### Added

- Add provider for Simple Icons.
- Add `--icon-set` flag to `mix ex_icon.gen.icons`.

### Changed

- Change `c:ExIcon.Provider.svg_folder/0` to `c:ExIcon.Provider.svg_folder/1`,
with the argument being the version.

## [0.2.0] - 2026-04-10

### Changed
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Add `ex_icon` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:ex_icon, "~> 0.2.0", only: :dev}
{:ex_icon, "~> 0.3.0", only: :dev}
]
end
```
Expand Down Expand Up @@ -111,8 +111,10 @@ substantially by adding attributes.
## Providers

Providers for specific icon libraries are based on the `ExIcon.Provider`
behaviour. Currently, ExIcon includes a single provider for
[Lucide](https://lucide.dev/).
behaviour. The library currently supports these providers:

- [Lucide](https://lucide.dev/)
- [Simple Icons](https://simpleicons.org/)

## Contributing

Expand Down
2 changes: 1 addition & 1 deletion lib/ex_icon.ex
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ defmodule ExIcon do
provider_name = provider_name(provider)

tmp_dir = Path.join([tmp_dir, provider_name, version])
tmp_svg_dir = Path.join(tmp_dir, provider.svg_folder())
tmp_svg_dir = Path.join(tmp_dir, provider.svg_folder(version))

clear_folder!(tmp_dir)

Expand Down
4 changes: 3 additions & 1 deletion lib/ex_icon/lucide.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
defmodule ExIcon.Lucide do
@moduledoc """
ExIcon provider for Lucide icons.

https://lucide.dev
"""

@behaviour ExIcon.Provider
Expand All @@ -11,7 +13,7 @@ defmodule ExIcon.Lucide do
end

@impl true
def svg_folder do
def svg_folder(_) do
"icons"
end
end
2 changes: 1 addition & 1 deletion lib/ex_icon/provider.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ defmodule ExIcon.Provider do
@doc """
Returns the folder that contains the SVG files in the unpacked release.
"""
@callback svg_folder() :: String.t()
@callback svg_folder(version) :: String.t() when version: String.t()
end
19 changes: 19 additions & 0 deletions lib/ex_icon/simple_icons.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
defmodule ExIcon.SimpleIcons do
@moduledoc """
ExIcon provider for Simple Icons.

https://simpleicons.org
"""

@behaviour ExIcon.Provider

@impl true
def release_url(version) when is_binary(version) do
"https://github.com/simple-icons/simple-icons/archive/refs/tags/#{version}.zip"
end

@impl true
def svg_folder(version) do
"simple-icons-#{version}/icons"
end
end
46 changes: 42 additions & 4 deletions lib/mix/tasks/ex_icon.gen.icons.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,36 @@ defmodule Mix.Tasks.ExIcon.Gen.Icons do

## Usage

mix ex_icon.gen
Download and generate icons for all configured providers:

mix ex_icon.gen.icons

Download and generate icons for a single named provider:

mix ex_icon.gen.icons --icon-set lucide

The value must reference one of the top level keys in your configuration
file.
"""

use Mix.Task

@switches [
strict: [
icon_set: :string
]
]

@tmp_dir "ex_icon"

@impl Mix.Task
def run(_) do
def run(args) do
{opts, []} = OptionParser.parse!(args, @switches)

case ExIcon.read_config() do
{:ok, config} ->
tmp_dir = Path.join([System.tmp_dir!(), @tmp_dir])
download_and_generate_all(config, tmp_dir)

do_run(config, tmp_dir, opts[:icon_set])
IO.puts("Done.")

{:error, reason} ->
Expand All @@ -35,6 +51,28 @@ defmodule Mix.Tasks.ExIcon.Gen.Icons do
end
end

defp do_run(config, tmp_dir, nil) do
download_and_generate_all(config, tmp_dir)
end

defp do_run(config, tmp_dir, icon_set) when is_binary(icon_set) do
icon_set = String.to_atom(icon_set)

if opts = Keyword.get(config, icon_set) do
download_and_generate({icon_set, opts}, tmp_dir)
else
IO.puts("""
Icon set #{icon_set} not found in configuration.

Available icon sets:

#{inspect(Keyword.keys(config))}
""")

exit({:shutdown, 1})
end
end

defp download_and_generate_all(config, tmp_dir) do
Enum.each(config, &download_and_generate(&1, tmp_dir))
after
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule ExIcon.MixProject do
use Mix.Project

@source_url "https://github.com/woylie/ex_icon"
@version "0.2.0"
@version "0.3.0"

def project do
[
Expand Down
Loading