diff --git a/packages/documentation-framework/layouts/sideNavLayout/sideNavLayout.js b/packages/documentation-framework/layouts/sideNavLayout/sideNavLayout.js index de89641546..406d2c598b 100644 --- a/packages/documentation-framework/layouts/sideNavLayout/sideNavLayout.js +++ b/packages/documentation-framework/layouts/sideNavLayout/sideNavLayout.js @@ -37,6 +37,9 @@ import { Footer } from '@patternfly/documentation-framework/components'; export const RtlContext = createContext(false); +const DARK_MODE_CLASS = 'pf-v6-theme-dark'; +const DARK_MODE_STORAGE_KEY = 'dark-mode'; + const HeaderTools = ({ versions, hasVersionSwitcher, @@ -72,7 +75,6 @@ const HeaderTools = ({ const toggleDarkTheme = (_evt, selected) => { const darkThemeToggleClicked = !selected === isDarkTheme; - document.querySelector('html').classList.toggle('pf-v6-theme-dark', darkThemeToggleClicked); setIsDarkTheme(darkThemeToggleClicked); }; @@ -245,12 +247,49 @@ export const SideNavLayout = ({ children, groupedRoutes, navOpen: navOpenProp }) const [versions, setVersions] = useState({ ...staticVersions }); const [isRTL, setIsRTL] = useState(false); - const [isDarkTheme, setIsDarkTheme] = React.useState(false); + + const mediaQuery = () => window.matchMedia('(prefers-color-scheme: dark)'); + const getLocalStorageDarkMode = () => { + if (localStorage !== undefined) { + return localStorage.getItem(DARK_MODE_STORAGE_KEY); + } else { + return null; + } + } + const setLocalStorageDarkMode = (isEnabled) => { + if (localStorage !== undefined) { + localStorage.setItem(DARK_MODE_STORAGE_KEY, isEnabled); + updateDarkMode(); + } + } + + const updateDarkMode = () => { + const isEnabled = getLocalStorageDarkMode() === null ? mediaQuery().matches : getLocalStorageDarkMode() === 'true'; + const { classList } = document.documentElement; + + if (isEnabled) { + classList.add(DARK_MODE_CLASS); + } else { + classList.remove(DARK_MODE_CLASS); + } + }; + + const [isDarkTheme, setIsDarkTheme] = React.useState( + getLocalStorageDarkMode() === null ? mediaQuery().matches : getLocalStorageDarkMode() === 'true' + ); + + const toggleDarkTheme = (darkThemeEnabled) => { + setLocalStorageDarkMode(darkThemeEnabled); + setIsDarkTheme(darkThemeEnabled); + }; useEffect(() => { + updateDarkMode(); + if (typeof window === 'undefined') { return; } + if (hasVersionSwitcher && window.fetch) { fetch('/versions.json').then((res) => { if (res.ok) { @@ -258,6 +297,10 @@ export const SideNavLayout = ({ children, groupedRoutes, navOpen: navOpenProp }) } }); } + + return () => { + document.removeEventListener('visibilitychange', handleVisibilityChange); + }; }, []); const SideBar = ( @@ -339,7 +382,7 @@ export const SideNavLayout = ({ children, groupedRoutes, navOpen: navOpenProp }) isRTL={isRTL} setIsRTL={setIsRTL} isDarkTheme={isDarkTheme} - setIsDarkTheme={setIsDarkTheme} + setIsDarkTheme={toggleDarkTheme} /> )} diff --git a/packages/documentation-site/package.json b/packages/documentation-site/package.json index 8070a3691e..843bfc3b34 100644 --- a/packages/documentation-site/package.json +++ b/packages/documentation-site/package.json @@ -17,7 +17,7 @@ "screenshots": "pf-docs-framework screenshots" }, "dependencies": { - "@patternfly/documentation-framework": "6.0.6", + "@patternfly/documentation-framework": "6.0.8", "@patternfly/react-catalog-view-extension": "6.0.0", "@patternfly/react-console": "6.0.0", "@patternfly/react-docs": "7.0.0",