Skip to content

Commit c687a95

Browse files
betkoBeáta Brassai
andauthored
Fix stepMarked prop of the StepMarker when the step props is not default 1 (#581)
Co-authored-by: Beáta Brassai <[email protected]>
1 parent 703f79a commit c687a95

File tree

8 files changed

+314
-18
lines changed

8 files changed

+314
-18
lines changed

example/src/Examples.tsx

Lines changed: 114 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1-
import React, {useState} from 'react';
2-
import {Text, View, StyleSheet} from 'react-native';
3-
import Slider, {SliderProps} from '@react-native-community/slider';
1+
import React, {FC, useState} from 'react';
2+
import {Text, View, StyleSheet, Image} from 'react-native';
3+
import Slider, {MarkerProps, SliderProps} from '@react-native-community/slider';
44

55
export interface Props {
66
title: string;
77
render(): JSX.Element;
88
platform?: string;
99
}
1010

11+
const CONSTANTS = {
12+
MAX_VALUE: 100,
13+
MIN_VALUE: 10,
14+
STEP: 10,
15+
DEFAULT_STEP_RESOLUTION: 100,
16+
} as const;
17+
1118
const SliderExample = (props: SliderProps) => {
1219
const [value, setValue] = useState(props.value ?? 0);
1320
return (
@@ -262,20 +269,113 @@ const SlidingCustomStepsThumbImageWithNumbersAndDifferentWidth = (
262269
);
263270
};
264271

272+
const MyStepMarker: FC<MarkerProps> = ({stepMarked, currentValue}) => {
273+
return stepMarked ? (
274+
<View style={styles.background}>
275+
<View style={styles.separator} />
276+
<View style={styles.label}>
277+
{currentValue !== undefined ? (
278+
<Text>{currentValue}</Text>
279+
) : (
280+
<Text>{'-'}</Text>
281+
)}
282+
<Image
283+
style={styles.tinyLogo}
284+
source={Image.resolveAssetSource(
285+
require('./resources/twitter-small.png'),
286+
)}
287+
/>
288+
</View>
289+
</View>
290+
) : (
291+
<View style={styles.divider} />
292+
);
293+
};
294+
295+
const SliderExampleWithCustomMarker = (props: SliderProps) => {
296+
const [value, setValue] = useState(props.value ?? CONSTANTS.MIN_VALUE);
297+
298+
return (
299+
<View>
300+
<Text style={styles.text}>{value && +value.toFixed(3)}</Text>
301+
<Slider
302+
step={CONSTANTS.STEP}
303+
style={[styles.slider, props.style]}
304+
minimumValue={CONSTANTS.MIN_VALUE}
305+
maximumValue={CONSTANTS.MAX_VALUE}
306+
thumbImage={require('./resources/empty.png')}
307+
tapToSeek
308+
{...props}
309+
value={value}
310+
onValueChange={setValue}
311+
lowerLimit={1}
312+
StepMarker={MyStepMarker}
313+
minimumTrackTintColor={'#00629A'}
314+
maximumTrackTintColor={'#979EA4'}
315+
/>
316+
</View>
317+
);
318+
};
319+
265320
export default SliderExample;
266321

267322
const styles = StyleSheet.create({
268-
slider: {
269-
width: 300,
270-
opacity: 1,
271-
marginTop: 10,
272-
},
273323
text: {
274324
fontSize: 14,
275325
textAlign: 'center',
276326
fontWeight: '500',
277327
margin: 0,
278328
},
329+
divider: {
330+
width: 2,
331+
height: 20,
332+
backgroundColor: '#ffffff',
333+
justifyContent: 'center',
334+
alignItems: 'center',
335+
},
336+
separator: {
337+
width: 2,
338+
height: 20,
339+
backgroundColor: '#00629A',
340+
justifyContent: 'center',
341+
alignItems: 'center',
342+
},
343+
label: {
344+
marginTop: 10,
345+
width: 45,
346+
paddingVertical: 5,
347+
paddingHorizontal: 10,
348+
backgroundColor: '#ffffff',
349+
shadowColor: '#000000',
350+
shadowOffset: {
351+
width: 0,
352+
height: 1,
353+
},
354+
shadowOpacity: 0.4,
355+
shadowRadius: 4,
356+
justifyContent: 'center',
357+
alignItems: 'center',
358+
},
359+
background: {
360+
justifyContent: 'center',
361+
alignItems: 'center',
362+
},
363+
tinyLogo: {
364+
marginVertical: 5,
365+
aspectRatio: 1,
366+
flex: 1,
367+
height: '100%',
368+
width: '100%',
369+
},
370+
minMaxLabel: {
371+
flexDirection: 'row',
372+
zIndex: -1,
373+
},
374+
slider: {
375+
width: 300,
376+
opacity: 1,
377+
marginTop: 10,
378+
},
279379
outer: {
280380
width: 20,
281381
height: 20,
@@ -502,6 +602,12 @@ export const examples: Props[] = [
502602
return <InvertedSliderWithStepMarker />;
503603
},
504604
},
605+
{
606+
title: 'Custom step marker settings',
607+
render() {
608+
return <SliderExampleWithCustomMarker />;
609+
},
610+
},
505611
{
506612
title: 'Inverted slider direction',
507613
render() {

example/src/resources/empty.png

1.68 KB
Loading

package/src/Slider.tsx

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,15 @@ const SliderComponent = (
216216
);
217217
const [width, setWidth] = useState(0);
218218

219+
const step = localProps.step
220+
? localProps.step
221+
: constants.DEFAULT_STEP_RESOLUTION;
222+
219223
const options = Array.from(
220224
{
221-
length:
222-
(localProps.maximumValue! - localProps.minimumValue!) /
223-
(localProps.step
224-
? localProps.step
225-
: constants.DEFAULT_STEP_RESOLUTION) +
226-
1,
225+
length: (localProps.maximumValue! - localProps.minimumValue!) / step + 1,
227226
},
228-
(_, index) => index,
227+
(_, index) => localProps.minimumValue! + index * step,
229228
);
230229

231230
const defaultStyle =

package/src/__tests__/Slider.test.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as React from 'react';
22
import renderer from 'react-test-renderer';
33
import Slider from '../Slider';
4+
import {View} from 'react-native';
45

56
describe('<Slider />', () => {
67
it('renders enabled slider', () => {
@@ -60,4 +61,29 @@ describe('<Slider />', () => {
6061

6162
expect(tree).toMatchSnapshot();
6263
});
64+
65+
it('renders a slider with custom stepMaker', () => {
66+
const tree = renderer
67+
.create(
68+
<Slider
69+
value={2}
70+
minimumValue={0}
71+
maximumValue={4}
72+
StepMarker={({stepMarked}) => {
73+
return stepMarked ? (
74+
<View>
75+
<View style={{width: '10px', backgroundColor: 'red'}} />
76+
</View>
77+
) : (
78+
<View>
79+
<View style={{width: '10px', backgroundColor: 'green'}} />
80+
</View>
81+
);
82+
}}
83+
/>,
84+
)
85+
.toJSON();
86+
87+
expect(tree).toMatchSnapshot();
88+
});
6389
});

package/src/__tests__/__snapshots__/Slider.test.tsx.snap

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,163 @@ exports[`<Slider /> renders a slider with custom props 1`] = `
443443
</View>
444444
`;
445445

446+
exports[`<Slider /> renders a slider with custom stepMaker 1`] = `
447+
<View
448+
onLayout={[Function]}
449+
style={
450+
[
451+
{
452+
"defaultIndicatorIdle": {
453+
"backgroundColor": "#C0C0C0",
454+
"height": 10,
455+
"width": 2,
456+
},
457+
"defaultIndicatorMarked": {
458+
"backgroundColor": "#CCCCCC",
459+
"height": 20,
460+
"width": 5,
461+
},
462+
"defaultSlider": {},
463+
"defaultSlideriOS": {
464+
"height": 40,
465+
},
466+
"sliderMainContainer": {
467+
"width": "100%",
468+
"zIndex": 1,
469+
},
470+
"stepIndicatorElement": {
471+
"alignContent": "center",
472+
"alignItems": "center",
473+
},
474+
"stepNumber": {
475+
"alignItems": "center",
476+
"marginTop": 20,
477+
"position": "absolute",
478+
},
479+
"stepsIndicator": {
480+
"flex": 1,
481+
"flexDirection": "row",
482+
"justifyContent": "space-between",
483+
"top": 10,
484+
"zIndex": 2,
485+
},
486+
"thumbImage": {
487+
"alignContent": "center",
488+
"alignItems": "center",
489+
"position": "absolute",
490+
},
491+
"thumbImageContainer": {
492+
"alignContent": "center",
493+
"alignItems": "center",
494+
"justifyContent": "center",
495+
"position": "absolute",
496+
"zIndex": 3,
497+
},
498+
"trackMarkContainer": {
499+
"alignContent": "center",
500+
"alignItems": "center",
501+
"alignSelf": "center",
502+
"justifyContent": "center",
503+
"position": "absolute",
504+
"zIndex": 3,
505+
},
506+
},
507+
{
508+
"height": 40,
509+
},
510+
{
511+
"justifyContent": "center",
512+
},
513+
]
514+
}
515+
>
516+
<View
517+
pointerEvents="none"
518+
style={
519+
[
520+
{
521+
"flex": 1,
522+
"flexDirection": "row",
523+
"justifyContent": "space-between",
524+
"top": 10,
525+
"zIndex": 2,
526+
},
527+
{
528+
"marginHorizontal": 0,
529+
},
530+
]
531+
}
532+
>
533+
<View
534+
style={
535+
{
536+
"alignContent": "center",
537+
"alignItems": "center",
538+
}
539+
}
540+
>
541+
<View
542+
style={
543+
{
544+
"alignContent": "center",
545+
"alignItems": "center",
546+
"alignSelf": "center",
547+
"justifyContent": "center",
548+
"position": "absolute",
549+
"zIndex": 3,
550+
}
551+
}
552+
>
553+
<View>
554+
<View
555+
style={
556+
{
557+
"backgroundColor": "green",
558+
"width": "10px",
559+
}
560+
}
561+
/>
562+
</View>
563+
</View>
564+
</View>
565+
</View>
566+
<RNCSlider
567+
StepMarker={[Function]}
568+
disabled={false}
569+
inverted={false}
570+
lowerLimit={-9007199254740991}
571+
maximumValue={4}
572+
minimumValue={0}
573+
onChange={[Function]}
574+
onRNCSliderAccessibilityAction={null}
575+
onRNCSliderSlidingComplete={null}
576+
onRNCSliderSlidingStart={null}
577+
onRNCSliderValueChange={[Function]}
578+
onResponderTerminationRequest={[Function]}
579+
onStartShouldSetResponder={[Function]}
580+
step={0}
581+
style={
582+
[
583+
{
584+
"width": 0,
585+
"zIndex": 1,
586+
},
587+
{
588+
"height": 40,
589+
},
590+
{
591+
"alignContent": "center",
592+
"alignItems": "center",
593+
},
594+
]
595+
}
596+
tapToSeek={false}
597+
upperLimit={9007199254740991}
598+
value={2}
599+
/>
600+
</View>
601+
`;
602+
446603
exports[`<Slider /> renders disabled slider 1`] = `
447604
<View
448605
onLayout={[Function]}

package/src/components/StepsIndicator.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const StepsIndicator = ({
4747
isTrue={currentValue === i}
4848
thumbImage={thumbImage}
4949
StepMarker={StepMarker}
50+
currentValue={currentValue}
5051
/>
5152
{renderStepNumber ? (
5253
<StepNumber

0 commit comments

Comments
 (0)