[Slider] Fix Android hitSlop by replacing touchArea overlay with responder system#3951
[Slider] Fix Android hitSlop by replacing touchArea overlay with responder system#3951
Conversation
The touchArea view (absoluteFillObject) sat between the track and thumb in z-order, intercepting touches in the thumb's hitSlop zone on Android. Replaced with onStartShouldSetResponder + onResponderRelease on the container, leveraging the responder system's bubbling pattern where the deepest child (thumb) wins for direct touches. Made-with: Cursor
✅ PR Description Validation PassedAll required sections are properly filled out:
Your PR is good for review! 🚀 This validation ensures all sections from the PR template are properly filled. |
How to reproduceDrop this into import React, {useState} from 'react';
import {Platform} from 'react-native';
import {View, Text, Slider, Switch, Incubator} from 'react-native-ui-lib';
const TAG = `[Slider-${Platform.OS}]`;
export default function PlaygroundScreen() {
const [disabled, setDisabled] = useState(false);
return (
<View flex padding-20>
<Text text60 marginB-20>
Slider Debug ({Platform.OS})
</Text>
<View row centerV marginB-20>
<Text text70 marginR-10>
Disabled
</Text>
<Switch value={disabled} onValueChange={setDisabled}/>
</View>
<Text text70 marginB-10>
Slider
</Text>
<View
style={{width: '100%', height: 60, justifyContent: 'center'}}
onTouchStart={() => console.log(`${TAG} - PARENT onTouchStart`)}
onTouchEnd={() => console.log(`${TAG} - PARENT onTouchEnd`)}
>
<Slider
value={30}
minimumValue={0}
maximumValue={100}
disabled={disabled}
onSeekStart={() => console.log(`${TAG} - Slider - onSeekStart`)}
onSeekEnd={() => console.log(`${TAG} - Slider - onSeekEnd`)}
onValueChange={(v: number) => console.log(`${TAG} - Slider - onValueChange: ${v.toFixed(1)}`)}
/>
</View>
<Text text70 marginT-40 marginB-10>
Incubator.Slider
</Text>
<View
style={{width: '100%', height: 60, justifyContent: 'center'}}
onTouchStart={() => console.log(`${TAG} - PARENT onTouchStart (Incubator)`)}
onTouchEnd={() => console.log(`${TAG} - PARENT onTouchEnd (Incubator)`)}
>
<Incubator.Slider
value={30}
minimumValue={0}
maximumValue={100}
disabled={disabled}
onSeekStart={() => console.log(`${TAG} - Incubator.Slider - onSeekStart`)}
onSeekEnd={() => console.log(`${TAG} - Incubator.Slider - onSeekEnd`)}
onValueChange={(v: number) => console.log(`${TAG} - Incubator.Slider - onValueChange: ${v.toFixed(1)}`)}
/>
</View>
</View>
);
}What to test
|
| const lastOffset = useSharedValue(0); | ||
|
|
||
| const gesture = Gesture.Pan() | ||
| .hitSlop(hitSlop ?? DEFAULT_THUMB_HIT_SLOP) |
There was a problem hiding this comment.
You already have the default in the destructor
| .hitSlop(hitSlop ?? DEFAULT_THUMB_HIT_SLOP) | |
| .hitSlop(hitSlop) |
I think this (modified) change along with changing the internal implementation from Slider to Incubator.Slider is enough (I think we've discussed testing the incubator version).
I've tested it on my device and it works, with that said I would not HF it and make sure it's fully tested (and also - please test on iOS)
There was a problem hiding this comment.
If you do agree then also edit the description and changelog.
Either way please remove "React Native Gesture Responder System docs"
There was a problem hiding this comment.
In the private screen - it seems that the video is no longer available, you can use a link from here IMO
Description
Fixes an Android bug where touches near the Slider thumb fail to start a drag.
Slider – The
touchAreaoverlay (absoluteFillObject) intercepted touches in the thumb'shitSlopzone before they reached the PanResponder.Replaced it with the container's Gesture Responder System (
onStartShouldSetResponder + onResponderRelease) — the thumb (deepest child) wins for direct touches, the container handles track taps.hitSlopnow works consistently on both platforms.Incubator.Slider – Added
.hitSlop()to the RNGHGesture.Pan()on the thumb, so the gesture handler natively recognizes touches in the expanded hit area on Android.Also added
hitSlopto the Pan gesture mock in jest setup.Changelog
Slider, Incubator.Slider - Fixed Android bug where touches near the thumb failed to start a drag.
Additional info