npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-draggable

v4.6.0

Published

React draggable component

Readme

React-Draggable

CI npm version npm downloads gzip size

A simple component for making elements draggable.

[Demo | Changelog]

<Draggable>
  <div>I can now be moved around!</div>
</Draggable>

Table of Contents

Installation

npm install react-draggable
# or
yarn add react-draggable
// ES Modules
import Draggable from 'react-draggable';
import { DraggableCore } from 'react-draggable';

// CommonJS
const Draggable = require('react-draggable');
const { DraggableCore } = require('react-draggable');

TypeScript types are included.

Compatibility

| Version | React Version | |---------|---------------| | 4.x | 16.3+ | | 3.x | 15 - 16 | | 2.x | 0.14 - 15 |

Quick Start

import React, { useRef } from 'react';
import Draggable from 'react-draggable';

function App() {
  const nodeRef = useRef(null);

  return (
    <Draggable nodeRef={nodeRef}>
      <div ref={nodeRef}>Drag me!</div>
    </Draggable>
  );
}

View the Demo and its source for more examples.

API

<Draggable>

A <Draggable> element wraps an existing element and extends it with new event handlers and styles. It does not create a wrapper element in the DOM.

Draggable items are moved using CSS Transforms. This allows items to be dragged regardless of their current positioning (relative, absolute, or static). Elements can also be moved between drags without incident.

If the item you are dragging already has a CSS Transform applied, it will be overwritten by <Draggable>. Use an intermediate wrapper (<Draggable><span>...</span></Draggable>) in this case.

Props

type DraggableEventHandler = (e: Event, data: DraggableData) => void | false;

type DraggableData = {
  node: HTMLElement,
  x: number, y: number,
  deltaX: number, deltaY: number,
  lastX: number, lastY: number,
};

| Prop | Type | Default | Description | |------|------|---------|-------------| | allowAnyClick | boolean | false | Allow dragging on non-left-button clicks | | allowMobileScroll | boolean | false | Don't prevent touchstart, allowing scrolling inside containers | | axis | 'both' \| 'x' \| 'y' \| 'none' | 'both' | Axis to allow dragging on | | bounds | object \| string | - | Restrict movement. Use 'parent', a CSS selector, or {left, top, right, bottom} | | cancel | string | - | CSS selector for elements that should not initiate drag | | defaultClassName | string | 'react-draggable' | Class name applied to the element | | defaultClassNameDragging | string | 'react-draggable-dragging' | Class name applied while dragging | | defaultClassNameDragged | string | 'react-draggable-dragged' | Class name applied after drag | | defaultPosition | {x: number, y: number} | {x: 0, y: 0} | Starting position | | disabled | boolean | false | Disable dragging | | enableUserSelectHack | boolean | true | Add user-select: none while dragging | | grid | [number, number] | - | Snap to grid [x, y] | | handle | string | - | CSS selector for the drag handle | | nodeRef | React.RefObject | - | Ref to the DOM element. Required for React Strict Mode | | offsetParent | HTMLElement | - | Custom offsetParent for drag calculations | | onDrag | DraggableEventHandler | - | Called while dragging | | onMouseDown | (e: MouseEvent) => void | - | Called on mouse down | | onStart | DraggableEventHandler | - | Called when dragging starts. Return false to cancel | | onStop | DraggableEventHandler | - | Called when dragging stops | | position | {x: number, y: number} | - | Controlled position | | positionOffset | {x: number \| string, y: number \| string} | - | Position offset (supports percentages) | | scale | number | 1 | Scale factor for dragging inside transformed parents |

Note: Setting className, style, or transform on <Draggable> will error. Set them on the child element.

<DraggableCore>

For users that require full control, <DraggableCore> provides drag callbacks without managing state or styles. It does not set any transforms; you must handle positioning yourself.

See React-Resizable and React-Grid-Layout for usage examples.

Props

<DraggableCore> accepts a subset of <Draggable> props:

  • allowAnyClick
  • allowMobileScroll
  • cancel
  • disabled
  • enableUserSelectHack
  • grid
  • handle
  • nodeRef
  • offsetParent
  • onDrag
  • onMouseDown
  • onStart
  • onStop
  • scale

Using nodeRef

To avoid ReactDOM.findDOMNode() deprecation warnings in React Strict Mode, pass a nodeRef prop:

function App() {
  const nodeRef = useRef(null);

  return (
    <Draggable nodeRef={nodeRef}>
      <div ref={nodeRef}>Drag me!</div>
    </Draggable>
  );
}

For custom components, forward both the ref and props:

const MyComponent = forwardRef((props, ref) => (
  <div {...props} ref={ref}>Draggable content</div>
));

function App() {
  const nodeRef = useRef(null);

  return (
    <Draggable nodeRef={nodeRef}>
      <MyComponent ref={nodeRef} />
    </Draggable>
  );
}

Controlled vs. Uncontrolled

<Draggable> is a 'batteries-included' component that manages its own state. For complete control, use <DraggableCore>.

For programmatic repositioning while using <Draggable>'s state management, pass the position prop:

function ControlledDraggable() {
  const nodeRef = useRef(null);
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const handleDrag = (e, data) => {
    setPosition({ x: data.x, y: data.y });
  };

  const resetPosition = () => setPosition({ x: 0, y: 0 });

  return (
    <>
      <button onClick={resetPosition}>Reset</button>
      <Draggable nodeRef={nodeRef} position={position} onDrag={handleDrag}>
        <div ref={nodeRef}>Drag me or reset!</div>
      </Draggable>
    </>
  );
}

Contributing

  • Fork the project
  • Run yarn dev to start the development server
  • Make changes and add tests
  • Run yarn test to ensure tests pass
  • Submit a PR

Release Checklist

  1. Update CHANGELOG.md
  2. Run make release-patch, make release-minor, or make release-major
  3. Run make publish

License

MIT