HTML5 drag events is a quite complicated specification.
Mostly because it is very stateful, and many properties and functions
only make sense in one situation and not the rest.
For example, the effectAllowed
property can only be set successfully
in a dragstart
event, and setting it in another will be ignored.
Another example, the dragend
should be attached to the object dragged,
while the dragleave
should be attached to potential drop target.
One more, the dragover
event listener is required on a drop target.
Otherwise the drop event will be cancelled.
Consequently, I've chosen to present a slightly opinionated API for drag events, mitigating most of potential errors. In case it prevents you from using it, please report your use case in an issue. I hope by also providing the decoders, the library can still help you setup your own event listeners.
There seems to be two main use cases for drag events:
The rest of the documentation presents the API with those use cases in mind.
{ dataTransfer : DataTransfer
, mouseEvent : Html.Events.Extra.Mouse.Event
}
Type that get returned by a browser drag event. It corresponds to a JavaScript DragEvent.
Since a DragEvent
inherits from MouseEvent
,
all mouse event related properties are provided in the
mouseEvent
attribute of type Mouse.Event
.
Please refer to the Mouse
module for more information on this value.
{ files : List File
, types : List String
, dropEffect : String
}
Hold the data being dragged during a drag and drop operation. This corresponds to JavaScript DataTransfer.
The files
attribute holds the list of files being dragged.
Each file is of the type File
provided by elm/file.
The types
attribute contains a list of strings providing
the different formats of objects being dragged.
The dropEffect
attribute provides feedback on the selected effect
for the current drag and drop operation. It can be one of:
"none"
: the item may not be dropped"copy"
: a copy of the source item is made at the new location"move"
: the item is moved to a new location"link"
: a link to the source is somehow established at the new locationBeware that contrary to JavaScript, you have no way of modifying
dropEffect
in elm. This is provided purely for information as read only,
like any other elm value.
The effectAllowed
property is not provided since it has
no use in the context of elm.
The items
property is not provided by lack of compatibility.
onFileFromOS : FileDropConfig msg -> List (Html.Attribute msg)
Events listeners for a file drop target element.
PS: incompatible with onDropTarget
since both functions
use the same events listeners.
If you need to have a drop target working for both files and DOM elements,
you can directly use onDropTarget
.
{ onOver : Event -> msg
, onDrop : Event -> msg
, onEnter : Maybe (Event -> msg)
, onLeave : Maybe (Event -> msg)
}
Configuration of a file drop target.
PS: dragenter
and dragleave
are kind of inconsistent since they
bubble up from children items (not consistently depending on borders in addition).
You should prefer to let them be Nothing
, or to add the CSS property
pointer-events: none
to all children.
I encourage you to read this blog post before you take the decision to use HTML5 drag and drop API instead of your own custom solution.
onSourceDrag : DraggedSourceConfig msg -> List (Html.Attribute msg)
Drag events listeners for the source dragged element.
{ effectAllowed : EffectAllowed
, onStart : EffectAllowed -> Json.Decode.Value -> msg
, onEnd : Event -> msg
, onDrag : Maybe (Event -> msg)
}
Configuration of a draggable element.
You should provide message taggers for dragstart
and dragend
events.
You can (but it is more compute-intensive) provide a message tagger for drag
events.
{ move : Basics.Bool
, copy : Basics.Bool
, link : Basics.Bool
}
Drop effects allowed for this draggable element.
Set to True
all effects allowed.
This is used in the port of the dragstart
event.
startPortData : EffectAllowed -> Json.Decode.Value -> { effectAllowed : String, event : Json.Decode.Value }
Put the effect allowed and the dragstart event in a data format that can be sent through port.
effectAllowedToString : EffectAllowed -> String
Convert EffectAllowed
into its String equivalent.
onDropTarget : DropTargetConfig msg -> List (Html.Attribute msg)
Drag events listeners for the drop target element.
PS: dragenter
and dragleave
are kind of inconsistent since they
bubble up from children items (not consistently depending on borders in addition).
You should prefer to let them be Nothing
, or to add the CSS property
pointer-events: none
to all children.
{ dropEffect : DropEffect
, onOver : DropEffect -> Json.Decode.Value -> msg
, onDrop : Event -> msg
, onEnter : Maybe (Event -> msg)
, onLeave : Maybe (Event -> msg)
}
Configuration of a drop target.
You should provide message taggers for dragover
and drop
events.
You can also provide message taggers for dragenter
and dragleave
events.
Drop effect as configured by the drop target. This will change the visual aspect of the mouse icon.
If the drop target sets (via port on dragover
) a drop effect
incompatible with the effects allowed for the dragged item,
the drop will not happen.
overPortData : DropEffect -> Json.Decode.Value -> { dropEffect : String, event : Json.Decode.Value }
Put the drop effect and the dragover event in a data format that can be sent through port.
dropEffectToString : DropEffect -> String
Convert a DropEffect
into its string equivalent.
eventDecoder : Json.Decode.Decoder Event
Drag.Event
default decoder.
It is provided in case you would like to reuse/extend it.
dataTransferDecoder : Json.Decode.Decoder DataTransfer
DataTransfer
decoder.
It is provided in case you would like to reuse/extend it.
fileListDecoder : Json.Decode.Decoder a -> Json.Decode.Decoder (List a)
Transform a personalized File
decoder into a List File
decoder
since Json.Decode.list
does not work for the list of files.