Skip to content

Commit 37df0aa

Browse files
committed
fix(ui): #2368 add slider tap gesture
1 parent 5124260 commit 37df0aa

File tree

1 file changed

+44
-22
lines changed

1 file changed

+44
-22
lines changed

src/components/Slider.tsx

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,36 @@ const Slider = ({
5050
panX.value = stepPositions[valueIndex];
5151
}, [sliderWidth, value, steps, stepPositions, panX]);
5252

53-
const gesture = Gesture.Pan()
53+
const findClosestStep = (currentPosition: number): number => {
54+
'worklet';
55+
return stepPositions.reduce((closestStep, currentStep) => {
56+
// Calculate the difference between the current step and the current position
57+
const currentDifference = Math.abs(currentStep - currentPosition);
58+
const closestDifference = Math.abs(closestStep - currentPosition);
59+
60+
// If the current step is closer, update the closest step
61+
return currentDifference < closestDifference ? currentStep : closestStep;
62+
});
63+
};
64+
65+
const tapGesture = Gesture.Tap().onStart((event) => {
66+
const closestStep = findClosestStep(event.x);
67+
panX.value = closestStep;
68+
69+
if (onValueChange) {
70+
const stepIndex = stepPositions.indexOf(closestStep);
71+
runOnJS(onValueChange)(steps[stepIndex]);
72+
}
73+
});
74+
75+
const panGesture = Gesture.Pan()
5476
.onStart(() => {
5577
prevPanX.value = panX.value;
5678
})
5779
.onUpdate((event) => {
5880
panX.value = clamp(prevPanX.value + event.translationX, 0, sliderWidth);
5981
})
6082
.onEnd(() => {
61-
const findClosestStep = (currentPosition: number): number => {
62-
return stepPositions.reduce((prev, curr) => {
63-
return Math.abs(curr - currentPosition) <
64-
Math.abs(prev - currentPosition)
65-
? curr
66-
: prev;
67-
});
68-
};
69-
7083
const closestStep = findClosestStep(panX.value);
7184
panX.value = withSpring(closestStep);
7285

@@ -90,19 +103,23 @@ const Slider = ({
90103
style={styles.container}
91104
onLayout={(e): void => setSliderWidth(e.nativeEvent.layout.width)}>
92105
<View style={styles.sliderContainer}>
93-
<ThemedView style={styles.track} color="green32" />
94-
<Animated.View style={[styles.track, trailStyle]} />
95-
{stepPositions.map((pos, index) => (
96-
<View
97-
key={`step-${index}`}
98-
style={[styles.stepContainer, { left: pos - 2 }]}>
99-
<ThemedView style={styles.stepMarker} color="white" />
100-
<Text13UP style={styles.stepLabel} numberOfLines={1}>
101-
${steps[index]}
102-
</Text13UP>
106+
<GestureDetector gesture={tapGesture}>
107+
<View style={styles.trackHitbox}>
108+
<ThemedView style={styles.track} color="green32" />
109+
<Animated.View style={[styles.track, trailStyle]} />
110+
{stepPositions.map((pos, index) => (
111+
<View
112+
key={`step-${index}`}
113+
style={[styles.stepContainer, { left: pos - 2 }]}>
114+
<ThemedView style={styles.stepMarker} color="white" />
115+
<Text13UP style={styles.stepLabel} numberOfLines={1}>
116+
${steps[index]}
117+
</Text13UP>
118+
</View>
119+
))}
103120
</View>
104-
))}
105-
<GestureDetector gesture={gesture}>
121+
</GestureDetector>
122+
<GestureDetector gesture={panGesture}>
106123
<Animated.View style={[styles.knob, animatedStyle]}>
107124
<ThemedView style={styles.knobOuter} color="green">
108125
<ThemedView style={styles.knobInner} color="white" />
@@ -126,6 +143,11 @@ const styles = StyleSheet.create({
126143
alignItems: 'center',
127144
justifyContent: 'center',
128145
},
146+
trackHitbox: {
147+
justifyContent: 'center',
148+
height: 30,
149+
width: '100%',
150+
},
129151
track: {
130152
borderRadius: 3,
131153
height: 8,

0 commit comments

Comments
 (0)