Live demo: peterh32.github.io/react-drag-drop-container
-
Very easy to implement and understand.
-
Works on mouse and touch devices.
-
Automatically scrolls the page when you drag to the edge, so you can drag to a target that's initially offscreen.
-
Optional drag handles (with
dragHandleClassName
prop). -
Can automatically highlight the dropTarget when dragging over it (
highlightClassName
property). -
Can constrain dragging to one dimension with
xOnly
andyOnly
properties. -
Useful options like
dragClone
(drag a copy of the element),customDragElement
(drag a custom element rather than the source element), anddisappearDraggedElement
(make the original element completely disappear while dragging). -
Can implement using the components as wrappers or by passing them a render prop.
Install it in your project using npm:
npm install react-drag-drop-container --save
Set up a draggable element and a drop target for it:
import { DragDropContainer, DropTarget } from 'react-drag-drop-container';
<DragDropContainer targetKey="foo" >
<div>Drag Me!</div>
</DragDropContainer>
<DropTarget targetKey="foo" >
<p>I'm a valid drop target for the object above since we both have the same targetKey!</p>
</DropTarget>
-
While dragging, the
onDragEnter
andonDragLeave
events fire in theDropTarget
. On a successful drop, theonHit
event fires. These all pass the event data shown. -
On a successful drop, the
onDrop
event fires in theDragDropContainer
, passing back the event data shown.
<DragDropContainer
targetKey="foo"
dragData={some object}
onDrop={some method}
onDragStart={some method}
onDrag={some method}
onDragEnd={some method}
>
<div>Drag Me!</div>
</DragDropContainer>
targetKey
: Determines what DropTargets it can be dropped on.
dragData
:Custom data to pass to the drop target.
onDrop
: Callback that fires after a successful drop on a compatible target. See onDrop Event Data, below.
onDragStart
, onDrag
, onDragEnd
(less commonly used): Callbacks during the drag process. See details in DropTarget Callbacks below.
Passed back to DragDropContainer
in the onDrop
event:
{
dropData: [whatever you put in the dropData prop for the DropTarget]
dropElem: [reference to the DOM element being dragged]
dragData: [whatever you put in the dragData prop]
target: [reference to the DragDropContainer DOM element]
...plus a lot of standard react/js event data
}
<DropTarget
targetKey="foo"
dropData={some object}
onHit={some function}
onDragEnter={some function}
onDragLeave={some function}
>
<p>Drop something on me</p>
</DropTarget>
dropData
: Custom data to pass back to the DragDropContainer.
onDragEnter
, onDragLeave
, onHit
: Callbacks that fire when a compatible DragDropContainer
passes over. onHit
is when a compatible container is dropped on the target. See event data below.
Passed in onDragEnter
, onDragLeave
, and onHit
:
{
dragData: [whatever you put in the dragData prop for the DragDropContainer]
dragElem: [reference to the DOM element being dragged]
containerElem: [reference to the DragDropContainer DOM element]
target: [reference to the DropContainer DOM element]
...plus a lot of standard event data
}
Wrap the element in multiple DropTarget
s, one for each targetKey
:
<DropTarget targetKey="foo">
<DropTarget targetKey="bar">
<div>You can drop a "foo" or a "bar on me</div>
</DropTarget>
</DropTarget>
Wrap the element in a DragDropContainer
and a DropTarget
:
<DragDropContainer targetKey="foo">
<DropTarget targetKey="bar">
<div>You can drop a "bar" on me, or drag and drop me onto a "foo"</div>
</DropTarget>
</DragDropContainer>
By default the container for your DropTarget has the classname 'highlighted' applied when a compatible DragDropContainer is hovering over it.
<style>
.highlighted .my_target {background-color: 'lightblue'}
</style>
<DropTarget targetKey="foo" onHit={this.dropped}>
<div className="my_target">I turn blue when you drag a "foo" over me</div>
</DropTarget>
...or do it manually with the onDragEnter and onDragLeave events:
<DropTarget targetKey="foo"
onHit={this.dropped}
onDragEnter={this.highlight}
onDragLeave={this.unHighlight}
>
<div>Drop something on me</div>
</DropTarget>
...where highlight
and unHighlight
are your own methods.
Use event.containerElem
to hide or delete the original element after a successful
drop. In your DropTarget element:
...
dropped(e){
e.containerElem.style.visibility = 'hidden';
}
render() {
return <DropTarget targetKey="foo" onHit={this.dropped}>[element code]</DropTarget>
}
...
If you prefer, you can specify a render prop rather than a child component for DragDropContainer
or DropTarget
.
These are equivalent:
<DragDropContainer targetKey="foo">
<div>Drag Me!</div>
</DragDropContainer>
and
<DragDropContainer
targetKey="foo">
render={() => return <div>Drag Me!</div>}
/>
These are not required, but you'll almost always want to set them.
Data about the dragged item that you want to pass to the target. Default is empty object.
Optional string to specify which DropTargets will accept which DragDropContainers. Default is 'ddc'.
If a DOM node is provided, we'll drag it instead of the actual object (which will remain in place).
Example:
const elem = <div class="drag_elem">Drag Me</div>;
<DragDropContainer customDragElement={elem}>
If true, then dragging an element causes it to disappear such that it takes up no space. Defaults to
false, so that the original element space is still reserved while you are dragging. Not compatible with
dragClone
.
If true, then the user appears to be dragging a copy of the original element (false by default, so that the user appears to be dragging the element itself).
Opacity of the element while it's dragging. (Sometimes you want to be able to see what's below the element you're dragging.) Default is 0.9 (e.g. 90%).
Class name for drag handle(s). Optional. If omitted, the whole thing is grabbable.
Tip: If you are using drag handles on an element that contains an image,
use <img draggable="false"...
to prevent the browser from letting users
drag the image itself, which can be confusing.
If true, dragging is turned off.
If true, then dragging is constrained to the x- or y direction, respectively.
The z-index for the dragged item. Defaults to 1000 (so that it floats over the target). If that doesn't work for you, change it here.
All optional. You'll generally set onDrop
, but often skip the others.
Runs when you start dragging. dragData
is whatever you passed in with
the dragData prop.
Runs as you drag. currentTarget
is the DOM element you're currently dragging
over; x
and y
are the current position.
When you drop.
Triggered after a drop onto a compatible DropTarget. This gets passed an event object, see onDrop Event Data.
Optional string to specify which DragDropContainers this target will accept.
Data to be provided to the DragDropContainer when it is dropped on the target.
CSS classname to apply when a compatible DragDropContainer is hovering over the DropTarget. Defaults to highlighted
. Set to empty string if you do not want any highlight behavior.
All optional; specify in props.
The event e contains
{
dragData: [whatever you put in the dragData prop for DragDropContainer]
dragElem: [reference to the DOM element being dragged]
containerElem: [reference to the DragDropContainer DOM element]
sourceElem: [reference to the DOM element containing children of DragDropContainer]
}
To view locally, clone the repository then
$ npm run install
$ npm run build
$ npm run watch
The demo will run on http://localhost:8080/
File locations:
/src Source code for components
/demo Source code for demo
/lib/bundle.js Transpiled output
/public Demo files, compiled
MIT License
Copyright (c) 2017.