@momo-kits/slider 0.0.34-beta → 0.0.36-beta

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