fix(theme-common): do not persist color mode for OS-triggered changes (#7200)

* fix(theme-common): do not persist color mode if switch is disabled

* New setColorMode(null) API

* reset to default without RPCS
This commit is contained in:
Joshua Chen 2022-04-21 23:29:08 +08:00 committed by GitHub
parent 71ba449a28
commit 1412441987
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -65,10 +65,39 @@ function useContextValue(): ContextValue {
getInitialColorMode(defaultMode), getInitialColorMode(defaultMode),
); );
const setColorMode = useCallback((newColorMode: ColorMode) => { useEffect(() => {
setColorModeState(newColorMode); // A site is deployed without disableSwitch
storeColorMode(newColorMode); // => User visits the site and has a persisted value
}, []); // => Site later enabled disableSwitch
// => Clear the previously stored value to apply the site's setting
if (disableSwitch) {
ColorModeStorage.del();
}
}, [disableSwitch]);
const setColorMode = useCallback(
(newColorMode: ColorMode | null, options: {persist?: boolean} = {}) => {
const {persist = true} = options;
if (newColorMode) {
setColorModeState(newColorMode);
if (persist) {
storeColorMode(newColorMode);
}
} else {
if (respectPrefersColorScheme) {
setColorModeState(
window.matchMedia('(prefers-color-scheme: dark)').matches
? ColorModes.dark
: ColorModes.light,
);
} else {
setColorModeState(defaultMode);
}
ColorModeStorage.del();
}
},
[respectPrefersColorScheme, defaultMode],
);
useEffect(() => { useEffect(() => {
document.documentElement.setAttribute( document.documentElement.setAttribute(
@ -85,13 +114,9 @@ function useContextValue(): ContextValue {
if (e.key !== ColorModeStorageKey) { if (e.key !== ColorModeStorageKey) {
return; return;
} }
try { const storedColorMode = ColorModeStorage.get();
const storedColorMode = ColorModeStorage.get(); if (storedColorMode !== null) {
if (storedColorMode !== null) { setColorMode(coerceToColorMode(storedColorMode));
setColorMode(coerceToColorMode(storedColorMode));
}
} catch (err) {
console.error(err);
} }
}; };
window.addEventListener('storage', onChange); window.addEventListener('storage', onChange);
@ -109,12 +134,12 @@ function useContextValue(): ContextValue {
return undefined; return undefined;
} }
const mql = window.matchMedia('(prefers-color-scheme: dark)'); const mql = window.matchMedia('(prefers-color-scheme: dark)');
const onChange = ({matches}: MediaQueryListEvent) => { const onChange = () => {
if (window.matchMedia('print').matches || previousMediaIsPrint.current) { if (window.matchMedia('print').matches || previousMediaIsPrint.current) {
previousMediaIsPrint.current = window.matchMedia('print').matches; previousMediaIsPrint.current = window.matchMedia('print').matches;
return; return;
} }
setColorMode(matches ? ColorModes.dark : ColorModes.light); setColorMode(null);
}; };
mql.addListener(onChange); mql.addListener(onChange);
return () => mql.removeListener(onChange); return () => mql.removeListener(onChange);
@ -139,7 +164,6 @@ function useContextValue(): ContextValue {
); );
} }
setColorMode(ColorModes.light); setColorMode(ColorModes.light);
storeColorMode(ColorModes.light);
}, },
setDarkTheme() { setDarkTheme() {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
@ -148,7 +172,6 @@ function useContextValue(): ContextValue {
); );
} }
setColorMode(ColorModes.dark); setColorMode(ColorModes.dark);
storeColorMode(ColorModes.dark);
}, },
}), }),
[colorMode, setColorMode], [colorMode, setColorMode],