样式修改

This commit is contained in:
董宏凯 committed 2026-05-22 15:26:20 +08:00
1 parent 284445e0c9
commit ab6b6876aa
4 files changed
+84 -47

No files matched your search

+59 -24
View File
@@ -1,4 +1,10 @@
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import React, {
createContext,
useContext,
useEffect,
useState,
type ReactNode,
} from 'react';
import { useTheme as useNextTheme } from 'next-themes';
// 主题类型
@@ -76,12 +82,24 @@ const themes: Record<ThemeType, ThemeConfig> = {
},
};
const STORAGE_KEY = 'strategy-theme';
function readPersistedTheme(): ThemeType {
if (typeof window === 'undefined') {
return 'dark';
}
const saved = localStorage.getItem(STORAGE_KEY);
return saved === 'light' ? 'light' : 'dark';
}
// 主题上下文
interface ThemeContextType {
theme: ThemeType;
themeConfig: ThemeConfig;
toggleTheme: () => void;
setTheme: (theme: ThemeType) => void;
/** next-themes 完成挂载前为 false,避免 hydration 与 DOM 不同步 */
mounted: boolean;
}
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
@@ -92,35 +110,52 @@ interface ThemeProviderProps {
}
export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
const { setTheme: setNextTheme } = useNextTheme();
const [theme, setThemeState] = useState<ThemeType>(() => {
// 从 localStorage 读取保存的主题
const saved = localStorage.getItem('strategy-theme');
return (saved as ThemeType) || 'dark';
});
const { resolvedTheme, setTheme: setNextTheme } = useNextTheme();
const [mounted, setMounted] = useState(false);
// 切换主题
const toggleTheme = () => {
setThemeState((prev) => (prev === 'dark' ? 'light' : 'dark'));
};
// 设置特定主题
const setTheme = (newTheme: ThemeType) => {
setThemeState(newTheme);
};
// 保存到 localStorage,并同步 html class 与 next-themes
useEffect(() => {
localStorage.setItem('strategy-theme', theme);
document.documentElement.classList.remove('dark', 'light');
document.documentElement.classList.add(theme);
setNextTheme(theme);
}, [theme, setNextTheme]);
setMounted(true);
}, []);
// 迁移 / 规范化 localStorage,避免与 next-themes 冲突导致闪回浅色
useEffect(() => {
if (!mounted) return;
const current = localStorage.getItem(STORAGE_KEY);
const legacy = localStorage.getItem('theme');
if (current !== 'light' && current !== 'dark') {
const fallback =
legacy === 'light' || legacy === 'dark' ? legacy : 'dark';
setNextTheme(fallback);
} else if (!current && legacy && (legacy === 'light' || legacy === 'dark')) {
setNextTheme(legacy);
}
if (legacy) {
localStorage.removeItem('theme');
}
}, [mounted, setNextTheme]);
const theme: ThemeType = mounted
? resolvedTheme === 'light'
? 'light'
: 'dark'
: readPersistedTheme();
const toggleTheme = () => {
setNextTheme(theme === 'dark' ? 'light' : 'dark');
};
const setTheme = (newTheme: ThemeType) => {
setNextTheme(newTheme);
};
const themeConfig = themes[theme];
return (
<ThemeContext.Provider value={{ theme, themeConfig, toggleTheme, setTheme }}>
<ThemeContext.Provider
value={{ theme, themeConfig, toggleTheme, setTheme, mounted }}
>
{children}
</ThemeContext.Provider>
);