Add admin HK color customization fields to theme editor
Local Build and Deploy / deploy (push) Successful in 58s

- Add 6 new admin color DB keys (admin_canvas, admin_surface, admin_text,
  admin_text_muted, admin_border, admin_sidebar_bg) that override the
  derived admin palette
- Extract adminPaletteCss() from themePaletteCss() for reuse
- Generate admin CSS variables in both :root and html.dark with overrides
- Persist admin color settings via saveTheme action
- Add Admin panel (HK) section to /admin/theme with color pickers
This commit is contained in:
openhands committed 2026-07-13 19:49:19 +02:00
1 parent 4dcf6fdce8
commit a16d9859e8
5 files changed
+134 -57

No files matched your search

+32 -23
View File
@@ -27,36 +27,45 @@ export interface AdminPalette {
focusRing: string;
}
export function deriveAdminPalette(colors: PublicThemeColors): AdminPalette {
const publicBackground = colors.color_background ?? "#f8fafc";
const blackRatio = contrastRatio("#000000", publicBackground) ?? 21;
const whiteRatio = contrastRatio("#ffffff", publicBackground) ?? 1;
const dark = whiteRatio > blackRatio;
const canvas = dark ? "#0b0f19" : "#f1f5f9";
const surface = dark ? "#151b27" : "#ffffff";
const surfaceElevated = dark ? "#1e2635" : "#f8fafc";
const text = dark ? "#f8fafc" : "#0f172a";
const muted = dark ? "#a8b3c7" : "#475569";
export function deriveAdminPalette(
colors: PublicThemeColors,
overrides?: Partial<AdminPalette>,
): AdminPalette {
const accent = colors.color_primary ?? "#f59e0b";
return {
canvas,
surface,
surfaceElevated,
text: readableColor(text, [canvas, surface, surfaceElevated]),
muted: readableColor(muted, [canvas, surface, surfaceElevated]),
border: dark ? "#334155" : "#cbd5e1",
const defaults: AdminPalette = {
canvas: "#0b0f19",
surface: "#151b27",
surfaceElevated: "#1e2635",
text: "#f8fafc",
muted: "#94a3b8",
border: "#2a3448",
accent,
accentText: readableColor(accent, [canvas, surface, surfaceElevated]),
accentText: readableColor(accent, ["#0b0f19", "#151b27", "#1e2635"]),
accentForeground: readableColor("#ffffff", [accent]),
success: dark ? "#4ade80" : "#15803d",
warning: dark ? "#facc15" : "#a16207",
error: dark ? "#f87171" : "#b91c1c",
info: dark ? "#38bdf8" : "#0369a1",
sidebar: dark ? "#101622" : "#172033",
success: "#22c55e",
warning: "#eab308",
error: "#ef4444",
info: "#3b82f6",
sidebar: "#080c18",
sidebarText: "#f8fafc",
overlay: "rgba(2, 6, 23, 0.72)",
focusRing: accent,
};
if (!overrides) return defaults;
return {
...defaults,
...overrides,
accent,
accentText: readableColor(accent, [overrides.canvas ?? defaults.canvas, overrides.surface ?? defaults.surface, overrides.surfaceElevated ?? defaults.surfaceElevated]),
accentForeground: readableColor("#ffffff", [accent]),
success: overrides.success ?? defaults.success,
warning: overrides.warning ?? defaults.warning,
error: overrides.error ?? defaults.error,
info: overrides.info ?? defaults.info,
sidebarText: readableColor(overrides.sidebar ?? defaults.sidebar, [overrides.canvas ?? defaults.canvas, overrides.surface ?? defaults.surface]),
overlay: defaults.overlay,
focusRing: accent,
};
}
export function derivePublicForegrounds(c: PublicThemeColors) {