fix(editor): the editor color scheme follows a switch between light and dark themes (#1100)

Switching the IDE theme kept an explicitly chosen editor color scheme, so a light theme could keep a dark editor. When the applied theme turns light or dark, a chosen scheme of the other kind now switches back to the theme's own; a scheme picked to go with the current theme is kept. Reacts to the applied theme, so Quick Switch, Settings, Welcome › Customize, other windows and Sync with OS are all covered.
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-11-04 04:31:59 +08:00
1 джерело 1ed9275da0
коміт e575bf8c24
3 files changed
+83 -4

No files matched your search

+34 -1
Переглянути файл
@@ -1,6 +1,6 @@
import { readFileSync } from "node:fs";
import { beforeAll, describe, expect, it } from "vitest";
import { _setSchemeSource, schemeCss, schemeTokens } from "./colorScheme";
import { _setSchemeSource, schemeAfterThemeChange, schemeCss, schemeTokens } from "./colorScheme";
import { fontWeightVars, validateEditorExtras } from "./editorSettings";
import type { Settings } from "./ipc";
import { useProject } from "./project";
@@ -66,6 +66,39 @@ describe("color schemes", () => {
}
});
it("switches a chosen scheme of the other kind back to the theme's own when the theme turns light or dark", async () => {
expect(schemeAfterThemeChange("one-dark", "light")).toBe("theme-default");
expect(schemeAfterThemeChange("solarized-light", "light")).toBeNull();
expect(schemeAfterThemeChange("theme-default", "light")).toBeNull();
const customs = { "custom-night": { name: "Night", parent: "dark" as const, attributes: {} } };
expect(schemeAfterThemeChange("custom-night", "light", customs)).toBe("theme-default");
expect(schemeAfterThemeChange("custom-night", "dark", customs)).toBeNull();
const root = document.documentElement;
root.dataset.theme = "dark";
const previous = useProject.getState().settings;
const scheme = () => useProject.getState().settings?.editor?.colorScheme;
useProject.setState({ settings: { editor: { colorScheme: "one-dark" } } as unknown as Settings });
const dispose = installColorScheme();
try {
root.dataset.theme = "light";
await Promise.resolve();
expect(scheme()).toBe("theme-default");
// A dark scheme chosen under the light theme stays until the theme changes again.
useProject.setState({ settings: { editor: { colorScheme: "dark" } } as unknown as Settings });
root.dataset.colorTheme = "solarized-light";
await Promise.resolve();
expect(scheme()).toBe("dark");
root.dataset.theme = "dark";
await Promise.resolve();
expect(scheme()).toBe("dark");
} finally {
dispose();
delete root.dataset.colorTheme;
useProject.setState({ settings: previous });
}
});
it("keeps editor weights out of the schemes", () => {
for (const id of ["light", "dark", "dark-hc"] as const) {
expect(schemeTokens(id).has("--fw-code")).toBe(false);
+19
Переглянути файл
@@ -259,6 +259,25 @@ export function effectiveScheme(
return themeScheme(root);
}
/** Light or dark: a built-in scheme's theme kind, a custom scheme's parent (null: unknown). */
export function schemeKind(id: string | undefined, customs: CustomColorSchemes = {}): "light" | "dark" | null {
if (isBuiltinTheme(id)) return themeKind(id);
return (id && customSchemes(customs)[id]?.parent) || null;
}
/**
* The scheme setting once the IDE theme has turned `kind`, or null to keep it: a chosen scheme
* of the other kind gives way to the theme's own, so a light theme doesn't keep a dark editor.
*/
export function schemeAfterThemeChange(
setting: string | undefined,
kind: "light" | "dark",
customs: CustomColorSchemes = {},
): string | null {
const current = schemeKind(setting, customs);
return current && current !== kind ? "theme-default" : null;
}
/** Scheme belonging to the active IDE theme (`data-theme` / `data-contrast`). */
export function themeScheme(
root: HTMLElement | null = typeof document !== "undefined" ? document.documentElement : null,