react-dnd-html5-backend icon indicating copy to clipboard operation
react-dnd-html5-backend copied to clipboard

Support for modifier keys while dragging

Open andersfly opened this issue 8 years ago • 6 comments

Right now it doesn't seem like modifier keys are supported while dragging items.

By modifier keys I mean like pressing the alt key to enter copy 'mode' instead of move 'mode'. Just like when moving files around in the Mac OS finder app, you have the option to hold down alt to copy instead of move.

A trivial solution to this, would be to listen for keydown events on the window while dragging, and then alter some state indicating whether or not it should copy. Unfortunately keyboard events won't trigger while dragging. (apparently the browser enters some 'drag' mode) Making this impossible.

However the HTML5 drag and drop api does support modifier keys: https://developer.mozilla.org/en-US/docs/Web/Events/drag

But since this is abstracted away in the backend, it needs to support this somehow, and propagate it to the 'end user' components.

Question is was this left out for some reason? Maybe bad performance?

andersfly avatar Feb 25 '16 10:02 andersfly

It’s something I didn’t have the need for, so I didn’t implement it. Instead, what I needed was specifying dropEffect per drag source so React DnD lets you do that:

return connectDragSource(<div />, { dropEffect: 'copy' })

I’m open to considering a pull request that somehow supports having user specify the behavior by keys if you have a specific API proposal for this. Personally I don’t plan to work on this feature.

gaearon avatar Feb 28 '16 14:02 gaearon

I put some effort into investigating this. And I actually came up with a work-around. The events: drag, dragover gets fired every time you move your mouse while dragging. And obviously these events also bubble, making it possible to catch them in a hoc setting a top your DragSource, DragLayer etc. and then rerender the underlying component. E.g.

export default detectDragModifierKeys()(
  DragSource(ItemTypes.FANCY_ITEM, myItemSource, myItemCollect)(MyItem)
);

This actually works, although a little awkward. Also if you listen for the event on the window, its possible to make all components aware of the current drag event, and what modifier keys might be pressed or not. This is particularly useful for a DragLayer. Do mind performance though :-)

One caveat though, is that the Drag'n'Drop API is extremely quirky at times, and modifier keys won't be detected on the drag event in Firefox. So in a real world scenario you would have to use dragover event instead. This event also gets fired on every mousemove, and when listening for the event on window/document, it has (afaik) pretty much the same effect.

I could be nice though, to have it directly supported in react dnd, and I'm planning to give it a shot at some time. But for now the above solution will do the trick. (If anyone out there is desperate, I'm happy to share a gist or something)

andersfly avatar Mar 04 '16 09:03 andersfly

Here is the gist: https://gist.github.com/andersfly/25ab13dbd1acc5eb915f

andersfly avatar Mar 04 '16 09:03 andersfly

My org would love this feature. I've had to do a workaround similar to @andersfly's.

lukeknep avatar May 16 '16 22:05 lukeknep

@lukeknep, @andersfly This may be interesting for you: https://github.com/gaearon/react-dnd-html5-backend/issues/58

hpurmann avatar Jan 13 '17 08:01 hpurmann

On behalf on @Timely I'm offering a US$100 for getting this feature implemented & released as part of the official react-dnd/react-dnd-html5-backend package.

Requirements:

  • Must support ALT as modifier key (our use case if for implementing copy), but a generic solution would be ideal.
  • Must be accepted into the official release of react-dnd
  • Bounty valid for 4 weeks, with possible extension if project maintainers (@gaearon & @darthtrevino?) are OK with bringing this in but require more time for review.

Related issues:

  • https://github.com/react-dnd/react-dnd-html5-backend/issues/58
  • https://github.com/react-dnd/react-dnd/issues/394
  • https://github.com/react-dnd/react-dnd/issues/657

I'd be happy to transfer the bounty to the project maintainers for escrow.

/cc @lukeknep @andersfly @hpurmann

t1mmen avatar Feb 28 '17 17:02 t1mmen