/**
* 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 React, {type ReactNode} from 'react';
import clsx from 'clsx';
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 (
<>