Themes

Themes provide semantic style tokens for templates, views, components, and layouts. Use theme tokens instead of hardcoded colors whenever possible.

Register Built-In Themes

Six themes ship with the framework: phosphor, catppuccin-mocha, catppuccin-latte, gruvbox-dark, nord, and tokyonight. Register the ones you want by name (or loop Charming::UI::Theme.built_in_names for all of them):

class MyApp::Application < Charming::Application
  theme :phosphor, built_in: "phosphor"
  theme :mocha, built_in: "catppuccin-mocha"
  theme :nord, built_in: "nord"

  default_theme :phosphor
end

Register Custom Themes

Register a custom JSON theme file with from::

class MyApp::Application < Charming::Application
  theme :custom, from: "config/themes/custom.json"
  default_theme :custom
end

Relative paths resolve from Application.root when set, otherwise from the current working directory.

Derive Themes

extends: builds a theme from an already-registered one, merging overrides: (token name → style spec) on top:

theme :base, built_in: "phosphor"
theme :high_contrast, extends: :base, overrides: {
  text: {foreground: "#ffffff", bold: true},
  title: {foreground: "#FFD75F", bold: true}
}

Override colors are literal (hex strings, named symbols, or 256-color indexes) — the parent’s palette names are resolved when the parent loads. Register the parent before extending it.

Color Capability

Themes are written in truecolor and degrade automatically. At boot, Charming::UI::ColorSupport classifies the terminal — NO_COLOR wins, then COLORTERM (truecolor/24bit), then TERM — into one of :truecolor, :color256, :color16, or :none. Hex colors downconvert to the nearest 256-color index or basic ANSI color as needed; at :none, color codes are omitted entirely (text attributes like bold survive).

Force a level when needed (tests pin :truecolor for stable output):

Charming::UI::ColorSupport.level = :color256
Charming::UI::ColorSupport.level = nil   # back to auto-detection

Use Theme Tokens

Theme tokens return Charming::UI::Style objects:

text "Welcome", style: theme.title
text "Status", style: theme.muted
text "Alert", style: theme.info

Default tokens:

Token Meaning
text Primary text
title Bright title text
muted Secondary text
border Border styling
selected Selected/focused item styling
info Informational accent
warn Warning accent

Tokens are style objects, so they can be chained:

theme.title.align(:center).width(40)
theme.border.border(:rounded).padding(1, 2)

Runtime Theme Switching

Switch themes from a controller with:

use_theme :phosphor

Generated apps expose a theme picker command:

command "Theme", :open_theme_palette

open_theme_palette opens a command-palette-like list of registered themes.

Theme JSON Shape

Theme JSON files contain a styles object and may contain a palette and background:

{
  "palette": {
    "cyan": "#00ffff"
  },
  "background": "#101820",
  "styles": {
    "title": { "foreground": "cyan", "bold": true },
    "muted": { "foreground": "#777777" },
    "border": { "foreground": "cyan" }
  }
}

Style options mirror Charming::UI::Style methods: foreground/background colors, text attributes, padding, border, width, height, and alignment.


This site uses Just the Docs, a documentation theme for Jekyll.