Merge pull request #67 from brunolemos/fix/react-16

Fix for React Native to 0.43.3+ / React 16+
This commit is contained in:
Jean Regisser
2017-06-03 16:45:20 +02:00
committed by GitHub
3 changed files with 113 additions and 124 deletions

View File

@@ -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

View File

@@ -1,6 +1,6 @@
{
"name": "react-native-slider",
"version": "0.9.1",
"version": "0.10.0",
"description": "A pure JavaScript <Slider /> 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"
}
}

View File

@@ -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({
<View {...other} style={[mainStyles.container, style]} onLayout={this._measureContainer}>
<View
style={[{backgroundColor: maximumTrackTintColor,}, mainStyles.track, trackStyle]}
renderToHardwareTextureAndroid={true}
onLayout={this._measureTrack} />
<Animated.View style={[mainStyles.track, trackStyle, minimumTrackStyle]} />
<Animated.View
renderToHardwareTextureAndroid={true}
style={[mainStyles.track, trackStyle, minimumTrackStyle]} />
<Animated.View
onLayout={this._measureThumb}
renderToHardwareTextureAndroid={true}
style={[
{backgroundColor: thumbTintColor},
mainStyles.thumb, thumbStyle,
{
transform: [
{ translateX: thumbLeft },
{ translateY: -(trackSize.height + thumbSize.height) / 2 }
{ translateY: 0 }
],
...valueVisibleStyle
}
@@ -289,13 +277,14 @@ var Slider = React.createClass({
{this._renderThumbImage()}
</Animated.View>
<View
renderToHardwareTextureAndroid={true}
style={[defaultStyles.touchArea, touchOverflowStyle]}
{...this._panResponder.panHandlers}>
{debugTouchArea === true && this._renderDebugThumbTouchRect(thumbLeft)}
</View>
</View>
);
},
};
_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 <Image source={thumbImage} />;
}
});
};
}
var defaultStyles = StyleSheet.create({
container: {
@@ -546,5 +537,3 @@ var defaultStyles = StyleSheet.create({
opacity: 0.5,
}
});
module.exports = Slider;