Skip to content

Commit 87f8076

Browse files
liuyibianzone
authored andcommitted
style: optimize
1 parent 8b97c54 commit 87f8076

File tree

3 files changed

+29
-16
lines changed

3 files changed

+29
-16
lines changed

config/hooks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export const menus = [
3131
'useCounter',
3232
'useTextSelection',
3333
'useWebSocket',
34+
'useTheme',
3435
],
3536
},
3637
{

packages/hooks/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import useVirtualList from './useVirtualList';
7575
import useWebSocket from './useWebSocket';
7676
import useWhyDidYouUpdate from './useWhyDidYouUpdate';
7777
import useMutationObserver from './useMutationObserver';
78+
import useTheme from './useTheme';
7879

7980
export {
8081
useRequest,
@@ -156,4 +157,5 @@ export {
156157
useRafTimeout,
157158
useResetState,
158159
useMutationObserver,
160+
useTheme,
159161
};

packages/hooks/src/useTheme/index.ts

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,64 @@
11
import { useEffect, useState } from 'react';
22
import useMemoizedFn from '../useMemoizedFn';
33

4+
export enum ThemeMode {
5+
LIGHT = 'light',
6+
DARK = 'dark',
7+
SYSTEM = 'system',
8+
}
9+
10+
export type ThemeModeType = `${ThemeMode}`;
11+
412
const matchMedia = window.matchMedia('(prefers-color-scheme: dark)');
513

614
function useCurrentTheme() {
715
const [theme, setTheme] = useState<'light' | 'dark'>(() => {
8-
return matchMedia.matches ? 'dark' : 'light';
16+
return matchMedia.matches ? ThemeMode.DARK : ThemeMode.LIGHT;
917
});
1018

1119
useEffect(() => {
12-
// 监听系统颜色切换
13-
const listener: MediaQueryList['onchange'] = (event) => {
20+
const onThemeChange: MediaQueryList['onchange'] = (event) => {
1421
if (event.matches) {
15-
setTheme('dark');
22+
setTheme(ThemeMode.DARK);
1623
} else {
17-
setTheme('light');
24+
setTheme(ThemeMode.LIGHT);
1825
}
1926
};
2027

21-
matchMedia.addEventListener('change', listener);
28+
matchMedia.addEventListener('change', onThemeChange);
2229

2330
return () => {
24-
matchMedia.removeEventListener('change', listener);
31+
matchMedia.removeEventListener('change', onThemeChange);
2532
};
2633
}, []);
34+
2735
return theme;
2836
}
2937

30-
export type ThemeModeType = 'light' | 'dark' | 'system';
31-
32-
type PropsType = {
38+
type Options = {
3339
localStorageKey?: string;
3440
};
3541

36-
export function useTheme(props: PropsType = {}) {
37-
const { localStorageKey } = props;
42+
export default function useTheme(options: Options = {}) {
43+
const { localStorageKey } = options;
44+
3845
const [themeMode, setThemeMode] = useState<ThemeModeType>(() => {
3946
const preferredThemeMode =
4047
localStorageKey?.length && (localStorage.getItem(localStorageKey) as ThemeModeType | null);
41-
return preferredThemeMode ? preferredThemeMode : 'system';
48+
49+
return preferredThemeMode ? preferredThemeMode : ThemeMode.SYSTEM;
4250
});
4351

4452
const setThemeModeWithLocalStorage = (mode: ThemeModeType) => {
4553
setThemeMode(mode);
46-
localStorageKey?.length && localStorage.setItem(localStorageKey, mode);
54+
55+
if (localStorageKey?.length) {
56+
localStorage.setItem(localStorageKey, mode);
57+
}
4758
};
4859

4960
const currentTheme = useCurrentTheme();
50-
51-
const theme = themeMode === 'system' ? currentTheme : themeMode;
61+
const theme = themeMode === ThemeMode.SYSTEM ? currentTheme : themeMode;
5262

5363
return {
5464
theme,

0 commit comments

Comments
 (0)