function useContextValue()

in packages/docusaurus-theme-common/src/contexts/colorMode.tsx [60:156]


function useContextValue(): ContextValue {
  const {
    colorMode: {defaultMode, disableSwitch, respectPrefersColorScheme},
  } = useThemeConfig();
  const [colorMode, setColorModeState] = useState(
    getInitialColorMode(defaultMode),
  );

  const setColorMode = useCallback((newColorMode: ColorMode) => {
    setColorModeState(newColorMode);
    storeColorMode(newColorMode);
  }, []);

  useEffect(() => {
    document.documentElement.setAttribute(
      'data-theme',
      coerceToColorMode(colorMode),
    );
  }, [colorMode]);

  useEffect(() => {
    if (disableSwitch) {
      return undefined;
    }
    const onChange = (e: StorageEvent) => {
      if (e.key !== ColorModeStorageKey) {
        return;
      }
      try {
        const storedColorMode = ColorModeStorage.get();
        if (storedColorMode !== null) {
          setColorMode(coerceToColorMode(storedColorMode));
        }
      } catch (err) {
        console.error(err);
      }
    };
    window.addEventListener('storage', onChange);
    return () => window.removeEventListener('storage', onChange);
  }, [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);

  useEffect(() => {
    if (disableSwitch && !respectPrefersColorScheme) {
      return undefined;
    }
    const mql = window.matchMedia('(prefers-color-scheme: dark)');
    const onChange = ({matches}: MediaQueryListEvent) => {
      if (window.matchMedia('print').matches || previousMediaIsPrint.current) {
        previousMediaIsPrint.current = window.matchMedia('print').matches;
        return;
      }
      setColorMode(matches ? ColorModes.dark : ColorModes.light);
    };
    mql.addListener(onChange);
    return () => mql.removeListener(onChange);
  }, [setColorMode, disableSwitch, respectPrefersColorScheme]);

  return useMemo(
    () => ({
      colorMode,
      setColorMode,
      get isDarkTheme() {
        if (process.env.NODE_ENV === 'development') {
          console.error(
            '`useColorMode().isDarkTheme` is deprecated. Please use `useColorMode().colorMode === "dark"` instead.',
          );
        }
        return colorMode === ColorModes.dark;
      },
      setLightTheme() {
        if (process.env.NODE_ENV === 'development') {
          console.error(
            '`useColorMode().setLightTheme` is deprecated. Please use `useColorMode().setColorMode("light")` instead.',
          );
        }
        setColorMode(ColorModes.light);
        storeColorMode(ColorModes.light);
      },
      setDarkTheme() {
        if (process.env.NODE_ENV === 'development') {
          console.error(
            '`useColorMode().setDarkTheme` is deprecated. Please use `useColorMode().setColorMode("dark")` instead.',
          );
        }
        setColorMode(ColorModes.dark);
        storeColorMode(ColorModes.dark);
      },
    }),
    [colorMode, setColorMode],
  );
}