@momo-kits/slider 0.0.34-beta → 0.0.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Slider.js CHANGED
@@ -1 +1,738 @@
1
- var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.default=void 0;var _extends2=_interopRequireDefault(require("@babel/runtime/helpers/extends"));var _classCallCheck2=_interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));var _createClass2=_interopRequireDefault(require("@babel/runtime/helpers/createClass"));var _inherits2=_interopRequireDefault(require("@babel/runtime/helpers/inherits"));var _possibleConstructorReturn2=_interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));var _getPrototypeOf2=_interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));var _react=_interopRequireWildcard(require("react"));var _propTypes=_interopRequireDefault(require("prop-types"));var _reactNative=require("react-native");var _lodash=require("lodash");var _core=require("@momo-kits/core");var _DefaultMarker=_interopRequireDefault(require("./DefaultMarker"));var _DefaultLabel=_interopRequireDefault(require("./DefaultLabel"));var _converters=require("./converters");var _jsxFileName="/Users/trinh.ho2/momo-folk/kits/src/libs/slider/dist/Slider.js";function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap();var cacheNodeInterop=new WeakMap();return(_getRequireWildcardCache=function _getRequireWildcardCache(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop;})(nodeInterop);}function _interopRequireWildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule){return obj;}if(obj===null||typeof obj!=="object"&&typeof obj!=="function"){return{default:obj};}var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj)){return cache.get(obj);}var newObj={};var hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj){if(key!=="default"&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;if(desc&&(desc.get||desc.set)){Object.defineProperty(newObj,key,desc);}else{newObj[key]=obj[key];}}}newObj.default=obj;if(cache){cache.set(obj,newObj);}return newObj;}function _createSuper(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct();return function _createSuperInternal(){var Super=(0,_getPrototypeOf2.default)(Derived),result;if(hasNativeReflectConstruct){var NewTarget=(0,_getPrototypeOf2.default)(this).constructor;result=Reflect.construct(Super,arguments,NewTarget);}else{result=Super.apply(this,arguments);}return(0,_possibleConstructorReturn2.default)(this,result);};}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}var Slider=function(_Component){(0,_inherits2.default)(Slider,_Component);var _super=_createSuper(Slider);function Slider(props){var _this;(0,_classCallCheck2.default)(this,Slider);_this=_super.call(this,props);_this.subscribePanResponder=function(){var customPanResponder=function customPanResponder(start,move,end){return _reactNative.PanResponder.create({onStartShouldSetPanResponder:function onStartShouldSetPanResponder(){return true;},onStartShouldSetPanResponderCapture:function onStartShouldSetPanResponderCapture(){return true;},onMoveShouldSetPanResponder:function onMoveShouldSetPanResponder(){return true;},onMoveShouldSetPanResponderCapture:function onMoveShouldSetPanResponderCapture(){return true;},onPanResponderGrant:function onPanResponderGrant(){return start();},onPanResponderMove:function onPanResponderMove(evt,gestureState){return move(gestureState);},onPanResponderTerminationRequest:function onPanResponderTerminationRequest(){return false;},onPanResponderRelease:function onPanResponderRelease(evt,gestureState){return end(gestureState);},onPanResponderTerminate:function onPanResponderTerminate(evt,gestureState){return end(gestureState);},onShouldBlockNativeResponder:function onShouldBlockNativeResponder(){return true;}});};_this._panResponderBetween=customPanResponder(function(gestureState){_this.startOne(gestureState);_this.startTwo(gestureState);},function(gestureState){_this.moveOne(gestureState);_this.moveTwo(gestureState);},function(gestureState){_this.endOne(gestureState);_this.endTwo(gestureState);});_this._panResponderOne=customPanResponder(_this.startOne,_this.moveOne,_this.endOne);_this._panResponderTwo=customPanResponder(_this.startTwo,_this.moveTwo,_this.endTwo);};_this.startOne=function(){var _this$props=_this.props,enabledOne=_this$props.enabledOne,onChangeStart=_this$props.onChangeStart;var onePressed=_this.state.onePressed;if(enabledOne){onChangeStart();_this.setState({onePressed:!onePressed});}};_this.startTwo=function(){var _this$props2=_this.props,enabledTwo=_this$props2.enabledTwo,onChangeStart=_this$props2.onChangeStart;var twoPressed=_this.state.twoPressed;if(enabledTwo){onChangeStart();_this.setState({twoPressed:!twoPressed});}};_this.moveOne=function(gestureState){var _this$props3=_this.props,enabledOne=_this$props3.enabledOne,vertical=_this$props3.vertical,allowOverlap=_this$props3.allowOverlap,minMarkerOverlapDistance=_this$props3.minMarkerOverlapDistance,touchDimensions=_this$props3.touchDimensions,snapped=_this$props3.snapped,onChange=_this$props3.onChange,onMarkersPosition=_this$props3.onMarkersPosition,_this$props3$allowRan=_this$props3.allowRange,allowRange=_this$props3$allowRan===void 0?[]:_this$props3$allowRan,min=_this$props3.min,max=_this$props3.max;var _this$state=_this.state,pastOne=_this$state.pastOne,positionTwo=_this$state.positionTwo,valueOne=_this$state.valueOne,valueTwo=_this$state.valueTwo,sliderLength=_this$state.sliderLength;if(!enabledOne){return;}var accumDistance=vertical?-gestureState.dy:gestureState.dx;var accumDistanceDisplacement=vertical?gestureState.dx:gestureState.dy;var unconfined=_reactNative.I18nManager.isRTL?pastOne-accumDistance:accumDistance+pastOne;var bottom=0;var trueTop=positionTwo-(allowOverlap?0:minMarkerOverlapDistance>0?minMarkerOverlapDistance:_this.stepLength);var top=trueTop===0?0:trueTop||sliderLength;var confined=unconfined<bottom?bottom:unconfined>top?top:unconfined;var slipDisplacement=touchDimensions.slipDisplacement;if(Math.abs(accumDistanceDisplacement)<slipDisplacement||!slipDisplacement){var value=(0,_converters.positionToValue)(confined,_this.optionsArray,sliderLength);if((allowRange==null?void 0:allowRange.length)>0&&value<(0,_lodash.get)(allowRange,'[0]',min))return;if((allowRange==null?void 0:allowRange.length)>1&&value>(0,_lodash.get)(allowRange,'[1]',max))return;var snappedValue=(0,_converters.valueToPosition)(value,_this.optionsArray,sliderLength);_this.setState({positionOne:snapped?snappedValue:confined});if(value!==valueOne){_this.setState({valueOne:value},function(){var _this$state2=_this.state,newValueOne=_this$state2.valueOne,newPositionOne=_this$state2.positionOne;var change=[newValueOne];if(valueTwo){change.push(valueTwo);}onChange(change);onMarkersPosition([newPositionOne,positionTwo]);});}}};_this.moveTwo=function(gestureState){var _this$props4=_this.props,enabledTwo=_this$props4.enabledTwo,vertical=_this$props4.vertical,allowOverlap=_this$props4.allowOverlap,minMarkerOverlapDistance=_this$props4.minMarkerOverlapDistance,touchDimensions=_this$props4.touchDimensions,snapped=_this$props4.snapped,onChange=_this$props4.onChange,onMarkersPosition=_this$props4.onMarkersPosition;var _this$state3=_this.state,pastTwo=_this$state3.pastTwo,positionOne=_this$state3.positionOne,sliderLength=_this$state3.sliderLength,valueTwo=_this$state3.valueTwo,valueOne=_this$state3.valueOne;if(!enabledTwo){return;}var accumDistance=vertical?-gestureState.dy:gestureState.dx;var accumDistanceDisplacement=vertical?gestureState.dx:gestureState.dy;var unconfined=_reactNative.I18nManager.isRTL?pastTwo-accumDistance:accumDistance+pastTwo;var bottom=positionOne+(allowOverlap?0:minMarkerOverlapDistance>0?minMarkerOverlapDistance:_this.stepLength);var top=sliderLength;var confined=unconfined<bottom?bottom:unconfined>top?top:unconfined;var slipDisplacement=touchDimensions.slipDisplacement;if(Math.abs(accumDistanceDisplacement)<slipDisplacement||!slipDisplacement){var value=(0,_converters.positionToValue)(confined,_this.optionsArray,sliderLength);var snappedValue=(0,_converters.valueToPosition)(value,_this.optionsArray,sliderLength);_this.setState({positionTwo:snapped?snappedValue:confined});if(value!==valueTwo){_this.setState({valueTwo:value},function(){console.log(valueOne);var _this$state4=_this.state,newValueTwo=_this$state4.valueTwo,newPositionTwo=_this$state4.positionTwo;onChange([valueOne,newValueTwo]);onMarkersPosition([positionOne,newPositionTwo]);});}}};_this.endOne=function(gestureState){var _this$props5=_this.props,onToggleOne=_this$props5.onToggleOne,onChangeFinish=_this$props5.onChangeFinish;var _this$state5=_this.state,positionOne=_this$state5.positionOne,onePressed=_this$state5.onePressed,valueOne=_this$state5.valueOne,valueTwo=_this$state5.valueTwo;if(gestureState.moveX===0&&onToggleOne){onToggleOne();return;}_this.setState({pastOne:positionOne,onePressed:!onePressed},function(){var change=[valueOne];if(valueTwo){change.push(valueTwo);}onChangeFinish(change);});};_this.endTwo=function(gestureState){var _this$props6=_this.props,onToggleTwo=_this$props6.onToggleTwo,onChangeFinish=_this$props6.onChangeFinish;var _this$state6=_this.state,twoPressed=_this$state6.twoPressed,positionTwo=_this$state6.positionTwo,valueOne=_this$state6.valueOne,valueTwo=_this$state6.valueTwo;if(gestureState.moveX===0&&onToggleTwo){onToggleTwo();return;}_this.setState({twoPressed:!twoPressed,pastTwo:positionTwo},function(){onChangeFinish([valueOne,valueTwo]);});};var _this$props7=_this.props,optionsArray=_this$props7.optionsArray,_min=_this$props7.min,_max=_this$props7.max,step=_this$props7.step,length=_this$props7.length,values=_this$props7.values;_this.optionsArray=optionsArray||(0,_converters.createArray)(_min,_max,step);var defaultSliderLength=length;_this.stepLength=defaultSliderLength/_this.optionsArray.length;var initialValues=values.map(function(value){return(0,_converters.valueToPosition)(value,_this.optionsArray,defaultSliderLength);});_this.state={valueOne:values[0],valueTwo:values[1],pastOne:initialValues[0],pastTwo:initialValues[1],positionOne:initialValues[0],positionTwo:initialValues[1],sliderLength:defaultSliderLength};_this.subscribePanResponder();return _this;}(0,_createClass2.default)(Slider,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var prevPositionOne=prevState.positionOne,prevPositionTwo=prevState.positionTwo;var _this$state7=this.state,positionOne=_this$state7.positionOne,positionTwo=_this$state7.positionTwo,onePressed=_this$state7.onePressed,twoPressed=_this$state7.twoPressed,sliderLength=_this$state7.sliderLength;var _this$props8=this.props,onMarkersPosition=_this$props8.onMarkersPosition,min=_this$props8.min,max=_this$props8.max,step=_this$props8.step,values=_this$props8.values,optionsArray=_this$props8.optionsArray;if(typeof positionOne==='undefined'&&typeof positionTwo!=='undefined'){return;}if(positionOne!==prevPositionOne||positionTwo!==prevPositionTwo){onMarkersPosition([positionOne,positionTwo]);}if(onePressed||twoPressed){return;}var nextState={};if(prevProps.min!==min||prevProps.max!==max||prevProps.step!==step||prevProps.values[0]!==values[0]||prevState.sliderLength!==sliderLength||prevProps.values[1]!==values[1]||prevState.sliderLength!==sliderLength&&prevProps.values[1]){this.optionsArray=optionsArray||(0,_converters.createArray)(min,max,step);this.stepLength=sliderLength/this.optionsArray.length;var positionOneValue=(0,_converters.valueToPosition)(values[0],this.optionsArray,sliderLength);nextState.valueOne=values[0];nextState.pastOne=positionOneValue;nextState.positionOne=positionOneValue;var positionTwoValue=(0,_converters.valueToPosition)(values[1],this.optionsArray,sliderLength);nextState.valueTwo=values[1];nextState.pastTwo=positionTwoValue;nextState.positionTwo=positionTwoValue;this.setState(nextState);}}},{key:"onContentLayout",value:function onContentLayout(e){var _this$props9=this.props,vertical=_this$props9.vertical,length=_this$props9.length;if(!length){var layoutLength=vertical?e.nativeEvent.layout.height:e.nativeEvent.layout.width;this.setState({sliderLength:layoutLength});}}},{key:"render",value:function render(){var _this2=this;var _this$state8=this.state,positionOne=_this$state8.positionOne,positionTwo=_this$state8.positionTwo,onePressed=_this$state8.onePressed,valueOne=_this$state8.valueOne,twoPressed=_this$state8.twoPressed,valueTwo=_this$state8.valueTwo,sliderLength=_this$state8.sliderLength;var _this$props10=this.props,style=_this$props10.style,selectedStyle=_this$props10.selectedStyle,unselectedStyle=_this$props10.unselectedStyle,markerOffsetX=_this$props10.markerOffsetX,markerOffsetY=_this$props10.markerOffsetY,values=_this$props10.values,customMarker=_this$props10.customMarker,customMarkerLeft=_this$props10.customMarkerLeft,customMarkerRight=_this$props10.customMarkerRight,_this$props10$isMarke=_this$props10.isMarkersSeparated,isMarkersSeparated=_this$props10$isMarke===void 0?false:_this$props10$isMarke,customLabel=_this$props10.customLabel,touchDimensions=_this$props10.touchDimensions,containerStyle=_this$props10.containerStyle,vertical=_this$props10.vertical,trackStyle=_this$props10.trackStyle,markerContainerStyle=_this$props10.markerContainerStyle,enabledOne=_this$props10.enabledOne,enabledTwo=_this$props10.enabledTwo,markerStyle=_this$props10.markerStyle,pressedMarkerStyle=_this$props10.pressedMarkerStyle,disabledMarkerStyle=_this$props10.disabledMarkerStyle,valuePrefix=_this$props10.valuePrefix,valueSuffix=_this$props10.valueSuffix,enableLabel=_this$props10.enableLabel,imageBackgroundSource=_this$props10.imageBackgroundSource;var twoMarkers=values.length===2;var trackOneLength=positionOne;var trackOneStyle=twoMarkers?unselectedStyle:selectedStyle||styles.selectedTrack;var trackThreeLength=twoMarkers?sliderLength-positionTwo:0;var trackThreeStyle=unselectedStyle;var trackTwoLength=sliderLength-trackOneLength-trackThreeLength;var trackTwoStyle=twoMarkers?selectedStyle||styles.selectedTrack:unselectedStyle;var Marker=customMarker;var MarkerLeft=customMarkerLeft;var MarkerRight=customMarkerRight;var Label=customLabel;var borderRadius=touchDimensions.borderRadius;var touchStyle={borderRadius:borderRadius||0};var markerContainerOne={top:markerOffsetY-24,left:trackOneLength+markerOffsetX-24};var markerContainerTwo={top:markerOffsetY-24,right:trackThreeLength-markerOffsetX-24};var newContainerStyle=[styles.container,containerStyle];if(vertical){newContainerStyle.push({transform:[{rotate:'-90deg'}]});}var body=_react.default.createElement(_reactNative.View,{style:{alignItems:'center'},__source:{fileName:_jsxFileName,lineNumber:499,columnNumber:13}},_react.default.createElement(_reactNative.View,{style:[styles.fullTrack,{width:sliderLength}],__source:{fileName:_jsxFileName,lineNumber:500,columnNumber:17}},_react.default.createElement(_reactNative.View,{style:[styles.track,trackStyle,trackOneStyle,{width:trackOneLength}],__source:{fileName:_jsxFileName,lineNumber:501,columnNumber:21}}),_react.default.createElement(_reactNative.View,(0,_extends2.default)({style:[styles.track,trackStyle,trackTwoStyle,{width:trackTwoLength}]},twoMarkers?this._panResponderBetween.panHandlers:{},{__source:{fileName:_jsxFileName,lineNumber:509,columnNumber:21}})),twoMarkers&&_react.default.createElement(_reactNative.View,{style:[styles.track,trackStyle,trackThreeStyle,{width:trackThreeLength}],__source:{fileName:_jsxFileName,lineNumber:519,columnNumber:25}}),_react.default.createElement(_reactNative.View,{style:[styles.markerContainer,markerContainerOne,markerContainerStyle,positionOne>sliderLength/2&&styles.topMarkerContainer],__source:{fileName:_jsxFileName,lineNumber:528,columnNumber:21}},_react.default.createElement(_reactNative.View,(0,_extends2.default)({style:[styles.touch,touchStyle],ref:function ref(component){return _this2._markerOne=component;}},this._panResponderOne.panHandlers,{__source:{fileName:_jsxFileName,lineNumber:536,columnNumber:25}}),isMarkersSeparated===false?_react.default.createElement(Marker,{enabled:enabledOne,pressed:onePressed,markerStyle:markerStyle,pressedMarkerStyle:pressedMarkerStyle,disabledMarkerStyle:disabledMarkerStyle,currentValue:valueOne,valuePrefix:valuePrefix,valueSuffix:valueSuffix,__source:{fileName:_jsxFileName,lineNumber:543,columnNumber:37}}):_react.default.createElement(MarkerLeft,{enabled:enabledOne,pressed:onePressed,markerStyle:markerStyle,pressedMarkerStyle:pressedMarkerStyle,disabledMarkerStyle:disabledMarkerStyle,currentValue:valueOne,valuePrefix:valuePrefix,valueSuffix:valueSuffix,__source:{fileName:_jsxFileName,lineNumber:554,columnNumber:37}}))),twoMarkers&&positionOne!==sliderLength&&_react.default.createElement(_reactNative.View,{style:[styles.markerContainer,markerContainerTwo,markerContainerStyle],__source:{fileName:_jsxFileName,lineNumber:568,columnNumber:25}},_react.default.createElement(_reactNative.View,(0,_extends2.default)({style:[styles.touch,touchStyle],ref:function ref(component){return _this2._markerTwo=component;}},this._panResponderTwo.panHandlers,{__source:{fileName:_jsxFileName,lineNumber:575,columnNumber:29}}),isMarkersSeparated===false?_react.default.createElement(Marker,{pressed:twoPressed,markerStyle:markerStyle,pressedMarkerStyle:pressedMarkerStyle,disabledMarkerStyle:disabledMarkerStyle,currentValue:valueTwo,enabled:enabledTwo,valuePrefix:valuePrefix,valueSuffix:valueSuffix,__source:{fileName:_jsxFileName,lineNumber:582,columnNumber:41}}):_react.default.createElement(MarkerRight,{pressed:twoPressed,markerStyle:markerStyle,pressedMarkerStyle:pressedMarkerStyle,disabledMarkerStyle:disabledMarkerStyle,currentValue:valueTwo,enabled:enabledTwo,valuePrefix:valuePrefix,valueSuffix:valueSuffix,__source:{fileName:_jsxFileName,lineNumber:593,columnNumber:41}})))));return _react.default.createElement(_reactNative.View,{style:style,onLayout:function onLayout(e){return _this2.onContentLayout(e);},__source:{fileName:_jsxFileName,lineNumber:612,columnNumber:13}},enableLabel&&_react.default.createElement(Label,{oneMarkerValue:valueOne,twoMarkerValue:valueTwo,oneMarkerLeftPosition:positionOne,twoMarkerLeftPosition:positionTwo,oneMarkerPressed:onePressed,twoMarkerPressed:twoPressed,__source:{fileName:_jsxFileName,lineNumber:614,columnNumber:21}}),imageBackgroundSource&&_react.default.createElement(_reactNative.ImageBackground,{source:imageBackgroundSource,style:[styles.full,newContainerStyle],__source:{fileName:_jsxFileName,lineNumber:624,columnNumber:21}},body),!imageBackgroundSource&&_react.default.createElement(_reactNative.View,{style:newContainerStyle,__source:{fileName:_jsxFileName,lineNumber:632,columnNumber:21}},body));}}]);return Slider;}(_react.Component);exports.default=Slider;var styles=_reactNative.StyleSheet.create({container:{position:'relative',height:50,justifyContent:'center'},fullTrack:{flexDirection:'row'},track:{height:4,backgroundColor:'#A7A7A7'},selectedTrack:{backgroundColor:_core.Colors.primary},markerContainer:{position:'absolute',width:48,height:48,backgroundColor:'transparent',justifyContent:'center',alignItems:'center'},topMarkerContainer:{zIndex:1},touch:{backgroundColor:'transparent',justifyContent:'center',alignItems:'center',alignSelf:'stretch'},full:{width:'100%',height:'100%'}});Slider.defaultProps={values:[0],onChangeStart:function onChangeStart(){},onChange:function onChange(){},onChangeFinish:function onChangeFinish(){},onMarkersPosition:function onMarkersPosition(){},step:1,min:0,max:10,touchDimensions:{height:50,width:50,borderRadius:15,slipDisplacement:200},customMarker:_DefaultMarker.default,customMarkerLeft:_DefaultMarker.default,customMarkerRight:_DefaultMarker.default,customLabel:_DefaultLabel.default,markerOffsetX:0,markerOffsetY:0,onToggleOne:undefined,onToggleTwo:undefined,enabledOne:true,enabledTwo:true,allowOverlap:false,snapped:false,vertical:false,minMarkerOverlapDistance:0,length:280};Slider.propTypes={style:_propTypes.default.oneOfType([_propTypes.default.object,_propTypes.default.array]),selectedStyle:_propTypes.default.oneOfType([_propTypes.default.object,_propTypes.default.array]),unselectedStyle:_propTypes.default.oneOfType([_propTypes.default.object,_propTypes.default.array]),markerOffsetX:_propTypes.default.number,markerOffsetY:_propTypes.default.number,values:_propTypes.default.arrayOf(_propTypes.default.number),customMarker:_propTypes.default.func,customMarkerLeft:_propTypes.default.func,customMarkerRight:_propTypes.default.func,isMarkersSeparated:_propTypes.default.bool,touchDimensions:_propTypes.default.object,containerStyle:_propTypes.default.oneOfType([_propTypes.default.object,_propTypes.default.array]),vertical:_propTypes.default.bool,trackStyle:_propTypes.default.oneOfType([_propTypes.default.object,_propTypes.default.array]),markerContainerStyle:_propTypes.default.oneOfType([_propTypes.default.object,_propTypes.default.array]),enabledOne:_propTypes.default.bool,enabledTwo:_propTypes.default.bool,onChangeStart:_propTypes.default.func,onChange:_propTypes.default.func,onChangeFinish:_propTypes.default.func,onMarkersPosition:_propTypes.default.func,step:_propTypes.default.number,min:_propTypes.default.number,max:_propTypes.default.number,customLabel:_propTypes.default.any,onToggleOne:_propTypes.default.func,onToggleTwo:_propTypes.default.func,allowOverlap:_propTypes.default.bool,snapped:_propTypes.default.bool,minMarkerOverlapDistance:_propTypes.default.number,length:_propTypes.default.number,allowRange:_propTypes.default.arrayOf(_propTypes.default.number)};
1
+ import React, {Component} from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import {
4
+ StyleSheet,
5
+ PanResponder,
6
+ View,
7
+ I18nManager,
8
+ ImageBackground,
9
+ Text,
10
+ } from 'react-native';
11
+ import {get} from 'lodash';
12
+ import {Colors, Spacing} from '@momo-kits/core';
13
+ import DefaultMarker from './DefaultMarker';
14
+ import DefaultLabel from './DefaultLabel';
15
+ import {createArray, valueToPosition, positionToValue} from './converters';
16
+
17
+ export default class Slider extends Component {
18
+ constructor(props) {
19
+ super(props);
20
+ const {optionsArray, min, max, step, length, values} = this.props;
21
+ this.optionsArray = optionsArray || createArray(min, max, step);
22
+ const defaultSliderLength = length;
23
+ this.stepLength = defaultSliderLength / this.optionsArray.length;
24
+ const initialValues = values.map(value =>
25
+ valueToPosition(value, this.optionsArray, defaultSliderLength),
26
+ );
27
+ console.warn('initialValues', initialValues);
28
+ this.state = {
29
+ valueOne: values[0],
30
+ valueTwo: values[1],
31
+ pastOne: initialValues[0],
32
+ pastTwo: initialValues[1],
33
+ positionOne: initialValues[0],
34
+ positionTwo: initialValues[1],
35
+ sliderLength: defaultSliderLength,
36
+ };
37
+ this.subscribePanResponder();
38
+ }
39
+
40
+ subscribePanResponder = () => {
41
+ const customPanResponder = (start, move, end) =>
42
+ PanResponder.create({
43
+ onStartShouldSetPanResponder: () => true,
44
+ onStartShouldSetPanResponderCapture: () => true,
45
+ onMoveShouldSetPanResponder: () => true,
46
+ onMoveShouldSetPanResponderCapture: () => true,
47
+ onPanResponderGrant: () => start(),
48
+ onPanResponderMove: (evt, gestureState) => move(gestureState),
49
+ onPanResponderTerminationRequest: () => false,
50
+ onPanResponderRelease: (evt, gestureState) => end(gestureState),
51
+ onPanResponderTerminate: (evt, gestureState) => end(gestureState),
52
+ onShouldBlockNativeResponder: () => true,
53
+ });
54
+
55
+ this._panResponderBetween = customPanResponder(
56
+ gestureState => {
57
+ this.startOne(gestureState);
58
+ this.startTwo(gestureState);
59
+ },
60
+ gestureState => {
61
+ this.moveOne(gestureState);
62
+ this.moveTwo(gestureState);
63
+ },
64
+ gestureState => {
65
+ this.endOne(gestureState);
66
+ this.endTwo(gestureState);
67
+ },
68
+ );
69
+
70
+ this._panResponderOne = customPanResponder(
71
+ this.startOne,
72
+ this.moveOne,
73
+ this.endOne,
74
+ );
75
+ this._panResponderTwo = customPanResponder(
76
+ this.startTwo,
77
+ this.moveTwo,
78
+ this.endTwo,
79
+ );
80
+ };
81
+
82
+ startOne = () => {
83
+ const {enabledOne, onChangeStart} = this.props;
84
+ const {onePressed} = this.state;
85
+ if (enabledOne) {
86
+ onChangeStart();
87
+ this.setState({
88
+ onePressed: !onePressed,
89
+ });
90
+ }
91
+ };
92
+
93
+ startTwo = () => {
94
+ const {enabledTwo, onChangeStart} = this.props;
95
+ const {twoPressed} = this.state;
96
+ if (enabledTwo) {
97
+ onChangeStart();
98
+ this.setState({
99
+ twoPressed: !twoPressed,
100
+ });
101
+ }
102
+ };
103
+
104
+ moveOne = gestureState => {
105
+ const {
106
+ enabledOne,
107
+ vertical,
108
+ allowOverlap,
109
+ minMarkerOverlapDistance,
110
+ // sliderLength,
111
+ touchDimensions,
112
+ snapped,
113
+ onChange,
114
+ onMarkersPosition,
115
+ allowRange = [],
116
+ min,
117
+ max,
118
+ } = this.props;
119
+ const {pastOne, positionTwo, valueOne, valueTwo, sliderLength} = this.state;
120
+ if (!enabledOne) {
121
+ return;
122
+ }
123
+
124
+ const accumDistance = vertical ? -gestureState.dy : gestureState.dx;
125
+ const accumDistanceDisplacement = vertical
126
+ ? gestureState.dx
127
+ : gestureState.dy;
128
+
129
+ const unconfined = I18nManager.isRTL
130
+ ? pastOne - accumDistance
131
+ : accumDistance + pastOne;
132
+ const bottom = 0;
133
+ const trueTop =
134
+ positionTwo -
135
+ (allowOverlap
136
+ ? 0
137
+ : minMarkerOverlapDistance > 0
138
+ ? minMarkerOverlapDistance
139
+ : this.stepLength);
140
+ const top = trueTop === 0 ? 0 : trueTop || sliderLength;
141
+ const confined =
142
+ unconfined < bottom ? bottom : unconfined > top ? top : unconfined;
143
+ const {slipDisplacement} = touchDimensions;
144
+
145
+ if (
146
+ Math.abs(accumDistanceDisplacement) < slipDisplacement ||
147
+ !slipDisplacement
148
+ ) {
149
+ const value = positionToValue(confined, this.optionsArray, sliderLength);
150
+
151
+ if (allowRange?.length > 0 && value < get(allowRange, '[0]', min)) return;
152
+ if (allowRange?.length > 1 && value > get(allowRange, '[1]', max)) return;
153
+
154
+ const snappedValue = valueToPosition(
155
+ value,
156
+ this.optionsArray,
157
+ sliderLength,
158
+ );
159
+
160
+ this.setState({
161
+ positionOne: snapped ? snappedValue : confined,
162
+ });
163
+
164
+ if (value !== valueOne) {
165
+ this.setState(
166
+ {
167
+ valueOne: value,
168
+ },
169
+ () => {
170
+ const {valueOne: newValueOne, positionOne: newPositionOne} =
171
+ this.state;
172
+ const change = [newValueOne];
173
+ if (valueTwo) {
174
+ change.push(valueTwo);
175
+ }
176
+ onChange(change);
177
+
178
+ onMarkersPosition([newPositionOne, positionTwo]);
179
+ },
180
+ );
181
+ }
182
+ }
183
+ };
184
+
185
+ moveTwo = gestureState => {
186
+ const {
187
+ enabledTwo,
188
+ vertical,
189
+ allowOverlap,
190
+ minMarkerOverlapDistance,
191
+ // sliderLength,
192
+ touchDimensions,
193
+ snapped,
194
+ onChange,
195
+ onMarkersPosition,
196
+ } = this.props;
197
+ const {pastTwo, positionOne, sliderLength, valueTwo, valueOne} = this.state;
198
+ if (!enabledTwo) {
199
+ return;
200
+ }
201
+
202
+ const accumDistance = vertical ? -gestureState.dy : gestureState.dx;
203
+ const accumDistanceDisplacement = vertical
204
+ ? gestureState.dx
205
+ : gestureState.dy;
206
+
207
+ const unconfined = I18nManager.isRTL
208
+ ? pastTwo - accumDistance
209
+ : accumDistance + pastTwo;
210
+ const bottom =
211
+ positionOne +
212
+ (allowOverlap
213
+ ? 0
214
+ : minMarkerOverlapDistance > 0
215
+ ? minMarkerOverlapDistance
216
+ : this.stepLength);
217
+ const top = sliderLength;
218
+ const confined =
219
+ unconfined < bottom ? bottom : unconfined > top ? top : unconfined;
220
+ const {slipDisplacement} = touchDimensions;
221
+
222
+ if (
223
+ Math.abs(accumDistanceDisplacement) < slipDisplacement ||
224
+ !slipDisplacement
225
+ ) {
226
+ const value = positionToValue(confined, this.optionsArray, sliderLength);
227
+
228
+ const snappedValue = valueToPosition(
229
+ value,
230
+ this.optionsArray,
231
+ sliderLength,
232
+ );
233
+
234
+ this.setState({
235
+ positionTwo: snapped ? snappedValue : confined,
236
+ });
237
+
238
+ if (value !== valueTwo) {
239
+ this.setState(
240
+ {
241
+ valueTwo: value,
242
+ },
243
+ () => {
244
+ console.log(valueOne);
245
+ const {valueTwo: newValueTwo, positionTwo: newPositionTwo} =
246
+ this.state;
247
+ onChange([valueOne, newValueTwo]);
248
+
249
+ onMarkersPosition([positionOne, newPositionTwo]);
250
+ },
251
+ );
252
+ }
253
+ }
254
+ };
255
+
256
+ endOne = gestureState => {
257
+ const {onToggleOne, onChangeFinish} = this.props;
258
+ const {positionOne, onePressed, valueOne, valueTwo} = this.state;
259
+ if (gestureState.moveX === 0 && onToggleOne) {
260
+ onToggleOne();
261
+ return;
262
+ }
263
+
264
+ this.setState(
265
+ {
266
+ pastOne: positionOne,
267
+ onePressed: !onePressed,
268
+ },
269
+ () => {
270
+ const change = [valueOne];
271
+ if (valueTwo) {
272
+ change.push(valueTwo);
273
+ }
274
+ onChangeFinish(change);
275
+ },
276
+ );
277
+ };
278
+
279
+ endTwo = gestureState => {
280
+ const {onToggleTwo, onChangeFinish} = this.props;
281
+ const {twoPressed, positionTwo, valueOne, valueTwo} = this.state;
282
+ if (gestureState.moveX === 0 && onToggleTwo) {
283
+ onToggleTwo();
284
+ return;
285
+ }
286
+
287
+ this.setState(
288
+ {
289
+ twoPressed: !twoPressed,
290
+ pastTwo: positionTwo,
291
+ },
292
+ () => {
293
+ onChangeFinish([valueOne, valueTwo]);
294
+ },
295
+ );
296
+ };
297
+
298
+ componentDidUpdate(prevProps, prevState) {
299
+ const {positionOne: prevPositionOne, positionTwo: prevPositionTwo} =
300
+ prevState;
301
+
302
+ const {positionOne, positionTwo, onePressed, twoPressed, sliderLength} =
303
+ this.state;
304
+ const {onMarkersPosition, min, max, step, values, optionsArray} =
305
+ this.props;
306
+
307
+ if (
308
+ typeof positionOne === 'undefined' &&
309
+ typeof positionTwo !== 'undefined'
310
+ ) {
311
+ return;
312
+ }
313
+
314
+ if (positionOne !== prevPositionOne || positionTwo !== prevPositionTwo) {
315
+ onMarkersPosition([positionOne, positionTwo]);
316
+ }
317
+
318
+ if (onePressed || twoPressed) {
319
+ return;
320
+ }
321
+
322
+ const nextState = {};
323
+ if (
324
+ prevProps.min !== min ||
325
+ prevProps.max !== max ||
326
+ prevProps.step !== step ||
327
+ prevProps.values[0] !== values[0] ||
328
+ prevState.sliderLength !== sliderLength ||
329
+ prevProps.values[1] !== values[1] ||
330
+ (prevState.sliderLength !== sliderLength && prevProps.values[1])
331
+ ) {
332
+ this.optionsArray = optionsArray || createArray(min, max, step);
333
+
334
+ this.stepLength = sliderLength / this.optionsArray.length;
335
+
336
+ const positionOneValue = valueToPosition(
337
+ values[0],
338
+ this.optionsArray,
339
+ sliderLength,
340
+ );
341
+ // eslint-disable-next-line prefer-destructuring
342
+ nextState.valueOne = values[0];
343
+ nextState.pastOne = positionOneValue;
344
+ nextState.positionOne = positionOneValue;
345
+
346
+ const positionTwoValue = valueToPosition(
347
+ values[1],
348
+ this.optionsArray,
349
+ sliderLength,
350
+ );
351
+ // eslint-disable-next-line prefer-destructuring
352
+ nextState.valueTwo = values[1];
353
+ nextState.pastTwo = positionTwoValue;
354
+ nextState.positionTwo = positionTwoValue;
355
+
356
+ // eslint-disable-next-line react/no-did-update-set-state
357
+ this.setState(nextState);
358
+ }
359
+ }
360
+
361
+ onContentLayout(e) {
362
+ const {vertical, length} = this.props;
363
+ if (!length) {
364
+ const layoutLength = vertical
365
+ ? e.nativeEvent.layout.height
366
+ : e.nativeEvent.layout.width;
367
+ this.setState({
368
+ sliderLength: layoutLength,
369
+ });
370
+ }
371
+ }
372
+
373
+ render() {
374
+ const {
375
+ positionOne,
376
+ positionTwo,
377
+ onePressed,
378
+ valueOne,
379
+ twoPressed,
380
+ valueTwo,
381
+ sliderLength,
382
+ } = this.state;
383
+ const {
384
+ style,
385
+ selectedStyle,
386
+ unselectedStyle,
387
+ // sliderLength,
388
+ markerOffsetX,
389
+ markerOffsetY,
390
+ values,
391
+ customMarker,
392
+ customMarkerLeft,
393
+ customMarkerRight,
394
+ isMarkersSeparated = false,
395
+ customLabel,
396
+ touchDimensions,
397
+ containerStyle,
398
+ vertical,
399
+ trackStyle,
400
+ markerContainerStyle,
401
+ enabledOne,
402
+ enabledTwo,
403
+ markerStyle,
404
+ pressedMarkerStyle,
405
+ disabledMarkerStyle,
406
+ valuePrefix,
407
+ valueSuffix,
408
+ enableLabel,
409
+ imageBackgroundSource,
410
+ } = this.props;
411
+ const twoMarkers = values.length === 2; // when allowOverlap, positionTwo could be 0, identified as string '0' and throwing 'RawText 0 needs to be wrapped in <Text>' error
412
+
413
+ const trackOneLength = positionOne;
414
+ const trackOneStyle = twoMarkers
415
+ ? unselectedStyle
416
+ : selectedStyle || styles.selectedTrack;
417
+ const trackThreeLength = twoMarkers ? sliderLength - positionTwo : 0;
418
+ const trackThreeStyle = unselectedStyle;
419
+ const trackTwoLength = sliderLength - trackOneLength - trackThreeLength;
420
+ const trackTwoStyle = twoMarkers
421
+ ? selectedStyle || styles.selectedTrack
422
+ : unselectedStyle;
423
+ const Marker = customMarker;
424
+
425
+ const MarkerLeft = customMarkerLeft;
426
+ const MarkerRight = customMarkerRight;
427
+
428
+ const Label = customLabel;
429
+
430
+ const {borderRadius} = touchDimensions;
431
+ const touchStyle = {
432
+ borderRadius: borderRadius || 0,
433
+ };
434
+
435
+ const markerContainerOne = {
436
+ top: markerOffsetY - 24,
437
+ left: trackOneLength + markerOffsetX - 24,
438
+ };
439
+
440
+ const markerContainerTwo = {
441
+ top: markerOffsetY - 24,
442
+ right: trackThreeLength - markerOffsetX - 24,
443
+ };
444
+
445
+ const newContainerStyle = [styles.container, containerStyle];
446
+
447
+ if (vertical) {
448
+ newContainerStyle.push({
449
+ transform: [{rotate: '-90deg'}],
450
+ });
451
+ }
452
+
453
+ const body = (
454
+ <View style={{alignItems: 'center'}}>
455
+ <View style={[styles.fullTrack, {width: sliderLength}]}>
456
+ <View
457
+ style={[
458
+ styles.track,
459
+ trackStyle,
460
+ trackOneStyle,
461
+ {width: trackOneLength},
462
+ ]}
463
+ />
464
+ <View
465
+ style={[
466
+ styles.track,
467
+ trackStyle,
468
+ trackTwoStyle,
469
+ {width: trackTwoLength},
470
+ ]}
471
+ {...(twoMarkers ? this._panResponderBetween.panHandlers : {})}
472
+ />
473
+ {twoMarkers && (
474
+ <View
475
+ style={[
476
+ styles.track,
477
+ trackStyle,
478
+ trackThreeStyle,
479
+ {width: trackThreeLength},
480
+ ]}
481
+ />
482
+ )}
483
+ <View
484
+ style={[
485
+ styles.markerContainer,
486
+ markerContainerOne,
487
+ markerContainerStyle,
488
+ positionOne > sliderLength / 2 && styles.topMarkerContainer,
489
+ ]}>
490
+ <View
491
+ style={[styles.touch, touchStyle]}
492
+ ref={component => (this._markerOne = component)}
493
+ {...this._panResponderOne.panHandlers}>
494
+ {isMarkersSeparated === false ? (
495
+ <>
496
+ {onePressed && (
497
+ <View style={styles.valueContainer}>
498
+ <Text>{valueOne}</Text>
499
+ </View>
500
+ )}
501
+ <Marker
502
+ enabled={enabledOne}
503
+ pressed={onePressed}
504
+ markerStyle={markerStyle}
505
+ pressedMarkerStyle={pressedMarkerStyle}
506
+ disabledMarkerStyle={disabledMarkerStyle}
507
+ currentValue={valueOne}
508
+ valuePrefix={valuePrefix}
509
+ valueSuffix={valueSuffix}
510
+ />
511
+ </>
512
+ ) : (
513
+ <>
514
+ {onePressed && (
515
+ <View style={styles.valueContainer}>
516
+ <Text>{valueTwo}</Text>
517
+ </View>
518
+ )}
519
+ <MarkerLeft
520
+ enabled={enabledOne}
521
+ pressed={onePressed}
522
+ markerStyle={markerStyle}
523
+ pressedMarkerStyle={pressedMarkerStyle}
524
+ disabledMarkerStyle={disabledMarkerStyle}
525
+ currentValue={valueOne}
526
+ valuePrefix={valuePrefix}
527
+ valueSuffix={valueSuffix}
528
+ />
529
+ </>
530
+ )}
531
+ </View>
532
+ </View>
533
+ {twoMarkers && positionOne !== sliderLength && (
534
+ <View
535
+ style={[
536
+ styles.markerContainer,
537
+ markerContainerTwo,
538
+ markerContainerStyle,
539
+ ]}>
540
+ <View
541
+ style={[styles.touch, touchStyle]}
542
+ ref={component => (this._markerTwo = component)}
543
+ {...this._panResponderTwo.panHandlers}>
544
+ {isMarkersSeparated === false ? (
545
+ <>
546
+ {twoPressed && (
547
+ <View style={styles.valueContainer}>
548
+ <Text>{valueTwo}</Text>
549
+ </View>
550
+ )}
551
+ <Marker
552
+ pressed={twoPressed}
553
+ markerStyle={markerStyle}
554
+ pressedMarkerStyle={pressedMarkerStyle}
555
+ disabledMarkerStyle={disabledMarkerStyle}
556
+ currentValue={valueTwo}
557
+ enabled={enabledTwo}
558
+ valuePrefix={valuePrefix}
559
+ valueSuffix={valueSuffix}
560
+ />
561
+ </>
562
+ ) : (
563
+ <>
564
+ {twoPressed && (
565
+ <View style={styles.valueContainer}>
566
+ <Text>{valueTwo}</Text>
567
+ </View>
568
+ )}
569
+ <MarkerRight
570
+ pressed={twoPressed}
571
+ markerStyle={markerStyle}
572
+ pressedMarkerStyle={pressedMarkerStyle}
573
+ disabledMarkerStyle={disabledMarkerStyle}
574
+ currentValue={valueTwo}
575
+ enabled={enabledTwo}
576
+ valuePrefix={valuePrefix}
577
+ valueSuffix={valueSuffix}
578
+ />
579
+ </>
580
+ )}
581
+ </View>
582
+ </View>
583
+ )}
584
+ </View>
585
+ </View>
586
+ );
587
+
588
+ return (
589
+ <View style={style} onLayout={e => this.onContentLayout(e)}>
590
+ {enableLabel && (
591
+ <Label
592
+ oneMarkerValue={valueOne}
593
+ twoMarkerValue={valueTwo}
594
+ oneMarkerLeftPosition={positionOne}
595
+ twoMarkerLeftPosition={positionTwo}
596
+ oneMarkerPressed={onePressed}
597
+ twoMarkerPressed={twoPressed}
598
+ />
599
+ )}
600
+ {imageBackgroundSource && (
601
+ <ImageBackground
602
+ source={imageBackgroundSource}
603
+ style={[styles.full, newContainerStyle]}>
604
+ {body}
605
+ </ImageBackground>
606
+ )}
607
+ {!imageBackgroundSource && (
608
+ <View style={newContainerStyle}>{body}</View>
609
+ )}
610
+ </View>
611
+ );
612
+ }
613
+ }
614
+
615
+ const styles = StyleSheet.create({
616
+ container: {
617
+ position: 'relative',
618
+ height: 50,
619
+ justifyContent: 'center',
620
+ },
621
+ fullTrack: {
622
+ flexDirection: 'row',
623
+ },
624
+ track: {
625
+ height: 4,
626
+ backgroundColor: Colors.black_03,
627
+ borderRadius: 2,
628
+ },
629
+ selectedTrack: {
630
+ backgroundColor: Colors.pink_05_b,
631
+ },
632
+ markerContainer: {
633
+ position: 'absolute',
634
+ width: 48,
635
+ height: 48,
636
+ backgroundColor: 'transparent',
637
+ justifyContent: 'center',
638
+ alignItems: 'center',
639
+ },
640
+ topMarkerContainer: {
641
+ zIndex: 1,
642
+ },
643
+ touch: {
644
+ backgroundColor: 'transparent',
645
+ justifyContent: 'center',
646
+ alignItems: 'center',
647
+ alignSelf: 'stretch',
648
+ },
649
+ full: {width: '100%', height: '100%'},
650
+ valueContainer: {
651
+ width: 40,
652
+ height: 32,
653
+ borderRadius: Spacing.S,
654
+ backgroundColor: Colors.white,
655
+ justifyContent: 'center',
656
+ alignItems: 'center',
657
+ position: 'absolute',
658
+ top: -36,
659
+ shadowColor: '#000',
660
+ shadowOffset: {
661
+ width: 0,
662
+ height: 4,
663
+ },
664
+ shadowOpacity: 0.24,
665
+ shadowRadius: 6,
666
+ elevation: 12,
667
+ },
668
+ });
669
+
670
+ Slider.defaultProps = {
671
+ values: [0],
672
+ onChangeStart: () => {},
673
+ onChange: () => {},
674
+ onChangeFinish: () => {},
675
+ onMarkersPosition: () => {},
676
+ step: 1,
677
+ min: 0,
678
+ max: 10,
679
+ touchDimensions: {
680
+ height: 50,
681
+ width: 50,
682
+ borderRadius: 15,
683
+ slipDisplacement: 200,
684
+ },
685
+ customMarker: DefaultMarker,
686
+ customMarkerLeft: DefaultMarker,
687
+ customMarkerRight: DefaultMarker,
688
+ customLabel: DefaultLabel,
689
+ markerOffsetX: 0,
690
+ markerOffsetY: 0,
691
+ onToggleOne: undefined,
692
+ onToggleTwo: undefined,
693
+ enabledOne: true,
694
+ enabledTwo: true,
695
+ allowOverlap: false,
696
+ snapped: false,
697
+ vertical: false,
698
+ minMarkerOverlapDistance: 0,
699
+ length: 280,
700
+ };
701
+
702
+ Slider.propTypes = {
703
+ style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
704
+ selectedStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
705
+ unselectedStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
706
+ markerOffsetX: PropTypes.number,
707
+ markerOffsetY: PropTypes.number,
708
+ values: PropTypes.arrayOf(PropTypes.number),
709
+ customMarker: PropTypes.func,
710
+ customMarkerLeft: PropTypes.func,
711
+ customMarkerRight: PropTypes.func,
712
+ isMarkersSeparated: PropTypes.bool,
713
+ touchDimensions: PropTypes.object,
714
+ containerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
715
+ vertical: PropTypes.bool,
716
+ trackStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
717
+ markerContainerStyle: PropTypes.oneOfType([
718
+ PropTypes.object,
719
+ PropTypes.array,
720
+ ]),
721
+ enabledOne: PropTypes.bool,
722
+ enabledTwo: PropTypes.bool,
723
+ onChangeStart: PropTypes.func,
724
+ onChange: PropTypes.func,
725
+ onChangeFinish: PropTypes.func,
726
+ onMarkersPosition: PropTypes.func,
727
+ step: PropTypes.number,
728
+ min: PropTypes.number,
729
+ max: PropTypes.number,
730
+ customLabel: PropTypes.any,
731
+ onToggleOne: PropTypes.func,
732
+ onToggleTwo: PropTypes.func,
733
+ allowOverlap: PropTypes.bool,
734
+ snapped: PropTypes.bool,
735
+ minMarkerOverlapDistance: PropTypes.number,
736
+ length: PropTypes.number,
737
+ allowRange: PropTypes.arrayOf(PropTypes.number),
738
+ };