From 6bd2fa4aa4fc93cc33a854dda5b157f691c814ae Mon Sep 17 00:00:00 2001 From: Bruno Lemos Date: Mon, 10 Apr 2017 20:07:24 -0300 Subject: [PATCH] Fix for React Native to 0.43.3+ / React 16+ --- README.md | 1 + package.json | 15 ++-- src/Slider.js | 223 ++++++++++++++++++++++++-------------------------- 3 files changed, 114 insertions(+), 125 deletions(-) diff --git a/README.md b/README.md index d13e06f1..a8c94921 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ npm i --save react-native-slider | <0.25.0 | <0.7.0 | | v0.25.x | v0.7.x | | v0.26.0+ | v0.8.x | +| v0.43.0+ | v0.10.x | ## Usage diff --git a/package.json b/package.json index f85c19ae..decd5d6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-slider", - "version": "0.9.1", + "version": "0.10.0", "description": "A pure JavaScript component for react-native", "main": "lib/Slider.js", "files": [ @@ -27,16 +27,15 @@ "url": "git@github.com:jeanregisser/react-native-slider.git" }, "dependencies": { - "react-addons-shallow-compare": "^15.0.2", - "style-equal": "^1.0.0" + "prop-types": "^15.5.6" }, "devDependencies": { "babel-cli": "^6.6.5", - "babel-eslint": "^3.1.15", - "eslint": "^0.23.0", - "eslint-plugin-react": "^2.5.2", - "react": "15.2.1", - "react-native": "^0.31.0", + "babel-eslint": "^7.2.1", + "eslint": "^3.19.0", + "eslint-plugin-react": "^6.10.3", + "react": "16.0.0-alpha.6", + "react-native": "0.43.3", "rimraf": "^2.5.2" } } diff --git a/src/Slider.js b/src/Slider.js index 92d94347..e0d7f11a 100644 --- a/src/Slider.js +++ b/src/Slider.js @@ -1,8 +1,7 @@ 'use strict'; import React, { - Component, - PropTypes + PureComponent, } from "react"; import { @@ -14,8 +13,7 @@ import { Easing } from "react-native"; -const shallowCompare = require('react-addons-shallow-compare'), - styleEqual = require('style-equal'); +import PropTypes from 'prop-types'; var TRACK_SIZE = 4; var THUMB_SIZE = 20; @@ -50,8 +48,8 @@ var DEFAULT_ANIMATION_CONFIGS = { // } }; -var Slider = React.createClass({ - propTypes: { +export default class Slider extends PureComponent { + static propTypes = { /** * Initial value of the slider. The value should be between minimumValue * and maximumValue, which default to 0 and 1 respectively. @@ -155,43 +153,42 @@ var Slider = React.createClass({ debugTouchArea: PropTypes.bool, /** - * Set to true to animate values with default 'timing' animation type - */ + * Set to true to animate values with default 'timing' animation type + */ animateTransitions : PropTypes.bool, /** - * Custom Animation type. 'spring' or 'timing'. - */ + * Custom Animation type. 'spring' or 'timing'. + */ animationType : PropTypes.oneOf(['spring', 'timing']), /** - * Used to configure the animation parameters. These are the same parameters in the Animated library. - */ + * Used to configure the animation parameters. These are the same parameters in the Animated library. + */ animationConfig : PropTypes.object, - }, - getInitialState() { - return { - containerSize: {width: 0, height: 0}, - trackSize: {width: 0, height: 0}, - thumbSize: {width: 0, height: 0}, - allMeasured: false, - value: new Animated.Value(this.props.value), - }; - }, - getDefaultProps() { - return { - value: 0, - minimumValue: 0, - maximumValue: 1, - step: 0, - minimumTrackTintColor: '#3f3f3f', - maximumTrackTintColor: '#b3b3b3', - thumbTintColor: '#343434', - thumbTouchSize: {width: 40, height: 40}, - debugTouchArea: false, - animationType: 'timing' - }; - }, + }; + + static defaultProps = { + value: 0, + minimumValue: 0, + maximumValue: 1, + step: 0, + minimumTrackTintColor: '#3f3f3f', + maximumTrackTintColor: '#b3b3b3', + thumbTintColor: '#343434', + thumbTouchSize: {width: 40, height: 40}, + debugTouchArea: false, + animationType: 'timing' + }; + + state = { + containerSize: {width: 0, height: 0}, + trackSize: {width: 0, height: 0}, + thumbSize: {width: 0, height: 0}, + allMeasured: false, + value: new Animated.Value(this.props.value), + }; + componentWillMount() { this._panResponder = PanResponder.create({ onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder, @@ -202,8 +199,9 @@ var Slider = React.createClass({ onPanResponderTerminationRequest: this._handlePanResponderRequestEnd, onPanResponderTerminate: this._handlePanResponderEnd, }); - }, - componentWillReceiveProps: function(nextProps) { + }; + + componentWillReceiveProps(nextProps) { var newValue = nextProps.value; if (this.props.value !== newValue) { @@ -214,21 +212,8 @@ var Slider = React.createClass({ this._setCurrentValue(newValue); } } - }, - shouldComponentUpdate: function(nextProps, nextState) { - // We don't want to re-render in the following cases: - // - when only the 'value' prop changes as it's already handled with the Animated.Value - // - when the event handlers change (rendering doesn't depend on them) - // - when the style props haven't actually change - - return shallowCompare( - { props: this._getPropsForComponentUpdate(this.props), state: this.state }, - this._getPropsForComponentUpdate(nextProps), - nextState - ) || !styleEqual(this.props.style, nextProps.style) - || !styleEqual(this.props.trackStyle, nextProps.trackStyle) - || !styleEqual(this.props.thumbStyle, nextProps.thumbStyle); - }, + }; + render() { var { minimumValue, @@ -247,10 +232,10 @@ var Slider = React.createClass({ var {value, containerSize, trackSize, thumbSize, allMeasured} = this.state; var mainStyles = styles || defaultStyles; var thumbLeft = value.interpolate({ - inputRange: [minimumValue, maximumValue], - outputRange: [0, containerSize.width - thumbSize.width], - //extrapolate: 'clamp', - }); + inputRange: [minimumValue, maximumValue], + outputRange: [0, containerSize.width - thumbSize.width], + //extrapolate: 'clamp', + }); var valueVisibleStyle = {}; if (!allMeasured) { valueVisibleStyle.opacity = 0; @@ -259,7 +244,6 @@ var Slider = React.createClass({ var minimumTrackStyle = { position: 'absolute', width: Animated.add(thumbLeft, thumbSize.width / 2), - marginTop: -trackSize.height, backgroundColor: minimumTrackTintColor, ...valueVisibleStyle }; @@ -270,17 +254,21 @@ var Slider = React.createClass({ - + {debugTouchArea === true && this._renderDebugThumbTouchRect(thumbLeft)} ); - }, + }; _getPropsForComponentUpdate(props) { var { @@ -310,56 +299,59 @@ var Slider = React.createClass({ } = props; return otherProps; - }, + }; - _handleStartShouldSetPanResponder: function(e: Object, /*gestureState: Object*/): boolean { + _handleStartShouldSetPanResponder = (e: Object, /*gestureState: Object*/): boolean => { // Should we become active when the user presses down on the thumb? return this._thumbHitTest(e); - }, + }; - _handleMoveShouldSetPanResponder: function(/*e: Object, gestureState: Object*/): boolean { + _handleMoveShouldSetPanResponder(/*e: Object, gestureState: Object*/): boolean { // Should we become active when the user moves a touch over the thumb? return false; - }, + }; - _handlePanResponderGrant: function(/*e: Object, gestureState: Object*/) { + _handlePanResponderGrant = (/*e: Object, gestureState: Object*/) => { this._previousLeft = this._getThumbLeft(this._getCurrentValue()); this._fireChangeEvent('onSlidingStart'); - }, - _handlePanResponderMove: function(e: Object, gestureState: Object) { + }; + + _handlePanResponderMove = (e: Object, gestureState: Object) => { if (this.props.disabled) { return; } this._setCurrentValue(this._getValue(gestureState)); this._fireChangeEvent('onValueChange'); - }, - _handlePanResponderRequestEnd: function(e: Object, gestureState: Object) { + }; + + _handlePanResponderRequestEnd(e: Object, gestureState: Object) { // Should we allow another component to take over this pan? return false; - }, - _handlePanResponderEnd: function(e: Object, gestureState: Object) { + }; + + _handlePanResponderEnd = (e: Object, gestureState: Object) => { if (this.props.disabled) { return; } this._setCurrentValue(this._getValue(gestureState)); this._fireChangeEvent('onSlidingComplete'); - }, + }; - _measureContainer(x: Object) { + _measureContainer = (x: Object) => { this._handleMeasure('containerSize', x); - }, + }; - _measureTrack(x: Object) { + _measureTrack = (x: Object) => { this._handleMeasure('trackSize', x); - }, + }; - _measureThumb(x: Object) { + _measureThumb = (x: Object) => { this._handleMeasure('thumbSize', x); - }, + }; - _handleMeasure(name: string, x: Object) { + _handleMeasure = (name: string, x: Object) => { var {width, height} = x.nativeEvent.layout; var size = {width: width, height: height}; @@ -378,18 +370,18 @@ var Slider = React.createClass({ allMeasured: true, }) } - }, + }; - _getRatio(value: number) { + _getRatio = (value: number) => { return (value - this.props.minimumValue) / (this.props.maximumValue - this.props.minimumValue); - }, + }; - _getThumbLeft(value: number) { + _getThumbLeft = (value: number) => { var ratio = this._getRatio(value); return ratio * (this.state.containerSize.width - this.state.thumbSize.width); - }, + }; - _getValue(gestureState: Object) { + _getValue = (gestureState: Object) => { var length = this.state.containerSize.width - this.state.thumbSize.width; var thumbLeft = this._previousLeft + gestureState.dx; @@ -408,35 +400,35 @@ var Slider = React.createClass({ ) ); } - }, + }; - _getCurrentValue() { + _getCurrentValue = () => { return this.state.value.__getValue(); - }, + }; - _setCurrentValue(value: number) { + _setCurrentValue = (value: number) => { this.state.value.setValue(value); - }, + }; - _setCurrentValueAnimated(value: number) { + _setCurrentValueAnimated = (value: number) => { var animationType = this.props.animationType; var animationConfig = Object.assign( - {}, - DEFAULT_ANIMATION_CONFIGS[animationType], - this.props.animationConfig, - {toValue : value} - ); + {}, + DEFAULT_ANIMATION_CONFIGS[animationType], + this.props.animationConfig, + {toValue : value} + ); Animated[animationType](this.state.value, animationConfig).start(); - }, + }; - _fireChangeEvent(event) { + _fireChangeEvent = (event) => { if (this.props[event]) { this.props[event](this._getCurrentValue()); } - }, + }; - _getTouchOverflowSize() { + _getTouchOverflowSize = () => { var state = this.state; var props = this.props; @@ -447,9 +439,9 @@ var Slider = React.createClass({ } return size; - }, + }; - _getTouchOverflowStyle() { + _getTouchOverflowStyle = () => { var {width, height} = this._getTouchOverflowSize(); var touchOverflowStyle = {}; @@ -469,15 +461,15 @@ var Slider = React.createClass({ } return touchOverflowStyle; - }, + }; - _thumbHitTest(e: Object) { + _thumbHitTest = (e: Object) => { var nativeEvent = e.nativeEvent; var thumbTouchRect = this._getThumbTouchRect(); return thumbTouchRect.containsPoint(nativeEvent.locationX, nativeEvent.locationY); - }, + }; - _getThumbTouchRect() { + _getThumbTouchRect = () => { var state = this.state; var props = this.props; var touchOverflowSize = this._getTouchOverflowSize(); @@ -488,9 +480,9 @@ var Slider = React.createClass({ props.thumbTouchSize.width, props.thumbTouchSize.height ); - }, + }; - _renderDebugThumbTouchRect(thumbLeft) { + _renderDebugThumbTouchRect = (thumbLeft) => { var thumbTouchRect = this._getThumbTouchRect(); var positionStyle = { left: thumbLeft, @@ -505,17 +497,16 @@ var Slider = React.createClass({ pointerEvents='none' /> ); - }, + }; - _renderThumbImage() { + _renderThumbImage = () => { var {thumbImage} = this.props; if (!thumbImage) return; return ; - } -}); - + }; +} var defaultStyles = StyleSheet.create({ container: { @@ -546,5 +537,3 @@ var defaultStyles = StyleSheet.create({ opacity: 0.5, } }); - -module.exports = Slider;