Pote — canonical color types, default palette, and top-level helpers.

This module defines the core color type definitions used throughout the entire library and provides access to the built-in default color palette.

Summary

Types

A theme resolver: (key :: String.t()) -> {:ok, rgb()} | :not_found.

Functions

Returns a specific color by name (alias for get_color/1).

Checks if a color name exists in the default palette.

Returns all available color names.

Returns the default color palette.

Looks up a color by atom name. Returns RGB tuple or nil.

Parses any color input to an RGB tuple.

Like parse/1 but raises on error.

Registers a theme resolver at runtime. Multiple resolvers can coexist in a stack — resolve_theme_color/1 walks the stack and returns the first non-:not_found result. Useful when several apps / themes are loaded side-by-side (e.g. tests for multiple consumers).

Resolves a theme key ("primary", "ternary", ...) to an RGB tuple.

Returns a combined theme resolver that walks the registered stack.

Returns the current list of registered theme resolvers (newest first).

Types

argb()

cmyk()

@type cmyk() :: {float(), float(), float(), float()}

color_input()

@type color_input() ::
  rgb() | hex() | hsl() | hsv() | cmyk() | xterm256() | atom() | String.t()

color_output()

@type color_output() :: rgb() | nil

hex()

@type hex() :: String.t()

hsl()

@type hsl() :: {float(), float(), float()}

hsv()

@type hsv() :: {float(), float(), float()}

rgb()

theme_resolver()

@type theme_resolver() :: (String.t() -> {:ok, rgb()} | :not_found)

A theme resolver: (key :: String.t()) -> {:ok, rgb()} | :not_found.

xterm256()

@type xterm256() :: 0..255

Functions

color(name)

@spec color(atom()) :: {integer(), integer(), integer()} | nil

Returns a specific color by name (alias for get_color/1).

color_exists?(name)

@spec color_exists?(atom()) :: boolean()

Checks if a color name exists in the default palette.

color_names()

@spec color_names() :: [atom()]

Returns all available color names.

default_colors()

@spec default_colors() :: map()

Returns the default color palette.

get_color(name)

@spec get_color(atom()) :: {integer(), integer(), integer()} | nil

Looks up a color by atom name. Returns RGB tuple or nil.

parse(input)

@spec parse(color_input()) :: {:ok, rgb()} | {:error, term()}

Parses any color input to an RGB tuple.

Accepts hex strings ("#FF0000", "FF0000"), RGB tuples ({255, 0, 0}), HSL/HSV tuples, atom names (:red, :blue), and xterm256 integers (0..255).

Delegates to Pote.Orchestrator.parse_color/1.

Returns {:ok, {r, g, b}} on success, {:error, reason} on failure.

parse!(input)

@spec parse!(color_input()) :: rgb()

Like parse/1 but raises on error.

put_theme_resolver(fun)

@spec put_theme_resolver(theme_resolver() | nil | :pop) :: :ok

Registers a theme resolver at runtime. Multiple resolvers can coexist in a stack — resolve_theme_color/1 walks the stack and returns the first non-:not_found result. Useful when several apps / themes are loaded side-by-side (e.g. tests for multiple consumers).

Pass nil to remove ALL resolvers. Pass :pop to remove the most recently registered one. Pass :clear as an alias for nil.

resolve_theme_color(key)

@spec resolve_theme_color(String.t() | atom()) :: {:ok, rgb()} | :not_found

Resolves a theme key ("primary", "ternary", ...) to an RGB tuple.

Strategy (in order):

  1. The configured theme resolver (via theme_resolver/0).
  2. Pote's built-in @default_colors.

Returns {:ok, {r, g, b}} or :not_found.

theme_resolver()

@spec theme_resolver() :: theme_resolver()

Returns a combined theme resolver that walks the registered stack.

The combined resolver tries each registered resolver in order and returns the first non-:not_found result. If no resolver is registered, returns a default that always yields :not_found.

Applications embedding Pote (e.g. Alaja) can register their own resolver to make "theme:<key>" lookups consult their theme system:

# In Alaja's startup:
Pote.put_theme_resolver(fn key ->
  case Alaja.Config.lookup_theme_color(key) do
    {:ok, rgb} -> {:ok, rgb}
    :error -> :not_found
  end
end)

Multiple resolvers may be registered; the first one to match wins. This is the recommended pattern when several apps / themes coexist (e.g. in tests for multiple consumers).

theme_resolvers()

@spec theme_resolvers() :: [theme_resolver()]

Returns the current list of registered theme resolvers (newest first).

The combined resolver returned by theme_resolver/0 walks this list in order until one of them returns {:ok, _}.