UNPKG

@kirz/react-native-toolkit

Version:

Toolkit to speed up React Native development

100 lines 3.82 kB
import Color from 'color'; import fontColorContrast from 'font-color-contrast'; import React, { createContext, useEffect, useMemo } from 'react'; import { cancelAnimation, interpolateColor, useAnimatedStyle, useSharedValue, withRepeat, withTiming } from 'react-native-reanimated'; import { useColorScheme } from '../hooks/useColorScheme'; export const ThemeContext = /*#__PURE__*/createContext({}); export function ThemeProvider(_ref) { let { children, theme } = _ref; const { colorScheme } = useColorScheme(); const skeletonValue = useSharedValue(0); const computedTheme = useMemo(() => { // @ts-ignore const colorsDef = theme.colors; const colors = Object.fromEntries(Object.entries(colorsDef).map(_ref2 => { let [name, color] = _ref2; if (typeof color === 'object' && typeof color !== 'function') { // @ts-ignore return [name, color[colorScheme]]; } return [name, color]; })); const typographyDef = theme.typography; const typography = Object.fromEntries(Object.entries(typographyDef).map(_ref3 => { let [name, textStyle] = _ref3; if (textStyle.color && typeof textStyle.color === 'object') { return [name, { ...textStyle, color: textStyle.color[colorScheme] }]; } return [name, textStyle]; })); const tempTheme = { ...theme, colors: colors, typography, getContrastColor: color => fontColorContrast(color) === '#ffffff' ? 'white' : 'black', parseColor: (obj, model) => new Color(obj, model) }; const finalColors = Object.fromEntries(Object.entries(colors).map(_ref4 => { let [name, color] = _ref4; if (typeof color === 'function') { // @ts-ignore return [name, color(tempTheme)]; } return [name, color]; })); return { ...tempTheme, colors: finalColors, getContrastColor: color => fontColorContrast(color) === '#ffffff' ? 'white' : 'black', parseColor: (obj, model) => new Color(obj, model) }; }, [theme, colorScheme]); const skeletonDef = useMemo(() => { return { color: computedTheme.colors.skeleton, // @ts-ignore interval: computedTheme.values.skeletonAnimationInterval ?? 800, // @ts-ignore transform: computedTheme.values.skeletonColorTransform ?? 0.3 }; }, [computedTheme]); const skeletonColors = useMemo(() => { const skeletonColorTransform = skeletonDef.transform; const color1 = skeletonDef.color; const colorObj = skeletonColorTransform < 0 ? computedTheme.parseColor(color1, 'rgb').darken(Math.abs(skeletonColorTransform)) : computedTheme.parseColor(color1, 'rgb').lighten(skeletonColorTransform); const color2 = `rgba(${colorObj.red()},${colorObj.green()},${colorObj.blue()},${colorObj.alpha()})`; return { color1, color2 }; }, [computedTheme, skeletonDef]); const skeletonStyle = useAnimatedStyle(() => ({ backgroundColor: interpolateColor(skeletonValue.value, [0, 1], [(skeletonColors === null || skeletonColors === void 0 ? void 0 : skeletonColors.color1) ?? 'rgba(255,255,255,0.3)', (skeletonColors === null || skeletonColors === void 0 ? void 0 : skeletonColors.color2) ?? 'rgba(255,255,255,0.3)']) }), [skeletonColors]); const contextData = useMemo(() => { return { theme: computedTheme, skeletonStyle }; }, [computedTheme, skeletonStyle]); useEffect(() => { skeletonValue.value = withRepeat(withTiming(1, { duration: skeletonDef.interval }), -1, true); return () => { cancelAnimation(skeletonValue); }; }, [skeletonDef.interval]); return /*#__PURE__*/React.createElement(ThemeContext.Provider, { value: contextData }, children); } //# sourceMappingURL=ThemeContext.js.map