react-dnd / dnd-core

Drag and drop sans the GUI [Legacy Repo]

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How do we implement dragOver and coordinate tracking?

gaearon opened this issue · comments

commented

In React DnD, we have an API to hook into continuously updating drag offset as you move the dragged item. There's a separate DragOffsetStore which is currently only used by DragLayerMixin. It is essential to separate tracking coordinates from the rest of state tracking, because only componenents interested in coordinates should subscribe to it. These events just fire way too often so subscribing everyone to them is not an option. And usually drag layer is the only thing that cares about the coordinates. Finally, in React DnD, there is also an over drop target hook that gets called continuously during drag. It complements enter and leave.

It is not yet clear to me how to translate these concepts to dnd-core.
Here are my initial thoughts:

  • We will not implement enter and leave on drop targets. This is already solveable by using addChangeListener and checking isOver(targetHandle, shallow) with first class support for nested drop targets using second parameter. So this is out of equation already.
  • We need over in drop target API. Its main use case is performing side effects continuously in response to user moving the mouse while dragging. For example, parent drop target may scroll window when you're dragging something too close to window bottom or top. I would like to rename it to dragOver so it's consistent with other methods that have a verb in their names. It would be called on all entered drop targets for which isOver() returns true. It would be up to drop zones to inquire about isOver(handle, shallow) if they only care about shallow drag over.
  • We don't want to fire change events on drag action for performance reasons. The only thing that may have changed is the coordinate, and we want to have a separate subscription mechanism for that. Now that I speak of this, I think coordinate tracking may be out of scope of this project altogether. If it aims to be backend-independent, there are cases where coordinates make zero or not as much sense (tests, multi-touch screens, etc). Sure, the backend should be able to call this.actions.dragOver so drop targets receive it, but I don't think it needs to pass any coordinates. Maybe the best option is to be ignorant about the additional data backend passes to beginDrag and dragOver without strictly calling it coordinates. Just expose getInitialDragData, getLastDragData on context and, instead of a single change event, expose change and drag events. It is up to consuming library to interpret that data.
commented

One interesting option is exposing Flux instance to consuming library it can subscribe to actions from its own stores. React DnD will then be able to have its own coordinate store. I'm not sold on this yet..

commented

Maybe we should just implement dragOver dispatching and delay thinking about coordinates until we get dnd-core working with React DnD in all other aspects. By that time, we'll already figure out the backend API so it will be easier.

commented

Coordinate tracking is now implemented.
Consult tests for details.