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:

  • onDragEnterA callback indicating that a draggable item collides with the drop for the first time.
  • onDragOverA callback called on every pointer/touch action and indicating that a drag is happening over the current drop instance.
  • onDragLeaveA callback indicating that the draggable item is no longer colliding with the drop.
  • onDropA callback indicating that the draggable item has been dropped into the drop.

Basic Usage

The following example demonstrates the droppable functionality in action.

Example
View Source
Change Theme:

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 the Droppable component.
  • Pass a custom React component to the useDroppable hook or the Droppable component.

Native HTML Element

  • To pass a native HTML Element to the useDroppable hook, obtain the ref object by using the React.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 the ref of the child component. If you require a reference, use the childRef.
    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:

    1. To obtain the ref, wrap the component in React.forwardRef.

          const 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 the element field to the ref, which will resolve to the HTML element underneath.

          const CustomComponent = React.forwardRef((props, ref) => {
              const element = React.useRef();
      
              React.useImperativeHandle(ref, () => ({
                  element: element.current
              }))
      
              return (
                  <div ref={element}>Drop Here</div>
              )
          });
    2. Obtain the ref of your CustomComponent and pass it to the useDroppable hook.

          const component = React.useRef();
          // ...
          useDroppable(component, {});
          // ...
          return (
              <CustomComponent ref={component}>Drop Here</CustomComponent>
          )
  • If the Component is a Class Component:

    1. Provide a public element getter as a class field of the component.

          class CustomComponent extends React.Component {
              _element = React.createRef();
      
              get element() {
                  return this._element;
              }
      
              render() {
                  return (
                      <div ref={this._element}>Drop Here</div>
                  )
              }
          }
    2. Wrap your CustomComponent into a Droppable.

          render() {
              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.

Example
View Source
Change Theme: