avatarNitin Sharma

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

7441

Abstract

act'</span>; <span class="hljs-keyword">import</span> { useDraggable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@dnd-kit/core'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">Draggable</span>(<span class="hljs-params">props</span>) { <span class="hljs-keyword">const</span> { attributes, listeners, setNodeRef, transform } = <span class="hljs-title function_">useDraggable</span>({ <span class="hljs-attr">id</span>: <span class="hljs-string">'draggable'</span>, }); <span class="hljs-keyword">const</span> style = transform ? { <span class="hljs-attr">transform</span>: <span class="hljs-string">translate3d(<span class="hljs-subst">${transform.x}</span>px, <span class="hljs-subst">${transform.y}</span>px, 0)</span>, } : <span class="hljs-literal">undefined</span>;

<span class="hljs-keyword">return</span> (
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{setNodeRef}</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{style}</span> {<span class="hljs-attr">...listeners</span>} {<span class="hljs-attr">...attributes</span>}&gt;</span>
        {props.children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
);

}</pre></div><p id="2d7c">Here, we defined a React component named Draggable which implements the functionality of a draggable element using the Dnd Kit library. The code imports the <code>useDraggable</code> hook from the <code>@dnd-kit/core</code> library, which is used to provide the drag-and-drop functionality for the component.</p><p id="134b">Then we used the ‘useDraggable’ hook which returns an object that contains several properties that are used to implement the draggable functionality.</p><p id="9cb1">The object contains the following properties:</p><ul><li>attributes: an object containing the HTML attributes required to make the component draggable</li><li>listeners: an object containing event listeners that are triggered when the user drags the component</li><li><code>setNodeRef</code>: a function that is used to set a reference to the DOM node of the component</li><li>transform: an object that contains the current x and y translation of the component in pixels</li></ul><p id="6091">The ‘Draggable’ component uses the ‘transform’ property to apply a translation to the component. This is done by creating a ‘style’ object that contains the translation and applying it to the component using the ‘style’ property.</p><p id="13b2">Lastly, we defined a button element that uses the ‘ref’ property to set the reference to the DOM node using the ‘setNodeRef’ function from the ‘useDraggable’ hook. The ‘listeners’ and ‘attributes’ objects from the hook are spread onto the component using the ‘…listeners’ and ‘…attributes’ syntax, respectively.</p><p id="7c08">Hope you got it.</p><ul><li><b>Defining a Droppable Component</b></li></ul><p id="4524">Now create a new file name <code>Droppable.jsx</code> inside the src folder of your React app and paste the below code.</p><div id="3b17"><pre><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>; <span class="hljs-keyword">import</span> { useDroppable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@dnd-kit/core'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">Droppable</span>(<span class="hljs-params">props</span>) { <span class="hljs-keyword">const</span> { isOver, setNodeRef } = <span class="hljs-title function_">useDroppable</span>({ <span class="hljs-attr">id</span>: <span class="hljs-string">'droppable'</span>, }); <span class="hljs-keyword">const</span> style = { <span class="hljs-attr">color</span>: isOver ? <span class="hljs-string">'blue'</span> : <span class="hljs-literal">undefined</span>, };

<span class="hljs-keyword">return</span> (
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">{setNodeRef}</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{style}</span>&gt;</span>
        {props.children}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
);

}</pre></div><p id="86d3">Here, the <code>useDroppable</code> hook returns an object that contains two properties:</p><ul><li><code>isOver</code>: a boolean value indicating whether the draggable component is currently over the droppable component</li><li><code>setNodeRef</code>: a function that is used to set a reference to the DOM node of the component</li></ul><p id="d99b">Then the code is simple, if the draggable component is over the droppable component then <code>isOver</code> will be true and because of that the color blue will be applied.</p><ul><li><b>Defining a Parent Component</b></li></ul><p id="40fa">Remember, we have to create a parent component that takes these two components.</p><p id="5c5d">So now let’s create that.</p><div id="de74"><pre><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">DndContext</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'@dnd-kit/core'</span>; <span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span> <span class="hljs-keyword">import</span> { <span class="hljs-title class_">Droppable</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'./Droppable'</span>; <span class="hljs-keyword">import</span> { <span class="hljs-title class_">Draggable</span> } <span class="hljs-keyword">from</span> <span class="hljs-string">'./Draggable'</span>;

<span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) { <span class="hljs-keyword">const</span> [isDropped, setIsDropped] = <span class="hljs-title function_">useState</span>(<span class="hljs-literal">false</span>); <span class="hljs-keyword">const</span> draggableMarkup = (

<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Draggable</span> &gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'drag_item'</span>&gt;</span>
    Drag me
  <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">Draggable</span>&gt;</span></span>

);

<span class="hljs-keyword">return</span> ( <span class="language-xml"><span class="hljs-tag"><<span class="hljs-name">DndContext</span> <span class="hljs-attr">onDragEnd</span>=<span class="hljs-string">{handleDragEnd}</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'section'</span>></span> <

Options

span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'draggable'</span>></span> {!isDropped ? draggableMarkup : null} <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'draggable'</span>></span> <span class="hljs-tag"><<span class="hljs-name">Droppable</span>></span> {isDropped ? draggableMarkup : 'Drop here'} <span class="hljs-tag"></<span class="hljs-name">Droppable</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">div</span>></span> <span class="hljs-tag"></<span class="hljs-name">DndContext</span>></span></span> );

<span class="hljs-keyword">function</span> <span class="hljs-title function_">handleDragEnd</span>(<span class="hljs-params">event</span>) { <span class="hljs-keyword">if</span> (event.<span class="hljs-property">over</span> && event.<span class="hljs-property">over</span>.<span class="hljs-property">id</span> === <span class="hljs-string">'droppable'</span>) { <span class="hljs-title function_">setIsDropped</span>(<span class="hljs-literal">true</span>); } } }

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span>;</pre></div><p id="464c">Here, in the App component, we have defined a state variable <code>isDropped</code> that keeps track of whether the draggable item has been dropped into the droppable area.</p><p id="0f1d">In simple terms, we have conditions to either display the draggable item or a message indicating where the item can be dropped.</p><p id="8c16">In the main render function, the code returns a <code>DndContext</code> component with a callback function <code>handleDragEnd</code> passed as a prop. The callback will be called when the drag-and-drop action is finished. Then we have two divs with the class "draggable"(for applying the same styles).</p><p id="adac">The first div has the <code>draggableMarkup</code> component as its child, but only if <code>isDropped</code> is <code>false</code>. The second div has a <code>Droppable</code> component as its child. If <code>isDropped</code> is <code>true</code>, the <code>draggableMarkup</code> component will be displayed, otherwise, it will display the text "Drop here".</p><p id="2e7d">Lastly, the <code>handleDragEnd</code> function checks if the <code>event.over</code> property exists and if the <code>id</code> of the <code>event.over</code> object is "droppable". If so, it updates the state by calling <code>setIsDropped(true)</code>.</p><ul><li><b>Add styles to your react app</b></li></ul><p id="42fa">Lastly, we need to apply styles to our React app. And for that, you can use any CSS framework but I will simply create a new App.css file inside the src folder and add the below code to it.</p><div id="aa66"><pre><span class="hljs-selector-class">.section</span> { <span class="hljs-attribute">display</span>: flex; <span class="hljs-attribute">align-items</span>: center; <span class="hljs-attribute">justify-content</span>: center; <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>; <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">37</span>, <span class="hljs-number">148</span>, <span class="hljs-number">251</span>); }

<span class="hljs-selector-class">.draggable</span> { <span class="hljs-attribute">display</span>: flex; <span class="hljs-attribute">align-items</span>: center; <span class="hljs-attribute">justify-content</span>: center; <span class="hljs-attribute">width</span>: <span class="hljs-number">20rem</span>; <span class="hljs-attribute">height</span>: <span class="hljs-number">20rem</span>; <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#9749FF</span>; <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">10px</span>; <span class="hljs-attribute">color</span>: white; }

<span class="hljs-selector-class">.drag_item</span> { <span class="hljs-attribute">padding</span>: <span class="hljs-number">5px</span> <span class="hljs-number">10px</span>; <span class="hljs-attribute">width</span>: <span class="hljs-number">8rem</span>; <span class="hljs-attribute">height</span>: auto; <span class="hljs-attribute">color</span>: black; <span class="hljs-attribute">background-color</span>: white; }</pre></div><p id="5f5b">That’s it, now you can run the app and see the output.</p><p id="5718">Hope you like it.</p><p id="348a">That’s it — thanks.</p><p id="f672">Also, there will be a series of posts about Dnd Kit in the future, so be sure to follow me.</p><p id="76e2"><a href="https://nitinfab.medium.com/membership"><i>Consider becoming a Medium member</i></a><i> if you appreciate reading stories like this and want to help me as a writer. It costs $5 per month and gives you <a href="https://nitinfab.medium.com/membership">unlimited access to Medium content</a>. I’ll get a little commission if you sign up via my link.</i></p><div id="9827" class="link-block"> <a href="https://readmedium.com/8-stupidly-simple-programming-side-hustle-that-you-can-start-in-2023-no-bs-93ec748d73ee"> <div> <div> <h2>8 Stupidly Simple Programming Side Hustle That You Can Start in 2023 — No BS!</h2> <div><h3>It’s tried and tested.</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*6JVh80iRQ0S5GnTU)"></div> </div> </div> </a> </div><div id="3368" class="link-block"> <a href="https://readmedium.com/30-killer-tools-that-are-so-valuable-that-they-feel-illegal-to-know-before-2023-9651cb86dd9f"> <div> <div> <h2>30+ Killer Tools That Are So Valuable That They Feel Illegal To Know Before 2023</h2> <div><h3>I bet that 99.99% of you don’t know about most of these tools.</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*9iINVEIMNbGJzdwL8UT3Fg.jpeg)"></div> </div> </div> </a> </div><div id="634d" class="link-block"> <a href="https://javascript.plainenglish.io/9-websites-that-will-help-you-learn-web-development-faster-for-free-eb81ccea1999"> <div> <div> <h2>9 Websites That Will Help You Learn Web Development Faster — For Free</h2> <div><h3>Sure, you’ve never heard of most of these.</h3></div> <div><p>javascript.plainenglish.io</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*C3MIxCh2jMzgEsn7)"></div> </div> </div> </a> </div></article></body>

Say Goodbye to React-DnD, Hello to Dnd Kit: The Future of Drag and Drop is Here!

One of the best libraries to create drag-and-drop capabilities.

Photo by Mia Baker on Unsplash

Previously, the go-to option for implementing drag-and-drop functionality in React was React-DnD. This library was widely recommended due to its robust features and ease of use for React developers.

However, there is now a new player in town that provides an even more powerful, better, and easier-to-learn solution: Dnd Kit.

While it’s important to acknowledge that React-DnD is still a good library, Dnd Kit offers a number of advantages that make it a compelling alternative.

For example, In terms of functionality, Dnd Kit offers a number of improvements over React-DnD. It’s more powerful, more efficient, and provides a better user experience. However, it’s up to individual developers to decide which library is the best fit for their needs.

If you ask me, I prefer Dnd Kit and used it most often and that’s the reason I am writing this post to make you familiar as well.

Please keep in mind that I followed the official documentation, thus the code appears identical. But I’ve done my best to explain the concept as simply as possible.

Also, there will be a series of posts in the future where I will explain some complex examples so follow me to get updated when I publish the next post.

Now let’s proceed further.

Why Dnd Kit?

According to the official website, Dnd Kit is a lightweight, modular, performant, accessible, and extendable drag-and-drop toolkit for React.

It makes it simple for you to drag and drop your components.

Talking about what you can create, there are literally tons of examples. Some of the best ones are as follows:

1. Kanban Board

2. Checker Game

3. Card Game

Cool, right?

Similarly, you can implement any drag-and-drop capability as you prefer.

So let’s deep dive and use Dnd Kit.

Making Use of Dnd Kit in Your React Application

First, we have to install Dnd Kit.

And it’s quite easy to install Dnd Kit inside your React project.

1. Installation

You should first have to create a React app using the standard command.

npx create-react-app appname

And then you can install the Dnd Kit package. For that, you simply need to install the core library which consists of most of the main functionality that you need.

So, within your React app, run the following command.

npm install @dnd-kit/core

There are some more Dnd Kit packages i.e. modifier and sortable which we will use in a later post.

2. Understand the Fundamentals of Dnd Kit

First, let me explain some fundamental concepts behind the Dnd Kit library.

Before using Dnd Kit, you should be familiar with ref in React. If you don’t know here is the documentation for that.

Now let’s proceed further.

To use the Dnd Kit library, you will need to define two components: a Draggable component and a Droppable component.

The Draggable component is the element that can be dragged and the Droppable component is where the Draggable component can be dropped.

Lastly, to ensure interaction between the Draggable and Droppable components, both components must be placed inside a DndContext component, which acts as a parent component.

This way, the DndContext component can manage the interactions between the two components and provide a centralized place to handle the drag-and-drop functionality.

Here is the sample code about what I have explained.

import React from 'react';
import {DndContext} from '@dnd-kit/core';

import {Draggable} from './Draggable';
import {Droppable} from './Droppable';

function App() {
  return (
    <DndContext>
      <Draggable />
      <Droppable />
    </DndContext>
  )
}

Don’t worry if the above code doesn’t make sense; we’ll go over it thoroughly later. Just remember that we have a DndContext parent component and two additional components within it.

3. A Drag and Drop Example

Now, you have understood some basic concepts of Dnd Kit let’s take a simple example of it.

Before that, let me show you what we are creating.

Here, the left column consists of a Draggable component, and the right column consists of a Droppable component.

So let’s create these two components.

  • Creating a Draggable Component

Create a new file name Draggable.jsx inside the src folder of your React app and paste the below code.

import React from 'react';
import { useDraggable } from '@dnd-kit/core';

export function Draggable(props) {
    const { attributes, listeners, setNodeRef, transform } = useDraggable({
        id: 'draggable',
    });
    const style = transform ? {
        transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`,
    } : undefined;

    return (
        <button ref={setNodeRef} style={style} {...listeners} {...attributes}>
            {props.children}
        </button>
    );
}

Here, we defined a React component named Draggable which implements the functionality of a draggable element using the Dnd Kit library. The code imports the useDraggable hook from the @dnd-kit/core library, which is used to provide the drag-and-drop functionality for the component.

Then we used the ‘useDraggable’ hook which returns an object that contains several properties that are used to implement the draggable functionality.

The object contains the following properties:

  • attributes: an object containing the HTML attributes required to make the component draggable
  • listeners: an object containing event listeners that are triggered when the user drags the component
  • setNodeRef: a function that is used to set a reference to the DOM node of the component
  • transform: an object that contains the current x and y translation of the component in pixels

The ‘Draggable’ component uses the ‘transform’ property to apply a translation to the component. This is done by creating a ‘style’ object that contains the translation and applying it to the component using the ‘style’ property.

Lastly, we defined a button element that uses the ‘ref’ property to set the reference to the DOM node using the ‘setNodeRef’ function from the ‘useDraggable’ hook. The ‘listeners’ and ‘attributes’ objects from the hook are spread onto the component using the ‘…listeners’ and ‘…attributes’ syntax, respectively.

Hope you got it.

  • Defining a Droppable Component

Now create a new file name Droppable.jsx inside the src folder of your React app and paste the below code.

import React from 'react';
import { useDroppable } from '@dnd-kit/core';

export function Droppable(props) {
    const { isOver, setNodeRef } = useDroppable({
        id: 'droppable',
    });
    const style = {
        color: isOver ? 'blue' : undefined,
    };


    return (
        <div ref={setNodeRef} style={style}>
            {props.children}
        </div>
    );
}

Here, the useDroppable hook returns an object that contains two properties:

  • isOver: a boolean value indicating whether the draggable component is currently over the droppable component
  • setNodeRef: a function that is used to set a reference to the DOM node of the component

Then the code is simple, if the draggable component is over the droppable component then isOver will be true and because of that the color blue will be applied.

  • Defining a Parent Component

Remember, we have to create a parent component that takes these two components.

So now let’s create that.

import React, { useState } from 'react';
import { DndContext } from '@dnd-kit/core';
import './App.css'
import { Droppable } from './Droppable';
import { Draggable } from './Draggable';

function App() {
  const [isDropped, setIsDropped] = useState(false);
  const draggableMarkup = (

    <Draggable >
      <div className='drag_item'>
        Drag me
      </div>
    </Draggable>
  );

  return (
    <DndContext onDragEnd={handleDragEnd}>
      <div className='section'>
        <div className='draggable'>
          {!isDropped ? draggableMarkup : null}
        </div>
        <div className='draggable'>
          <Droppable>
            {isDropped ? draggableMarkup : 'Drop here'}
          </Droppable>
        </div>
      </div>
    </DndContext>
  );

  function handleDragEnd(event) {
    if (event.over && event.over.id === 'droppable') {
      setIsDropped(true);
    }
  }
}

export default App;

Here, in the App component, we have defined a state variable isDropped that keeps track of whether the draggable item has been dropped into the droppable area.

In simple terms, we have conditions to either display the draggable item or a message indicating where the item can be dropped.

In the main render function, the code returns a DndContext component with a callback function handleDragEnd passed as a prop. The callback will be called when the drag-and-drop action is finished. Then we have two divs with the class "draggable"(for applying the same styles).

The first div has the draggableMarkup component as its child, but only if isDropped is false. The second div has a Droppable component as its child. If isDropped is true, the draggableMarkup component will be displayed, otherwise, it will display the text "Drop here".

Lastly, the handleDragEnd function checks if the event.over property exists and if the id of the event.over object is "droppable". If so, it updates the state by calling setIsDropped(true).

  • Add styles to your react app

Lastly, we need to apply styles to our React app. And for that, you can use any CSS framework but I will simply create a new App.css file inside the src folder and add the below code to it.

.section {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background-color: rgb(37, 148, 251);
}

.draggable {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20rem;
  height: 20rem;
  background-color: #9749FF;
  margin-right: 10px;
  color: white;
}

.drag_item {
  padding: 5px 10px;
  width: 8rem;
  height: auto;
  color: black;
  background-color: white;
}

That’s it, now you can run the app and see the output.

Hope you like it.

That’s it — thanks.

Also, there will be a series of posts about Dnd Kit in the future, so be sure to follow me.

Consider becoming a Medium member if you appreciate reading stories like this and want to help me as a writer. It costs $5 per month and gives you unlimited access to Medium content. I’ll get a little commission if you sign up via my link.

JavaScript
Web Development
Programming
Technology
Tech
Recommended from ReadMedium