Skip to content

[Incubator.Slider] Add useRelativeDrag prop for relative drag mode#3968

Open
adids1221 wants to merge 3 commits intomasterfrom
feat/incubator-slider-use-relative-drag
Open

[Incubator.Slider] Add useRelativeDrag prop for relative drag mode#3968
adids1221 wants to merge 3 commits intomasterfrom
feat/incubator-slider-use-relative-drag

Conversation

@adids1221
Copy link
Copy Markdown
Contributor

Description

Adds useRelativeDrag support to Incubator.Slider.

Uses a container-level RNGH Gesture.Pan() with pointerEvents="none" on the thumb — dragging anywhere on the slider moves the thumb relative to its current position instead of snapping to the touch point. Designed for single-thumb mode.

Changelog

Incubator.Slider - Added useRelativeDrag prop for relative drag mode.

Additional info

adids1221 and others added 2 commits April 9, 2026 11:50
Added .hitSlop() to the RNGH Gesture.Pan() on the thumb so the gesture
handler natively recognizes touches in the expanded hit area on Android.
Also added hitSlop to the Pan gesture mock in jest setup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a container-level RNGH Gesture.Pan() that moves the thumb relative
to its current position when useRelativeDrag is true. The thumb gets
pointerEvents="none" so the container gesture takes over, and isActive
is passed to keep the thumb's active styling in sync.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 9, 2026

✅ PR Description Validation Passed

All required sections are properly filled out:

  • Description
  • Changelog
  • Additional info

Your PR is good for review! 🚀


This validation ensures all sections from the PR template are properly filled.

@adids1221
Copy link
Copy Markdown
Contributor Author

How to reproduce

Drop this into PlaygroundScreen.tsx and test on Android and iOS:

import React, {useState} from 'react';
import {Platform} from 'react-native';
import {View, Text, 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>
        Incubator.Slider (normal)
      </Text>
      <View
        style={{width: '100%', height: 60, justifyContent: 'center'}}
        onTouchStart={() => console.log(`${TAG} - PARENT onTouchStart`)}
        onTouchEnd={() => console.log(`${TAG} - PARENT onTouchEnd`)}
      >
        <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>

      <Text text70 marginT-40 marginB-10>
        Incubator.Slider (useRelativeDrag)
      </Text>
      <View
        style={{width: '100%', height: 60, justifyContent: 'center'}}
        onTouchStart={() => console.log(`${TAG} - PARENT onTouchStart (relative)`)}
        onTouchEnd={() => console.log(`${TAG} - PARENT onTouchEnd (relative)`)}
      >
        <Incubator.Slider
          value={30}
          minimumValue={0}
          maximumValue={100}
          disabled={disabled}
          useRelativeDrag
          onSeekStart={() => console.log(`${TAG} - Incubator.Slider (relative) - onSeekStart`)}
          onSeekEnd={() => console.log(`${TAG} - Incubator.Slider (relative) - onSeekEnd`)}
          onValueChange={(v: number) => console.log(`${TAG} - Incubator.Slider (relative) - onValueChange: ${v.toFixed(1)}`)}
        />
      </View>
    </View>
  );
}

What to test

  • useRelativeDrag — relative movement: Drag anywhere on the slider (not just the thumb) → thumb should move relative to where the drag started, not snap to touch point
  • useRelativeDrag — track tap: Tapping the track (without dragging) should not snap the thumb
  • useRelativeDrag — thumb active style: Thumb should scale up while dragging from any point on the track
  • Normal mode — track tap: Tap anywhere on the track away from the thumb → value should jump to that position
  • Both modes — normal drag: Grab the thumb and drag → should work smoothly
  • Both platforms — disabled: Toggle disabled switch → neither slider should respond to touches

Base automatically changed from fix/incubator-slider-android-hitslop to master April 9, 2026 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants