native-variants
Version:
A library for handling variants in React Native components with theme support.
1 lines • 2.13 kB
JavaScript
import React,{createContext,useCallback,useContext,useEffect,useMemo,useState}from"react";import{Appearance}from"react-native";const ThemeContext=createContext(undefined);function resolveColorScheme(mode,systemScheme){if(mode==="system"){return systemScheme==="dark"?"dark":"light"}return mode}export function ThemeProvider({children,colors,defaultMode="system",onGetStorage,onSetStorage}){const[mode,setModeState]=useState(defaultMode);const[systemScheme,setSystemScheme]=useState(Appearance.getColorScheme());const[isHydrated,setIsHydrated]=useState(!onGetStorage);useEffect(()=>{if(onGetStorage){onGetStorage().then(storedMode=>{if(storedMode){setModeState(storedMode)}setIsHydrated(true)})}},[onGetStorage]);useEffect(()=>{const subscription=Appearance.addChangeListener(({colorScheme})=>{setSystemScheme(colorScheme)});return()=>subscription.remove()},[]);const setMode=useCallback(newMode=>{setModeState(newMode);if(onSetStorage){onSetStorage(newMode)}},[onSetStorage]);const toggle=useCallback(()=>{const currentScheme=resolveColorScheme(mode,systemScheme);const newMode=currentScheme==="light"?"dark":"light";setMode(newMode)},[mode,systemScheme,setMode]);const value=useMemo(()=>{const colorScheme=resolveColorScheme(mode,systemScheme);return{colorScheme,mode,isDark:colorScheme==="dark",colors:colorScheme==="dark"?colors.dark:colors.default,setMode,toggle}},[mode,systemScheme,colors,setMode,toggle]);if(!isHydrated){return null}return React.createElement(ThemeContext.Provider,{value:value},children)}export function useTheme(){const context=useContext(ThemeContext);if(!context){throw new Error("useTheme must be used within a ThemeProvider. "+"Make sure to wrap your app with <ThemeProvider colors={colorScheme}>.")}return context}export function useThemeColors(){const{colors}=useTheme();return colors}export function useIsDark(){const{isDark}=useTheme();return isDark}export function useColorScheme(){const{colorScheme}=useTheme();return colorScheme}export function createThemedStyles(styleFactory){return function useThemedStyles(){const{colors}=useTheme();return useMemo(()=>styleFactory(colors),[colors])}}