defmodule Iconify do
@moduledoc "./README.md" |> File.stream!() |> Enum.drop(1) |> Enum.join()
use Phoenix.Component
use Arrows
use Untangle
import Phoenix.LiveView.TagEngine
# import Phoenix.LiveView.HTMLEngine
# this is executed at compile time
@cwd File.cwd!()
@doc """
Renders an icon as a `Phoenix.Component` based on the given assigns.
## Examples
iex> assigns = %{icon: "heroicons-solid:user", class: "w-6 h-6", __changed__: nil}
iex> Iconify.iconify(assigns) # Returns rendered icon HTML
"""
def iconify(assigns) do
with {_, fun, assigns} <- prepare(assigns, assigns[:mode]) do
component(
fun,
assigns,
{__ENV__.module, __ENV__.function, __ENV__.file, __ENV__.line}
)
end
end
@doc """
Prepares an icon based on the given assigns and mode (such as CSS, inline SVG, or image URL).
## Examples
iex> {:css, _function, %{icon: "heroicons-solid:user", class: "w-4 h-4", icon_name: "heroicons-solid:user"}} = Iconify.prepare(%{icon: "heroicons-solid:user", __changed__: nil}, :css)
iex> {:inline, _fun, %{icon: "heroicons-solid:user"}} = Iconify.prepare(%{icon: "heroicons-solid:user", __changed__: nil}, :inline)
iex> {:img, _fun, %{src: "/images/icons/heroicons-solid/user.svg"}} = Iconify.prepare(%{icon: "heroicons-solid:user", __changed__: nil}, :img)
iex> {:set, _fun, %{href: "/images/icons/heroicons-solid.svg#user"}} = Iconify.prepare(%{icon: "heroicons-solid:user", __changed__: nil}, :set)
iex> {:img, _fun, %{src: "/images/icons/twemoji/rabbit.svg"}} = Iconify.prepare(%{icon: "twemoji:rabbit", __changed__: nil})
iex> {:css, _fun, %{icon_name: "heroicons-solid:question-mark-circle"}} = Iconify.prepare(%{icon: "non-existent-icon", __changed__: nil})
> Iconify.prepare(%{icon: "", __changed__: nil})
{:inline, _fun, %{icon: ""}}
"""
def prepare(assigns, opts \\ [])
def prepare(assigns, opts) when is_map(assigns) and is_list(opts) do
assigns =
assign_new(assigns, :class, fn ->
Application.get_env(:iconify_ex, :default_class, "w-4 h-4")
end)
icon = Map.fetch!(assigns, :icon)
case opts[:mode] || mode(icon) do
:set ->
href = href_for_prepared_set_icon(icon, opts)
{:set, &render_svg_for_sprite/1, assigns |> assign(:href, href)}
:img_url ->
maybe_prepare_icon_img(icon, opts)
:img ->
src = prepare_icon_img(icon, opts)
{:img, &render_svg_with_img/1, assigns |> assign(:src, src)}
:inline ->
{:inline, &prepare_icon_component(icon, opts).render/1, assigns}
:data ->
{:data, prepare_icon_data(icon, opts)}
_ ->
# :css by default
icon_name = prepare_icon_css(icon, opts)
{:css, &render_svg_with_css/1, assigns |> assign(:icon_name, icon_name)}
end
catch
{:fallback, "