diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 66d8048e7e..031ef59d08 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -21,6 +21,13 @@ const Home: NextPage = () => {
>
current theme mode :{mode}(click to change)
+
);
};
diff --git a/src/styles/themeProvider.tsx b/src/styles/themeProvider.tsx
index 27f94ca682..1aa488e380 100644
--- a/src/styles/themeProvider.tsx
+++ b/src/styles/themeProvider.tsx
@@ -3,11 +3,16 @@ import {
Global,
css,
} from '@emotion/react';
-import { createContext, useEffect, useRef, useState } from 'react';
+import { createContext, useEffect, useState } from 'react';
import type { PropsWithChildren } from 'react';
-import { ThemeMode, ThemeProviderProps, ThemeProviderValue } from './types';
+import {
+ Theme,
+ ThemeMode,
+ ThemeProviderProps,
+ ThemeProviderValue,
+} from './types';
import { lightTheme, darkTheme, globalThemeConstant } from './theme';
-import { SystemTheme, LocalStorageThemeMode } from '@/styles/utils';
+import { SystemTheme, localStorageThemeMode } from '@/styles/utils';
export const ThemeContext = createContext({
mode: 'light',
@@ -16,57 +21,53 @@ export const ThemeContext = createContext({
});
export const ThemeProvider = ({
- defaultThemeMode = 'light',
+ defaultTheme = 'light',
children,
}: PropsWithChildren) => {
- const { current: localStorageThemeMode } = useRef(
- new LocalStorageThemeMode()
- );
-
- const [mode, setMode] = useState(defaultThemeMode);
- const theme = mode === 'dark' ? darkTheme : lightTheme;
+ const [theme, setTheme] = useState(defaultTheme);
+ const [mode, setMode] = useState('auto');
+ const themeStyle = theme === 'light' ? lightTheme : darkTheme;
const changeMode = (themeMode: ThemeMode) => {
- setMode(themeMode);
+ themeMode !== mode && setMode(themeMode);
// Remember the theme mode which user selected for next time
localStorageThemeMode.set(themeMode);
};
useEffect(() => {
const systemTheme = new SystemTheme();
-
- // TODO: System theme mode and user theme mode which selected need to be prioritized
- // If user has selected a theme mode, use it
const selectedThemeMode = localStorageThemeMode.get();
- if (selectedThemeMode) {
- defaultThemeMode !== selectedThemeMode && setMode(selectedThemeMode);
+
+ const themeMode = selectedThemeMode || mode;
+ if (themeMode === 'auto') {
+ setTheme(systemTheme.get());
} else {
- // If user has not selected a theme mode, use system theme
- const systemThemeMode = systemTheme.get();
- defaultThemeMode !== systemThemeMode && setMode(systemThemeMode);
+ setTheme(themeMode);
}
// When system theme changed, change the theme mode
systemTheme.onChange(() => {
// TODO: There may be should be provided a way to let user choose whether to
- setMode(systemTheme.get());
+ if (mode === 'auto') {
+ setTheme(systemTheme.get());
+ }
});
return () => {
systemTheme.dispose();
};
- }, []);
+ }, [mode]);
return (
-
+
- {children}
+ {children}
);
};
diff --git a/src/styles/types.ts b/src/styles/types.ts
index ccfb39290a..95c5bba951 100644
--- a/src/styles/types.ts
+++ b/src/styles/types.ts
@@ -1,7 +1,8 @@
-export type ThemeMode = 'light' | 'dark';
+export type Theme = 'light' | 'dark';
+export type ThemeMode = Theme | 'auto';
export type ThemeProviderProps = {
- defaultThemeMode?: ThemeMode;
+ defaultTheme?: Theme;
};
export type ThemeProviderValue = {
diff --git a/src/styles/utils.ts b/src/styles/utils.ts
index bdc0ef8f18..dd04d4fb0b 100644
--- a/src/styles/utils.ts
+++ b/src/styles/utils.ts
@@ -1,4 +1,4 @@
-import { ThemeMode } from '@/styles/types';
+import { Theme, ThemeMode } from '@/styles/types';
export class SystemTheme {
media: MediaQueryList = window.matchMedia('(prefers-color-scheme: light)');
@@ -11,7 +11,7 @@ export class SystemTheme {
this.media.addEventListener('change', this.eventHandler);
}
- get = (): ThemeMode => {
+ get = (): Theme => {
if (typeof window === 'undefined') {
return 'light';
}
@@ -37,3 +37,5 @@ export class LocalStorageThemeMode {
localStorage.setItem(this.name, mode);
};
}
+
+export const localStorageThemeMode = new LocalStorageThemeMode();