Search documentation of mob

# Mob.Theme (mob v0.6.18)

Copy Markdown View Source

Design token system for Mob apps.

A theme is a compiled `%Mob.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 Mob.App`:

    use Mob.App, theme: Mob.Theme.Obsidian

Override individual tokens without leaving the theme:

    use Mob.App, theme: {Mob.Theme.Obsidian, primary: :rose_500}

Anyone can publish a theme as a Hex package — any module with `theme/0` returning a `Mob.Theme.t()` works:

    use Mob.App, theme: AcmeCorp.BrandTheme

## Building a theme from scratch

Pass a keyword list of overrides against the neutral base:

    use Mob.App, theme: [primary: :emerald_500, type_scale: 1.1]

Or change the theme at runtime (e.g. for accessibility or user preference):

    Mob.Theme.set(Mob.Theme.Obsidian)
    Mob.Theme.set({Mob.Theme.Obsidian, type_scale: 1.2})
    Mob.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 × scale

### Radius 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

### Types

color_value()
t()

### Functions

build(overrides \\ [])

Build a theme from a keyword list of overrides against the neutral base.

color_scheme()

Returns the current OS appearance: `:light` or `:dark`.

current()

Return the currently active theme (or the neutral base if none is set).

default()

Return the neutral base theme.

resolved_palette(theme \\ current())

Returns the active theme's palette resolved to ARGB integers — semantic tokens (`:primary`, `:on_surface`, …) walked through the theme's color map and then through `Mob.Renderer.colors/0`. Used to push concrete values to the native side (`Mob.Theme.set/1` does this automatically; callers usually don't need to invoke this directly).

set(theme)

Set the active theme. Accepts

## Types

# color_value()

    @type color_value() :: atom() | non_neg_integer()

# t()

    @type t() :: %Mob.Theme{
      background: term(),
      border: term(),
      error: term(),
      glass: 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(overrides \\ [])

    @spec build(keyword()) :: t()

Build a theme from a keyword list of overrides against the neutral base.

    Mob.Theme.build(primary: :emerald_500, type_scale: 1.1)

# color_scheme()

    @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 `MobBridge.getColorScheme()` yet.

# current()

    @spec current() :: t()

Return the currently active theme (or the neutral base if none is set).

# default()

    @spec default() :: t()

Return the neutral base theme.

# resolved_palette(theme \\ current())

    @spec resolved_palette(t()) :: %{required(atom()) => non_neg_integer()}

Returns the active theme's palette resolved to ARGB integers — semantic tokens (`:primary`, `:on_surface`, …) walked through the theme's color map and then through `Mob.Renderer.colors/0`. Used to push concrete values to the native side (`Mob.Theme.set/1` does this automatically; callers usually don't need to invoke this directly).

# set(theme)

    @spec set(t() | module() | {module(), keyword()} | keyword()) :: :ok

Set the active theme. Accepts:

- A compiled `%Mob.Theme{}` struct
- A theme module (`Mob.Theme.Obsidian`)
- A `{module, overrides}` tuple
- A keyword list of overrides against the neutral base