Skip to content

Commit d7eb359

Browse files
fix(web): align step markers with thumb position using thumbSize prop
- Pass thumbSize prop to StepsIndicator component - Use actual thumbSize value instead of hardcoded constant - Add WebProps type for proper TypeScript typing - Fix step marker alignment on web platform edges Fixes #743
1 parent c203192 commit d7eb359

File tree

6 files changed

+57
-8
lines changed

6 files changed

+57
-8
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ To use this library you need to ensure you are using the correct version of Reac
9696
| `maximumTrackImage` | Assigns a maximum track image. Only static images are supported. The leftmost pixel of the image will be stretched to fill the track. | Image<br/>.propTypes<br/>.source | iOS |
9797
| `minimumTrackImage` | Assigns a minimum track image. Only static images are supported. The rightmost pixel of the image will be stretched to fill the track. | Image<br/>.propTypes<br/>.source | iOS |
9898
| `thumbImage` | Sets an image for the thumb. Only static images are supported. Needs to be a URI of a local or network image; base64-encoded SVG is not supported. | Image<br/>.propTypes<br/>.source | |
99+
| `thumbSize` | Define the size of the thumb. Only for web<br/>Default value is 20px. | number | web |
99100
| `trackImage` | Assigns a single image for the track. Only static images are supported. The center pixel of the image will be stretched to fill the track. | Image<br/>.propTypes<br/>.source | iOS |
100-
| [`StepMarker`](#stepmarker) | Component to be rendered for each step on the track,<br/>with the possibility to change the styling, when thumb is at that given step | `FC<MarkerProps>` | iOS, Android, Windows |
101+
| [`StepMarker`](#stepmarker) | Component to be rendered for each step on the track,<br/>with the possibility to change the styling, when thumb is at that given step | `FC<MarkerProps>` | |
101102
| [`renderStepNumber`](#renderstepnumber) | Turns on the displaying of numbers of steps.<br/>Numbers of steps are displayed under the track | bool | iOS, Android, Windows |
102103
| `ref` | Reference object. | MutableRefObject | web |
103104
| `View` | [Inherited `View` props...](https://github.com/facebook/react-native-website/blob/master/docs/view.md#props) | | |

example-web/src/Examples.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,19 @@ export const examples: Props[] = [
232232
);
233233
},
234234
},
235+
// Check the fix for the issue #743
236+
{
237+
title: 'With step numbers',
238+
render() {
239+
return (
240+
<SliderExample
241+
minimumValue={1}
242+
maximumValue={5}
243+
step={1}
244+
renderStepNumber={true}
245+
style={[styles.slider, { height: 70 }]}
246+
/>
247+
);
248+
},
249+
},
235250
];

package/src/RNCSliderNativeComponent.web.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from 'react-native';
1212
//@ts-ignore
1313
import type {ImageSource} from 'react-native/Libraries/Image/ImageSource';
14+
import {constants} from './utils/constants';
1415

1516
type Event = Readonly<{
1617
nativeEvent: {
@@ -66,7 +67,7 @@ const RCTSliderWebComponent = React.forwardRef(
6667
inverted = false,
6768
disabled = false,
6869
trackHeight = 4,
69-
thumbSize = 20,
70+
thumbSize = constants.THUMB_SIZE,
7071
thumbImage,
7172
onRNCSliderSlidingStart = (_: Event) => {},
7273
onRNCSliderSlidingComplete = (_: Event) => {},

package/src/Slider.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,17 @@ type IOSProps = Readonly<{
6464
tapToSeek?: boolean;
6565
}>;
6666

67+
type WebProps = Readonly<{
68+
/**
69+
* The size of the thumb on the web platform.
70+
* Default value is 20px.
71+
*/
72+
thumbSize?: number;
73+
}>;
74+
6775
type Props = ViewProps &
6876
IOSProps &
77+
WebProps &
6978
WindowsProps &
7079
Readonly<{
7180
/**
@@ -301,6 +310,7 @@ const SliderComponent = (
301310
thumbImage={props.thumbImage}
302311
StepMarker={props.StepMarker}
303312
isLTR={inverted}
313+
thumbSize={props.thumbSize}
304314
/>
305315
) : null}
306316
<RCTSliderNativeComponent

package/src/components/StepsIndicator.tsx

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, {FC, Fragment, useCallback, useMemo} from 'react';
2-
import {View} from 'react-native';
2+
import {Platform, View, ViewStyle} from 'react-native';
33
import {StepNumber} from './StepNumber';
44
import {MarkerProps, SliderTrackMark} from './TrackMark';
55
//@ts-ignore
@@ -15,6 +15,7 @@ export const StepsIndicator = ({
1515
renderStepNumber,
1616
thumbImage,
1717
isLTR,
18+
thumbSize = constants.THUMB_SIZE,
1819
}: {
1920
options: number[];
2021
sliderWidth: number;
@@ -23,6 +24,7 @@ export const StepsIndicator = ({
2324
renderStepNumber?: boolean;
2425
thumbImage?: ImageSource;
2526
isLTR?: boolean;
27+
thumbSize?: number;
2628
}) => {
2729
const stepNumberFontStyle = useMemo(() => {
2830
return {
@@ -32,13 +34,33 @@ export const StepsIndicator = ({
3234
: constants.STEP_NUMBER_TEXT_FONT_BIG,
3335
};
3436
}, [options.length]);
37+
const platformDependentStyles = useMemo(() => {
38+
const isWeb = Platform.OS === 'web';
39+
return {
40+
stepIndicatorContainerStyle: isWeb
41+
? styles.stepsIndicator
42+
: {
43+
...styles.stepsIndicator,
44+
marginHorizontal: sliderWidth * constants.MARGIN_HORIZONTAL_PADDING,
45+
},
46+
stepIndicatorElementStyle: isWeb
47+
? {
48+
...styles.stepIndicatorElement,
49+
width: thumbSize,
50+
justifyContent: 'space-between' as const,
51+
}
52+
: styles.stepIndicatorElement,
53+
};
54+
}, [sliderWidth, thumbSize]);
3555
const values = isLTR ? options.reverse() : options;
3656

3757
const renderStepIndicator = useCallback(
3858
(i: number, index: number) => {
3959
return (
4060
<Fragment key={index}>
41-
<View style={styles.stepIndicatorElement} key={`${index}-View`}>
61+
<View
62+
style={platformDependentStyles.stepIndicatorElementStyle}
63+
key={`${index}-View`}>
4264
<SliderTrackMark
4365
key={`${index}-SliderTrackMark`}
4466
isTrue={currentValue === i}
@@ -67,16 +89,14 @@ export const StepsIndicator = ({
6789
thumbImage,
6890
renderStepNumber,
6991
stepNumberFontStyle,
92+
platformDependentStyles.stepIndicatorElementStyle,
7093
],
7194
);
7295

7396
return (
7497
<View
7598
pointerEvents="none"
76-
style={[
77-
styles.stepsIndicator,
78-
{marginHorizontal: sliderWidth * constants.MARGIN_HORIZONTAL_PADDING},
79-
]}>
99+
style={platformDependentStyles.stepIndicatorContainerStyle}>
80100
{values.map((i, index) => renderStepIndicator(i, index))}
81101
</View>
82102
);

package/src/utils/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import {Platform} from 'react-native';
33
export const constants = {
44
SLIDER_DEFAULT_INITIAL_VALUE: 0,
55
MARGIN_HORIZONTAL_PADDING: 0.05,
6+
// Default thumb size for web platform (used in step indicator positioning)
7+
THUMB_SIZE: 20,
68
STEP_NUMBER_TEXT_FONT_SMALL: 8,
79
STEP_NUMBER_TEXT_FONT_BIG: 12,
810
LIMIT_MIN_VALUE: Number.MIN_SAFE_INTEGER,

0 commit comments

Comments
 (0)