themeSlice.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import { createSlice, PayloadAction } from '@reduxjs/toolkit';
  2. import { lightTheme, darkTheme } from '../themes';
  3. // 定义主题类型
  4. export type ThemeType = 'light' | 'dark';
  5. // 定义主题配置类型
  6. export type ThemeConfig = typeof lightTheme;
  7. interface ThemeState {
  8. themeType: ThemeType;
  9. currentTheme: ThemeConfig;
  10. }
  11. // 从 localStorage 读取保存的主题,默认为 dark
  12. const getSavedTheme = (): ThemeType => {
  13. try {
  14. const saved = localStorage.getItem('app-theme');
  15. return saved === 'light' ? 'light' : 'dark';
  16. } catch {
  17. return 'dark';
  18. }
  19. };
  20. const initialThemeType = getSavedTheme();
  21. const initialState: ThemeState = {
  22. themeType: initialThemeType,
  23. currentTheme: initialThemeType === 'light' ? lightTheme : darkTheme,
  24. };
  25. const themeSlice = createSlice({
  26. name: 'theme',
  27. initialState,
  28. reducers: {
  29. setTheme: (state, action: PayloadAction<ThemeType>) => {
  30. const themeType = action.payload;
  31. state.themeType = themeType;
  32. state.currentTheme = themeType === 'light' ? lightTheme : darkTheme;
  33. // 保存到 localStorage
  34. try {
  35. localStorage.setItem('app-theme', themeType);
  36. } catch (error) {
  37. console.error('Failed to save theme to localStorage:', error);
  38. }
  39. },
  40. toggleTheme: (state) => {
  41. const newThemeType = state.themeType === 'light' ? 'dark' : 'light';
  42. state.themeType = newThemeType;
  43. state.currentTheme = newThemeType === 'light' ? lightTheme : darkTheme;
  44. // 保存到 localStorage
  45. try {
  46. localStorage.setItem('app-theme', newThemeType);
  47. } catch (error) {
  48. console.error('Failed to save theme to localStorage:', error);
  49. }
  50. },
  51. },
  52. });
  53. export const { setTheme, toggleTheme } = themeSlice.actions;
  54. export default themeSlice.reducer;