@momo-kits/slider 0.0.46-beta.46 → 0.0.46-beta.50

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