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"}
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"}, :css)
iex> Iconify.prepare(%{icon: "heroicons-solid:user"}, :inline)
{:inline, _fun, %{icon: "heroicons-solid:user"}}
iex> Iconify.prepare(%{icon: "heroicons-solid:user"}, :img)
{:img, _fun, %{src: "/images/icons/heroicons-solid/user.svg"}}
iex> Iconify.prepare(%{icon: "heroicons-solid:user"}, :set)
{:set, _fun, %{href: "/images/icons/heroicons-solid.svg#user"}}
iex> Iconify.prepare(%{icon: "twemoji:rabbit"})
{:img, _fun, %{src: "/images/icons/twemoji/rabbit.svg"}}
iex> Iconify.prepare(%{icon: "non-existent-icon"})
{:css, _fun, %{icon_name: "heroicons-solid:question-mark-circle"}}
> Iconify.prepare(%{icon: ""})
{:inline, _fun, %{icon: ""}}
"""
def prepare(assigns, opts \\ [])
def prepare(assigns, opts) when is_map(assigns) and is_list(opts) do
assigns =
Map.put_new_lazy(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 |> Enum.into(%{href: href})}
:img_url ->
maybe_prepare_icon_img(icon, opts)
:img ->
src = prepare_icon_img(icon, opts)
{:img, &render_svg_with_img/1, assigns |> Enum.into(%{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 |> Enum.into(%{icon_name: icon_name})}
end
catch
{:fallback, "