Skip to content

Add dashboard GUI for customizing theme colors #520

Description

@aebrer

Original Request

add a custom theme option to customize theme elements with a GUI

Summary

The dashboard's theme gallery offers eight curated themes, but their colors are hard-coded in CSS and cannot be modified. This issue adds a theme editor to the dashboard: edit the 17 colors of any theme's light and dark variants, create new custom themes, pick colors with a web color picker or hex input, and preview changes live. Changes default to browser-local storage; whether custom themes should instead live server-side (shared across browsers) is an open question to decide at assessment time.

Scope: dashboard only. The TUI theme system (terminal JSON themes) is out of scope.

Current Behavior

  • The dashboard theme gallery (packages/dashboard/src/client/components/theme-gallery.tsx) offers eight curated themes: entropist.ca (default), Dim, Solarized, Gruvbox, Caves of Qud, Van Gogh, Okabe-Ito, Paul Tol. Each theme is a family with a light and a dark variant.
  • Each variant defines 17 named colors: background, text, border, muted, four status colors (running, attention, idle, error), and nine syntax colors (comment, keyword, string, number, function, type, variable, operator, punctuation), plus one font per theme.
  • All palettes are hard-coded in packages/dashboard/src/client/styles/themes.css (private --<theme>-l-* / --<theme>-d-* properties mapped onto the public tokens --bg, --text, --border, --muted, --status-*, --syntax-*, --mono-font).
  • The chosen theme, color mode, and font persist in browser localStorage only (dreb.dashboard.theme, dreb.dashboard.colorMode, dreb.dashboard.font) — no server or RPC involvement.
  • There is no way to edit a theme's colors or add a new theme; no GUI for theme customization exists anywhere.

Proposed Behavior

  • A theme editor UI in the dashboard, alongside the existing theme gallery.
  • For any theme (curated or custom), edit all 17 palette colors of the light and dark variants using a web color picker and hex input.
  • Create new custom themes: name the theme, start from a copy of an existing theme, then edit its colors.
  • Live preview: while editing, the preview updates immediately; if the theme being edited is the active one, the page itself updates too.
  • Saving: browser-local by default (localStorage, consistent with the current appearance persistence). Server-side storage (shared across browsers/machines) is an open design question — see Open Questions.
  • Custom themes appear in the theme gallery alongside the curated themes and can be selected like any other theme.

Acceptance Criteria

  1. The dashboard's theme gallery includes a theme editor UI for customizing theme colors.
  2. For any theme (curated or custom), all 17 palette colors of the light and dark variants (background, text, border, muted, four status colors, nine syntax colors) can be edited via a web color picker or hex input. Invalid hex input is rejected with visible feedback (never silently written).
  3. The user can create a new custom theme by naming it and starting from a copy of an existing theme.
  4. Changing a color updates a live preview immediately, without saving.
  5. Edits and new themes persist across page reloads (in whichever storage location is chosen at assessment time).
  6. Custom themes appear in the theme gallery alongside the curated themes and can be selected.

Open Questions

  • Storage location: browser-local (default working assumption — matches the current per-browser model, no server involvement) vs. server-side (custom themes shared across all browsers/machines). To be decided at assessment time; the Technical Notes outline the implications of each option.

Context

  • packages/dashboard/src/client/components/theme-gallery.tsx — current gallery UI (self-contained preview cards via data-theme scoping)
  • packages/dashboard/src/client/state/appearance.ts — theme catalog, signals, localStorage persistence, cross-tab sync
  • packages/dashboard/src/client/styles/themes.css — curated palettes (17 colors per variant, light/dark mapping rules)
  • packages/dashboard/src/client/styles/tokens.css — baseline tokens (default theme)
  • Root README.md, dashboard section — documents the current curated gallery
  • The dashboard theme system is deliberately independent of the TUI theme system (terminal JSON themes with 51 color tokens — a separate system, out of scope here)

Technical Notes

  • Palette structure: each theme block in themes.css defines private --<theme>-l-* / --<theme>-d-* properties (17 each) and maps them onto the public tokens under [data-theme='x'] (light) and [data-theme='x'][data-color-mode='dark'] (dark). Edited values must flow through the same mapping so system/light/dark mode behavior is preserved.
  • Browser-local persistence (default): follow the existing state/appearance.ts pattern (guarded localStorage reads/writes, in-memory signal, cross-tab sync via storage events). Custom theme data (name + palettes) needs a new storage key plus a validation scheme.
  • If server-side is chosen at assessment time: the dashboard server needs endpoints to list/get/save custom themes; the fixed theme-catalog allowlist (with contract tests asserting sync between appearance.ts, the index.html bootstrap, and the themes.css scopes) must accommodate dynamic entries; also consider multi-user/multi-machine semantics and how curated themes stay editable-but-resettable.
  • Live preview: the gallery's preview cards already scope data-theme locally per card; an editor preview can reuse that mechanism with the edited palette applied inline.
  • The WCAG AA contrast notes in themes.css are authoring guidance; whether the editor enforces or merely reports contrast is a design decision.
  • Consideration (not a requirement): a way to reset an edited curated theme back to its original colors.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Nice to havedashboardDashboard server or clientenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions