Design token system for Dala apps.
A theme is a compiled %Dala.Theme{} struct — a flat map of semantic tokens
for colors, spacing, radii, and scale factors. The renderer resolves these
tokens at render time so every component picks up the active theme
automatically.
Using a named theme
Named themes are plain modules that export theme/0. Pass the module to
use Dala.App:
use Dala.App, theme: Dala.Theme.ObsidianOverride individual tokens without leaving the theme:
use Dala.App, theme: {Dala.Theme.Obsidian, primary: :rose_500}Anyone can publish a theme as a Hex package — any module with theme/0
returning a Dala.Theme.t() works:
use Dala.App, theme: AcmeCorp.BrandThemeBuilding a theme from scratch
Pass a keyword list of overrides against the neutral base:
use Dala.App, theme: [primary: :emerald_500, type_scale: 1.1]Or change the theme at runtime (e.g. for accessibility or user preference):
Dala.Theme.set(Dala.Theme.Obsidian)
Dala.Theme.set({Dala.Theme.Obsidian, type_scale: 1.2})
Dala.Theme.set(primary: :pink_500)Base theme
When no theme is set the renderer uses the neutral base — plain dark grays with a standard blue primary. Functional, not opinionated. Good enough for hello world; swap in a named theme when you want personality.
Token reference
Semantic color tokens
:primary — main action colour (default :blue_500)
:on_primary — text/icons on primary (default :white)
:secondary — secondary action colour (default :gray_600)
:on_secondary — text/icons on secondary (default :white)
:background — page/screen background (default :gray_900)
:on_background — text on background (default :gray_100)
:surface — card / sheet background (default :gray_800)
:surface_raised — elevated card background (default :gray_700)
:on_surface — text/icons on surface (default :gray_100)
:muted — secondary/placeholder text (default :gray_500)
:error — error state colour (default :red_500)
:on_error — text/icons on error (default :white)
:border — dividers and outlines (default :gray_700)Spacing tokens (scaled by space_scale)
:space_xs → 4 × scale
:space_sm → 8 × scale
:space_md → 16 × scale
:space_lg → 24 × scale
:space_xl → 32 × scaleRadius tokens
:radius_sm → theme.radius_sm (default 6)
:radius_md → theme.radius_md (default 10)
:radius_lg → theme.radius_lg (default 16)
:radius_pill → theme.radius_pill (default 100)Scale factors
type_scale: 1.0 # multiply all text sizes by this
space_scale: 1.0 # multiply all spacing tokens by this
Summary
Functions
Build a theme from a keyword list of overrides against the neutral base.
Returns the current OS appearance: :light or :dark.
Return the currently active theme (or the neutral base if none is set).
Return the neutral base theme.
Set the active theme. Accepts
Types
@type color_value() :: atom() | non_neg_integer()
@type t() :: %Dala.Theme{ background: term(), border: term(), error: term(), muted: term(), on_background: term(), on_error: term(), on_primary: term(), on_secondary: term(), on_surface: term(), primary: term(), radius_lg: term(), radius_md: term(), radius_pill: term(), radius_sm: term(), secondary: term(), space_scale: term(), surface: term(), surface_raised: term(), type_scale: term() }
Functions
Build a theme from a keyword list of overrides against the neutral base.
Dala.Theme.build(primary: :emerald_500, type_scale: 1.1)
@spec color_scheme() :: :light | :dark
Returns the current OS appearance: :light or :dark.
Reads from the platform NIF (UITraitCollection.userInterfaceStyle on
iOS, Configuration.uiMode & UI_MODE_NIGHT_MASK on Android). Falls back
to :light when running on the host BEAM (no NIF loaded), on platforms
that don't expose appearance, or on legacy Android apps that haven't
added dalaBridge.getColorScheme() yet.
@spec current() :: t()
Return the currently active theme (or the neutral base if none is set).
@spec default() :: t()
Return the neutral base theme.
Set the active theme. Accepts:
- A compiled
%Dala.Theme{}struct - A theme module (
Dala.Theme.Obsidian) - A
{module, overrides}tuple - A keyword list of overrides against the neutral base