@momo-kits/slider 0.0.44-beta → 0.0.44-beta.1

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,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
- 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();
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;
43
122
  }
44
123
 
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
- );
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);
73
177
 
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,
178
+ onMarkersPosition([newPositionOne, positionTwo]);
179
+ },
83
180
  );
84
- };
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
+ }
85
201
 
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
- };
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
+ }
96
263
 
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
- });
264
+ this.setState(
265
+ {
266
+ pastOne: positionOne,
267
+ onePressed: !onePressed,
268
+ },
269
+ () => {
270
+ const change = [valueOne];
271
+ if (valueTwo) {
272
+ change.push(valueTwo);
105
273
  }
106
- };
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
+ }
107
286
 
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
- }
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
+ }
133
313
 
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
- };
314
+ if (positionOne !== prevPositionOne || positionTwo !== prevPositionTwo) {
315
+ onMarkersPosition([positionOne, positionTwo]);
316
+ }
203
317
 
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
- }
318
+ if (onePressed || twoPressed) {
319
+ return;
320
+ }
226
321
 
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
- }
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,
291
433
  };
292
434
 
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
- );
435
+ const markerContainerOne = {
436
+ top: markerOffsetY - 24,
437
+ left: trackOneLength + markerOffsetX - 24,
316
438
  };
317
439
 
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
- );
440
+ const markerContainerTwo = {
441
+ top: markerOffsetY - 24,
442
+ right: trackThreeLength - markerOffsetX - 24,
340
443
  };
341
444
 
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
- }
445
+ const newContainerStyle = [styles.container, containerStyle];
410
446
 
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
- }
447
+ if (vertical) {
448
+ newContainerStyle.push({
449
+ transform: [{rotate: '-90deg'}],
450
+ });
421
451
  }
422
452
 
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>
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>
567
499
  </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>
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
+ )}
609
531
  </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}
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}
622
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
+ </>
623
580
  )}
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
- )}
581
+ </View>
635
582
  </View>
636
- );
637
- }
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
+ }
638
613
  }
639
614
 
640
615
  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,
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,
655
663
  },
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%' }
664
+ shadowOpacity: 0.24,
665
+ shadowRadius: 6,
666
+ elevation: 12,
667
+ },
674
668
  });
675
669
 
676
670
  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
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,
706
700
  };
707
701
 
708
702
  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)
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),
741
738
  };