From 0c807b35017a785c35bfd9251b955748b0e049d1 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Wed, 23 Feb 2022 18:55:57 +0300 Subject: [PATCH] feat: sync color mode between browser tabs (#6723) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Lorber --- .../src/theme/Toggle/index.tsx | 6 +++- .../src/utils/colorModeUtils.tsx | 31 ++++++++++++------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/docusaurus-theme-classic/src/theme/Toggle/index.tsx b/packages/docusaurus-theme-classic/src/theme/Toggle/index.tsx index 67dbd3054e..4a554f088b 100644 --- a/packages/docusaurus-theme-classic/src/theme/Toggle/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Toggle/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useState, useRef, memo} from 'react'; +import React, {useState, useRef, useEffect, memo} from 'react'; import type {Props} from '@theme/Toggle'; import {useThemeConfig, type ColorModeConfig} from '@docusaurus/theme-common'; import useIsBrowser from '@docusaurus/useIsBrowser'; @@ -31,6 +31,10 @@ const ToggleComponent = memo( const [focused, setFocused] = useState(false); const inputRef = useRef(null); + useEffect(() => { + setChecked(defaultChecked); + }, [defaultChecked]); + return (
void; }; -const ThemeStorage = createStorageSlot('theme'); +const ThemeStorageKey = 'theme'; +const ThemeStorage = createStorageSlot(ThemeStorageKey); const themes = { light: 'light', @@ -45,7 +46,7 @@ const getInitialTheme = (defaultMode: Themes | undefined): Themes => { }; const storeTheme = (newTheme: Themes) => { - createStorageSlot('theme').set(coerceToTheme(newTheme)); + ThemeStorage.set(coerceToTheme(newTheme)); }; function useColorModeContextValue(): ColorModeContextValue { @@ -69,17 +70,25 @@ function useColorModeContextValue(): ColorModeContextValue { useEffect(() => { if (disableSwitch) { - return; + return undefined; } - - try { - const storedTheme = ThemeStorage.get(); - if (storedTheme !== null) { - setTheme(coerceToTheme(storedTheme)); + const onChange = (e: StorageEvent) => { + if (e.key !== ThemeStorageKey) { + return; } - } catch (err) { - console.error(err); - } + try { + const storedTheme = ThemeStorage.get(); + if (storedTheme !== null) { + setTheme(coerceToTheme(storedTheme)); + } + } catch (err) { + console.error(err); + } + }; + window.addEventListener('storage', onChange); + return () => { + window.removeEventListener('storage', onChange); + }; }, [disableSwitch, setTheme]); // PCS is coerced to light mode when printing, which causes the color mode to