diff --git a/packages/docusaurus-theme-classic/src/inlineScripts.ts b/packages/docusaurus-theme-classic/src/inlineScripts.ts index 6d5db7a8eb..4a2e4694b6 100644 --- a/packages/docusaurus-theme-classic/src/inlineScripts.ts +++ b/packages/docusaurus-theme-classic/src/inlineScripts.ts @@ -30,43 +30,22 @@ export function getThemeInlineScript({ return `(function() { var defaultMode = '${defaultMode}'; var respectPrefersColorScheme = ${respectPrefersColorScheme}; - - function setDataThemeAttribute(theme) { - document.documentElement.setAttribute('data-theme', theme); + function getSystemColorMode() { + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } - function getQueryStringTheme() { try { return new URLSearchParams(window.location.search).get('${ThemeQueryStringKey}') - } catch (e) { - } + } catch (e) {} } - function getStoredTheme() { try { return window['${siteStorage.type}'].getItem('${themeStorageKey}'); - } catch (err) { - } + } catch (err) {} } - var initialTheme = getQueryStringTheme() || getStoredTheme(); - if (initialTheme !== null) { - setDataThemeAttribute(initialTheme); - } else { - if ( - respectPrefersColorScheme && - window.matchMedia('(prefers-color-scheme: dark)').matches - ) { - setDataThemeAttribute('dark'); - } else if ( - respectPrefersColorScheme && - window.matchMedia('(prefers-color-scheme: light)').matches - ) { - setDataThemeAttribute('light'); - } else { - setDataThemeAttribute(defaultMode === 'dark' ? 'dark' : 'light'); - } - } + document.documentElement.setAttribute('data-theme', initialTheme || (respectPrefersColorScheme ? getSystemColorMode() : defaultMode)); + document.documentElement.setAttribute('data-theme-choice', initialTheme || (respectPrefersColorScheme ? 'system' : defaultMode)); })();`; } diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index 9ab3d8f903..78c25c3e48 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -1555,12 +1555,13 @@ declare module '@theme/ColorModeToggle' { export interface Props { readonly className?: string; readonly buttonClassName?: string; - readonly value: ColorMode; + readonly respectPrefersColorScheme: boolean; + readonly value: ColorMode | null; /** * The parameter represents the "to-be" value. For example, if currently in - * dark mode, clicking the button should call `onChange("light")` + * light mode, clicking the button should call `onChange("dark")` */ - readonly onChange: (colorMode: ColorMode) => void; + readonly onChange: (colorMode: ColorMode | null) => void; } export default function ColorModeToggle(props: Props): ReactNode; @@ -1617,6 +1618,14 @@ declare module '@theme/Icon/LightMode' { export default function IconLightMode(props: Props): ReactNode; } +declare module '@theme/Icon/SystemColorMode' { + import type {ComponentProps} from 'react'; + + export interface Props extends ComponentProps<'svg'> {} + + export default function IconSystemColorMode(props: Props): JSX.Element; +} + declare module '@theme/Icon/Menu' { import type {ComponentProps, ReactNode} from 'react'; diff --git a/packages/docusaurus-theme-classic/src/theme/ColorModeToggle/index.tsx b/packages/docusaurus-theme-classic/src/theme/ColorModeToggle/index.tsx index 9be18f739c..92ffe74b11 100644 --- a/packages/docusaurus-theme-classic/src/theme/ColorModeToggle/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/ColorModeToggle/index.tsx @@ -11,40 +11,105 @@ import useIsBrowser from '@docusaurus/useIsBrowser'; import {translate} from '@docusaurus/Translate'; import IconLightMode from '@theme/Icon/LightMode'; import IconDarkMode from '@theme/Icon/DarkMode'; +import IconSystemColorMode from '@theme/Icon/SystemColorMode'; import type {Props} from '@theme/ColorModeToggle'; +import type {ColorMode} from '@docusaurus/theme-common'; import styles from './styles.module.css'; +// The order of color modes is defined here, and can be customized with swizzle +function getNextColorMode( + colorMode: ColorMode | null, + respectPrefersColorScheme: boolean, +) { + // 2-value transition + if (!respectPrefersColorScheme) { + return colorMode === 'dark' ? 'light' : 'dark'; + } + + // 3-value transition + switch (colorMode) { + case null: + return 'light'; + case 'light': + return 'dark'; + case 'dark': + return null; + default: + throw new Error(`unexpected color mode ${colorMode}`); + } +} + +function getColorModeLabel(colorMode: ColorMode | null): string { + switch (colorMode) { + case null: + return translate({ + message: 'system mode', + id: 'theme.colorToggle.ariaLabel.mode.system', + description: 'The name for the system color mode', + }); + case 'light': + return translate({ + message: 'light mode', + id: 'theme.colorToggle.ariaLabel.mode.light', + description: 'The name for the light color mode', + }); + case 'dark': + return translate({ + message: 'dark mode', + id: 'theme.colorToggle.ariaLabel.mode.dark', + description: 'The name for the dark color mode', + }); + default: + throw new Error(`unexpected color mode ${colorMode}`); + } +} + +function getColorModeAriaLabel(colorMode: ColorMode | null) { + return translate( + { + message: 'Switch between dark and light mode (currently {mode})', + id: 'theme.colorToggle.ariaLabel', + description: 'The ARIA label for the color mode toggle', + }, + { + mode: getColorModeLabel(colorMode), + }, + ); +} + +function CurrentColorModeIcon(): ReactNode { + // 3 icons are always rendered for technical reasons + // We use "data-theme-choice" to render the correct one + // This must work even before React hydrates + return ( + <> + + + + + ); +} + function ColorModeToggle({ className, buttonClassName, + respectPrefersColorScheme, value, onChange, }: Props): ReactNode { const isBrowser = useIsBrowser(); - - const title = translate( - { - message: 'Switch between dark and light mode (currently {mode})', - id: 'theme.colorToggle.ariaLabel', - description: 'The ARIA label for the navbar color mode toggle', - }, - { - mode: - value === 'dark' - ? translate({ - message: 'dark mode', - id: 'theme.colorToggle.ariaLabel.mode.dark', - description: 'The name for the dark color mode', - }) - : translate({ - message: 'light mode', - id: 'theme.colorToggle.ariaLabel.mode.light', - description: 'The name for the light color mode', - }), - }, - ); - return (
); diff --git a/packages/docusaurus-theme-classic/src/theme/ColorModeToggle/styles.module.css b/packages/docusaurus-theme-classic/src/theme/ColorModeToggle/styles.module.css index 37463e0fb3..2bf0aec96d 100644 --- a/packages/docusaurus-theme-classic/src/theme/ColorModeToggle/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/ColorModeToggle/styles.module.css @@ -25,11 +25,16 @@ background: var(--ifm-color-emphasis-200); } -[data-theme='light'] .darkToggleIcon, -[data-theme='dark'] .lightToggleIcon { +.toggleIcon { display: none; } +[data-theme-choice='system'] .systemToggleIcon, +[data-theme-choice='light'] .lightToggleIcon, +[data-theme-choice='dark'] .darkToggleIcon { + display: initial; +} + .toggleButtonDisabled { cursor: not-allowed; } diff --git a/packages/docusaurus-theme-classic/src/theme/Icon/SystemColorMode/index.tsx b/packages/docusaurus-theme-classic/src/theme/Icon/SystemColorMode/index.tsx new file mode 100644 index 0000000000..4bf506f2c5 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/Icon/SystemColorMode/index.tsx @@ -0,0 +1,20 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type {ReactNode} from 'react'; +import type {Props} from '@theme/Icon/SystemColorMode'; + +export default function IconSystemColorMode(props: Props): ReactNode { + return ( + + + + ); +} diff --git a/packages/docusaurus-theme-classic/src/theme/Navbar/ColorModeToggle/index.tsx b/packages/docusaurus-theme-classic/src/theme/Navbar/ColorModeToggle/index.tsx index 0108a20e9d..5250543f76 100644 --- a/packages/docusaurus-theme-classic/src/theme/Navbar/ColorModeToggle/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/Navbar/ColorModeToggle/index.tsx @@ -13,10 +13,10 @@ import styles from './styles.module.css'; export default function NavbarColorModeToggle({className}: Props): ReactNode { const navbarStyle = useThemeConfig().navbar.style; - const disabled = useThemeConfig().colorMode.disableSwitch; - const {colorMode, setColorMode} = useColorMode(); + const {disableSwitch, respectPrefersColorScheme} = useThemeConfig().colorMode; + const {colorModeChoice, setColorMode} = useColorMode(); - if (disabled) { + if (disableSwitch) { return null; } @@ -26,7 +26,8 @@ export default function NavbarColorModeToggle({className}: Props): ReactNode { buttonClassName={ navbarStyle === 'dark' ? styles.darkNavbarColorModeToggle : undefined } - value={colorMode} + respectPrefersColorScheme={respectPrefersColorScheme} + value={colorModeChoice} onChange={setColorMode} /> ); diff --git a/packages/docusaurus-theme-common/src/contexts/colorMode.tsx b/packages/docusaurus-theme-common/src/contexts/colorMode.tsx index f14f1f6325..4a2482f907 100644 --- a/packages/docusaurus-theme-common/src/contexts/colorMode.tsx +++ b/packages/docusaurus-theme-common/src/contexts/colorMode.tsx @@ -11,19 +11,49 @@ import React, { useEffect, useContext, useMemo, - useRef, type ReactNode, } from 'react'; -import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; import {ReactContextError} from '../utils/reactUtils'; import {createStorageSlot} from '../utils/storageUtils'; import {useThemeConfig} from '../utils/useThemeConfig'; +// The "effective" color mode +export type ColorMode = 'light' | 'dark'; + +// The color mode explicitly chosen by the user +// null => no choice has been made, or the choice has been reverted to OS value +export type ColorModeChoice = ColorMode | null; + +function getSystemColorMode(): ColorMode { + return window.matchMedia('(prefers-color-scheme: dark)').matches + ? 'dark' + : 'light'; +} + +function subscribeToMedia( + query: string, + listener: (event: MediaQueryListEvent) => void, +): () => void { + const mql = window.matchMedia(query); + mql.addEventListener('change', listener); + return () => mql.removeEventListener('change', listener); +} + +function subscribeToSystemColorModeChange( + onChange: (newSystemColorMode: ColorMode) => void, +): () => void { + return subscribeToMedia('(prefers-color-scheme: dark)', () => + onChange(getSystemColorMode()), + ); +} + type ContextValue = { - /** Current color mode. */ + /** The effective color mode. */ readonly colorMode: ColorMode; + /** The explicitly chosen color mode */ + readonly colorModeChoice: ColorModeChoice; /** Set new color mode. */ - readonly setColorMode: (colorMode: ColorMode) => void; + readonly setColorMode: (colorMode: ColorModeChoice) => void; // TODO Docusaurus v4 // legacy APIs kept for retro-compatibility: deprecate them @@ -37,16 +67,17 @@ const Context = React.createContext(undefined); const ColorModeStorageKey = 'theme'; const ColorModeStorage = createStorageSlot(ColorModeStorageKey); -const ColorModes = { - light: 'light', - dark: 'dark', -} as const; - -export type ColorMode = (typeof ColorModes)[keyof typeof ColorModes]; +// We use data-theme-choice="system", not an absent attribute +// This is easier to handle for users with CSS +const SystemAttribute = 'system'; // Ensure to always return a valid colorMode even if input is invalid -const coerceToColorMode = (colorMode?: string | null): ColorMode => - colorMode === ColorModes.dark ? ColorModes.dark : ColorModes.light; +const coerceToColorMode = (colorMode: string | null): ColorMode => + colorMode === 'dark' ? 'dark' : 'light'; +const coerceToColorModeChoice = (colorMode: string | null): ColorModeChoice => + colorMode === null || colorMode === SystemAttribute + ? null + : coerceToColorMode(colorMode); const ColorModeAttribute = { get: () => { @@ -62,15 +93,26 @@ const ColorModeAttribute = { }, }; -const readInitialColorMode = (): ColorMode => { - if (!ExecutionEnvironment.canUseDOM) { - throw new Error("Can't read initial color mode on the server"); - } - return ColorModeAttribute.get(); +const ColorModeChoiceAttribute = { + get: () => { + return coerceToColorModeChoice( + document.documentElement.getAttribute('data-theme-choice'), + ); + }, + set: (colorMode: ColorModeChoice) => { + document.documentElement.setAttribute( + 'data-theme-choice', + coerceToColorModeChoice(colorMode) ?? SystemAttribute, + ); + }, }; -const storeColorMode = (newColorMode: ColorMode) => { - ColorModeStorage.set(coerceToColorMode(newColorMode)); +const persistColorModeChoice = (newColorMode: ColorModeChoice) => { + if (newColorMode === null) { + ColorModeStorage.del(); + } else { + ColorModeStorage.set(coerceToColorMode(newColorMode)); + } }; // The color mode state is initialized in useEffect on purpose @@ -83,20 +125,33 @@ function useColorModeState() { colorMode: {defaultMode}, } = useThemeConfig(); - const [colorMode, setColorModeState] = useState(defaultMode); + const [colorMode, setColorModeState] = useState(defaultMode); + const [colorModeChoice, setColorModeChoiceState] = + useState(null); useEffect(() => { - setColorModeState(readInitialColorMode()); + setColorModeState(ColorModeAttribute.get()); + setColorModeChoiceState(ColorModeChoiceAttribute.get()); }, []); - return [colorMode, setColorModeState] as const; + return { + colorMode, + setColorModeState, + colorModeChoice, + setColorModeChoiceState, + } as const; } function useContextValue(): ContextValue { const { colorMode: {defaultMode, disableSwitch, respectPrefersColorScheme}, } = useThemeConfig(); - const [colorMode, setColorModeState] = useColorModeState(); + const { + colorMode, + setColorModeState, + colorModeChoice, + setColorModeChoiceState, + } = useColorModeState(); useEffect(() => { // A site is deployed without disableSwitch @@ -109,67 +164,70 @@ function useContextValue(): ContextValue { }, [disableSwitch]); const setColorMode = useCallback( - (newColorMode: ColorMode | null, options: {persist?: boolean} = {}) => { + ( + newColorModeChoice: ColorModeChoice, + options: {persist?: boolean} = {}, + ) => { const {persist = true} = options; - if (newColorMode) { + // Reset to system/default color mode + if (newColorModeChoice === null) { + // Set the effective color + const newColorMode = respectPrefersColorScheme + ? getSystemColorMode() + : defaultMode; ColorModeAttribute.set(newColorMode); setColorModeState(newColorMode); - if (persist) { - storeColorMode(newColorMode); - } - } else { - if (respectPrefersColorScheme) { - const osColorMode = window.matchMedia('(prefers-color-scheme: dark)') - .matches - ? ColorModes.dark - : ColorModes.light; - ColorModeAttribute.set(osColorMode); - setColorModeState(osColorMode); - } else { - ColorModeAttribute.set(defaultMode); - setColorModeState(defaultMode); - } - ColorModeStorage.del(); + // Set the chosen color + ColorModeChoiceAttribute.set(null); + setColorModeChoiceState(null); + } + // Happy case, when an explicit color is provided + else { + ColorModeAttribute.set(newColorModeChoice); + ColorModeChoiceAttribute.set(newColorModeChoice); + setColorModeState(newColorModeChoice); + setColorModeChoiceState(newColorModeChoice); + } + + if (persist) { + persistColorModeChoice(newColorModeChoice); } }, - [setColorModeState, respectPrefersColorScheme, defaultMode], + [ + setColorModeState, + setColorModeChoiceState, + respectPrefersColorScheme, + defaultMode, + ], ); + // Synchronize theme color/choice mode with browser storage useEffect(() => { - if (disableSwitch) { - return undefined; - } return ColorModeStorage.listen((e) => { - setColorMode(coerceToColorMode(e.newValue)); + setColorMode(coerceToColorModeChoice(e.newValue)); }); - }, [disableSwitch, setColorMode]); - - // PCS is coerced to light mode when printing, which causes the color mode to - // be reset to dark when exiting print mode, disregarding user settings. When - // the listener fires only because of a print/screen switch, we don't change - // color mode. See https://github.com/facebook/docusaurus/pull/6490 - const previousMediaIsPrint = useRef(false); + }, [setColorMode]); + // Synchronize theme color with system color useEffect(() => { - if (disableSwitch && !respectPrefersColorScheme) { + if (colorModeChoice !== null || !respectPrefersColorScheme) { return undefined; } - const mql = window.matchMedia('(prefers-color-scheme: dark)'); - const onChange = () => { - if (window.matchMedia('print').matches || previousMediaIsPrint.current) { - previousMediaIsPrint.current = window.matchMedia('print').matches; - return; - } - setColorMode(null); - }; - mql.addListener(onChange); - return () => mql.removeListener(onChange); - }, [setColorMode, disableSwitch, respectPrefersColorScheme]); + return subscribeToSystemColorModeChange((newSystemColorMode) => { + // Note: we don't use "setColorMode" on purpose + // The system changes should never be considered an explicit theme choice + // They only affect the "effective" color, and should never be persisted + // Note: this listener also fire when printing, see https://github.com/facebook/docusaurus/pull/6490 + setColorModeState(newSystemColorMode); + ColorModeAttribute.set(newSystemColorMode); + }); + }, [respectPrefersColorScheme, colorModeChoice, setColorModeState]); return useMemo( () => ({ colorMode, + colorModeChoice, setColorMode, get isDarkTheme() { if (process.env.NODE_ENV === 'development') { @@ -177,7 +235,7 @@ function useContextValue(): ContextValue { '`useColorMode().isDarkTheme` is deprecated. Please use `useColorMode().colorMode === "dark"` instead.', ); } - return colorMode === ColorModes.dark; + return colorMode === 'dark'; }, setLightTheme() { if (process.env.NODE_ENV === 'development') { @@ -185,7 +243,7 @@ function useContextValue(): ContextValue { '`useColorMode().setLightTheme` is deprecated. Please use `useColorMode().setColorMode("light")` instead.', ); } - setColorMode(ColorModes.light); + setColorMode('light'); }, setDarkTheme() { if (process.env.NODE_ENV === 'development') { @@ -193,10 +251,10 @@ function useContextValue(): ContextValue { '`useColorMode().setDarkTheme` is deprecated. Please use `useColorMode().setColorMode("dark")` instead.', ); } - setColorMode(ColorModes.dark); + setColorMode('dark'); }, }), - [colorMode, setColorMode], + [colorMode, colorModeChoice, setColorMode], ); } diff --git a/packages/docusaurus-theme-translations/locales/ar/theme-common.json b/packages/docusaurus-theme-translations/locales/ar/theme-common.json index be0e78a24e..0adafcb54a 100644 --- a/packages/docusaurus-theme-translations/locales/ar/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/ar/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "التبديل بين الوضع الداكن والفاتح (الحالي {mode})", "theme.colorToggle.ariaLabel.mode.dark": "الوضع الداكن", "theme.colorToggle.ariaLabel.mode.light": "الوضع الفاتح", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "تعديل هذه الصفحة", "theme.common.headingLinkTitle": "ارتباط مباشر بالعنوان {heading}", "theme.common.skipToMainContent": "انتقل إلى المحتوى الرئيسي", diff --git a/packages/docusaurus-theme-translations/locales/base/theme-common.json b/packages/docusaurus-theme-translations/locales/base/theme-common.json index 251596eb6e..bfd82ff2c3 100644 --- a/packages/docusaurus-theme-translations/locales/base/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/base/theme-common.json @@ -78,11 +78,13 @@ "theme.blog.tagTitle": "{nPosts} tagged with \"{tagName}\"", "theme.blog.tagTitle___DESCRIPTION": "The title of the page for a blog tag", "theme.colorToggle.ariaLabel": "Switch between dark and light mode (currently {mode})", - "theme.colorToggle.ariaLabel___DESCRIPTION": "The ARIA label for the navbar color mode toggle", + "theme.colorToggle.ariaLabel___DESCRIPTION": "The ARIA label for the color mode toggle", "theme.colorToggle.ariaLabel.mode.dark": "dark mode", "theme.colorToggle.ariaLabel.mode.dark___DESCRIPTION": "The name for the dark color mode", "theme.colorToggle.ariaLabel.mode.light": "light mode", "theme.colorToggle.ariaLabel.mode.light___DESCRIPTION": "The name for the light color mode", + "theme.colorToggle.ariaLabel.mode.system": "system mode", + "theme.colorToggle.ariaLabel.mode.system___DESCRIPTION": "The name for the system color mode", "theme.common.editThisPage": "Edit this page", "theme.common.editThisPage___DESCRIPTION": "The link label to edit the current page", "theme.common.headingLinkTitle": "Direct link to {heading}", diff --git a/packages/docusaurus-theme-translations/locales/bg/theme-common.json b/packages/docusaurus-theme-translations/locales/bg/theme-common.json index 7231cf8b1f..bc91fb0d36 100644 --- a/packages/docusaurus-theme-translations/locales/bg/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/bg/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Превключване между тъмен и светъл режим (В момента {mode})", "theme.colorToggle.ariaLabel.mode.dark": "тъмен режим", "theme.colorToggle.ariaLabel.mode.light": "светъл режим", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Редактирай тази страница", "theme.common.headingLinkTitle": "Директна връзка към {heading}", "theme.common.skipToMainContent": "Преминете към основното съдържание", diff --git a/packages/docusaurus-theme-translations/locales/bn/theme-common.json b/packages/docusaurus-theme-translations/locales/bn/theme-common.json index 7c42e91723..363a32d99d 100644 --- a/packages/docusaurus-theme-translations/locales/bn/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/bn/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Switch between dark and light mode (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "dark mode", "theme.colorToggle.ariaLabel.mode.light": "light mode", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "এই পেজটি এডিট করুন", "theme.common.headingLinkTitle": "{heading} এর সঙ্গে সরাসরি লিংকড", "theme.common.skipToMainContent": "স্কিপ করে মূল কন্টেন্ট এ যান", diff --git a/packages/docusaurus-theme-translations/locales/cs/theme-common.json b/packages/docusaurus-theme-translations/locales/cs/theme-common.json index e442f0eeff..8851c9e9a5 100644 --- a/packages/docusaurus-theme-translations/locales/cs/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/cs/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Switch between dark and light mode (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "dark mode", "theme.colorToggle.ariaLabel.mode.light": "light mode", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Upravit tuto stránku", "theme.common.headingLinkTitle": "Přímý odkaz na {heading}", "theme.common.skipToMainContent": "Přeskočit na hlavní obsah", diff --git a/packages/docusaurus-theme-translations/locales/da/theme-common.json b/packages/docusaurus-theme-translations/locales/da/theme-common.json index 157d231f6c..d640d5a410 100644 --- a/packages/docusaurus-theme-translations/locales/da/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/da/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Switch between dark and light mode (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "dark mode", "theme.colorToggle.ariaLabel.mode.light": "light mode", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Rediger denne side", "theme.common.headingLinkTitle": "Direkte link til {heading}", "theme.common.skipToMainContent": "Hop til hovedindhold", diff --git a/packages/docusaurus-theme-translations/locales/de/theme-common.json b/packages/docusaurus-theme-translations/locales/de/theme-common.json index 5a61097055..571b2a6340 100644 --- a/packages/docusaurus-theme-translations/locales/de/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/de/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Umschalten zwischen dunkler und heller Ansicht (momentan {mode})", "theme.colorToggle.ariaLabel.mode.dark": "dunkler Modus", "theme.colorToggle.ariaLabel.mode.light": "heller Modus", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Diese Seite bearbeiten", "theme.common.headingLinkTitle": "Direkter Link zur {heading}", "theme.common.skipToMainContent": "Zum Hauptinhalt springen", diff --git a/packages/docusaurus-theme-translations/locales/es/theme-common.json b/packages/docusaurus-theme-translations/locales/es/theme-common.json index 5b619fb72c..d6beceea85 100644 --- a/packages/docusaurus-theme-translations/locales/es/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/es/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Cambiar entre modo oscuro y claro (actualmente {mode})", "theme.colorToggle.ariaLabel.mode.dark": "modo oscuro", "theme.colorToggle.ariaLabel.mode.light": "modo claro", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Editar esta página", "theme.common.headingLinkTitle": "Enlace directo al {heading}", "theme.common.skipToMainContent": "Saltar al contenido principal", diff --git a/packages/docusaurus-theme-translations/locales/et/theme-common.json b/packages/docusaurus-theme-translations/locales/et/theme-common.json index e30c2e5a49..6767c6eb6c 100644 --- a/packages/docusaurus-theme-translations/locales/et/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/et/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Vaheta heleda ja tumeda teema vahel (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "tume teema", "theme.colorToggle.ariaLabel.mode.light": "hele teema", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Redigeeri seda lehte", "theme.common.headingLinkTitle": "Link {heading}", "theme.common.skipToMainContent": "Liigu peamise sisu juurde", diff --git a/packages/docusaurus-theme-translations/locales/fa/theme-common.json b/packages/docusaurus-theme-translations/locales/fa/theme-common.json index 55baf0df55..e50a196a89 100644 --- a/packages/docusaurus-theme-translations/locales/fa/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/fa/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "بین حالت تاریک و روشن سوئیچ کنید (الان {mode})", "theme.colorToggle.ariaLabel.mode.dark": "حالت تیره", "theme.colorToggle.ariaLabel.mode.light": "حالت روشن", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "ویرایش مطالب این صفحه", "theme.common.headingLinkTitle": "لینک مستقیم به {heading}", "theme.common.skipToMainContent": "پرش به مطلب اصلی", diff --git a/packages/docusaurus-theme-translations/locales/fil/theme-common.json b/packages/docusaurus-theme-translations/locales/fil/theme-common.json index 383cecc356..3525ad4c18 100644 --- a/packages/docusaurus-theme-translations/locales/fil/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/fil/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Switch between dark and light mode (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "dark mode", "theme.colorToggle.ariaLabel.mode.light": "light mode", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "I-edit ang page", "theme.common.headingLinkTitle": "Direktang link patungo sa {heading}", "theme.common.skipToMainContent": "Lumaktaw patungo sa pangunahing content", diff --git a/packages/docusaurus-theme-translations/locales/fr/theme-common.json b/packages/docusaurus-theme-translations/locales/fr/theme-common.json index 92c8e9eecb..6d5442c63a 100644 --- a/packages/docusaurus-theme-translations/locales/fr/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/fr/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Basculer entre le mode sombre et clair (actuellement {mode})", "theme.colorToggle.ariaLabel.mode.dark": "mode sombre", "theme.colorToggle.ariaLabel.mode.light": "mode clair", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Éditer cette page", "theme.common.headingLinkTitle": "Lien direct vers {heading}", "theme.common.skipToMainContent": "Aller au contenu principal", diff --git a/packages/docusaurus-theme-translations/locales/he/theme-common.json b/packages/docusaurus-theme-translations/locales/he/theme-common.json index cd2a67d1b7..aefd1a2784 100644 --- a/packages/docusaurus-theme-translations/locales/he/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/he/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Switch between dark and light mode (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "dark mode", "theme.colorToggle.ariaLabel.mode.light": "light mode", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "ערוך דף זה", "theme.common.headingLinkTitle": "קישור ישיר אל {heading}", "theme.common.skipToMainContent": "דלג לתוכן הראשי", diff --git a/packages/docusaurus-theme-translations/locales/hi/theme-common.json b/packages/docusaurus-theme-translations/locales/hi/theme-common.json index d5cce9cb56..658a3725de 100644 --- a/packages/docusaurus-theme-translations/locales/hi/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/hi/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Switch between dark and light mode (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "dark mode", "theme.colorToggle.ariaLabel.mode.light": "light mode", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "इस पेज को बदलें", "theme.common.headingLinkTitle": "{heading} का सीधा लिंक", "theme.common.skipToMainContent": "मुख्य कंटेंट तक स्किप करें", diff --git a/packages/docusaurus-theme-translations/locales/hu/theme-common.json b/packages/docusaurus-theme-translations/locales/hu/theme-common.json index 9f5b5c604e..d569ea0cb6 100644 --- a/packages/docusaurus-theme-translations/locales/hu/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/hu/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Váltás a sötét és világos mód között (jelenleg {mode} van beállítva)", "theme.colorToggle.ariaLabel.mode.dark": "Sötét mód", "theme.colorToggle.ariaLabel.mode.light": "Világos mód", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Szerkesztés GitHub-on", "theme.common.headingLinkTitle": "Közvetlen hivatkozás erre: {heading}", "theme.common.skipToMainContent": "Ugrás a fő tartalomhoz", diff --git a/packages/docusaurus-theme-translations/locales/id/theme-common.json b/packages/docusaurus-theme-translations/locales/id/theme-common.json index 9ec9037e3b..c8b4c037dd 100644 --- a/packages/docusaurus-theme-translations/locales/id/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/id/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Ubah antara modus gelap dan modus terang (saat ini {mode})", "theme.colorToggle.ariaLabel.mode.dark": "modus gelap", "theme.colorToggle.ariaLabel.mode.light": "modus terang", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Sunting halaman ini", "theme.common.headingLinkTitle": "Taut langsung ke {heading}", "theme.common.skipToMainContent": "Lewati ke konten utama", diff --git a/packages/docusaurus-theme-translations/locales/is/theme-common.json b/packages/docusaurus-theme-translations/locales/is/theme-common.json index 0d1121f408..c8498c56fa 100644 --- a/packages/docusaurus-theme-translations/locales/is/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/is/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Skiptu á milli rökkur stillingar og bjartar stillingar (núna {mode})", "theme.colorToggle.ariaLabel.mode.dark": "rökkur stilling", "theme.colorToggle.ariaLabel.mode.light": "björt stilling", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Breyttu þessari síðu", "theme.common.headingLinkTitle": "Beinn hlekkur að {heading}", "theme.common.skipToMainContent": "Hoppa yfir á aðal efni", diff --git a/packages/docusaurus-theme-translations/locales/it/theme-common.json b/packages/docusaurus-theme-translations/locales/it/theme-common.json index 41b0a5ac00..7a45a72f63 100644 --- a/packages/docusaurus-theme-translations/locales/it/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/it/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Passa dalla modalità scura a quella chiara (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "Modalità scura", "theme.colorToggle.ariaLabel.mode.light": "modalità luce", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Modifica questa pagina", "theme.common.headingLinkTitle": "Link diretto a {heading}", "theme.common.skipToMainContent": "Passa al contenuto principale", diff --git a/packages/docusaurus-theme-translations/locales/ja/theme-common.json b/packages/docusaurus-theme-translations/locales/ja/theme-common.json index 94801ba3be..72e587d616 100644 --- a/packages/docusaurus-theme-translations/locales/ja/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/ja/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "ダークモードを切り替える(現在は{mode})", "theme.colorToggle.ariaLabel.mode.dark": "ダークモード", "theme.colorToggle.ariaLabel.mode.light": "ライトモード", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "このページを編集", "theme.common.headingLinkTitle": "{heading} への直接リンク", "theme.common.skipToMainContent": "メインコンテンツまでスキップ", diff --git a/packages/docusaurus-theme-translations/locales/ko/theme-common.json b/packages/docusaurus-theme-translations/locales/ko/theme-common.json index b6d78580a5..a0265d101e 100644 --- a/packages/docusaurus-theme-translations/locales/ko/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/ko/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "어두운 모드와 밝은 모드 전환하기 (현재 {mode})", "theme.colorToggle.ariaLabel.mode.dark": "어두운 모드", "theme.colorToggle.ariaLabel.mode.light": "밝은 모드", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "페이지 편집", "theme.common.headingLinkTitle": "{heading}에 대한 직접 링크", "theme.common.skipToMainContent": "본문으로 건너뛰기", diff --git a/packages/docusaurus-theme-translations/locales/nb/theme-common.json b/packages/docusaurus-theme-translations/locales/nb/theme-common.json index 71e3d1e709..97cf5c0dcf 100644 --- a/packages/docusaurus-theme-translations/locales/nb/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/nb/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Bytt mellom mørk og lys utseende (nå {mode})", "theme.colorToggle.ariaLabel.mode.dark": "mørk utseende", "theme.colorToggle.ariaLabel.mode.light": "lys utseende", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Rediger denne siden", "theme.common.headingLinkTitle": "Direkte lenke til {heading}", "theme.common.skipToMainContent": "Gå til hovedinnhold", diff --git a/packages/docusaurus-theme-translations/locales/nl/theme-common.json b/packages/docusaurus-theme-translations/locales/nl/theme-common.json index 032e831150..e338293e17 100644 --- a/packages/docusaurus-theme-translations/locales/nl/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/nl/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Schakel tussen donkere en lichte modus (momenteel {mode})", "theme.colorToggle.ariaLabel.mode.dark": "donkere modus", "theme.colorToggle.ariaLabel.mode.light": "lichte modus", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Bewerk deze pagina", "theme.common.headingLinkTitle": "Direct link naar {heading}", "theme.common.skipToMainContent": "Ga naar hoofdinhoud", diff --git a/packages/docusaurus-theme-translations/locales/pl/theme-common.json b/packages/docusaurus-theme-translations/locales/pl/theme-common.json index 683dc4c517..e437ce3b17 100644 --- a/packages/docusaurus-theme-translations/locales/pl/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/pl/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Przełącz pomiędzy ciemnym a jasnym motywem (aktualnie ustawiony {mode})", "theme.colorToggle.ariaLabel.mode.dark": "ciemny motyw", "theme.colorToggle.ariaLabel.mode.light": "jasny motyw", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Edytuj tę stronę", "theme.common.headingLinkTitle": "Bezpośredni link do {heading}", "theme.common.skipToMainContent": "Przejdź do głównej zawartości", diff --git a/packages/docusaurus-theme-translations/locales/pt-BR/theme-common.json b/packages/docusaurus-theme-translations/locales/pt-BR/theme-common.json index b573ff721a..e064b2cb53 100644 --- a/packages/docusaurus-theme-translations/locales/pt-BR/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/pt-BR/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Alterar entre os modos claro e escuro (modo {mode} ativado)", "theme.colorToggle.ariaLabel.mode.dark": "modo escuro", "theme.colorToggle.ariaLabel.mode.light": "modo claro", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Editar essa página", "theme.common.headingLinkTitle": "Link direto para {heading}", "theme.common.skipToMainContent": "Pular para o conteúdo principal", diff --git a/packages/docusaurus-theme-translations/locales/pt-PT/theme-common.json b/packages/docusaurus-theme-translations/locales/pt-PT/theme-common.json index 3772b07e66..033783f6e8 100644 --- a/packages/docusaurus-theme-translations/locales/pt-PT/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/pt-PT/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Switch between dark and light mode (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "dark mode", "theme.colorToggle.ariaLabel.mode.light": "light mode", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Editar esta página", "theme.common.headingLinkTitle": "Link direto para {heading}", "theme.common.skipToMainContent": "Saltar para o conteúdo principal", diff --git a/packages/docusaurus-theme-translations/locales/ru/theme-common.json b/packages/docusaurus-theme-translations/locales/ru/theme-common.json index bc30a6c0c1..54c934e1fa 100644 --- a/packages/docusaurus-theme-translations/locales/ru/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/ru/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Переключение между темным и светлым режимом (сейчас используется {mode})", "theme.colorToggle.ariaLabel.mode.dark": "Тёмный режим", "theme.colorToggle.ariaLabel.mode.light": "Светлый режим", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Отредактировать эту страницу", "theme.common.headingLinkTitle": "Прямая ссылка на {heading}", "theme.common.skipToMainContent": "Перейти к основному содержимому", diff --git a/packages/docusaurus-theme-translations/locales/sl/theme-common.json b/packages/docusaurus-theme-translations/locales/sl/theme-common.json index 73ab8bb11c..3fc398b6b5 100644 --- a/packages/docusaurus-theme-translations/locales/sl/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/sl/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Preklopi med temnim in svetlim načinom (trenutno {mode})", "theme.colorToggle.ariaLabel.mode.dark": "temni način", "theme.colorToggle.ariaLabel.mode.light": "svetli način", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Uredi to stran", "theme.common.headingLinkTitle": "Direktna povezava na {heading}", "theme.common.skipToMainContent": "Preskoči na vsebino", diff --git a/packages/docusaurus-theme-translations/locales/sr/theme-common.json b/packages/docusaurus-theme-translations/locales/sr/theme-common.json index c4d5ff1d49..10d8f46cd5 100644 --- a/packages/docusaurus-theme-translations/locales/sr/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/sr/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Switch between dark and light mode (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "dark mode", "theme.colorToggle.ariaLabel.mode.light": "light mode", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Уреди ову страницу", "theme.common.headingLinkTitle": "Веза до {heading}", "theme.common.skipToMainContent": "Пређи на главни садржај", diff --git a/packages/docusaurus-theme-translations/locales/sv/theme-common.json b/packages/docusaurus-theme-translations/locales/sv/theme-common.json index 962e3465a6..2766be0afc 100644 --- a/packages/docusaurus-theme-translations/locales/sv/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/sv/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Växla mellan mörkt och ljust utseende (currently {mode})", "theme.colorToggle.ariaLabel.mode.dark": "mörkt utseende", "theme.colorToggle.ariaLabel.mode.light": "ljust utseende", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Redigera denna sida", "theme.common.headingLinkTitle": "Direktlänk till {heading}", "theme.common.skipToMainContent": "Hoppa till huvudinnehåll", diff --git a/packages/docusaurus-theme-translations/locales/tk/theme-common.json b/packages/docusaurus-theme-translations/locales/tk/theme-common.json index cb19c798db..3234e3172a 100644 --- a/packages/docusaurus-theme-translations/locales/tk/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/tk/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Gijeki ýa-da gündizki temany saýlamak (häzirki wagtda {mode} ulanylýar)", "theme.colorToggle.ariaLabel.mode.dark": "Gijeki tema", "theme.colorToggle.ariaLabel.mode.light": "Gündizki tema", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Bu sahypany üýtgetmek", "theme.common.headingLinkTitle": "{heading} sahypa göni geçiň", "theme.common.skipToMainContent": "Esasy mazmuna geç", diff --git a/packages/docusaurus-theme-translations/locales/tr/theme-common.json b/packages/docusaurus-theme-translations/locales/tr/theme-common.json index 665e94633b..f5b291c76f 100644 --- a/packages/docusaurus-theme-translations/locales/tr/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/tr/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Karanlık ve aydınlık mod arasında geçiş yapın (şu anda {mode})", "theme.colorToggle.ariaLabel.mode.dark": "Karanlık mod", "theme.colorToggle.ariaLabel.mode.light": "Aydınlık mod", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Bu sayfayı düzenle", "theme.common.headingLinkTitle": "{heading} doğrudan bağlantı", "theme.common.skipToMainContent": "Ana içeriğe geç", diff --git a/packages/docusaurus-theme-translations/locales/uk/theme-common.json b/packages/docusaurus-theme-translations/locales/uk/theme-common.json index 972b012c90..12aceb1a44 100644 --- a/packages/docusaurus-theme-translations/locales/uk/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/uk/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Перемикання між темним та світлим режимом (зараз використовується {mode})", "theme.colorToggle.ariaLabel.mode.dark": "Темний режим", "theme.colorToggle.ariaLabel.mode.light": "Світлий режим", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Відредагувати цю сторінку", "theme.common.headingLinkTitle": "Пряме посилання на {heading}", "theme.common.skipToMainContent": "Перейти до основного вмісту", diff --git a/packages/docusaurus-theme-translations/locales/vi/theme-common.json b/packages/docusaurus-theme-translations/locales/vi/theme-common.json index 37f33a067b..2a77737a72 100644 --- a/packages/docusaurus-theme-translations/locales/vi/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/vi/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "Chuyển đổi chế độ sáng và tối (hiện tại là {mode})", "theme.colorToggle.ariaLabel.mode.dark": "chế độ tối", "theme.colorToggle.ariaLabel.mode.light": "chế độ sáng", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "Sửa trang này", "theme.common.headingLinkTitle": "Đường dẫn trực tiếp đến {heading}", "theme.common.skipToMainContent": "Chuyển tới nội dung chính", diff --git a/packages/docusaurus-theme-translations/locales/zh-Hans/theme-common.json b/packages/docusaurus-theme-translations/locales/zh-Hans/theme-common.json index 590c87b50d..9e375d411d 100644 --- a/packages/docusaurus-theme-translations/locales/zh-Hans/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/zh-Hans/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "切换浅色/暗黑模式(当前为{mode})", "theme.colorToggle.ariaLabel.mode.dark": "暗黑模式", "theme.colorToggle.ariaLabel.mode.light": "浅色模式", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "编辑此页", "theme.common.headingLinkTitle": "{heading}的直接链接", "theme.common.skipToMainContent": "跳到主要内容", diff --git a/packages/docusaurus-theme-translations/locales/zh-Hant/theme-common.json b/packages/docusaurus-theme-translations/locales/zh-Hant/theme-common.json index c1d626bb2b..9fdfe723f8 100644 --- a/packages/docusaurus-theme-translations/locales/zh-Hant/theme-common.json +++ b/packages/docusaurus-theme-translations/locales/zh-Hant/theme-common.json @@ -41,6 +41,7 @@ "theme.colorToggle.ariaLabel": "切換淺色/深色模式(當前為{mode})", "theme.colorToggle.ariaLabel.mode.dark": "深色模式", "theme.colorToggle.ariaLabel.mode.light": "淺色模式", + "theme.colorToggle.ariaLabel.mode.system": "system mode", "theme.common.editThisPage": "編輯此頁", "theme.common.headingLinkTitle": "{heading}的直接連結", "theme.common.skipToMainContent": "跳至主要内容", diff --git a/website/docs/api/themes/theme-configuration.mdx b/website/docs/api/themes/theme-configuration.mdx index 7349ed7983..cca32b058d 100644 --- a/website/docs/api/themes/theme-configuration.mdx +++ b/website/docs/api/themes/theme-configuration.mdx @@ -1114,23 +1114,93 @@ export default { ### `useColorMode` {#use-color-mode} -A React hook to access the color context. This context contains functions for setting light and dark mode and exposes boolean variable, indicating which mode is currently in use. +A React hook to access the color context. This context contains functions for selecting light/dark/system mode and exposes the current color mode and the choice from the user. The color mode values **should not be used for dynamic content rendering** (see below). Usage example: ```jsx -import React from 'react'; // highlight-next-line import {useColorMode} from '@docusaurus/theme-common'; -const Example = () => { - // highlight-next-line - const {colorMode, setColorMode} = useColorMode(); +const MyColorModeButton = () => { + // highlight-start + const { + colorMode, // the "effective" color mode, never null + colorModeChoice, // the color mode chosen by the user, can be null + setColorMode, // set the color mode chosen by the user + } = useColorMode(); + // highlight-end - return

Dark mode is now {colorMode === 'dark' ? 'on' : 'off'}

; + return ( + + ); }; ``` +Attributes: + +- `colorMode: 'light' | 'dark'`: The effective color mode currently applied to the UI. It cannot be `null`. +- `colorModeChoice: 'light' | 'dark' | null`: The color mode explicitly chosen by the user. It can be `null` if user has not made any choice yet, or if they reset their choice to the system/default value. +- `setColorMode(colorModeChoice: 'light' | 'dark' | null, options: {persist: boolean}): void`: A function to call when the user explicitly chose a color mode. `null` permits to reset the choice to the system/default value. By default, the choice is persisted in `localStorage` and restored on page reload, but you can opt out with `{persist: false}`. + +:::warning + +Don't use `colorMode` and `colorModeChoice` while rendering React components. Doing so is likely to produce [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content), layout shifts and [React hydration](https://18.react.dev/reference/react-dom/client/hydrateRoot) mismatches if you use them to render JSX content dynamically. + +However, these values are safe to use **after React hydration**, in `useEffect` and event listeners, like in the `MyColorModeButton` example above. + +If you need to render content dynamically depending on the current theme, the only way to avoid FOUC, layout shifts and hydration mismatch is to rely on CSS selectors to render content dynamically, based on the `html` data attributes that we set before the page displays anything: + +```html + + + +``` + +```css +[data-theme='light'] +[data-theme='dark'] + +[data-theme-choice='light'] +[data-theme-choice='dark'] +[data-theme-choice='system'] +``` + +
+ Why are `colorMode` and `colorModeChoice` unsafe when rendering? + +To understand the problem, you need to understand how [React hydration](https://18.react.dev/reference/react-dom/client/hydrateRoot) works. + +During the static site generation phase, Docusaurus doesn't know what the user color mode choice is, and `useColorMode()` returns the following static values: + +- `colorMode = themeConfig.colorMode.defaultMode` +- `colorModeChoice = null` + +During the very first React client-side render (the hydration), React must produce the exact same HTML markup, and will also use these static values. + +The correct `colorMode` and `colorModeChoice` values will only be provided in the second React render. + +Typically, the following component will lead to **React hydration mismatches**. The label may switch from `light` to `dark` while React hydrates, leading to a confusing user experience. + +```jsx +import {useColorMode} from '@docusaurus/theme-common'; + +const DisplayCurrentColorMode = () => { + const {colorMode} = useColorMode(); + return {colorMode}; +}; +``` + +
+ +::: + :::note The component calling `useColorMode` must be a child of the `Layout` component.