Open ajstokar opened 3 years ago
Thanks for reproducing this very clearly. One thing I noticed/remembered is that when you are nesting DraxView
s, you should specify isParent
on the container DraxView
s. This causes them to create a DraxSubprovider
beneath them which links their nested Drax descendants to their position. Without this, if the container layout changes but the contained item layout does not change, the global positions of the nested views may become incorrect in the registry.
I was hopeful that specifying isParent
would be enough to fix this issue, but it is not. Without digging into the code, it seems clear to me that the container DraxView
(box) is taking precedence over its nested views (items) in the target calculation algorithm. The reason I suspect this is that if I set isReceptive={false}
on the box, the items light up correctly when being dragged over.
I have not looked at the logic in a long time, but this is not how I remember the intended behavior to be. The code can be found in this section: https://github.com/nuclearpasta/react-native-drax/blob/051295857fd840e38eb79ded9edabee31f8d7178/src/hooks/useDraxRegistry.ts#L148-L224
It iterates through all of the views in the registry and checks if the current drag is in them, if they are receptive or monitoring. It returns the most recently registered receiver that the drag is over. I believe my thought at the time was that the nested children would be registered after their parent container, so they would take precedence here. But it seems, at least in this example, that this is not the case. I am not sure if this was always broken, if it's case-by-case, or if something changed between versions of RN. I think perhaps the logic needs to be improved to more explicitly track view ancestry and give precedence to nested receivers.
I am sorry to say I do not know of any quick workaround off the top of my head. You could perhaps hack something together using monitors. Regrettably I do not know when I will have availability to return to this code more deeply.
Thank you so much for the write up. I also tried isParent={true} and it didn't help unfortunately. This use case is similar to the iOS app groups where you can drag items between each other AND within each other. If it gives you any extra motivation, I haven't found ANY other libraries that come close to what you've built. It's really impressive!
Thank you for the kind words. I am proud of what I've built so far, but I also see that it has so much further to go. With everything going on in my life and business over the past year, I have not been able to afford the time and energy to give this library the attention it deserves, and I feel a lot of guilt over that. I intentionally released it as a 0.x prerelease version because I knew we would gather feedback to learn how well the approach fit user needs, and it's possible the infrastructure could change significantly when I go back through it. All of the recent activity on the repo has been making me very antsy to find time though, so I am going to be looking for any opportunity to fit the Drax work into my primary work as soon as I can.
Good news, I fixed the other issue so this is the last one before we can feel good about using the library! Is there any other guidance / workaround you can provide to handle this one? It seems that when I hot reload and modify the contents of the parent DraxView, it works as intended. But when the DraxScrollView re-renders, it goes back to only receiving in the parent views.
The only workaround that came to mind was to use monitor events. Monitors are sort of like receivers, but they always receive monitor events even if they are not the targeted receiver of the drag. Theoretically you could make your nested views monitor drags over them and communicate up the chain that the outer container should turn receptive={false}
during them. Offhand, I do not know if changing the receptive flag mid-drag would cause unpredictable behavior though.
Ultimately the library needs to fix this behavior, or at least provide a way to explicitly specify the precedence of receivers.
Hi @lafiosca !
While creating a Snack for the List dragging issue, I found this one. When Items are dragged over Box's, the receiving style is applied. However, when Items are dragged over other Items, the receiving style is not applied. Let me know where I went wrong or if this may be an issue.
https://snack.expo.io/@adamommyx/drax-drag-and-receive-test