adobe / adobe/react-spectrum

Drag operations still occur on a parent element if the press starts on non-draggable child element

Open
#2,943 0 comments 0 reactions 0 assignees View on GitHub
browser bug ListView
Dominant language
TypeScript
Stars
15.9k
Forks
1.6k
Avg merge
3d 9m
Merged PRs (30d)
59

Description

# 🐛 Bug Report
Android Chrome specific

Specific to the following ListView bug: "Can start a drag operation on press and hold on a button/menu trigger on android (need to prevent drag when on interactable element)", mentioned in https://github.com/adobe/react-spectrum/issues/2897.
Reproduction steps:
1. Go to the draggable ListView story
2. Press and hold on a button within a draggable row
3. Note that the drag preview appears and that you can perform drag and drop operations. All other browsers prevent drag from starting

browser bug filed: https://bugs.chromium.org/p/chromium/issues/detail?id=1304488

## 🤔 Expected Behavior

Pressing and holding on a non-draggable element should not cause a drag operation on the draggable parent

## 😯 Current Behavior

Pressing and holding on a non-draggable element causes a drag operation on the draggable parent

## 💁 Possible Solution

Approaches tried:
- preventing default `onPointerDown` (doesn't work, see browser bug above) and in `onTouchStart` (doesn't work because React touch event handlers are passive by default and thus don't do anything when preventDefault is called)
- adding `dragstart` listener and calling `e.preventDefault` to various places in `usePress` (in `onPointerStart` and attaching it to the target, in a `useEffect` and attaching it to the `usePress` `ref` if any, to the `window`)
- Issues with the above: Only works if the element that the press starts on has `touch-action: none`, otherwise Chrome throws a warning and the event is not actually default prevented. If we prevent default on too many things, touch scrolling stops working
image

- making the non-draggable element "draggable=false" (no effect)
- preventing default and stopping propagation for non draggable element in their `onDragStart` (no effect because `onDragStart` doesn't fire)

Additional resources on touch events, why they are passive, :
https://developers.google.com/web/updates/2017/01/scrolling-intervention
## 🌍 Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| react-spectrum |. 3.16.4
| Browser |. Chrome 98
| Operating System | Android 10

## 🧢 Your Company/Team

RSP

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.