ahooks
Version:
react hooks library
66 lines (65 loc) • 2.62 kB
JavaScript
import { useEffect, useState } from 'react';
import useMemoizedFn from '../useMemoizedFn';
import isBrowser from '../utils/isBrowser';
export var ThemeMode;
(function (ThemeMode) {
ThemeMode["LIGHT"] = "light";
ThemeMode["DARK"] = "dark";
ThemeMode["SYSTEM"] = "system";
})(ThemeMode || (ThemeMode = {}));
const useCurrentTheme = () => {
const matchMedia = isBrowser ? window.matchMedia('(prefers-color-scheme: dark)') : undefined;
const [theme, setTheme] = useState(() => {
if (isBrowser) {
return (matchMedia === null || matchMedia === void 0 ? void 0 : matchMedia.matches) ? ThemeMode.DARK : ThemeMode.LIGHT;
}
else {
return ThemeMode.LIGHT;
}
});
useEffect(() => {
const onThemeChange = (event) => {
if (event.matches) {
setTheme(ThemeMode.DARK);
}
else {
setTheme(ThemeMode.LIGHT);
}
};
if (matchMedia === null || matchMedia === void 0 ? void 0 : matchMedia.addEventListener) {
matchMedia.addEventListener('change', onThemeChange);
}
else if (matchMedia === null || matchMedia === void 0 ? void 0 : matchMedia.addListener) {
matchMedia.addListener(onThemeChange);
}
return () => {
if (matchMedia === null || matchMedia === void 0 ? void 0 : matchMedia.removeEventListener) {
matchMedia.removeEventListener('change', onThemeChange);
}
else if (matchMedia === null || matchMedia === void 0 ? void 0 : matchMedia.removeListener) {
matchMedia.removeListener(onThemeChange);
}
};
}, []);
return theme;
};
export default function useTheme(options = {}) {
const { localStorageKey } = options;
const [themeMode, setThemeMode] = useState(() => {
const preferredThemeMode = (localStorageKey === null || localStorageKey === void 0 ? void 0 : localStorageKey.length) && localStorage.getItem(localStorageKey);
return preferredThemeMode || ThemeMode.SYSTEM;
});
const setThemeModeWithLocalStorage = (mode) => {
setThemeMode(mode);
if (localStorageKey === null || localStorageKey === void 0 ? void 0 : localStorageKey.length) {
localStorage.setItem(localStorageKey, mode);
}
};
const currentTheme = useCurrentTheme();
const theme = themeMode === ThemeMode.SYSTEM ? currentTheme : themeMode;
return {
theme,
themeMode,
setThemeMode: useMemoizedFn(setThemeModeWithLocalStorage),
};
}