UNPKG

react-native-shimmer-placeholder

Version:

<h2 align="center"> React Native Shimmer Placeholder </h2> <p align="center"> <a href="https://www.npmjs.com/package/react-native-shimmer-placeholder"><img src="https://img.shields.io/npm/v/react-native-shimmer-placeholder.svg?style=flat-square"></a>

160 lines (153 loc) 4.25 kB
import { Animated, Platform, StyleSheet, View } from "react-native"; // import liraries import React, { Component } from "react"; import LinearGradient from "react-native-linear-gradient"; import PropTypes from "prop-types"; // create a component class ShimmerPlaceHolder extends Component { constructor(props) { super(props); this.state = { beginShimmerPosition: new Animated.Value(-1) }; } componentDidMount() { const { autoRun } = this.props; if (autoRun) { this.loopAnimated(); } } componentWillUnmount() { const shimmerAnimated = this.getAnimated(); shimmerAnimated.stop(); } loopAnimated() { const shimmerAnimated = this.getAnimated(); const { visible } = this.props; shimmerAnimated.start(({ finished }) => { if (!visible && finished) { this.loopAnimated(); } }); } getAnimated = () => { this.state.beginShimmerPosition.setValue(-1); return Animated.timing(this.state.beginShimmerPosition, { toValue: 1, delay: this.props.delay, duration: this.props.duration, useNativeDriver: true, isInteraction: this.props.isInteraction }); }; render() { const { width, reverse, height, colorShimmer, style, widthShimmer, children, visible, backgroundColorBehindBorder, hasBorder, location } = this.props; let outputRange = [-width, width]; if (reverse) { outputRange = outputRange.reverse(); } const linearTranslate = this.state.beginShimmerPosition.interpolate({ inputRange: [-1, 1], outputRange: outputRange }); return ( <View style={!visible ? [{ height, width }, styles.container, style] : []} > {!visible ? ( <View style={{ flex: 1, backgroundColor: colorShimmer[0] }}> {/* USING TRANSFORM */} <Animated.View style={{ flex: 1, transform: [{ translateX: linearTranslate }] }} > <LinearGradient colors={colorShimmer} style={{ flex: 1, width: width * widthShimmer }} start={{ x: -1, y: 0.5 }} end={{ x: 2, y: 0.5 }} locations={location} /> </Animated.View> {/* Force run children */} <View style={{ width: 0, height: 0 }}>{this.props.children}</View> {/* If style has border */} {((style && style.borderRadius) || hasBorder) && Platform.OS === "android" ? ( <View style={{ position: "absolute", top: -40, bottom: -40, right: -40, left: -40, borderRadius: style.borderRadius || width / 2 + 40 / 2, borderWidth: 40, borderColor: backgroundColorBehindBorder }} /> ) : null} </View> ) : ( children )} </View> ); } } ShimmerPlaceHolder.defaultProps = { width: 200, height: 15, widthShimmer: 1, duration: 1000, delay: 0, colorShimmer: ["#ebebeb", "#c5c5c5", "#ebebeb"], reverse: false, autoRun: false, visible: false, backgroundColorBehindBorder: "white", hasBorder: false, location: [0.3, 0.5, 0.7], isInteraction: true }; // define your styles const styles = StyleSheet.create({ container: { overflow: "hidden" } }); ShimmerPlaceHolder.propTypes = { width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), widthShimmer: PropTypes.number, duration: PropTypes.number, delay: PropTypes.number, colorShimmer: PropTypes.array, reverse: PropTypes.bool, autoRun: PropTypes.bool, visible: PropTypes.bool, children: PropTypes.any, style: PropTypes.any, backgroundColorBehindBorder: PropTypes.string, hasBorder: PropTypes.bool, location: PropTypes.array, isInteraction: PropTypes.bool }; export default ShimmerPlaceHolder;