fix: Theme override does not persist between navigations (#11176)

This commit is contained in:
Tom Moor
2026-01-13 19:30:58 -05:00
committed by GitHub
parent 1675c42364
commit d2c70ea5fa
3 changed files with 39 additions and 4 deletions
@@ -10,7 +10,12 @@ import { Theme } from "~/stores/UiStore";
export const AppearanceAction = observer(() => {
const { t } = useTranslation();
const { ui } = useStores();
const { resolvedTheme } = ui;
const { resolvedTheme, themeOverride } = ui;
// Hide when theme is locked via query parameter
if (themeOverride) {
return null;
}
return (
<Action>
+14 -3
View File
@@ -1,4 +1,4 @@
import { useMemo } from "react";
import { useEffect, useMemo } from "react";
import { breakpoints } from "@shared/styles";
import {
buildDarkTheme,
@@ -6,7 +6,7 @@ import {
buildPitchBlackTheme,
} from "@shared/styles/theme";
import type { CustomTheme } from "@shared/types";
import type { Theme } from "~/stores/UiStore";
import { Theme } from "~/stores/UiStore";
import useMediaQuery from "~/hooks/useMediaQuery";
import useStores from "./useStores";
import useQuery from "./useQuery";
@@ -28,7 +28,18 @@ export default function useBuildTheme(
const isMobile = useMediaQuery(`(max-width: ${breakpoints.tablet}px)`);
const isPrinting = useMediaQuery("print");
const queryTheme = (params.get("theme") as Theme) || undefined;
const resolvedTheme = overrideTheme ?? queryTheme ?? ui.resolvedTheme;
// Store the theme override in UiStore so it persists during navigation
useEffect(() => {
if (
queryTheme &&
(queryTheme === Theme.Light || queryTheme === Theme.Dark)
) {
ui.setThemeOverride(queryTheme);
}
}, [queryTheme, ui]);
const resolvedTheme = overrideTheme ?? ui.resolvedTheme;
const theme = useMemo(
() =>
+19
View File
@@ -43,6 +43,10 @@ class UiStore {
@observable
theme: Theme;
// themeOverride is set when a theme query parameter is detected, persists for the session
@observable
themeOverride: Theme | undefined;
// systemTheme represents the system UI theme (Settings -> General in macOS)
@observable
systemTheme: SystemTheme;
@@ -156,6 +160,17 @@ class UiStore {
});
};
/**
* Set a theme override from a query parameter. This persists for the session
* but is not saved to localStorage.
*
* @param theme The theme to override with, or undefined to clear.
*/
@action
setThemeOverride = (theme: Theme | undefined) => {
this.themeOverride = theme;
};
@action
setActiveDocument = (document: Document | string): void => {
if (typeof document === "string") {
@@ -300,6 +315,10 @@ class UiStore {
@computed
get resolvedTheme(): Theme | SystemTheme {
if (this.themeOverride) {
return this.themeOverride;
}
if (this.theme === "system") {
return this.systemTheme;
}