tui: settings — theme picker (color schemes) #145

Closed
opened 2026-04-14 20:14:16 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As a user with strong preferences about terminal colors, I want to pick from a small set of curated color themes (and persist the choice), so that the TUI matches my terminal palette.

Background

The Settings → Appearance section currently has a single boolean (canvas_inertia). The TUI uses hardcoded Color::Cyan, Color::DarkGray, etc. throughout. Centralising these into a theme struct unlocks future per-theme styling.

Acceptance criteria

Theme model

  • New Theme struct in loom-tui/src/theme.rs with named slots: accent, border_focus, border_idle, selection_bg, selection_fg, placeholder, error, success, warn, info
  • Built-in themes: default-dark, tokyo-night, gruvbox, nord, solarized-dark, monochrome
  • Themes loaded statically (no external files for v1)
  • Settings → Appearance gains a "theme" field (combobox via existing string_picker)

Wire-through

  • All hardcoded Color::Cyan/etc. in screens replaced with ctx.theme().accent / ctx.theme().border_focus / etc.
  • AppCtx gains theme: Arc<Theme> populated from settings
  • Reload theme on LoomEvent::SettingsChanged (already wired)

Persistence

  • Theme name stored as appearance.theme: String in AppSettings

Tests

  • Unit: switching theme name swaps the Color slots
  • Unit: unknown theme name falls back to default-dark with a tracing warn

Out of scope

  • User-defined themes via TOML files (v2)
  • Per-screen overrides
  • Light themes (terminal usage is overwhelmingly dark)

References

  • crates/loom-tui/src/screens/*.rs (hardcoded Color::* references)
  • crates/loom-core/src/models/settings.rs (AppSettings::canvas_inertia)
## User story As a user with strong preferences about terminal colors, I want to pick from a small set of curated color themes (and persist the choice), so that the TUI matches my terminal palette. ## Background The Settings → Appearance section currently has a single boolean (`canvas_inertia`). The TUI uses hardcoded `Color::Cyan`, `Color::DarkGray`, etc. throughout. Centralising these into a theme struct unlocks future per-theme styling. ## Acceptance criteria ### Theme model - [ ] New `Theme` struct in `loom-tui/src/theme.rs` with named slots: `accent`, `border_focus`, `border_idle`, `selection_bg`, `selection_fg`, `placeholder`, `error`, `success`, `warn`, `info` - [ ] Built-in themes: `default-dark`, `tokyo-night`, `gruvbox`, `nord`, `solarized-dark`, `monochrome` - [ ] Themes loaded statically (no external files for v1) - [ ] Settings → Appearance gains a "theme" field (combobox via existing `string_picker`) ### Wire-through - [ ] All hardcoded `Color::Cyan`/etc. in screens replaced with `ctx.theme().accent` / `ctx.theme().border_focus` / etc. - [ ] `AppCtx` gains `theme: Arc<Theme>` populated from settings - [ ] Reload theme on `LoomEvent::SettingsChanged` (already wired) ### Persistence - [ ] Theme name stored as `appearance.theme: String` in `AppSettings` ### Tests - [ ] Unit: switching theme name swaps the `Color` slots - [ ] Unit: unknown theme name falls back to `default-dark` with a tracing warn ## Out of scope - User-defined themes via TOML files (v2) - Per-screen overrides - Light themes (terminal usage is overwhelmingly dark) ## References - `crates/loom-tui/src/screens/*.rs` (hardcoded `Color::*` references) - `crates/loom-core/src/models/settings.rs` (`AppSettings::canvas_inertia`)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/loom#145
No description provided.