if Code.ensure_loaded?(Surface) do
defmodule Iconify.Icon do
use Surface.MacroComponent
# any icon from iconify: https://icones.js.org
prop iconify, :string, required: false, static: true
prop icon, :string, required: false, static: true
# shorthand for heroicons solid icons
prop solid, :string, required: false, static: true
# shorthand for heroicons outline icons
prop outline, :string, required: false, static: true
# pass SVG markup directly
prop svg, :string, default: nil, required: false, static: true
prop mode, :atom, required: false, static: true
prop class, :css_class, default: nil
def expand(attributes, _content, meta) do
static_props =
Surface.MacroComponent.eval_static_props!(__MODULE__, attributes, meta.caller)
svg = svg_icon(static_props)
icon = prepare_icon_name(static_props)
class =
Surface.AST.find_attribute_value(attributes, :class) ||
Application.get_env(:iconify_ex, :default_class, "w-4 h-4")
# TODO? simply include the phoenix component like so instead of duplicating logic, see https://github.com/surface-ui/surface/pull/685#issuecomment-1505978390
# quote_surface caller: meta.caller do
# ~F"""
# <Iconify.iconify class={^class} icon={^icon} />
# """
# end
if is_nil(svg) do
case Iconify.prepare(%{icon: icon}, static_props[:mode]) do
{:css, _fun, %{icon_name: icon_name}} ->
# icon_class = "#{Iconify.css_class()} #{icon_css_name} #{class_to_string(class)}"
quote_surface do
~F"""
<div iconify={^icon_name} class={^class} aria-hidden="true" />
"""
end
{:img, _fun, %{src: src}} ->
quote_surface do
~F"""
<img
src={^src}
class={^class}
onload={if Iconify.using_svg_inject?(), do: "SVGInject(this)"}
aria-hidden="true"
/>
"""
end
{:inline, fun, _assigns} ->
quote_surface do
~F"""
<{^fun} class={^class} />
"""
end
{:set, _fun, %{href: href}} ->
quote_surface do
~F"""
<svg class={^class} aria-hidden="true"><use href={^href} class={^class} /></svg>
"""
end
end
else
quote_surface do
~F"""
<div class={^class} aria-hidden="true">{^svg}</div>
"""
end
end
end
defmacro icon_name(icon) do
name = prepare_icon_name(icon)
Iconify.prepare(%{icon: name}, :css)
|> IO.inspect(label: "prepared icon")
name
end
defp svg_icon(%{svg: svg}) when is_binary(svg) do
svg
end
defp svg_icon(%{iconify: "<svg" <> _ = svg}) do
svg
end
defp svg_icon(_) do
nil
end
defp prepare_icon_name(%{iconify: icon})
when is_binary(icon) or (is_atom(icon) and not is_nil(icon)) do
icon
end
defp prepare_icon_name(%{icon: icon})
when is_binary(icon) or (is_atom(icon) and not is_nil(icon)) do
icon
end
defp prepare_icon_name(%{solid: icon})
when is_binary(icon) or (is_atom(icon) and not is_nil(icon)) do
"heroicons-solid:#{icon}"
end
defp prepare_icon_name(%{outline: icon})
when is_binary(icon) or (is_atom(icon) and not is_nil(icon)) do
"heroicons-outline:#{icon}"
end
defp prepare_icon_name(icon)
when is_binary(icon) or (is_atom(icon) and not is_nil(icon)) do
icon
end
defp prepare_icon_name(assigns) do
e = "iconify: icon name not found in assigns"
IO.inspect(assigns, label: e)
# raise e
""
end
def class_to_string(class) when is_binary(class) do
class
end
def class_to_string(%{original: class}) do
class
# |> class_to_string()
end
def class_to_string(class) when is_list(class) do
if Keyword.keyword?(class) do
IO.inspect(class, label: "kccccc")
Surface.css_class(class)
else
IO.inspect(class, label: "lccccc")
Enum.join(class, " ")
end
end
def class_to_string(class) do
IO.inspect(class, label: "occccc")
Surface.css_class(class)
end
end
end