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