mirror of
https://github.com/facebook/docusaurus.git
synced 2025-07-25 12:38:57 +02:00
feat: sync color mode between browser tabs (#6723)
Co-authored-by: Sébastien Lorber <slorber@users.noreply.github.com>
This commit is contained in:
parent
26d223dbeb
commit
0c807b3501
2 changed files with 25 additions and 12 deletions
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* 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 type {Props} from '@theme/Toggle';
|
||||||
import {useThemeConfig, type ColorModeConfig} from '@docusaurus/theme-common';
|
import {useThemeConfig, type ColorModeConfig} from '@docusaurus/theme-common';
|
||||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||||
|
@ -31,6 +31,10 @@ const ToggleComponent = memo(
|
||||||
const [focused, setFocused] = useState(false);
|
const [focused, setFocused] = useState(false);
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setChecked(defaultChecked);
|
||||||
|
}, [defaultChecked]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={clsx(styles.toggle, className, {
|
className={clsx(styles.toggle, className, {
|
||||||
|
|
|
@ -24,7 +24,8 @@ type ColorModeContextValue = {
|
||||||
readonly setDarkTheme: () => void;
|
readonly setDarkTheme: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ThemeStorage = createStorageSlot('theme');
|
const ThemeStorageKey = 'theme';
|
||||||
|
const ThemeStorage = createStorageSlot(ThemeStorageKey);
|
||||||
|
|
||||||
const themes = {
|
const themes = {
|
||||||
light: 'light',
|
light: 'light',
|
||||||
|
@ -45,7 +46,7 @@ const getInitialTheme = (defaultMode: Themes | undefined): Themes => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const storeTheme = (newTheme: Themes) => {
|
const storeTheme = (newTheme: Themes) => {
|
||||||
createStorageSlot('theme').set(coerceToTheme(newTheme));
|
ThemeStorage.set(coerceToTheme(newTheme));
|
||||||
};
|
};
|
||||||
|
|
||||||
function useColorModeContextValue(): ColorModeContextValue {
|
function useColorModeContextValue(): ColorModeContextValue {
|
||||||
|
@ -69,17 +70,25 @@ function useColorModeContextValue(): ColorModeContextValue {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (disableSwitch) {
|
if (disableSwitch) {
|
||||||
return;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
const onChange = (e: StorageEvent) => {
|
||||||
try {
|
if (e.key !== ThemeStorageKey) {
|
||||||
const storedTheme = ThemeStorage.get();
|
return;
|
||||||
if (storedTheme !== null) {
|
|
||||||
setTheme(coerceToTheme(storedTheme));
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
try {
|
||||||
console.error(err);
|
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]);
|
}, [disableSwitch, setTheme]);
|
||||||
|
|
||||||
// PCS is coerced to light mode when printing, which causes the color mode to
|
// PCS is coerced to light mode when printing, which causes the color mode to
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue