diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js index 68d7a9c0d1..41849d6105 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.js @@ -42,10 +42,10 @@ export default ({children, className: languageClassName, metastring}) => { const button = useRef(null); let highlightLines = []; - const {theme} = useThemeContext(); + const {isDarkTheme} = useThemeContext(); const lightModeTheme = prism.theme || defaultTheme; const darkModeTheme = prism.darkTheme || lightModeTheme; - const prismTheme = theme === 'dark' ? darkModeTheme : lightModeTheme; + const prismTheme = isDarkTheme ? darkModeTheme : lightModeTheme; if (metastring && highlightLinesRangeRegex.test(metastring)) { const highlightLinesRange = metastring.match(highlightLinesRangeRegex)[1]; diff --git a/packages/docusaurus-theme-classic/src/theme/Navbar/index.js b/packages/docusaurus-theme-classic/src/theme/Navbar/index.js index 76cc27849d..ca5ea5022d 100644 --- a/packages/docusaurus-theme-classic/src/theme/Navbar/index.js +++ b/packages/docusaurus-theme-classic/src/theme/Navbar/index.js @@ -52,7 +52,7 @@ function Navbar() { const [sidebarShown, setSidebarShown] = useState(false); const [isSearchBarExpanded, setIsSearchBarExpanded] = useState(false); - const {theme, setTheme} = useThemeContext(); + const {isDarkTheme, setLightTheme, setDarkTheme} = useThemeContext(); const {navbarRef, isNavbarVisible} = useHideableNavbar(hideOnScroll); useLockBodyScroll(sidebarShown); @@ -65,11 +65,8 @@ function Navbar() { }, [setSidebarShown]); const onToggleChange = useCallback( - e => { - const newTheme = e.target.checked ? 'dark' : ''; - setTheme(newTheme); - }, - [setTheme], + e => (e.target.checked ? setDarkTheme() : setLightTheme()), + [setLightTheme, setDarkTheme], ); const logoUrl = useBaseUrl(logo.src); @@ -134,7 +131,7 @@ function Navbar() { )} @@ -160,7 +157,7 @@ function Navbar() { {!disableDarkMode && sidebarShown && ( )} diff --git a/packages/docusaurus-theme-classic/src/theme/ThemeContext.js b/packages/docusaurus-theme-classic/src/theme/ThemeContext.js index a37dd428f1..71179ff882 100644 --- a/packages/docusaurus-theme-classic/src/theme/ThemeContext.js +++ b/packages/docusaurus-theme-classic/src/theme/ThemeContext.js @@ -8,8 +8,9 @@ import React from 'react'; const ThemeContext = React.createContext({ - theme: null, - setTheme: () => {}, + isDarkTheme: false, + setLightTheme: () => {}, + setDarkTheme: () => {}, }); export default ThemeContext; diff --git a/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.js b/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.js index d9ad97b80b..fb59221830 100644 --- a/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.js +++ b/packages/docusaurus-theme-classic/src/theme/ThemeProvider/index.js @@ -11,10 +11,10 @@ import useTheme from '@theme/hooks/useTheme'; import ThemeContext from '@theme/ThemeContext'; function ThemeProvider(props) { - const [theme, setTheme] = useTheme(); + const {isDarkTheme, setLightTheme, setDarkTheme} = useTheme(); return ( - + {props.children} ); diff --git a/packages/docusaurus-theme-classic/src/theme/hooks/useTheme.js b/packages/docusaurus-theme-classic/src/theme/hooks/useTheme.js index f625e94ab0..fd5c0d871a 100644 --- a/packages/docusaurus-theme-classic/src/theme/hooks/useTheme.js +++ b/packages/docusaurus-theme-classic/src/theme/hooks/useTheme.js @@ -5,25 +5,48 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import {useState, useCallback, useEffect} from 'react'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +const themes = { + light: '', + dark: 'dark', +}; + const useTheme = () => { const { siteConfig: {themeConfig: {disableDarkMode}} = {}, } = useDocusaurusContext(); - const [theme, setTheme] = React.useState( + const [theme, setTheme] = useState( typeof document !== 'undefined' ? document.documentElement.getAttribute('data-theme') - : '', + : themes.light, ); + const setThemeSyncWithLocalStorage = useCallback( + newTheme => { + try { + localStorage.setItem('theme', newTheme); + } catch (err) { + console.error(err); + } + }, + [setTheme], + ); + const setLightTheme = useCallback(() => { + setTheme(themes.light); + setThemeSyncWithLocalStorage(themes.light); + }, []); + const setDarkTheme = useCallback(() => { + setTheme(themes.dark); + setThemeSyncWithLocalStorage(themes.dark); + }, []); - React.useEffect(() => { + useEffect(() => { document.documentElement.setAttribute('data-theme', theme); }, [theme]); - React.useEffect(() => { + useEffect(() => { if (disableDarkMode) { return; } @@ -38,19 +61,11 @@ const useTheme = () => { } }, [setTheme]); - const setThemeSyncWithLocalStorage = React.useCallback( - nextTheme => { - try { - localStorage.setItem('theme', nextTheme); - setTheme(nextTheme); - } catch (err) { - console.error(err); - } - }, - [setTheme], - ); - - return [theme, setThemeSyncWithLocalStorage]; + return { + isDarkTheme: theme === themes.dark, + setLightTheme, + setDarkTheme, + }; }; export default useTheme; diff --git a/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js b/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js index b0796f88a2..6b2d1ec7fd 100644 --- a/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js +++ b/packages/docusaurus-theme-live-codeblock/src/theme/CodeBlock/index.js @@ -49,10 +49,10 @@ export default ({ const button = useRef(null); let highlightLines = []; - const {theme} = useThemeContext(); + const {isDarkTheme} = useThemeContext(); const lightModeTheme = prism.theme || defaultTheme; const darkModeTheme = prism.darkTheme || lightModeTheme; - const prismTheme = theme === 'dark' ? darkModeTheme : lightModeTheme; + const prismTheme = isDarkTheme ? darkModeTheme : lightModeTheme; if (metastring && highlightLinesRangeRegex.test(metastring)) { const highlightLinesRange = metastring.match(highlightLinesRangeRegex)[1];