@momo-kits/slider 0.0.10 → 0.0.18-beta-6

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