Getting Started with the Droppable
The useDroppable
hook and Droppable
component allow a native HTMLElement or custom React Component to become a drop
target during a drag
.
The droppable
functionality provides the following callbacks which enable the developer to implement custom positioning, styling, or behavior based on the current application state and the event arguments:
- onDragEnter—A callback indicating that a
draggable
item collides with thedrop
for the first time. - onDragOver—A callback called on every
pointer
/touch
action and indicating that adrag
is happening over the currentdrop
instance. - onDragLeave—A callback indicating that the
draggable
item is no longer colliding with thedrop
. - onDrop—A callback indicating that the
draggable
item has been dropped into thedrop
.
Basic Usage
The following example demonstrates the droppable
functionality in action.
Registering for Drop
Before registering for drop
, provide a common DragAndDrop
parent for all drag
and drop
components. This enables the communication between the two functionalities.
import { DragAndDrop } from '@progress/kendo-react-common';
// ..
return (
<DragAndDrop>
<DragComponent />
<DropComponent />
<DropComponent />
<DropComponent />
<DropComponent />
</DragAndDrop>
);
To register an element/component to the useDroppable
hook, pass it as the first parameter. For the Droppable
component, it is enough to provide a single children
prop to the component.
In the following section, you will learn how to:
- Pass a native HTML element to the
useDroppable
hook or theDroppable
component. - Pass a custom React component to the
useDroppable
hook or theDroppable
component.
Native HTML Element
- To pass a native HTML Element to the
useDroppable
hook, obtain theref
object by using theReact.useRef
hook.
You can use the same
ref
object for other parts of your application, as long as you do not mutate it directly.
const element = React.useRef();
// ...
useDroppable(element, {});
// ...
return <div ref={element}>Drop Here</div>;
- To pass a native HTML Element to the
Droppable
component, it is enough to pass the desired element as a direct child.
render() {
return (
<Droppable>
<div>Drop Here</div>
</Droppable>
)
}
- The
Droppable
component will obtain theref
of the child component. If you require areference
, use thechildRef
.
element = React.createRef();
// ...
componentDidMount() {
// Sample code
element.current.focus();
}
// ...
render() {
return (
<Droppable childRef={this.element}>
<div>Drop Here</div>
</Droppable>
)
}
Custom React Component
There are two ways to pass a custom React Component to the useDroppable
hook:
-
If the Component is a Functional Component:
-
To obtain the
ref
, wrap the component inReact.forwardRef
.jsxconst CustomComponent = React.forwardRef((props, ref) => { return <div ref={ref}>Drop Here</div>; });
Alternatively, if you are already using the
ref
and applying additional properties, add theelement
field to the ref, which will resolve to the HTML element underneath.jsxconst CustomComponent = React.forwardRef((props, ref) => { const element = React.useRef(); React.useImperativeHandle(ref, () => ({ element: element.current })); return <div ref={element}>Drop Here</div>; });
-
Obtain the
ref
of yourCustomComponent
and pass it to theuseDroppable
hook.jsxconst component = React.useRef(); // ... useDroppable(component, {}); // ... return <CustomComponent ref={component}>Drop Here</CustomComponent>;
-
-
If the Component is a Class Component:
-
Provide a public
element
getter as a class field of the component.jsxclass CustomComponent extends React.Component { _element = React.createRef(); get element() { return this._element; } render() { return <div ref={this._element}>Drop Here</div>; } }
-
Wrap your
CustomComponent
into aDroppable
.jsxrender() { return ( <Droppable> <CustomComponent>Drop Here</CustomComponent> </Droppable> ) }
-
Handling Drop Events
The KendoReact drop
callbacks provide additional information that you can leverage to implement custom styling that depends on the current drag
state.
The following example demonstrates how to utilize the drop
callbacks in order to show a visual clue on where the current drag
will be dropped. Try to drag an item from one list to the other.