@momo-kits/slider 0.0.36-beta → 0.0.36

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