diff --git a/MultiSlider.js b/MultiSlider.js index 24ff948..b5ab6fd 100755 --- a/MultiSlider.js +++ b/MultiSlider.js @@ -54,6 +54,7 @@ export default class MultiSlider extends React.Component { minMarkerOverlapDistance: 0, minMarkerOverlapStepDistance: 0, testID: '', + allowSliderClick: false }; constructor(props) { @@ -121,18 +122,33 @@ export default class MultiSlider extends React.Component { } subscribePanResponder = () => { - var customPanResponder = (start, move, end) => { + var customPanResponder = (start, move, end, isClicked = false) => { return PanResponder.create({ onStartShouldSetPanResponder: (evt, gestureState) => true, - onStartShouldSetPanResponderCapture: (evt, gestureState) => true, - onMoveShouldSetPanResponder: (evt, gestureState) => true, - onMoveShouldSetPanResponderCapture: (evt, gestureState) => true, - onPanResponderGrant: (evt, gestureState) => start(), - onPanResponderMove: (evt, gestureState) => move(gestureState), - onPanResponderTerminationRequest: (evt, gestureState) => false, - onPanResponderRelease: (evt, gestureState) => end(gestureState), - onPanResponderTerminate: (evt, gestureState) => end(gestureState), - onShouldBlockNativeResponder: (evt, gestureState) => true, + onStartShouldSetPanResponderCapture: (evt, gestureState) => false, + onMoveShouldSetPanResponder: (evt, gestureState) => false, + onMoveShouldSetPanResponderCapture: (evt, gestureState) => false, + onPanResponderGrant: (evt, gestureState) => { + if (!isClicked) start(); + }, + onPanResponderMove: (evt, gestureState) => { + if (!isClicked) move(gestureState); + }, + onPanResponderTerminationRequest: (evt, gestureState) => true, + onPanResponderRelease: (evt, gestureState) => { + if (isClicked && Math.abs(gestureState.dx) <= 1) { + /*if its coming from slider and distance is not covered than only move the thumb + because we are preventing it to move when user drag on slider*/ + // console.log("onStartShouldSetPanResponder else " + (Math.abs(gestureState.dx) >= 1) + " " + gestureState.dx) + move(gestureState); + } else { + end(gestureState); + } + }, + onPanResponderTerminate: (evt, gestureState) => { + if (!isClicked) end(gestureState); + }, + onShouldBlockNativeResponder: (evt, gestureState) => false, }); }; @@ -151,11 +167,19 @@ export default class MultiSlider extends React.Component { }, ); + this._panResponderOneTapped = customPanResponder( + this.startOne, + this.moveOneTapped, + this.endOne, + true + ); + this._panResponderOne = customPanResponder( this.startOne, this.moveOne, this.endOne, ); + this._panResponderTwo = customPanResponder( this.startTwo, this.moveTwo, @@ -181,6 +205,73 @@ export default class MultiSlider extends React.Component { } }; + moveOneTapped = gestureState => { + if (!this.props.enabledOne) { + return; + } + const accumDistance = this.props.vertical + ? -gestureState.dy + : gestureState.dx; + const accumDistanceDisplacement = this.props.vertical + ? gestureState.dx + : gestureState.dy; + let unconfined; + gestureState.x0 = gestureState.x0 - 20; //default slide x to -20 because thumb value is much So, -20 is perfect + unconfined = gestureState.x0; + var bottom = 0; + var trueTop = + this.state.positionTwo - + (this.props.allowOverlap + ? 0 + : this.props.minMarkerOverlapDistance > 0 + ? this.props.minMarkerOverlapDistance + : this.stepLength); + var top = trueTop === 0 ? 0 : trueTop || this.props.sliderLength; + var confined = + unconfined < bottom ? bottom : unconfined > top ? top : unconfined; + var slipDisplacement = this.props.touchDimensions.slipDisplacement; + if ( + Math.abs(accumDistanceDisplacement) < slipDisplacement || + !slipDisplacement + ) { + var value = positionToValue( + confined, + this.optionsArray, + this.props.sliderLength, + ); + var snapped = valueToPosition( + value, + this.optionsArray, + this.props.sliderLength, + ); + this.setState({ + positionOne: this.props.snapped ? snapped : confined, + }); + if (value !== this.state.valueOne) { + this.setState( + { + valueOne: value, + }, + () => { + var change = [this.state.valueOne]; + if (this.state.valueTwo) { + change.push(this.state.valueTwo); + } + this.props.onValuesChange(change); + this.props.onMarkersPosition([ + this.state.positionOne, + ]); + this.setState({ + pastOne: this.state.positionOne + }); + // console.log("tapped => position when tap : " + this.state.positionOne + " position two is " + this.state.positionTwo) + }, + ); + this.endOne(value); + } + } + }; + moveOne = gestureState => { if (!this.props.enabledOne) { return; @@ -324,6 +415,11 @@ export default class MultiSlider extends React.Component { }; endOne = gestureState => { + + if (!this.props.enabledOne) { + return; + } + if (gestureState.moveX === 0 && this.props.onToggleOne) { this.props.onToggleOne(); return; @@ -352,6 +448,11 @@ export default class MultiSlider extends React.Component { }; endTwo = gestureState => { + + if (!this.props.enabledTwo) { + return; + } + if (gestureState.moveX === 0 && this.props.onToggleTwo) { this.props.onToggleTwo(); return; @@ -437,7 +538,8 @@ export default class MultiSlider extends React.Component { nextState.valueTwo = this.props.values[1]; nextState.pastTwo = positionTwo; nextState.positionTwo = positionTwo; - + nextState.onePressed = false; + nextState.twoPressed = false; this.setState(nextState); } } @@ -671,17 +773,43 @@ export default class MultiSlider extends React.Component { twoMarkerPressed={this.state.twoPressed} /> )} - {this.props.imageBackgroundSource && ( - - {body} - + + {/* when showing two thumb and with image background*/} + {(this.props.imageBackgroundSource && twoMarkers) && ( + + {body} + + )} + + {/* when showing one thumb and with image background*/} + {(this.props.imageBackgroundSource && !twoMarkers) && ( + + {body} + )} - {!this.props.imageBackgroundSource && ( - {body} + + {/* when showing two thumb and without image background*/} + {(!this.props.imageBackgroundSource && twoMarkers) && ( + (this._markerOne = component)}>{body} + )} + + {/* when showing one thumb and without image background*/} + {(!this.props.imageBackgroundSource && !twoMarkers) && ( + (this._markerOne = component)} + {...(this.props.allowSliderClick ? this._panResponderOneTapped.panHandlers : {})} + > + {body} + )} + ); } diff --git a/index.d.ts b/index.d.ts index 9222a39..05f3ffa 100644 --- a/index.d.ts +++ b/index.d.ts @@ -94,6 +94,7 @@ export interface MultiSliderProps { imageBackgroundSource?: string; enableLabel?: boolean; vertical?: boolean; + allowSliderClick?: boolean; } export default class MultiSlider extends React.Component {}