# All files / src/theme useColorSchemeProvider.ts

100% Statements 116/116
100% Branches 6/6
100% Functions 1/1
100% Lines 116/116

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    1171x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    1x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
    4x
     "use client";
    import { useMemo } from "react";
    import { type UseStateInitializer } from "../types.js";
    import { useEnsuredState } from "../useEnsuredState.js";
    import {
      type ColorSchemeContext,
      type ColorSchemeMode,
      type ColorSchemeModeBehavior,
    } from "./useColorScheme.js";
    import { useColorSchemeMetaTag } from "./useColorSchemeMetaTag.js";
    import { usePrefersDarkTheme } from "./usePrefersColorScheme.js";

    /**
     * @remarks \@since 6.0.0
     */
    export interface ColorSchemeProviderOptions
      extends Partial<ColorSchemeModeBehavior> {
      /**
       * Set this to `true` to prevent a `<meta name="color-scheme" content="{COLOR_SCHEME}">`
       * from being added to the `document.head`.
       *
       * @defaultValue `false`
       */
      disableMetaTag?: boolean;

      /**
       * The current color scheme mode that is being used by your app. This should
       * match the `$color-scheme` SCSS variable.
       *
       * @defaultValue `"light"`
       */
      defaultColorSchemeMode?: UseStateInitializer<ColorSchemeMode>;
    }

    /**
     * @example
     * ```tsx
     * import {
     *   ColorSchemeProvider,
     *   useColorSchemeProvider,
     *   type ColorSchemeMode,
     * } from "@react-md/core";
     * import { type PropsWithChildren, type ReactElement } from "react";
     * import Cookies from "js-cookie";
     *
     * function MyColorSchemeProvider(props: PropsWithChildren): ReactElement {
     *   const { children } = props;
     *
     *   const [colorSchemeMode, setColorSchemeMode] = useState<ColorSchemeMode>(
     *     () => Cookies.get("colorSchemeMode") || "system"
     *   );
     *   const value = useColorSchemeProvider({
     *     colorSchemeMode,
     *     setColorSchemeMode(nextValue) {
     *       setColorSchemeMode((prevValue) => {
     *         const value = typeof nextValue === "function"
     *           ? nextValue(prevValue)
     *           : nextValue;
     *
     *         Cookies.set("colorSchemeMode", value);
     *         return value;
     *       });
     *     }
     *   });
     *
     *   return <ColorSchemeProvider value={value}>{children}</ColorSchemeProvider>
     * }
     * ```
     * @remarks \@since 6.0.0
     */
    export function useColorSchemeProvider(
      options?: { [key in keyof ColorSchemeModeBehavior]?: never } & {
        disableMetaTag?: boolean;
        defaultColorSchemeMode?: UseStateInitializer<ColorSchemeMode>;
      }
    ): ColorSchemeContext;
    export function useColorSchemeProvider(
      options: ColorSchemeModeBehavior & {
        disableMetaTag?: boolean;
        defaultColorSchemeMode?: never;
      }
    ): ColorSchemeContext;
    export function useColorSchemeProvider(
      options: ColorSchemeProviderOptions = {}
    ): ColorSchemeContext {
      const {
        disableMetaTag,
        colorSchemeMode: value,
        setColorSchemeMode: setValue,
        defaultColorSchemeMode,
      } = options;

      const [colorSchemeMode, setColorSchemeMode] = useEnsuredState({
        value,
        setValue,
        defaultValue: defaultColorSchemeMode,
      });
      const prefersDarkTheme = usePrefersDarkTheme(colorSchemeMode !== "system");
      const derivedColorScheme = prefersDarkTheme ? "dark" : "light";
      const colorScheme =
        colorSchemeMode === "system" ? derivedColorScheme : colorSchemeMode;

      useColorSchemeMetaTag({
        disabled: disableMetaTag,
        colorScheme,
      });

      return useMemo<ColorSchemeContext>(
        () => ({
          colorScheme,
          colorSchemeMode,
          setColorSchemeMode,
        }),
        [colorScheme, colorSchemeMode, setColorSchemeMode]
      );
    }