UNPKG

react-native-ui-lib

Version:

[![Build Status](https://travis-ci.org/wix/react-native-ui-lib.svg?branch=master)](https://travis-ci.org/wix/react-native-ui-lib) [![npm](https://img.shields.io/npm/v/react-native-ui-lib.svg)](https://www.npmjs.com/package/react-native-ui-lib) [![NPM Down

137 lines (136 loc) 4.51 kB
import React from "react"; import { StyleSheet, Animated } from "react-native"; import _ from "lodash"; import { BaseComponent } from "../../commons"; import { Constants } from "../../helpers"; import { Colors } from "../../style"; import View from "../../components/view"; // TODO: add finisher animation (check icon animation or something) // TODO: remove deprecated functionality /** * @description: Scanner component for progress indication * @extends: Animated.View * @extendslink: https://github.com/oblador/react-native-animatable * @gif: https://media.giphy.com/media/l49JVcxoclUXbryiA/giphy.gif * @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/animationScreens/CardScannerScreen.js */ export default class AnimatedScanner extends BaseComponent { constructor(props) { super(props); this.state = { animatedProgress: new Animated.Value(0), isDone: false }; if (!_.isNumber(props.progress)) { console.warn("[react-native-ui-lib]! please check out the new api for AnimatedScanner. progress now accepts number instead of Animated Value"); // eslint-disable-line } } componentDidMount() { const { progress, duration } = this.props; if (progress > 0) { this.animate(progress, duration); } } generateStyles() { this.styles = createStyles(this.props); } componentWillReceiveProps(nextProps) { const { progress } = this.props; if (nextProps.progress !== progress) { this.animate(nextProps.progress, nextProps.duration); } } componentWillUnmount() { this.state.animatedProgress.stopAnimation(); } animate(toValue, duration) { const { animatedProgress } = this.state; Animated.timing(animatedProgress, { toValue, duration }).start(({ finished }) => { if (finished) { const isDone = toValue >= 100; this.setState({ isDone }); _.invoke(this.props, "onBreakpoint", { progress: toValue, isDone }); } }); } renderNew() { const { opacity, backgroundColor, hideScannerLine } = this.props; const { isDone, animatedProgress } = this.state; return (<View style={{ ...StyleSheet.absoluteFillObject }}> <Animated.View style={[ this.styles.container, opacity && { opacity }, backgroundColor && { backgroundColor }, { left: animatedProgress.interpolate({ inputRange: [0, 100], outputRange: ["0%", "100%"] }) } ]}> {isDone && !hideScannerLine && <View style={this.styles.scanner}/>} </Animated.View> </View>); } render() { if (_.isNumber(this.props.progress)) { return this.renderNew(); } // todo: deprecate return this.renderOld(); } // todo: deprecate renderOld() { const { progress, opacity, backgroundColor } = this.props; return (<Animated.View style={[ this.styles.container, opacity && { opacity }, backgroundColor && { backgroundColor }, { right: progress.interpolate({ inputRange: [0, 5, 55, 100], outputRange: [ Constants.screenWidth, Constants.screenWidth / 2, Constants.screenWidth / 3, 0 ] }) } ]}> {JSON.stringify(progress) !== "100" && (<View style={this.styles.scanner}/>)} </Animated.View>); } } AnimatedScanner.displayName = "AnimatedScanner"; AnimatedScanner.defaultProps = { progress: 0, duration: 1000 }; function createStyles() { return StyleSheet.create({ container: { position: "absolute", top: 0, bottom: 0, left: 0, right: 0, backgroundColor: Colors.white, opacity: 0.9 }, scanner: { position: "absolute", left: 0, top: 0, bottom: 0, right: 0, borderWidth: StyleSheet.hairlineWidth, borderColor: Colors.dark50 } }); }