TermUI.Theme (TermUI v1.0.0)
View SourceTheme system for application-wide visual consistency.
Themes define colors, semantic meanings, and component style defaults. The theme system supports runtime switching and notifies subscribers of changes.
TermUI.Runtime does not start or subscribe to this server. Without a running
theme server, read helpers return the built-in dark theme. To switch themes,
supervise TermUI.Theme, subscribe from an application-owned process, and
cause the Elm root to update or force a render when a notification arrives.
Theme Structure
A theme contains:
:name- Theme identifier (e.g.,:dark,:light):colors- Base colors (background, foreground, primary, etc.):semantic- Semantic colors (success, warning, error, etc.):components- Per-component style defaults
Built-in Themes
:dark- Dark background with light text (default):light- Light background with dark text:high_contrast- High contrast for accessibility
Examples
# Start theme server
Theme.start_link(theme: :dark)
# Get current theme
theme = Theme.get_theme()
# Switch themes at runtime
Theme.set_theme(:light)
# Subscribe to theme changes
Theme.subscribe()
receive do
{:theme_changed, new_theme} -> handle_change(new_theme)
end
# Get colors
bg = Theme.get_color(:background)
error = Theme.get_semantic(:error)
# Get component style
style = Theme.get_component_style(:button, :focused)
Summary
Functions
Returns a specification to start this module under a supervisor.
Creates a theme from a keyword list or map, merging with a base theme.
Gets a built-in theme by name.
Gets a base color from the current theme.
Gets a component style from the current theme.
Gets a semantic color from the current theme.
Gets the current theme.
Lists all available built-in themes.
Sets the current theme.
Starts the theme server.
Creates a style from theme values with optional overrides.
Subscribes the calling process to theme change notifications.
Unsubscribes the calling process from theme change notifications.
Validates a theme struct.
Types
@type color() :: TermUI.Renderer.Style.color()
@type component_styles() :: %{ required(atom()) => %{required(atom()) => TermUI.Renderer.Style.t()} }
@type t() :: %TermUI.Theme{ colors: colors(), components: component_styles(), name: atom(), semantic: semantic() }
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
Creates a theme from a keyword list or map, merging with a base theme.
Options
:base- Base theme to merge with (default:dark):name- Theme name:colors- Color overrides:semantic- Semantic color overrides:components- Component style overrides
Examples
# Create custom theme based on dark
{:ok, theme} = Theme.from(
base: :dark,
name: :my_theme,
colors: %{primary: :magenta}
)
Gets a built-in theme by name.
@spec get_color(atom(), GenServer.server()) :: color() | nil
Gets a base color from the current theme.
Examples
Theme.get_color(:background) # => :black
Theme.get_color(:primary) # => :blue
@spec get_component_style(atom(), atom(), GenServer.server()) :: TermUI.Renderer.Style.t() | nil
Gets a component style from the current theme.
Examples
Theme.get_component_style(:button, :focused)
Theme.get_component_style(:text_input, :normal)
@spec get_semantic(atom(), GenServer.server()) :: color() | nil
Gets a semantic color from the current theme.
Examples
Theme.get_semantic(:error) # => :red
Theme.get_semantic(:success) # => :green
@spec get_theme(GenServer.server()) :: t()
Gets the current theme.
@spec list_builtin() :: [atom()]
Lists all available built-in themes.
@spec set_theme(atom() | t(), GenServer.server()) :: :ok | {:error, term()}
Sets the current theme.
Accepts a theme name atom (for built-in themes) or a Theme struct. Notifies all subscribers of the change.
Examples
Theme.set_theme(:light)
Theme.set_theme(%Theme{name: :custom, ...})
@spec start_link(keyword()) :: GenServer.on_start()
Starts the theme server.
Options
:theme- Initial theme (atom name or Theme struct, default:dark):name- GenServer name (defaultElixir.TermUI.Theme)
Examples
Theme.start_link(theme: :dark)
Theme.start_link(theme: :light, name: MyApp.Theme)
@spec style_from_theme(atom(), atom(), keyword(), GenServer.server()) :: TermUI.Renderer.Style.t()
Creates a style from theme values with optional overrides.
Useful for components that want to use theme defaults but allow customization.
Examples
# Use theme button style as base, override foreground
style = Theme.style_from_theme(:button, :normal, fg: :red)
@spec subscribe(GenServer.server()) :: :ok
Subscribes the calling process to theme change notifications.
Subscribers receive {:theme_changed, theme} messages when the theme changes.
@spec unsubscribe(GenServer.server()) :: :ok
Unsubscribes the calling process from theme change notifications.
Validates a theme struct.
Returns :ok if valid, {:error, reasons} if invalid.