From 14124419874987cde7618dbb71b62c991e69f998 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Thu, 21 Apr 2022 23:29:08 +0800 Subject: [PATCH] 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 --- .../src/contexts/colorMode.tsx | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/packages/docusaurus-theme-common/src/contexts/colorMode.tsx b/packages/docusaurus-theme-common/src/contexts/colorMode.tsx index ee7d4eb54f54..a2347f1c0141 100644 --- a/packages/docusaurus-theme-common/src/contexts/colorMode.tsx +++ b/packages/docusaurus-theme-common/src/contexts/colorMode.tsx @@ -65,10 +65,39 @@ function useContextValue(): ContextValue { getInitialColorMode(defaultMode), ); - const setColorMode = useCallback((newColorMode: ColorMode) => { - setColorModeState(newColorMode); - storeColorMode(newColorMode); - }, []); + useEffect(() => { + // A site is deployed without disableSwitch + // => 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(() => { document.documentElement.setAttribute( @@ -85,13 +114,9 @@ function useContextValue(): ContextValue { if (e.key !== ColorModeStorageKey) { return; } - try { - const storedColorMode = ColorModeStorage.get(); - if (storedColorMode !== null) { - setColorMode(coerceToColorMode(storedColorMode)); - } - } catch (err) { - console.error(err); + const storedColorMode = ColorModeStorage.get(); + if (storedColorMode !== null) { + setColorMode(coerceToColorMode(storedColorMode)); } }; window.addEventListener('storage', onChange); @@ -109,12 +134,12 @@ function useContextValue(): ContextValue { return undefined; } const mql = window.matchMedia('(prefers-color-scheme: dark)'); - const onChange = ({matches}: MediaQueryListEvent) => { + const onChange = () => { if (window.matchMedia('print').matches || previousMediaIsPrint.current) { previousMediaIsPrint.current = window.matchMedia('print').matches; return; } - setColorMode(matches ? ColorModes.dark : ColorModes.light); + setColorMode(null); }; mql.addListener(onChange); return () => mql.removeListener(onChange); @@ -139,7 +164,6 @@ function useContextValue(): ContextValue { ); } setColorMode(ColorModes.light); - storeColorMode(ColorModes.light); }, setDarkTheme() { if (process.env.NODE_ENV === 'development') { @@ -148,7 +172,6 @@ function useContextValue(): ContextValue { ); } setColorMode(ColorModes.dark); - storeColorMode(ColorModes.dark); }, }), [colorMode, setColorMode],