import * as React from "react"; import { Animated, Platform, StyleSheet, View } from "react-native"; const getOutputRange = (width, isReversed) => isReversed ? [width, -width] : [-width, width]; type Props = { width?: number, height?: number, delay?: number, duration?: number, isInteraction?: boolean, }; type State = { beginShimmerPosition?: Animated.Value, }; const defaultProps = { delay: 0, duration: 1000, isInteraction: true }; class ShimmerPlaceholder extends React.PureComponent { static defaultProps = defaultProps; state = { beginShimmerPosition: new Animated.Value(-1) } getAnimated = () => { const { delay, duration, isInteraction } = this.props; return Animated.loop(Animated.timing(this.state.beginShimmerPosition, { toValue: 1, delay, duration, useNativeDriver: !["web"].includes(Platform.OS), isInteraction })); } animatedValue = this.getAnimated() render() { return ( ); } } const BasedShimmerPlaceholder = (props) => { const { width = 200, height = 15, // duration = 1000, // delay = 0, shimmerColors = ["#ebebeb", "#c5c5c5", "#ebebeb"], isReversed = false, stopAutoRun = false, visible, location = [0.3, 0.5, 0.7], style, contentStyle, shimmerStyle, // isInteraction = true, LinearGradient = View, // LinearGradient = global.Expo ? global.Expo.LinearGradient : View, children, animatedValue, beginShimmerPosition, shimmerWidthPercent = 1, } = props; const linearTranslate = beginShimmerPosition.interpolate({ inputRange: [-1, 1], outputRange: getOutputRange(width, isReversed) }); React.useEffect(() => { if (!stopAutoRun) { animatedValue.start(); } return () => { animatedValue.stop(); }; }, [stopAutoRun]); React.useEffect(() => { if (visible) { animatedValue.stop(); } if (!visible && !stopAutoRun) { animatedValue.start(); } }, [visible, stopAutoRun]); return ( {/* Force render children to restrict rendering twice */} {children} { !visible && ( ) } ); }; const styles = StyleSheet.create({ container: { overflow: "hidden" }, }); /** * To create ShimmerPlaceholder by Linear Gradient. Only useful when you use 3rd party, * For example: react-native-linear-gradient * @param {Linear Gradient Component} LinearGradient - 'expo-linear-gradient' by default * * @example * * import LinearGradient from 'react-native-linear-gradient'; * import { createShimmerPlaceholder } from 'react-native-shimmer-placeholder' * * const ShimmerPlaceHolder = createShimmerPlaceholder(LinearGradient) * * ... * * */ export const createShimmerPlaceholder = (LinearGradient = View) => React.forwardRef((props, ref) => // @ts-ignore ); export default ShimmerPlaceholder;