React-Draggable is a popular library for implementing drag-and-drop functionality in React. It allows you to make elements draggable within a specified container, enabling interactive user interfaces. You can easily implement draggable components with features such as constraints, bounds, and axis restrictions.
In this guide, we’ll walk through how to use React-Draggable to create draggable components in React.
1. Setting Up the Project
To get started, you need to install the react-draggable library. If you haven’t created a React project yet, you can do so by using the following command:
npx create-react-app draggable-demo
cd draggable-demo
npm install react-draggable
2. Creating a Basic Draggable Component
The core of React-Draggable is the Draggable
component, which can be used to make any element draggable. Below is a simple example of how to create a draggable box.
Example: Basic Draggable Box
import React from 'react';
import Draggable from 'react-draggable';
const DraggableBox = () => {
return (
<div className="App">
<Draggable>
<div className="box">
<h3>Drag Me!</h3>
</div>
</Draggable>
</div>
);
}
export default DraggableBox;
Explanation:
Draggable
: TheDraggable
component wraps around the element that you want to make draggable.div.box
: This is the draggable element. You can put any content inside this element, and it will become draggable.
Styling (CSS)
/* App.css */
.box {
width: 150px;
height: 150px;
background-color: #4caf50;
display: flex;
justify-content: center;
align-items: center;
color: white;
text-align: center;
border-radius: 8px;
cursor: move;
}
What Happens:
- The box becomes draggable, and you can move it around the screen by clicking and dragging it.
3. Adding Constraints and Bounds
You can add constraints to limit the draggable element to a specific area. The bounds
prop allows you to restrict the movement of the element within a certain area.
Example: Draggable Box with Bounds
import React from 'react';
import Draggable from 'react-draggable';
const DraggableBoxWithBounds = () => {
return (
<div className="App">
<Draggable bounds="parent">
<div className="box">
<h3>Drag Me Within Parent</h3>
</div>
</Draggable>
</div>
);
}
export default DraggableBoxWithBounds;
Explanation:
bounds="parent"
: This restricts the movement of the draggable element within its parent container.- You can set custom bounds using either
"parent"
(the parent element),"body"
, or a specific CSS selector (e.g.,".container"
).
Styling (CSS)
/* App.css */
.App {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.box {
width: 150px;
height: 150px;
background-color: #4caf50;
display: flex;
justify-content: center;
align-items: center;
color: white;
text-align: center;
border-radius: 8px;
cursor: move;
}
What Happens:
- The draggable box can now only be moved within its parent container.
4. Constrained Movement on Specific Axes
You can restrict the dragging behavior to a specific axis—either horizontal (x
) or vertical (y
). This can be useful when you only want the element to be draggable along one axis.
Example: Horizontal Draggable Box
import React from 'react';
import Draggable from 'react-draggable';
const HorizontalDraggableBox = () => {
return (
<div className="App">
<Draggable axis="x">
<div className="box">
<h3>Drag Me Horizontally</h3>
</div>
</Draggable>
</div>
);
}
export default HorizontalDraggableBox;
Example: Vertical Draggable Box
import React from 'react';
import Draggable from 'react-draggable';
const VerticalDraggableBox = () => {
return (
<div className="App">
<Draggable axis="y">
<div className="box">
<h3>Drag Me Vertically</h3>
</div>
</Draggable>
</div>
);
}
export default VerticalDraggableBox;
Explanation:
axis="x"
: Restricts the movement to the horizontal axis.axis="y"
: Restricts the movement to the vertical axis.
5. Tracking the Position of the Draggable Element
You can track the position of the draggable component using the onDrag
event, which provides the current position (x, y) of the element. This can be useful for updating the position in your component state or performing other actions when the element is being dragged.
Example: Tracking Position During Drag
import React, { useState } from 'react';
import Draggable from 'react-draggable';
const TrackPosition = () => {
const [position, setPosition] = useState({ x: 0, y: 0 });
const handleDrag = (e, data) => {
setPosition({ x: data.x, y: data.y });
};
return (
<div className="App">
<Draggable onDrag={handleDrag}>
<div className="box">
<h3>Drag Me!</h3>
</div>
</Draggable>
<div>
<p>Position: x: {position.x}, y: {position.y}</p>
</div>
</div>
);
};
export default TrackPosition;
Explanation:
onDrag={handleDrag}
: TheonDrag
event is fired while the element is being dragged. Thedata
object provides the current position of the element (x, y).setPosition
: Updates the state with the current position of the draggable element, which is displayed on the screen.
Styling (CSS)
/* App.css */
.App {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.box {
width: 150px;
height: 150px;
background-color: #4caf50;
display: flex;
justify-content: center;
align-items: center;
color: white;
text-align: center;
border-radius: 8px;
cursor: move;
}
What Happens:
- The position of the box is updated and displayed in real-time as you drag it around the screen.
6. Draggable Component with Handle
You can specify a handle element to control dragging. This means the user can only drag the component by interacting with a specific part of it.
Example: Draggable Box with Handle
import React from 'react';
import Draggable from 'react-draggable';
const DraggableWithHandle = () => {
return (
<div className="App">
<Draggable handle=".handle">
<div className="box">
<div className="handle">
<h3>Drag Me by This Handle!</h3>
</div>
</div>
</Draggable>
</div>
);
};
export default DraggableWithHandle;
Explanation:
handle=".handle"
: The.handle
class specifies the area of the component that can be used to drag it. In this case, only the header inside the.handle
class will allow dragging.
Styling (CSS)
/* App.css */
.App {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.box {
width: 200px;
height: 150px;
background-color: #4caf50;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: white;
text-align: center;
border-radius: 8px;
cursor: move;
}
.handle {
width: 100%;
background-color: #333;
padding: 10px;
text-align: center;
cursor: move;
}
What Happens:
- The component is only draggable when the user clicks and drags the handle (the header), not the entire box.