(This might actually be more of a web platform question, if that’s the case, and if this an area where the web platform just isn’t that great that would be interesting to hear)
We were getting to the point where it was time to add a little polish to the dragging and dropping. So why not change the cursor. Well, we’ve been really struggling to do that.
To be able to focus on this problem I thought, I’d enhance the example code in the library we were using to change the cursor and the user drags and drops. The behavior I want is…
When the user hovers of a draggable element we get the grab cursor
When the user start dragging they see the grabbing cursor
When the user drags over a drop zone they get the move cursor
Here’s my PR (I know I should probably make an Ellie… and I will… once… I get things working better).
There are some videos if you don’t want to actually run the code.
In the last update I made, things are (mostly) working in Safari. Chrome and Firefox seem to have a few more issues, but nothing is perfect yet.
Does anyone have any ideas for different approaches that might work better? Or examples where (something a lot like this) is working correctly?
That library is great. I’ve only hit a couple of issues while working on Elm Designer (GitHub - passiomatic/elm-designer: A visual code generator for Elm UI.). The editor uses that library extensively so you may want to take a look if you need to implement a drag & drop for a tree list or something like that.
This won’t really answer your question about changing the cursor but… It is worth being aware of the difference between Html drag-and-drop and drag-and-drop in general, because it can be confusing when reading about the topic what exactly people are talking about.
The Html DnD stuff is primarily aimed at drag and drop between the web and the operating system or other applications. For example, you drag an image from your desktop onto your web app, and that triggers the image upload.
You can also have DnD within a web app. For example, you have some drawing app with a menu of widgets, and you want to drag a widget onto your drawing. In that case you might consider not using Html DnD events to do it, because they do come with some restrictions. You can implement your own DnD in pure Elm and that is often a better path to take for this.
For example, I initially implemented DnD using Html drag-and-drop events. Then I wanted to change the appearance of the thing being dragged depending on where it was dragged. But Html DnD makes this impossible, since you cannot read or write the value of the item being dragged. This is for security reasons, since a malicious script running on your browser could potentially snag something as it drags over it. The solution was to implement our own DnD purely in Elm within our web application to cover the cases where we are just dragging and dropping within the application itself.
If its implemented purely in Elm, you will be able to examine the state of the thing being dragged, and can set up some events to detect when it goes over some area of interest, and set the cursor or whatever you need in response.
@rupert that is super helpful. I had not understood about those 2 different DnD scenarios and I’m sure this is has caused me some real confusion. The good news is, we’re dealing with the second scenario (dragging and HTML element from one place in an Elm app to another place in the same Elm app), so that gives me hope. Doing it all in Elm makes a lot of sense.
As I’m thinking about this I can start to see how I would implement this purely in Elm. Did you use the drag (and other related events? Or did you just use the mouseup and mousedown… and mousemove… and the other mouse events?
We did not use the drag event, since that is for HTML drag and drop. We detect the drag by looking at mouse down and then mouse move over a threshold distance. I actually tried to build a slightly higher level API around mouse/touch using the pointer API, to simplify doing things like that, you can find it here: elm-pointer 1.0.1