defmodule FlintUI.Theme do
@moduledoc """
Theme and helpers.
"""
@enforce_keys [:name, :ui]
defstruct [:name, :ui]
## Variants
@doc """
Returns the list of the theme size variants (e.g. for
width, height, radius, etc).
"""
def size_variants, do: FlintUI.Theme.Default.size_variants()
def size_variants(exclude_list) when is_list(exclude_list) do
size_variants() -- exclude_list
end
@doc """
Returns the list of the theme radius variants.
"""
def radius_variants, do: FlintUI.Theme.Default.radius() |> Map.keys()
def radius_variants(exclude_list) when is_list(exclude_list) do
radius_variants() -- exclude_list
end
def semantic_colors, do: FlintUI.Theme.Default.semantic_colors()
def shade_colors, do: FlintUI.Theme.Default.shade_colors()
## Theme
def theme do
if Application.get_env(:flint_ui, :config)[:dev],
do: merge_theme(),
else: Memoize.resolve(:theme, fn -> merge_theme() end)
end
def theme(component) when is_atom(component) do
get_theme_component(component)
end
def theme(component) when is_binary(component) do
String.to_atom(component) |> get_theme_component()
end
@doc """
Returns the theme component by name (e.g. `:badge`).
If the component is not found, it returns nil.
"""
def get_theme_component(component) do
theme().ui[component] || nil
end
def get_in_theme(component, keys) do
get_in(theme(component), keys)
end
def user_config do
Application.get_env(:flint_ui, :config, %{})
|> Map.get(:overrides, %{})
|> Map.new()
end
# Merge default theme with the user theme
defp merge_theme do
default_theme = FlintUI.Theme.Default.values()
theme = DeepMerge.deep_merge(default_theme, user_config())
struct(__MODULE__, theme)
end
end