@kirz/react-native-toolkit
Version:
Toolkit to speed up React Native development
100 lines • 3.82 kB
JavaScript
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