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

184 lines (159 loc) 4.38 kB
import React from 'react'; import PropTypes from 'prop-types'; import {StyleSheet, View, Animated} from 'react-native'; import Interactable from 'react-native-interactable'; import _ from 'lodash'; import {Constants} from '../../helpers'; import {BaseComponent} from '../../commons'; import * as presenter from './CarouselPresenter'; export default class Carousel2 extends BaseComponent { static displayName = 'IGNORE'; static propTypes = { pageWidth: PropTypes.number, initialPage: PropTypes.number, loop: PropTypes.bool, }; static defaultProps = { pageWidth: Constants.screenWidth, initialPage: 0, }; constructor(props) { super(props); this.deltaX = new Animated.Value(0); this.onStop = this.onStop.bind(this); this.state = { currentPage: props.initialPage, }; } componentWillMount() { this.updateCarouselPosition(); } onStop(event) { const offset = event.nativeEvent.x; const newPage = presenter.calcPageIndex(-offset, this.props); const {currentPage} = this.state; this.setState({ currentPage: newPage, }, () => { if (currentPage !== newPage) { _.invoke(this.props, 'onChangePage', newPage, currentPage); } }); if (presenter.isOutOfBounds(-offset, this.props)) { this.updateCarouselPosition(); } } updateCarouselPosition() { const position = { x: -presenter.calcOffset(this.props, this.state), y: 0, }; this.setState({position}); if (!this.carousel) { return; } this.carousel.snapTo({index: 1}); } getSnappingPoints() { const {pageWidth, loop} = this.props; let length = presenter.getChildrenLength(this.props); if (loop) { length += 2; } const snappingPoints = _.times(length, (i) => { return { x: -i * pageWidth, id: i, tension: 500, damping: 0.6, }; }); return snappingPoints; } // generateInputRange() { // const {pageWidth} = this.props; // return _.times(this.getPagesLength(), i => -i * pageWidth).reverse(); // } // generateOutputRange(index, values) { // const {pageWidth} = this.props; // const inputRange = this.generateInputRange(); // return _.map(inputRange, (input) => { // const valueIndex = Number(-index * pageWidth === input); // return values[valueIndex]; // }); // } generateStyles() { this.styles = createStyles(this.props); } cloneChild(child) { if (!child.key) { return child; } return React.cloneElement(child, { key: `${child.key}-clone`, }); } renderPages() { const {loop} = this.props; let {children} = this.props; const length = presenter.getChildrenLength(this.props); if (loop) { children = [ this.cloneChild(children[length - 1]), ...children, this.cloneChild(children[0]), ]; } return children; // const inputRange = this.generateInputRange(); // return _.forEach(children, (page) => { // const titleStyle = { // color: this.deltaX.interpolate({ // inputRange, // outputRange: this.generateOutputRange(pageIndex, [Colors.dark60, Colors.dark10]), // }), // transform: [{ // scale: this.deltaX.interpolate({ // inputRange, // outputRange: this.generateOutputRange(pageIndex, [0.8, 1.2]), // }), // }], // }; // return ( // {page} // ); // }); } render() { const carouselWidth = presenter.calcCarouselWidth(this.props); const {position} = this.state; return ( <View style={this.styles.container}> <Interactable.View ref={(carousel) => { this.carousel = carousel; }} horizontalOnly dragToss={0.05} snapPoints={this.getSnappingPoints()} onStop={this.onStop} animatedValueX={this.deltaX} initialPosition={position} style={[this.styles.scrollStrip, {width: carouselWidth}]} > {this.renderPages()} </Interactable.View> </View> ); } } function createStyles() { return StyleSheet.create({ container: { flex: 1, }, scrollStrip: { flexDirection: 'row', flex: 1, borderBottomWidth: 1, }, }); }