Skip to content

Conversation

@m-bert
Copy link
Contributor

@m-bert m-bert commented Oct 1, 2025

Description

Right now, if one changes enabled property of handlers to false, they can never activate again. In the following example:

const [enabled, setEnabled] = useState(false);
const pan = Gesture.Pan().enabled(enabled)

gesture will never become active, even if enabled changes to true. Same happens when enabled is set to true and then changed to false and true again.

This happens because we set enabled to true by default in setGestureConfig, thus the following check:

if (config.enabled !== undefined && this.enabled !== config.enabled) { ... }

passes only when config.enabled is false.

I've set enabled to null by default, and then if config.enabled is defined, it is assigned given value. Else default will be true. To fix the issue, I've removed reset of enabled in resetConfig method.

Alternative approach would be to follow Android implementation and always react to changes in enabled even in cases like false $\rightarrow$ false and true $\rightarrow$ true.

Test plan

Tested on the following code:
import React from 'react';
import { Button, StyleSheet, View } from 'react-native';
import {
  Gesture,
  GestureDetector,
  GestureHandlerRootView,
  NativeDetector,
  usePan,
} from 'react-native-gesture-handler';
import Animated, {
  useAnimatedStyle,
  useSharedValue,
} from 'react-native-reanimated';

export default function EmptyExample() {
  const [showDetector, setShowDetector] = React.useState(true);

  const [enablePan1, setEnablePan1] = React.useState(true);
  const enablePan2 = useSharedValue(true);

  const pan1 = Gesture.Pan().enabled(enablePan1);

  const pan2 = usePan({
    enabled: enablePan2,
  });

  const as = useAnimatedStyle(() => {
    return {
      backgroundColor: enablePan2.value ? 'lightgreen' : 'crimson',
    };
  });

  return (
    <GestureHandlerRootView style={styles.container}>
      <Button
        title="Toggle old API enabled!"
        onPress={() => {
          setEnablePan1((prev) => !prev);
        }}
      />

      <GestureDetector gesture={pan1}>
        <View
          style={[
            styles.box,
            { backgroundColor: enablePan1 ? 'lightgreen' : 'crimson' },
          ]}
        />
      </GestureDetector>

      <Button
        title="Toggle new API enabled!"
        onPress={() => {
          enablePan2.value = !enablePan2.value;
        }}
      />

      <Button
        title="Toggle NativeDetetor"
        onPress={() => {
          setShowDetector((prev) => !prev);
        }}
      />

      {showDetector && (
        <NativeDetector gesture={pan2}>
          <Animated.View style={[styles.box, as]} />
        </NativeDetector>
      )}
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },

  box: {
    width: 200,
    height: 200,
    borderRadius: 20,
  },
});

@m-bert m-bert requested a review from j-piasecki October 3, 2025 11:40
@m-bert
Copy link
Contributor Author

m-bert commented Oct 23, 2025

I've changed it a bit and removed reset of enabled in resetConfig as discussed offline. I've also updated an example on which I've tested these changed. Let me know what you think (cc @j-piasecki)

@m-bert m-bert merged commit 6eb7261 into next Oct 23, 2025
1 check passed
@m-bert m-bert deleted the @mbert/change-enable-behavior-on-web branch October 23, 2025 14:18
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.

4 participants