All files / ThemeProvider ThemeProvider.tsx

81.08% Statements 30/37
45.83% Branches 11/24
75% Functions 6/8
82.75% Lines 24/29

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 9638x           38x 38x   38x         38x 1890x   38x 1x   1x                                                   38x 5x 5x 5x 5x 5x   5x   5x             5x           38x   38x         5x                   38x         5x 5x        
import React, { createContext, useContext } from "react";
import {
  DefaultTheme,
  ThemeProviderProps,
  ColorPaletteProps,
} from "./ThemeProvider.types";
import { generateRadixColors } from "../../helpers/colors/generateRadixColors";
import colors from "../../tokens/colors.json";
 
const ThemeContext = createContext<DefaultTheme>({
  theme: null,
  setTheme: () => {},
});
 
const useTheme = () => {
  return useContext(ThemeContext);
};
const useUpdateTheme = () => {
  const { setTheme } = useTheme();
 
  return React.useCallback(
    ({
      accents,
      gray = colors.theme.gray,
      appearance = colors.theme.appearance.light as "light" | "dark",
    }: ThemeProviderProps) => {
      const colorPalette = generateColorPalette(accents, appearance, gray);
 
      setTheme(
        colorPalette
          ? {
              colorPalette,
              appearance,
              gray,
              background:
                appearance === "light"
                  ? colors.theme.background.light
                  : colors.theme.background.dark,
            }
          : null
      );
    },
    [setTheme]
  );
};
 
const ThemeProvider = ({
  accents,
  gray = colors.theme.gray,
  appearance = colors.theme.appearance.light as "light" | "dark",
  background,
  children,
}: ThemeProviderProps) => {
  const colorPalette = generateColorPalette(accents, appearance, gray);
 
  const [theme, setTheme] = React.useState(colorPalette ? {
    colorPalette,
    appearance,
    gray,
    background: background ?? appearance === "light" ? colors.theme.background.light : colors.theme.background.dark,
  }: null);
 
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};
export { ThemeProvider, useTheme, useUpdateTheme };
 
const generateThemeAccent = (
  accent: string,
  appearance: "light" | "dark",
  gray: string
) => {
  return {
    main: accent,appearance,
    ...generateRadixColors({
      appearance, accent, gray,
      background: appearance === "light" 
        ? colors.theme.background.light 
        : colors.theme.background.dark,
    }),
  };
};
const generateColorPalette = (
  accents: ThemeProviderProps["accents"],
  appearance: "light" | "dark",
  gray: string
) => {
  return accents ? Object.keys(accents).reduce((palette, key) => {
      return { ...palette, [key]: generateThemeAccent(accents[key], appearance, gray)};
    },
    {} as { [key: string]: ColorPaletteProps }
  ) : null;
}