Registry / web-framework / react-draggable

react-draggable

JSON →
library4.5.0jsnpmunverified

react-draggable is a React component library that makes HTML elements draggable within a web application. The current stable version is 4.5.0, with minor bugfix releases occurring periodically within a major version, and major versions released less frequently, indicating a stable and mature project. A key differentiator is that it doesn't create an additional wrapper element in the DOM, directly extending the wrapped element with event handlers and styles. It uses CSS Transforms for movement, allowing elements to be dragged regardless of their initial positioning and enabling movement between drags without issue. The library offers both a higher-order `Draggable` component for simple use cases and a lower-level `DraggableCore` for more fine-grained control over drag interactions, supporting both controlled and uncontrolled component patterns. It also ships with TypeScript types.

npm install react-draggable
INSTALL
IMPORT
SIG · REACT-DRAGGABLE
R
react-draggable
web-frameworkjavascriptv4.5.0
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Draggable
import Draggable from 'react-draggable';
const Draggable = require('react-draggable');
Draggable is the default export for the primary component.
DraggableCore
import { DraggableCore } from 'react-draggable';
const DraggableCore = require('react-draggable').DraggableCore;
DraggableCore is a named export providing a lower-level drag primitive.
DraggableEvent, DraggableData
import type { DraggableEvent, DraggableData } from 'react-draggable';
Type imports for event objects and data passed to drag handlers.

This quickstart demonstrates various configurations of the Draggable component, including basic dragging, axis-locked dragging, handle/cancel selectors, grid snapping, scaling, and controlled positioning. It also shows a basic usage of DraggableCore.

import React from 'react'; import ReactDOM from 'react-dom'; import Draggable, { DraggableCore } from 'react-draggable'; interface AppState { activeDrags: number; deltaPosition: { x: number; y: number; }; controlledPosition: { x: number; y: number; }; } class App extends React.Component<{}, AppState> { state = { activeDrags: 0, deltaPosition: { x: 0, y: 0 }, controlledPosition: { x: -400, y: 200 } }; handleDrag = (e: any, ui: any) => { const { x, y } = this.state.deltaPosition; this.setState({ deltaPosition: { x: x + ui.deltaX, y: y + ui.deltaY } }); }; onStart = () => { this.setState({ activeDrags: ++this.state.activeDrags }); }; onStop = () => { this.setState({ activeDrags: --this.state.activeDrags }); }; // For controlled component adjustXPos = (e: any) => { e.preventDefault(); e.stopPropagation(); const { x, y } = this.state.controlledPosition; this.setState({ controlledPosition: { x: x - 10, y } }); }; adjustYPos = (e: any) => { e.preventDefault(); e.stopPropagation(); const { x, y } = this.state.controlledPosition; this.setState({ controlledPosition: { x, y: y - 10 } }); }; onControlledDrag = (e: any, ui: any) => { const { x, y } = this.state.controlledPosition; this.setState({ controlledPosition: { x: x + ui.deltaX, y: y + ui.deltaY } }); }; onControlledDragStop = (e: any, ui: any) => { this.onStop(); this.onControlledDrag(e, ui); }; render() { const dragHandlers = { onStart: this.onStart, onStop: this.onStop }; const { deltaPosition, controlledPosition } = this.state; return ( <div> <h1>React Draggable Demo</h1> <Draggable {...dragHandlers}> <div className="box"> <div>I can be dragged!</div> </div> </Draggable> <Draggable axis="x" {...dragHandlers}> <div className="box"> <div>Only horizontal dragging</div> </div> </Draggable> <Draggable axis="y" {...dragHandlers}> <div className="box"> <div>Only vertical dragging</div> </div> </Draggable> <Draggable handle=".handle" {...dragHandlers}> <div className="box"> <div className="handle">Drag from here</div> <div>Clicking here won't move me</div> </div> </Draggable> <Draggable cancel=".no-drag" {...dragHandlers}> <div className="box"> <div className="no-drag">Clicking here won't move me</div> <div>Drag from here</div> </div> </Draggable> <Draggable grid={[25, 25]} {...dragHandlers}> <div className="box"> <div>I snap to a 25 x 25 grid</div> </div> </Draggable> <Draggable scale={0.5} {...dragHandlers}> <div className="box"> <div>I am 50% scale</div> </div> </Draggable> <Draggable defaultPosition={{x: 0, y: 0}} position={controlledPosition} onDrag={this.onControlledDrag} onStop={this.onControlledDragStop} > <div className="box"> I am a controlled component. <br /> My position is ({controlledPosition.x}, {controlledPosition.y}) <br /> <button onClick={this.adjustXPos}>Adjust x (-10)</button> <button onClick={this.adjustYPos}>Adjust y (-10)</button> </div> </Draggable> <h2>DraggableCore</h2> <DraggableCore {...dragHandlers}> <div className="box no-cursor"> I'm a DraggableCore.<br /> I only fire events.<br /> My position is ({deltaPosition.x}, {deltaPosition.y}) </div> </DraggableCore> </div> ); } } // Basic CSS for demonstration const styleSheet = document.createElement('style'); styleSheet.innerHTML = ` .box { background: #eee; border: 1px solid #999; border-radius: 3px; width: 180px; height: 180px; margin: 10px; padding: 10px; float: left; cursor: grab; font-family: monospace; font-size: 14px; text-align: center; } .box .handle { cursor: grab; background-color: #ccc; padding: 5px; margin-bottom: 5px; } .box .no-drag { cursor: not-allowed; background-color: #fdd; padding: 5px; margin-bottom: 5px; } .box.no-cursor { cursor: default; } `; document.head.appendChild(styleSheet); ReactDOM.render(<App />, document.getElementById('root'));
Debug
Known issues
breakingVersion 2.0.0 introduced significant breaking changes, specifically affecting event callbacks and the usage of `position` and `defaultPosition` props. Previous implementations will need to be updated to match the new API.
fix
Review the v2.0.0 changelog and the official documentation for updated `onStart`, `onDrag`, `onStop` callback signatures and how to manage component position using `position` (controlled) or `defaultPosition` (uncontrolled).
affects: >=2.0.0
gotchaIf the element you are wrapping with Draggable already has CSS Transforms applied, Draggable will overwrite them. This is because Draggable uses CSS Transforms for its positioning.
fix
To avoid overwriting existing transforms, wrap your target element in an intermediate `<span>` or `<div>` element, and apply Draggable to this new wrapper: `<Draggable><span>Your Element</span></Draggable>`.
affects: >=0.10
breakingVersion 2.1.0 fixed an issue where `handle` or `cancel` selectors might be improperly missed if the event originated from a child of the handle or cancel element. This change, while a fix, might alter behavior for existing workarounds.
fix
Test your existing Draggable implementations, especially those relying on `handle` or `cancel` props, after upgrading to v2.1.0 or newer. Remove any workarounds you might have implemented for the previous incorrect behavior.
affects: >=2.1.0
gotchaDragging on iDevices could cause the entire window to scroll instead of just the draggable element.
fix
Ensure you are using `react-draggable@4.5.0` or newer, which includes a fix for this issue. You might also need to explicitly prevent default touch behaviors on the draggable element or its parent if the problem persists with older versions.
affects: <4.5.0
Errors
Common errors & fixes
Cannot read properties of undefined (reading 'clientX') or cannot access clientX of undefined
This typically occurs on some touch-enabled platforms due to issues with event object normalization in older versions.
fix
Upgrade `react-draggable` to version 2.0.2 or newer, as this version specifically addressed bugs related to `clientX` being undefined on certain touch platforms.
Error: Argument 1 of Window.getComputedStyle does not implement interface Element.
An invalid argument was passed to `window.getComputedStyle`, often related to how SVG elements or non-standard DOM nodes were being handled.
fix
Update `react-draggable` to version 2.2.1 or newer. This version includes a bugfix for `getComputedStyle` errors.
Object doesn't support property or method 'constructor' in IE10
An incompatibility with JavaScript constructors in Internet Explorer 10 was causing errors during component initialization.
fix
Upgrade `react-draggable` to version 2.0.1 or newer. This version contains a specific fix for the IE10 constructor bug.
Upgrade
Version history
4.5.0latest on npm
Audit
Dependencies
reactrequiredPeer dependency for React applications.
react-domrequiredPeer dependency for rendering React components to the DOM.
Agent activity
2 hits · last 30 days
node
2
Resources
react-draggable — npm install react-draggable · libregistry