Drag with `preventScroll`: pointerup is skipped if fires before timeout

Author: thorn0Created Sep 13, 2025Updated Sep 13, 2025

Describe the bug

With preventScroll, pointerdown schedules a timeout. If pointerup occurs before this timeout, it's ignored. It doesn't clean up the state of the gesture and things get broken.

Sandbox or Video

Open https://use-gesture.netlify.app/docs/options/#preventscroll on mobile. Quickly touch and release the torus. See how it's get activated and stuck. Now there is no way to make it react to gestures again.

Information:

  • Use Gesture version: 10.3.1
  • Device: phone
  • OS: Android
  • Browser: Chrome

Checklist:

  • I've read the documentation.
  • If this is an issue with drag, I've tried setting touch-action: none to the draggable element.

Workaround:

javascript
const originalPointerUp = dragAction.engine.prototype.pointerUp;
dragAction.engine.prototype.pointerUp = function (event: PointerEvent) {
  if (this.state._pointerActive && !this.state._active) {
    this.clean();
    return;
  }
  originalPointerUp.call(this, event);
};