All files / packages/ui/src/themes ThemeContext.tsx

100% Statements 17/17
100% Branches 8/8
100% Functions 4/4
100% Lines 17/17

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                    24x         24x             24x                         24x         24x 6x   6x 6x       6x 6x               6x   6x                 24x 668x 668x 663x           5x    
/// <reference types="nativewind/types" />
import React, { createContext, useContext, useMemo } from "react";
import { View } from "react-native";
 
import { darkColors, lightColors } from "./colors";
import { metrics } from "./metrics";
import { Theme, ThemeMode } from "./types";
import { textStyles } from "./typography";
import { createThemeVars } from "./utils";
 
export const themeVars = {
  light: createThemeVars(lightColors),
  dark: createThemeVars(darkColors),
};
 
export const lightTheme: Theme = {
  colors: lightColors,
  metrics,
  typography: textStyles,
  isDark: false,
};
 
export const darkTheme: Theme = {
  colors: darkColors,
  metrics,
  typography: textStyles,
  isDark: true,
};
 
interface ThemeContextValue {
  theme: Theme;
  mode: ThemeMode;
  isDark: boolean;
}
 
const ThemeContext = createContext<ThemeContextValue | undefined>(undefined);
 
export const ThemeProvider: React.FC<{
  children: React.ReactNode;
  mode?: ThemeMode;
}> = ({ children, mode: overrideMode }) => {
  const mode = overrideMode || "light";
 
  const theme = useMemo(
    () => (mode === "dark" ? darkTheme : lightTheme),
    [mode],
  );
 
  const value = useMemo(
    () => ({
      theme,
      mode,
      isDark: mode === "dark",
    }),
    [mode, theme],
  );
 
  const activeVars = themeVars[mode] || themeVars.light;
 
  return (
    <ThemeContext.Provider value={value}>
      <View style={activeVars} className="flex-1">
        {children}
      </View>
    </ThemeContext.Provider>
  );
};
 
export const useTheme = () => {
  const context = useContext(ThemeContext);
  if (!context) {
    return {
      theme: lightTheme,
      mode: "light" as ThemeMode,
      isDark: false,
    };
  }
  return context;
};