defmodule FlintUI.API.Attribute do
@moduledoc """
Phoenix LiveView attribute helpers.
"""
alias FlintUI.Theme
@doc """
Defines a class attribute for the component trying to
fetch the default value from the theme if no default value
is provided.
"""
defmacro color(opts \\ []) do
name = Keyword.get(opts, :name) |> component_name(__CALLER__)
default = Keyword.get(opts, :default, Theme.get_in_theme(name, [:default, :color]) || :dark)
doc = Keyword.get(opts, :doc, "The color of the #{humanize_name(name)}.")
quote do
attr(:color, :atom,
default: unquote(default),
doc: unquote(doc)
)
end
end
@doc """
Defines a size attribute for the component trying to
fetch the default value and values list from the theme
if no values are provided for those.
"""
defmacro size(opts \\ []) do
name = Keyword.get(opts, :name) |> component_name(__CALLER__)
values = Keyword.get(opts, :values, Theme.size_variants())
default = Keyword.get(opts, :default, Theme.get_in_theme(name, [:default, :size]) || :md)
doc = Keyword.get(opts, :doc, "The size of the #{humanize_name(name)}.")
quote do
attr(:size, :atom,
values: unquote(values),
default: unquote(default),
doc: unquote(doc)
)
end
end
@doc """
Defines a radius attribute for the component trying to
fetch the default value and values list from the theme
if no values are provided for those.
"""
defmacro radius(opts \\ []) do
name = Keyword.get(opts, :name) |> component_name(__CALLER__)
values = Keyword.get(opts, :values, Theme.radius_variants())
default = Keyword.get(opts, :default, Theme.get_in_theme(name, [:default, :radius]) || :full)
doc = Keyword.get(opts, :doc, "The radius of the #{humanize_name(name)}.")
quote do
attr(:radius, :atom,
values: unquote(values),
default: unquote(default),
doc: unquote(doc)
)
end
end
defp component_name(nil, caller) do
FlintUI.Component.module_to_component_name(caller.module)
end
defp component_name(name, _caller) when is_binary(name) do
FlintUI.Component.string_to_component_name(name)
end
defp component_name(name, _caller) when is_atom(name), do: name
defp humanize_name(name) when is_atom(name) do
FlintUI.Component.humanize_component_name(name)
end
@doc """
Tries to convert an user input value value to an integer value
and returns a default value if the conversion fails.
"""
def as_integer(value, default \\ nil)
def as_integer(value, _default) when is_integer(value), do: value
def as_integer(value, _default) when is_float(value), do: trunc(value)
def as_integer(value, default) when is_binary(value) do
try do
String.to_integer(value)
rescue
ArgumentError -> default
end
end
def as_integer(_value, default), do: default
@doc """
Tries to convert an user input value to a boolean value
and returns a default value if the conversion fails.
"""
def as_boolean(value, default \\ false)
def as_boolean(value, _default) when is_boolean(value), do: value
def as_boolean("true", _default), do: true
def as_boolean("1", _default), do: true
def as_boolean("false", _default), do: false
def as_boolean("0", _default), do: false
def as_boolean(value, default) when is_binary(value) do
case Integer.parse(value) do
{int, _rest} -> as_boolean(int, default)
_ -> default
end
end
def as_boolean(value, _default) when is_number(value) do
if value > 0, do: true, else: false
end
def as_boolean(_value, default), do: default
end