Harlock.Theme (harlock v0.8.0)

Copy Markdown View Source

Visual theme tokens used by the renderer.

The renderer reads :header, :focus, :selection, :border and :primary; :accent, :muted and :error are general-purpose tokens for apps. Three built-in themes ship, and colors are downgraded to what the terminal supports, so the same theme renders reasonably on truecolor, 256-color, 16-color, and monochrome terminals.

Tokens (each a Harlock.Render.Style.t()):

  • :header — table column headers. Default: bold: true.
  • :focus — active focus indicator. Default: reverse: true.
  • :selection — selected rows / cells. Default: bg: :cyan.
  • :border — default box border style. Default: %Style{} (no fg/bg).
  • :primary — primary brand / accent surface. Default: fg: :cyan.
  • :accent — secondary accent. Default: fg: :magenta.
  • :muted — de-emphasised text. Default: dim: true.
  • :error — error / destructive surface. Default: fg: :red.

Setting a theme

Harlock.run(MyApp, init_arg, theme: %Harlock.Theme{
  focus:     %Style{reverse: true, fg: :yellow},
  selection: %Style{bg: :blue, fg: :white}
})

# Or use a built-in:
Harlock.run(MyApp, init_arg, theme: Harlock.Theme.builtin(:dark))

Omitting the option uses Harlock.Theme.default/0, which matches the pre-theming hard-coded values byte-for-byte. The default theme is intentionally minimal — apps that want a visible identity pick a built-in or build their own.

Built-in themes

  • :default — minimal, terminal-native colors.
  • :dark — opinionated dark palette suitable for cave-dwellers.
  • :high_contrast — bright primaries / strong borders, biased for readability over aesthetics.

Look up with Harlock.Theme.builtin/1.

Reading inside a callback

def view(model) do
  accent = Harlock.Theme.get(:primary)
  text("hello", style: accent)
end

The runtime stashes the theme in the process dictionary before invoking update/2 and view/1, mirroring the Harlock.Focus pattern. Don't call get/1 outside a Harlock callback — there's nothing in the dictionary.

Summary

Types

t()

A theme is the bag of styled tokens the renderer looks up.

Functions

Build a theme from a keyword list or a map. Unspecified tokens take their default values.

Return one of the built-in themes by name. Available: :default, :dark, :high_contrast.

The default theme. Minimal, terminal-native colors; its output is pinned byte-for-byte by a golden-frame test so it does not drift between releases. :primary is the default style for menu, tree and a select's open list; :accent, :muted and :error are for apps, via get/1.

Look up a theme token. Returns the value from the theme installed by the runtime, or the default if no theme is in scope.

Types

t()

@type t() :: %Harlock.Theme{
  accent: Harlock.Render.Style.t(),
  border: Harlock.Render.Style.t(),
  error: Harlock.Render.Style.t(),
  focus: Harlock.Render.Style.t(),
  header: Harlock.Render.Style.t(),
  muted: Harlock.Render.Style.t(),
  primary: Harlock.Render.Style.t(),
  selection: Harlock.Render.Style.t()
}

token()

@type token() ::
  :header | :focus | :selection | :border | :primary | :accent | :muted | :error

A theme is the bag of styled tokens the renderer looks up.

Functions

build(theme)

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

Build a theme from a keyword list or a map. Unspecified tokens take their default values.

builtin(atom)

@spec builtin(:default | :dark | :high_contrast) :: t()

Return one of the built-in themes by name. Available: :default, :dark, :high_contrast.

default()

@spec default() :: t()

The default theme. Minimal, terminal-native colors; its output is pinned byte-for-byte by a golden-frame test so it does not drift between releases. :primary is the default style for menu, tree and a select's open list; :accent, :muted and :error are for apps, via get/1.

get(token)

@spec get(token()) :: Harlock.Render.Style.t()

Look up a theme token. Returns the value from the theme installed by the runtime, or the default if no theme is in scope.