feat(dashboard): add terminalBackground field to DashboardTheme
Wires the xterm.js terminal pane background color into the theme system. Previously hardcoded as #0d2626; now reads from DashboardTheme.terminalBackground with #000000 as default. Users can override via ~/.hermes/dashboard-themes/*.yaml: terminalBackground: "#1a0a2e"
This commit is contained in:
@@ -36,6 +36,7 @@ import { usePageHeader } from "@/contexts/usePageHeader";
|
||||
import { useI18n } from "@/i18n";
|
||||
import { api } from "@/lib/api";
|
||||
import { PluginSlot } from "@/plugins";
|
||||
import { useTheme } from "@/themes";
|
||||
|
||||
function buildWsUrl(
|
||||
authParam: [string, string],
|
||||
@@ -66,8 +67,9 @@ function generateChannelId(): string {
|
||||
// with cream foreground — we intentionally don't pick monokai or a loud
|
||||
// theme, because the TUI's skin engine already paints the content; the
|
||||
// terminal chrome just needs to sit quietly inside the dashboard.
|
||||
const TERMINAL_THEME = {
|
||||
background: "#0d2626",
|
||||
// `background` is omitted here — it's supplied dynamically from the active
|
||||
// theme's `terminalBackground` field so users can control it via YAML themes.
|
||||
const TERMINAL_THEME_STATIC = {
|
||||
foreground: "#f0e6d2",
|
||||
cursor: "#f0e6d2",
|
||||
cursorAccent: "#0d2626",
|
||||
@@ -157,6 +159,13 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
|
||||
: false,
|
||||
);
|
||||
|
||||
const { theme } = useTheme();
|
||||
const terminalBg = theme.terminalBackground ?? "#000000";
|
||||
const terminalTheme = useMemo(
|
||||
() => ({ ...TERMINAL_THEME_STATIC, background: terminalBg }),
|
||||
[terminalBg],
|
||||
);
|
||||
|
||||
// The dashboard keeps ChatPage mounted persistently so the PTY survives tab
|
||||
// switches. That is great for ordinary /chat navigation, but it means query
|
||||
// param changes do NOT remount the component. Resume-in-chat from the
|
||||
@@ -312,7 +321,7 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
|
||||
// Browser-embedded chat runs the TUI in inline mode. Keep transcript
|
||||
// history in xterm.js so the browser wheel can scroll it directly.
|
||||
scrollback: 5000,
|
||||
theme: TERMINAL_THEME,
|
||||
theme: terminalTheme,
|
||||
});
|
||||
termRef.current = term;
|
||||
|
||||
@@ -721,6 +730,14 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
|
||||
};
|
||||
}, [isActive]);
|
||||
|
||||
// Keep the live xterm theme in sync when the active theme's terminal
|
||||
// background changes (e.g. user switches to a custom YAML theme mid-session).
|
||||
useEffect(() => {
|
||||
const term = termRef.current;
|
||||
if (!term) return;
|
||||
term.options.theme = { ...TERMINAL_THEME_STATIC, background: terminalBg };
|
||||
}, [terminalBg]);
|
||||
|
||||
// Layout:
|
||||
// outer flex column — sits inside the dashboard's content area
|
||||
// row split — terminal pane (flex-1) + sidebar (fixed width, lg+)
|
||||
@@ -828,7 +845,7 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
|
||||
"p-2 sm:p-3",
|
||||
)}
|
||||
style={{
|
||||
backgroundColor: TERMINAL_THEME.background,
|
||||
backgroundColor: terminalBg,
|
||||
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
|
||||
}}
|
||||
>
|
||||
@@ -852,7 +869,7 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
|
||||
"bottom-2 right-2 px-2 py-1 text-xs sm:bottom-3 sm:right-3 sm:px-2.5 sm:py-1.5",
|
||||
"lg:bottom-4 lg:right-4",
|
||||
)}
|
||||
style={{ color: TERMINAL_THEME.foreground }}
|
||||
style={{ color: TERMINAL_THEME_STATIC.foreground }}
|
||||
>
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
<Copy className="h-3 w-3 shrink-0" />
|
||||
|
||||
@@ -297,6 +297,12 @@ function applyTheme(theme: DashboardTheme) {
|
||||
injectFontStylesheet(theme.typography.fontUrl);
|
||||
applyCustomCSS(theme.customCSS);
|
||||
applyLayoutVariant(theme.layoutVariant);
|
||||
|
||||
// Terminal background — read by ChatPage via useTheme(); also available as CSS var.
|
||||
root.style.setProperty(
|
||||
"--theme-terminal-background",
|
||||
theme.terminalBackground ?? "#0d2626",
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -51,6 +51,7 @@ export const defaultTheme: DashboardTheme = {
|
||||
},
|
||||
typography: DEFAULT_TYPOGRAPHY,
|
||||
layout: DEFAULT_LAYOUT,
|
||||
terminalBackground: "#000000",
|
||||
};
|
||||
|
||||
export const midnightTheme: DashboardTheme = {
|
||||
|
||||
@@ -162,6 +162,9 @@ export interface DashboardTheme {
|
||||
/** Per-component CSS-var overrides. See `ThemeComponentStyles`. */
|
||||
componentStyles?: ThemeComponentStyles;
|
||||
colorOverrides?: ThemeColorOverrides;
|
||||
/** Background color for the embedded terminal pane (xterm.js).
|
||||
* Hex string. Defaults to `"#0d2626"` when absent. */
|
||||
terminalBackground?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user