react-draggable is a React component that makes any of its children draggable. It provides a simple and flexible way to add drag-and-drop functionality to elements within a React application. It's built on top of the excellent 'Draggable' library but specifically designed for React, taking advantage of React's component-based architecture.
Key Features and Concepts:
1. Simple Integration: You wrap the component you want to make draggable with the `<Draggable>` component.
2. Controlled vs. Uncontrolled:
* Uncontrolled: Using `defaultPosition` allows the Draggable component to manage its own position internally. This is simpler for basic use cases.
* Controlled: Using `position` requires you to manage the draggable item's position in your component's state. You must also provide `onDrag` or `onStop` callbacks to update this state, giving you precise control over the element's movement.
3. Axis Restriction: The `axis` prop ('x', 'y', 'both', 'none') allows you to restrict movement to horizontal, vertical, or no axis.
4. Bounds: The `bounds` prop can restrict the draggable element's movement to a specific area. This can be a parent container ('parent'), an object with {left, top, right, bottom} coordinates, or a CSS selector string.
5. Handles and Cancels:
* The `handle` prop (a CSS selector) specifies which part of the draggable element can be used to initiate dragging.
* The `cancel` prop (a CSS selector) specifies elements within the draggable area that, when clicked, will *not* initiate dragging.
6. Grid Snapping: The `grid` prop takes an array `[x, y]` to snap the draggable element's position to a grid.
7. Callbacks: It provides several callback functions for different stages of the drag event:
* `onStart`: Called when dragging starts.
* `onDrag`: Called continuously while dragging.
* `onStop`: Called when dragging stops.
* These callbacks receive event objects and data objects containing information like current x, y positions.
Use Cases:
* Creating interactive dashboards where users can rearrange widgets.
* Implementing draggable modals or dialog boxes.
* Building puzzle games or drag-and-drop interfaces.
* Developing tools where elements need to be positioned freely by the user.
Installation:
`npm install react-draggable` or `yarn add react-draggable`
Example Code
import React, { useState } from 'react';
import Draggable from 'react-draggable';
import './App.css'; // Assuming you have some basic CSS for styling
function App() {
const [activeDrags, setActiveDrags] = useState(0);
const [deltaPosition, setDeltaPosition] = useState({
x: 0, y: 0
});
const handleStart = () => {
setActiveDrags(prev => prev + 1);
};
const handleDrag = (e, ui) => {
const { x, y } = deltaPosition;
setDeltaPosition({
x: x + ui.deltaX,
y: y + ui.deltaY,
});
};
const handleStop = () => {
setActiveDrags(prev => prev - 1);
};
const dragHandlers = { onStart: handleStart, onStop: handleStop };
return (
<div className="App">
<h1>React Draggable Examples</h1>
<h2>Basic Draggable (Uncontrolled)</h2>
<div className="draggable-container" style={{ height: '200px', width: '300px', border: '2px solid blue', position: 'relative', overflow: 'hidden' }}>
<Draggable {...dragHandlers} defaultPosition={{x: 25, y: 25}} bounds="parent">
<div className="box">
<div>Drag Me!</div>
<p>I'm restricted to my parent.</p>
</div>
</Draggable>
</div>
<h2>Draggable with Custom Handle</h2>
<Draggable {...dragHandlers} handle=".handle" defaultPosition={{x: 0, y: 100}}>
<div className="box" style={{ background: '#e0ffe0', border: '1px solid green' }}>
<div className="handle" style={{ background: 'green', color: 'white', padding: '5px', cursor: 'grab' }}>Drag Handle</div>
<p>You can only drag me by the green handle.</p>
</div>
</Draggable>
<h2>Controlled Draggable</h2>
<Draggable position={deltaPosition} onDrag={handleDrag} {...dragHandlers}>
<div className="box" style={{ background: '#ffe0e0', border: '1px solid red' }}>
<p>I'm controlled by state.</p>
<p>x: {deltaPosition.x.toFixed(0)}, y: {deltaPosition.y.toFixed(0)}</p>
</div>
</Draggable>
<div className="status">
<p>Number of active drags: {activeDrags}</p>
</div>
</div>
);
}
export default App;
/* App.css for basic styling */
/*
.App {
font-family: sans-serif;
text-align: center;
padding: 20px;
}
.draggable-container {
margin: 20px auto;
background-color: #f0f0f0;
}
.box {
width: 150px;
height: 80px;
border: 1px solid #ccc;
background-color: #fff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: grab;
box-shadow: 2px 2px 5px rgba(0,0,0,0.2);
user-select: none;
position: relative;
}
.box:active {
cursor: grabbing;
}
.status {
margin-top: 40px;
font-size: 0.9em;
color: #555;
}
*/








react-draggable