Packages
Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.
Current section
Files
Jump to
Current section
Files
lib/raxol/ui/theming/theme_manager.ex
defmodule Raxol.UI.Theming.ThemeManager do
@moduledoc """
Unified manager for themes and color palettes in the UI system.
Consolidates ThemeManager and ColorManager functionality.
"""
use Raxol.Core.Behaviours.BaseManager
require Logger
defstruct [
:current_theme,
:available_themes,
:theme_cache,
:current_palette,
:palettes,
:contrast_ratio
]
@type t :: %__MODULE__{
current_theme: String.t() | nil,
available_themes: map(),
theme_cache: map(),
current_palette: map() | nil,
palettes: map(),
contrast_ratio: float()
}
## Client API - Theme Management
def get_theme(manager \\ __MODULE__, theme_id) do
GenServer.call(manager, {:get_theme, theme_id})
end
def set_theme(manager \\ __MODULE__, theme_id) do
GenServer.call(manager, {:set_theme, theme_id})
end
def list_themes(manager \\ __MODULE__) do
GenServer.call(manager, :list_themes)
end
## Client API - Color Management
def update_palette(manager \\ __MODULE__, palette) do
GenServer.call(manager, {:update_palette, palette})
end
def get_palette(manager \\ __MODULE__) do
GenServer.call(manager, :get_palette)
end
def set_contrast_ratio(manager \\ __MODULE__, ratio) do
GenServer.call(manager, {:set_contrast_ratio, ratio})
end
def get_contrast_ratio(manager \\ __MODULE__) do
GenServer.call(manager, :get_contrast_ratio)
end
## GenServer Implementation
@impl Raxol.Core.Behaviours.BaseManager
def init_manager(opts) do
state = %__MODULE__{
current_theme: nil,
available_themes: %{},
theme_cache: %{},
current_palette: nil,
palettes: %{},
contrast_ratio: Keyword.get(opts, :contrast_ratio, 4.5)
}
{:ok, state}
end
## Theme Handlers
@impl true
def handle_call({:get_theme, theme_id}, _from, state) do
theme = Map.get(state.available_themes, theme_id)
{:reply, theme, state}
end
def handle_call({:set_theme, theme_id}, _from, state) do
case Map.get(state.available_themes, theme_id) do
nil ->
{:reply, {:error, :theme_not_found}, state}
theme ->
new_state = %{state | current_theme: theme_id}
{:reply, {:ok, theme}, new_state}
end
end
def handle_call(:list_themes, _from, state) do
themes = Map.keys(state.available_themes)
{:reply, themes, state}
end
## Color Handlers
def handle_call({:update_palette, palette}, _from, state) do
new_state = %{state | current_palette: palette}
{:reply, :ok, new_state}
end
def handle_call(:get_palette, _from, state) do
{:reply, state.current_palette, state}
end
def handle_call({:set_contrast_ratio, ratio}, _from, state) do
new_state = %{state | contrast_ratio: ratio}
{:reply, :ok, new_state}
end
def handle_call(:get_contrast_ratio, _from, state) do
{:reply, state.contrast_ratio, state}
end
@impl true
def handle_call(_request, _from, state) do
{:reply, :ok, state}
end
@impl true
def handle_cast(_msg, state) do
{:noreply, state}
end
@impl true
def handle_info(_info, state) do
{:noreply, state}
end
end