mirror of
https://github.com/zhigang1992/react-native-slider.git
synced 2026-01-12 22:50:54 +08:00
Merge pull request #67 from brunolemos/fix/react-16
Fix for React Native to 0.43.3+ / React 16+
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
15
package.json
15
package.json
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
221
src/Slider.js
221
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({
|
||||
<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;
|
||||
|
||||
Reference in New Issue
Block a user