diff --git a/.gitignore b/.gitignore
index 7329cd05..47d37e31 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,5 @@ local.properties
node_modules/
npm-debug.log
lib
+
+package-lock.json
diff --git a/Example/app.js b/Example/app.js
index d45917f0..682531fc 100644
--- a/Example/app.js
+++ b/Example/app.js
@@ -11,6 +11,7 @@ var {
View,
SliderIOS,
} = ReactNative;
+import { LinearGradient } from 'expo';
var DEFAULT_VALUE = 0.2;
@@ -143,6 +144,51 @@ var SliderExample = React.createClass({
thumbTintColor='#0c6692'
/>
+
+
+ )}
+ customMinimumTrack={(
+
+ )}
+ customThumb={(
+
+ )}
+ />
+
);
},
diff --git a/README.md b/README.md
index 673f3dd4..90f3aad3 100644
--- a/README.md
+++ b/README.md
@@ -73,28 +73,30 @@ Try this example [live on Expo Snack](https://snack.expo.io/HkbAqpbwb).
## Props
-Prop | Type | Optional | Default | Description
---------------------- | -------- | -------- | ------------------------- | -----------
-value | number | Yes | 0 | Initial value of the slider
-disabled | bool | Yes | false | If true the user won't be able to move the slider
-minimumValue | number | Yes | 0 | Initial minimum value of the slider
-maximumValue | number | Yes | 1 | Initial maximum value of the slider
-step | number | Yes | 0 | Step value of the slider. The value should be between 0 and maximumValue - minimumValue)
-minimumTrackTintColor | string | Yes | '#3f3f3f' | The color used for the track to the left of the button
-maximumTrackTintColor | string | Yes | '#b3b3b3' | The color used for the track to the right of the button
-thumbTintColor | string | Yes | '#343434' | The color used for the thumb
-thumbTouchSize | object | Yes | `{width: 40, height: 40}` | The size of the touch area that allows moving the thumb. The touch area has the same center as the visible thumb. This allows to have a visually small thumb while still allowing the user to move it easily.
-onValueChange | function | Yes | | Callback continuously called while the user is dragging the slider
-onSlidingStart | function | Yes | | Callback called when the user starts changing the value (e.g. when the slider is pressed)
-onSlidingComplete | function | Yes | | Callback called when the user finishes changing the value (e.g. when the slider is released)
-style | [style](http://facebook.github.io/react-native/docs/view.html#style) | Yes | | The style applied to the slider container
-trackStyle | [style](http://facebook.github.io/react-native/docs/view.html#style) | Yes | | The style applied to the track
-thumbStyle | [style](http://facebook.github.io/react-native/docs/view.html#style) | Yes | | The style applied to the thumb
-thumbImage | [source](http://facebook.github.io/react-native/docs/image.html#source) | Yes | | Sets an image for the thumb.
-debugTouchArea | bool | Yes | false | Set this to true to visually see the thumb touch rect in green.
-animateTransitions | bool | Yes | false | Set to true if you want to use the default 'spring' animation
-animationType | string | Yes | 'timing' | Set to 'spring' or 'timing' to use one of those two types of animations with the default [animation properties](https://facebook.github.io/react-native/docs/animations.html).
-animationConfig | object | Yes | undefined | Used to configure the animation parameters. These are the same parameters in the [Animated library](https://facebook.github.io/react-native/docs/animations.html).
+Prop | Type | Optional | Default | Description
+--------------------- | --------- | -------- | ------------------------- | -----------
+value | number | Yes | 0 | Initial value of the slider
+disabled | bool | Yes | false | If true the user won't be able to move the slider
+minimumValue | number | Yes | 0 | Initial minimum value of the slider
+customMinimumTrack | number | Yes | 1 | Initial maximum value of the slider
+step | number | Yes | 0 | Step value of the slider. The value should be between 0 and maximumValue - minimumValue)
+minimumTrackTintColor | string | Yes | '#3f3f3f' | The color used for the track to the left of the button
+customMinimumTrack | component | Yes | | Sets an custom component used for the track to the left of the button.
+maximumTrackTintColor | string | Yes | '#b3b3b3' | The color used for the track to the right of the button
+customMaximumTrack | component | Yes | | Sets an custom component used for the track to the right of the button.
+thumbTintColor | string | Yes | '#343434' | The color used for the thumb
+thumbTouchSize | object | Yes | `{width: 40, height: 40}` | The size of the touch area that allows moving the thumb. The touch area has the same center as the visible thumb. This allows to have a visually small thumb while still allowing the user to move it easily.
+onValueChange | function | Yes | | Callback continuously called while the user is dragging the slider
+onSlidingStart | function | Yes | | Callback called when the user starts changing the value (e.g. when the slider is pressed)
+onSlidingComplete | function | Yes | | Callback called when the user finishes changing the value (e.g. when the slider is released)
+style | [style](http://facebook.github.io/react-native/docs/view.html#style) | Yes | | The style applied to the slider container
+trackStyle | [style](http://facebook.github.io/react-native/docs/view.html#style) | Yes | | The style applied to the track
+thumbStyle | [style](http://facebook.github.io/react-native/docs/view.html#style) | Yes | | The style applied to the thumb
+customThumb | component | Yes | | Sets an custom component for the thumb.
+debugTouchArea | bool | Yes | false | Set this to true to visually see the thumb touch rect in green.
+animateTransitions | bool | Yes | false | Set to true if you want to use the default 'spring' animation
+animationType | string | Yes | 'timing' | Set to 'spring' or 'timing' to use one of those two types of animations with the default [animation properties](https://facebook.github.io/react-native/docs/animations.html).
+animationConfig | object | Yes | undefined | Used to configure the animation parameters. These are the same parameters in the [Animated library](https://facebook.github.io/react-native/docs/animations.html).
---
diff --git a/package.json b/package.json
index ef322821..af920a3b 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,13 @@
{
- "name": "react-native-slider",
+ "name": "react-native-slider-custom",
"version": "0.11.0",
- "description": "A pure JavaScript component for react-native",
- "main": "lib/Slider.js",
+ "description": "A pure JavaScript component for react-native [Custom]",
+ "main": "src/Slider.js",
"files": [
"lib",
"src"
],
- "author": "Jean Regisser (https://github.com/jeanregisser)",
+ "author": "Emmanuel Mota forked from jeanregisser/react-native-slider",
"keywords": [
"react-component",
"react-native",
diff --git a/src/Slider.js b/src/Slider.js
index d02d812e..87b3319f 100644
--- a/src/Slider.js
+++ b/src/Slider.js
@@ -1,8 +1,6 @@
'use strict';
-import React, {
- PureComponent,
-} from "react";
+import React, { PureComponent } from 'react';
import {
Animated,
@@ -11,8 +9,8 @@ import {
PanResponder,
View,
Easing,
- ViewPropTypes
-} from "react-native";
+ ViewPropTypes,
+} from 'react-native';
import PropTypes from 'prop-types';
@@ -27,21 +25,23 @@ function Rect(x, y, width, height) {
}
Rect.prototype.containsPoint = function(x, y) {
- return (x >= this.x
- && y >= this.y
- && x <= this.x + this.width
- && y <= this.y + this.height);
+ return (
+ x >= this.x &&
+ y >= this.y &&
+ x <= this.x + this.width &&
+ y <= this.y + this.height
+ );
};
var DEFAULT_ANIMATION_CONFIGS = {
- spring : {
- friction : 7,
- tension : 100
+ spring: {
+ friction: 7,
+ tension: 100,
},
- timing : {
- duration : 150,
- easing : Easing.inOut(Easing.ease),
- delay : 0
+ timing: {
+ duration: 150,
+ easing: Easing.inOut(Easing.ease),
+ delay: 0,
},
// decay : { // This has a serious bug
// velocity : 1,
@@ -89,12 +89,22 @@ export default class Slider extends PureComponent {
*/
minimumTrackTintColor: PropTypes.string,
+ /**
+ * Custom component used for the track to the left of the button.
+ */
+ customMinimumTrack: PropTypes.any,
+
/**
* The color used for the track to the right of the button. Overrides the
* default blue gradient image.
*/
maximumTrackTintColor: PropTypes.string,
+ /**
+ * Custom component used for the track to the right of the button.
+ */
+ customMaximumTrack: PropTypes.any,
+
/**
* The color used for the thumb.
*/
@@ -107,9 +117,10 @@ export default class Slider extends PureComponent {
* to move it easily.
* The default is {width: 40, height: 40}.
*/
- thumbTouchSize: PropTypes.shape(
- {width: PropTypes.number, height: PropTypes.number}
- ),
+ thumbTouchSize: PropTypes.shape({
+ width: PropTypes.number,
+ height: PropTypes.number,
+ }),
/**
* Callback continuously called while the user is dragging the slider.
@@ -144,9 +155,9 @@ export default class Slider extends PureComponent {
thumbStyle: ViewPropTypes.style,
/**
- * Sets an image for the thumb.
+ * Sets an custom component for the thumb.
*/
- thumbImage: Image.propTypes.source,
+ customThumb: PropTypes.any,
/**
* Set this to true to visually see the thumb touch rect in green.
@@ -156,17 +167,17 @@ export default class Slider extends PureComponent {
/**
* Set to true to animate values with default 'timing' animation type
*/
- animateTransitions : PropTypes.bool,
+ animateTransitions: PropTypes.bool,
/**
* Custom Animation type. 'spring' or 'timing'.
*/
- animationType : PropTypes.oneOf(['spring', 'timing']),
+ animationType: PropTypes.oneOf(['spring', 'timing']),
/**
* Used to configure the animation parameters. These are the same parameters in the Animated library.
*/
- animationConfig : PropTypes.object,
+ animationConfig: PropTypes.object,
};
static defaultProps = {
@@ -177,15 +188,15 @@ export default class Slider extends PureComponent {
minimumTrackTintColor: '#3f3f3f',
maximumTrackTintColor: '#b3b3b3',
thumbTintColor: '#343434',
- thumbTouchSize: {width: 40, height: 40},
+ thumbTouchSize: { width: 40, height: 40 },
debugTouchArea: false,
- animationType: 'timing'
+ animationType: 'timing',
};
state = {
- containerSize: {width: 0, height: 0},
- trackSize: {width: 0, height: 0},
- thumbSize: {width: 0, height: 0},
+ containerSize: { width: 0, height: 0 },
+ trackSize: { width: 0, height: 0 },
+ thumbSize: { width: 0, height: 0 },
allMeasured: false,
value: new Animated.Value(this.props.value),
};
@@ -200,41 +211,44 @@ export default class Slider extends PureComponent {
onPanResponderTerminationRequest: this._handlePanResponderRequestEnd,
onPanResponderTerminate: this._handlePanResponderEnd,
});
- };
+ }
componentWillReceiveProps(nextProps) {
var newValue = nextProps.value;
if (this.props.value !== newValue) {
if (this.props.animateTransitions) {
- this._setCurrentValueAnimated(newValue);
- }
- else {
- this._setCurrentValue(newValue);
+ this._setCurrentValueAnimated(newValue || this.props.value);
+ } else {
+ this._setCurrentValue(newValue || this.props.value);
}
}
- };
+ }
render() {
var {
minimumValue,
maximumValue,
minimumTrackTintColor,
+ customMinimumTrack,
maximumTrackTintColor,
+ customMaximumTrack,
thumbTintColor,
- thumbImage,
+ customThumb,
styles,
style,
trackStyle,
thumbStyle,
debugTouchArea,
- onValueChange,
- thumbTouchSize,
- animationType,
- animateTransitions,
...other
} = this.props;
- var {value, containerSize, trackSize, thumbSize, allMeasured} = this.state;
+ var {
+ value,
+ containerSize,
+ trackSize,
+ thumbSize,
+ allMeasured,
+ } = this.state;
var mainStyles = styles || defaultStyles;
var thumbLeft = value.interpolate({
inputRange: [minimumValue, maximumValue],
@@ -250,46 +264,67 @@ export default class Slider extends PureComponent {
position: 'absolute',
width: Animated.add(thumbLeft, thumbSize.width / 2),
backgroundColor: minimumTrackTintColor,
- ...valueVisibleStyle
+ ...valueVisibleStyle,
};
var touchOverflowStyle = this._getTouchOverflowStyle();
return (
-
+
+ onLayout={this._measureTrack}
+ >
+ {customMaximumTrack}
+
+ style={[mainStyles.track, trackStyle, minimumTrackStyle]}
+ >
+ {customMinimumTrack}
+
- {this._renderThumbImage()}
+ {customThumb}
- {debugTouchArea === true && this._renderDebugThumbTouchRect(thumbLeft)}
+ {...this._panResponder.panHandlers}
+ >
+ {debugTouchArea === true &&
+ this._renderDebugThumbTouchRect(thumbLeft)}
);
- };
+ }
_getPropsForComponentUpdate(props) {
var {
@@ -300,13 +335,15 @@ export default class Slider extends PureComponent {
style,
trackStyle,
thumbStyle,
- ...otherProps,
+ ...otherProps
} = props;
return otherProps;
- };
+ }
- _handleStartShouldSetPanResponder = (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);
};
@@ -314,7 +351,7 @@ export default class Slider extends PureComponent {
_handleMoveShouldSetPanResponder(/*e: Object, gestureState: Object*/): boolean {
// Should we become active when the user moves a touch over the thumb?
return false;
- };
+ }
_handlePanResponderGrant = (/*e: Object, gestureState: Object*/) => {
this._previousLeft = this._getThumbLeft(this._getCurrentValue());
@@ -333,7 +370,7 @@ export default class Slider extends PureComponent {
_handlePanResponderRequestEnd(e: Object, gestureState: Object) {
// Should we allow another component to take over this pan?
return false;
- };
+ }
_handlePanResponderEnd = (e: Object, gestureState: Object) => {
if (this.props.disabled) {
@@ -357,12 +394,16 @@ export default class Slider extends PureComponent {
};
_handleMeasure = (name: string, x: Object) => {
- var {width, height} = x.nativeEvent.layout;
- var size = {width: width, height: height};
+ var { width, height } = x.nativeEvent.layout;
+ var size = { width: width, height: height };
var storeName = `_${name}`;
var currentSize = this[storeName];
- if (currentSize && width === currentSize.width && height === currentSize.height) {
+ if (
+ currentSize &&
+ width === currentSize.width &&
+ height === currentSize.height
+ ) {
return;
}
this[storeName] = size;
@@ -373,36 +414,49 @@ export default class Slider extends PureComponent {
trackSize: this._trackSize,
thumbSize: this._thumbSize,
allMeasured: true,
- })
+ });
}
};
_getRatio = (value: number) => {
- return (value - this.props.minimumValue) / (this.props.maximumValue - this.props.minimumValue);
+ return (
+ (value - this.props.minimumValue) /
+ (this.props.maximumValue - this.props.minimumValue)
+ );
};
_getThumbLeft = (value: number) => {
var ratio = this._getRatio(value);
- return ratio * (this.state.containerSize.width - this.state.thumbSize.width);
+ return (
+ ratio * (this.state.containerSize.width - this.state.thumbSize.width)
+ );
};
_getValue = (gestureState: Object) => {
+ const { vertical, step, minimumValue, maximumValue } = this.props;
var length = this.state.containerSize.width - this.state.thumbSize.width;
- var thumbLeft = this._previousLeft + gestureState.dx;
+ var thumbLeft = vertical
+ ? this._previousLeft + gestureState.dy
+ : this._previousLeft + gestureState.dx;
var ratio = thumbLeft / length;
- if (this.props.step) {
- return Math.max(this.props.minimumValue,
- Math.min(this.props.maximumValue,
- this.props.minimumValue + Math.round(ratio * (this.props.maximumValue - this.props.minimumValue) / this.props.step) * this.props.step
- )
+ if (step) {
+ return Math.max(
+ minimumValue,
+ Math.min(
+ maximumValue,
+ minimumValue +
+ Math.round((ratio * (maximumValue - minimumValue)) / step) * step,
+ ),
);
} else {
- return Math.max(this.props.minimumValue,
- Math.min(this.props.maximumValue,
- ratio * (this.props.maximumValue - this.props.minimumValue) + this.props.minimumValue
- )
+ return Math.max(
+ minimumValue,
+ Math.min(
+ maximumValue,
+ ratio * (maximumValue - minimumValue) + minimumValue,
+ ),
);
}
};
@@ -416,18 +470,18 @@ export default class Slider extends PureComponent {
};
_setCurrentValueAnimated = (value: number) => {
- var animationType = this.props.animationType;
+ var animationType = this.props.animationType;
var animationConfig = Object.assign(
{},
DEFAULT_ANIMATION_CONFIGS[animationType],
this.props.animationConfig,
- {toValue : value}
+ { toValue: value, useNativeDriver: true },
);
Animated[animationType](this.state.value, animationConfig).start();
};
- _fireChangeEvent = (event) => {
+ _fireChangeEvent = event => {
if (this.props[event]) {
this.props[event](this._getCurrentValue());
}
@@ -439,15 +493,21 @@ export default class Slider extends PureComponent {
var size = {};
if (state.allMeasured === true) {
- size.width = Math.max(0, props.thumbTouchSize.width - state.thumbSize.width);
- size.height = Math.max(0, props.thumbTouchSize.height - state.containerSize.height);
+ size.width = Math.max(
+ 0,
+ props.thumbTouchSize.width - state.thumbSize.width,
+ );
+ size.height = Math.max(
+ 0,
+ props.thumbTouchSize.height - state.containerSize.height,
+ );
}
return size;
};
_getTouchOverflowStyle = () => {
- var {width, height} = this._getTouchOverflowSize();
+ var { width, height } = this._getTouchOverflowSize();
var touchOverflowStyle = {};
if (width !== undefined && height !== undefined) {
@@ -471,7 +531,10 @@ export default class Slider extends PureComponent {
_thumbHitTest = (e: Object) => {
var nativeEvent = e.nativeEvent;
var thumbTouchRect = this._getThumbTouchRect();
- return thumbTouchRect.containsPoint(nativeEvent.locationX, nativeEvent.locationY);
+ return thumbTouchRect.containsPoint(
+ nativeEvent.locationX,
+ nativeEvent.locationY,
+ );
};
_getThumbTouchRect = () => {
@@ -480,14 +543,17 @@ export default class Slider extends PureComponent {
var touchOverflowSize = this._getTouchOverflowSize();
return new Rect(
- touchOverflowSize.width / 2 + this._getThumbLeft(this._getCurrentValue()) + (state.thumbSize.width - props.thumbTouchSize.width) / 2,
- touchOverflowSize.height / 2 + (state.containerSize.height - props.thumbTouchSize.height) / 2,
+ touchOverflowSize.width / 2 +
+ this._getThumbLeft(this._getCurrentValue()) +
+ (state.thumbSize.width - props.thumbTouchSize.width) / 2,
+ touchOverflowSize.height / 2 +
+ (state.containerSize.height - props.thumbTouchSize.height) / 2,
props.thumbTouchSize.width,
- props.thumbTouchSize.height
+ props.thumbTouchSize.height,
);
};
- _renderDebugThumbTouchRect = (thumbLeft) => {
+ _renderDebugThumbTouchRect = thumbLeft => {
var thumbTouchRect = this._getThumbTouchRect();
var positionStyle = {
left: thumbLeft,
@@ -499,18 +565,10 @@ export default class Slider extends PureComponent {
return (
);
};
-
- _renderThumbImage = () => {
- var {thumbImage} = this.props;
-
- if (!thumbImage) return;
-
- return ;
- };
}
var defaultStyles = StyleSheet.create({
@@ -540,5 +598,5 @@ var defaultStyles = StyleSheet.create({
position: 'absolute',
backgroundColor: 'green',
opacity: 0.5,
- }
+ },
});