nuclearpasta / react-native-drax

A drag-and-drop system for React Native
MIT License
554 stars 69 forks source link

Drag starts on press instead of long press #148

Closed tomgiam closed 2 years ago

tomgiam commented 2 years ago

Hi, I'm trying to use this library to create a scrollable SectionList. So far I can drag the section headers and the items, but I have a problem because the drag starts as soon as I touch the screen i.e. on press instead of long press, so I can't scroll the list unless I comment out "onDragStart={() => {console.log("drag item");}}"

The drag is supposed to start on long press by default. How do I force that? Any workarounds?

If I use DraxView on a smaller part of the UI e.g. an icon or image in the section or list item, that fixes the problem, but then the UI of what gets dragged is just the icon or image instead of the entire section or list item. Is there a way to specify the UI that gets dragged?

Note: It would also be nice to be able to drag the whole section UI, and not just the section header, but I tried that and it didn't work. I used nested DraxViews.

Using: "react-native": "0.68.2", "react-native-gesture-handler": "~2.2.1",

The basic structure is:

<DraxProvider>
 <View>
  <DraxScrollView>
   {this.props.Items.map((section) => (
    <View>
     <DraxView payload={section} onDragStart={() => {console.log("drag section");}}>
      <Text>{section.Title}</Text>
     </Draxview>
     {section.map((item) => (
      <DraxView payload={item} onDragStart={() => {console.log("drag item");}}>
       <Text>{item.Title}</Text>
      </Draxview>
     ))}
    </View>
   ))}
  <DraxScrollView>
 <View>
</DraxProvider>
lafiosca commented 2 years ago

Since you're building with DraxViews, which have a default long-press delay of 0, you will need to specify it in the DraxView props like: longPressDelay={250}. I hope that helps with your first problem. For the rest, I don't know how much luck you will have without additional changes to the library. I have not been actively developing Drax for quite some time, and there are several outstanding issues related to nested views, such as #137

lafiosca commented 2 years ago

I tagged this with DraxList as well because ideally section list functionality would be built into the library either as an enhancement to DraxList or as a new DraxSectionList component.

lafiosca commented 2 years ago

Given that this issue is phrased as specifically asking about the long press, please let me know if the longPressDelay prop works for you, and then I will close the issue.

tomgiam commented 2 years ago

Thanks, that resolves my issue! I don't see any other showstoppers at the moment. I will know for sure when I get more functionality implemented. There are 3 things that I see at the moment; 1. After a successful drop, how do I cancel the animation that brings the dragged image back to where it was dragged from? 2. The dragged Image only shows a subset of the DraxView elements (some text and no images). Is this intentional or a result of the way that I have defined my elements? 3. This is an enhancement request. It would be nice to have a prop like renderDragItem, so that the user can specify the UI of what will be dragged.

lafiosca commented 2 years ago

@tomgiam Apologies, I was on vacation. For (1), your handler can return a DraxSnapbackTargetPreset.None to cancel the animation. For (2), I'm not sure offhand, might be a styling config issue or an actual bug. For (3), take a look at the renderHoverContent prop which is also used in the react-native-drax-example color dropper.

tomgiam commented 2 years ago

@lafiosca Thanks, DraxSnapbackTargetPreset.None works!. I did notice one other issue. The first few drag drops work correctly, but then the drag image initial display location is not over the image being dragged, but 100-200 pixels above or below it. This fixes itself if I refresh the screen (e.g. navigate away and back).

lafiosca commented 2 years ago

If this offset behavior is consistently wrong and can be reproduced in a simple project or snack, please open a separate issue to track it. (I don't want to get your hopes up though, as I will not personally have time to look into it... but at least if there is an issue open, people can be aware and someone may investigate further.)