@@ -0,0 +1,40 @@
|
||||
/** 外观主题:浅色 / 深色 / 跟随系统。写到 html[data-theme] + localStorage,避免首屏闪白。 */
|
||||
|
||||
export type Appearance = "light" | "dark" | "system";
|
||||
|
||||
export const THEME_STORAGE_KEY = "yingqing-appearance";
|
||||
|
||||
export function normalizeAppearance(value: unknown): Appearance {
|
||||
if (value === "light" || value === "dark" || value === "system") return value;
|
||||
return "system";
|
||||
}
|
||||
|
||||
export function resolveTheme(appearance: Appearance): "light" | "dark" {
|
||||
if (appearance === "light" || appearance === "dark") return appearance;
|
||||
if (typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
return "dark";
|
||||
}
|
||||
return "light";
|
||||
}
|
||||
|
||||
export function applyTheme(appearance: Appearance | string | null | undefined) {
|
||||
if (typeof document === "undefined") return;
|
||||
const normalized = normalizeAppearance(appearance);
|
||||
const theme = resolveTheme(normalized);
|
||||
const root = document.documentElement;
|
||||
root.setAttribute("data-theme", theme);
|
||||
root.style.colorScheme = theme;
|
||||
try {
|
||||
localStorage.setItem(THEME_STORAGE_KEY, normalized);
|
||||
} catch {
|
||||
/* ignore quota / private mode */
|
||||
}
|
||||
}
|
||||
|
||||
export function readStoredAppearance(): Appearance {
|
||||
try {
|
||||
return normalizeAppearance(localStorage.getItem(THEME_STORAGE_KEY));
|
||||
} catch {
|
||||
return "system";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user