Skip to content

Commit 8402825

Browse files
authored
Merge pull request #669 from woylie/fix/ensure-icon-fun-atoms-exist
fix/ensure icon fun atoms exist
2 parents ea2a4e3 + e38d655 commit 8402825

7 files changed

Lines changed: 84 additions & 52 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44

55
## Unreleased
66

7+
## [0.14.4] - 2026-04-09
8+
9+
### Fixed
10+
11+
- Fix an issue where the icon function name atoms don't exist yet when the icon
12+
component is rendered.
13+
714
## [0.14.3] - 2026-04-08
815

916
### Changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ The package can be installed by adding `doggo` to your list of dependencies in
1616
```elixir
1717
def deps do
1818
[
19-
{:doggo, "~> 0.14.3"}
19+
{:doggo, "~> 0.14.4"}
2020
]
2121
end
2222
```

lib/doggo/components/icon.ex

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,38 @@ defmodule Doggo.Components.Icon do
184184
"""
185185
end
186186

187-
quote do
188-
var!(assigns) =
189-
assigns
190-
|> var!()
191-
|> assign(:icon_module, unquote(icon_module))
192-
|> assign(:icon_fun, unquote(icon_fun))
187+
if is_nil(icon_fun) do
188+
mapping =
189+
Map.new(
190+
for {name, 1} <- icon_module.__info__(:functions) do
191+
{name |> Atom.to_string() |> String.replace("_", "-"), name}
192+
end
193+
)
194+
195+
quote do
196+
name = String.replace(var!(assigns).name, "_", "-")
197+
198+
icon_fun =
199+
Map.get(unquote(Macro.escape(mapping)), name) ||
200+
raise """
201+
Unknown icon: #{name}
202+
"""
203+
204+
var!(assigns) =
205+
assigns
206+
|> var!()
207+
|> assign(:icon_module, unquote(icon_module))
208+
|> assign(:icon_fun, icon_fun)
209+
|> assign(:name, nil)
210+
end
211+
else
212+
quote do
213+
var!(assigns) =
214+
assigns
215+
|> var!()
216+
|> assign(:icon_module, unquote(icon_module))
217+
|> assign(:icon_fun, unquote(icon_fun))
218+
end
193219
end
194220
end
195221

@@ -220,14 +246,6 @@ defmodule Doggo.Components.Icon do
220246
attr :module, :atom
221247
attr :fun, :atom
222248

223-
def dynamic_icon(%{module: module, fun: nil} = assigns)
224-
when is_atom(module) do
225-
{module, assigns} = Map.pop!(assigns, :module)
226-
{name, assigns} = Map.pop!(assigns, :name)
227-
name = String.replace(name, "-", "_")
228-
apply(module, String.to_existing_atom(name), [assigns])
229-
end
230-
231249
def dynamic_icon(%{module: module, fun: fun} = assigns)
232250
when is_atom(module) and is_atom(fun) do
233251
{module, assigns} = Map.pop!(assigns, :module)

lib/doggo/macros.ex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ defmodule Doggo.Macros do
4141
@doc since: unquote(since)
4242

4343
defmacro unquote(builder_name)(opts \\ []) do
44+
opts =
45+
if Keyword.has_key?(opts, :icon_module) do
46+
Keyword.update!(opts, :icon_module, &Macro.expand(&1, __CALLER__))
47+
else
48+
opts
49+
end
50+
4451
module = unquote(module)
4552
opts = Keyword.validate!(opts, unquote(defaults))
4653

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule Doggo.MixProject do
22
use Mix.Project
33

44
@source_url "https://github.com/woylie/doggo"
5-
@version "0.14.3"
5+
@version "0.14.4"
66

77
def project do
88
[

test/doggo/components_test.exs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ defmodule Doggo.ComponentsTest do
77
alias Phoenix.LiveView.JS
88
alias Phoenix.LiveView.LiveStream
99

10+
defmodule Icons do
11+
use Phoenix.Component
12+
13+
def render(assigns) do
14+
~H"""
15+
<svg class={@name}></svg>
16+
"""
17+
end
18+
19+
def info(assigns) do
20+
~H"""
21+
<svg class="info"></svg>
22+
"""
23+
end
24+
end
25+
1026
defmodule TestComponents do
1127
@moduledoc """
1228
Generates components for tests.
@@ -45,10 +61,10 @@ defmodule Doggo.ComponentsTest do
4561
build_field(gettext_module: Doggo.Gettext)
4662
build_field_group()
4763
build_frame()
48-
build_icon(icon_module: __MODULE__.Icons)
64+
build_icon(icon_module: Doggo.ComponentsTest.Icons)
4965

5066
build_icon(
51-
icon_module: __MODULE__.Icons,
67+
icon_module: Doggo.ComponentsTest.Icons,
5268
icon_fun: :render,
5369
name: :icon_with_fun
5470
)
@@ -86,22 +102,6 @@ defmodule Doggo.ComponentsTest do
86102
build_vertical_nav()
87103
build_vertical_nav_nested()
88104
build_vertical_nav_section()
89-
90-
defmodule Icons do
91-
use Phoenix.Component
92-
93-
def render(assigns) do
94-
~H"""
95-
<svg class={@name}></svg>
96-
"""
97-
end
98-
99-
def info(assigns) do
100-
~H"""
101-
<svg class="info"></svg>
102-
"""
103-
end
104-
end
105105
end
106106

107107
describe "__dog_components__/0" do

test/doggo/storybook_test.exs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ defmodule Doggo.StorybookTest do
22
use ExUnit.Case
33
use Phoenix.Component
44

5+
defmodule Icons do
6+
use Phoenix.Component
7+
8+
def render(assigns) do
9+
~H"""
10+
<svg class={@name}></svg>
11+
"""
12+
end
13+
14+
def info(assigns) do
15+
~H"""
16+
<svg class="info"></svg>
17+
"""
18+
end
19+
end
20+
521
defmodule TestComponents do
622
@moduledoc """
723
Generates components for tests.
@@ -57,13 +73,13 @@ defmodule Doggo.StorybookTest do
5773
build_frame()
5874

5975
build_icon(
60-
icon_module: __MODULE__.Icons,
76+
icon_module: Doggo.StorybookTest.Icons,
6177
names: ["info"],
6278
modifiers: [variant: [values: [nil, "yes"], default: nil]]
6379
)
6480

6581
build_icon(
66-
icon_module: __MODULE__.Icons,
82+
icon_module: Doggo.StorybookTest.Icons,
6783
icon_fun: :render,
6884
names: ["warning"],
6985
name: :icon_with_fun,
@@ -131,22 +147,6 @@ defmodule Doggo.StorybookTest do
131147
build_vertical_nav(
132148
modifiers: [variant: [values: [nil, "yes"], default: nil]]
133149
)
134-
135-
defmodule Icons do
136-
use Phoenix.Component
137-
138-
def render(assigns) do
139-
~H"""
140-
<svg class={@name}></svg>
141-
"""
142-
end
143-
144-
def info(assigns) do
145-
~H"""
146-
<svg class="info"></svg>
147-
"""
148-
end
149-
end
150150
end
151151

152152
for {name, info} <- TestComponents.__dog_components__() do

0 commit comments

Comments
 (0)