fix(web): sync data-seed-user-color-scheme so system dark-mode follows OS
This commit is contained in:
parent
6260cc3479
commit
2e391ce244
2 changed files with 29 additions and 1 deletions
|
|
@ -12,7 +12,14 @@ const THEME_INIT_SCRIPT = `
|
|||
try {
|
||||
var v = localStorage.getItem("mercury.theme");
|
||||
var mode = v === "light" ? "light-only" : v === "dark" ? "dark-only" : "system";
|
||||
document.documentElement.setAttribute("data-seed-color-mode", mode);
|
||||
var el = document.documentElement;
|
||||
el.setAttribute("data-seed-color-mode", mode);
|
||||
// Seed's "system" mode resolves dark ONLY when data-seed-user-color-scheme
|
||||
// reflects the OS preference — the CSS has no prefers-color-scheme media
|
||||
// query of its own. Sync it from matchMedia so "system" actually follows
|
||||
// the OS (light-only/dark-only ignore this attribute).
|
||||
var dark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
el.setAttribute("data-seed-user-color-scheme", dark ? "dark" : "light");
|
||||
} catch (e) {}
|
||||
})();
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -39,9 +39,19 @@ function persistTheme(theme: MercuryTheme): void {
|
|||
}
|
||||
}
|
||||
|
||||
/** Seed's "system" color-mode resolves dark only via data-seed-user-color-scheme
|
||||
* (there's no prefers-color-scheme media query in the tokens), so we sync it
|
||||
* from matchMedia. light-only/dark-only ignore this attribute. */
|
||||
function syncUserScheme(): void {
|
||||
if (typeof window === "undefined" || !window.matchMedia) return;
|
||||
const dark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
||||
document.documentElement.setAttribute("data-seed-user-color-scheme", dark ? "dark" : "light");
|
||||
}
|
||||
|
||||
function applyTheme(theme: MercuryTheme): void {
|
||||
if (typeof document === "undefined") return;
|
||||
document.documentElement.setAttribute("data-seed-color-mode", toColorMode(theme));
|
||||
syncUserScheme();
|
||||
}
|
||||
|
||||
export interface ThemeToggleProps {
|
||||
|
|
@ -60,6 +70,17 @@ export function ThemeToggle({ labels = DEFAULT_LABELS }: ThemeToggleProps) {
|
|||
// DOM before this ever mounts, so both agree from the first paint.
|
||||
const [theme, setTheme] = React.useState<MercuryTheme>(() => getStoredTheme());
|
||||
|
||||
// Keep data-seed-user-color-scheme synced to the OS so "system" mode follows
|
||||
// live OS light/dark changes without a reload.
|
||||
React.useEffect(() => {
|
||||
if (typeof window === "undefined" || !window.matchMedia) return;
|
||||
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
syncUserScheme();
|
||||
const onChange = () => syncUserScheme();
|
||||
mq.addEventListener?.("change", onChange);
|
||||
return () => mq.removeEventListener?.("change", onChange);
|
||||
}, []);
|
||||
|
||||
function handleChange(next: string) {
|
||||
const nextTheme = next as MercuryTheme;
|
||||
setTheme(nextTheme);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue