Convert Figma logo to code with AI

react-grid-layout logoreact-draggable

React draggable component

9,268
1,054
9,268
209

Top Related Projects

A draggable and resizable grid layout with responsive breakpoints, for React.

Beautiful and accessible drag and drop for lists with React

21,594

Drag and Drop for React

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

🖱 A resizable and draggable component for React.

10,644

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!

Quick Overview

React-Draggable is a lightweight, performant drag and drop library for React applications. It provides a simple way to make DOM elements draggable, with support for both mouse and touch events, making it suitable for desktop and mobile applications.

Pros

  • Easy to integrate with existing React projects
  • Supports both mouse and touch events for broad device compatibility
  • Highly customizable with various props and callbacks
  • Lightweight and performant, with minimal dependencies

Cons

  • Limited to dragging functionality; doesn't include features like resizing or sorting
  • May require additional setup for complex use cases or specific layouts
  • Documentation could be more comprehensive for advanced scenarios
  • Occasional issues with nested draggable elements

Code Examples

  1. Basic draggable element:
import React from 'react';
import Draggable from 'react-draggable';

function App() {
  return (
    <Draggable>
      <div>I can be dragged anywhere</div>
    </Draggable>
  );
}
  1. Draggable with bounds:
import React from 'react';
import Draggable from 'react-draggable';

function App() {
  return (
    <Draggable bounds="parent">
      <div>I can only be dragged within my parent</div>
    </Draggable>
  );
}
  1. Draggable with event handlers:
import React from 'react';
import Draggable from 'react-draggable';

function App() {
  const handleStart = (e, data) => console.log('Drag started', data);
  const handleDrag = (e, data) => console.log('Dragging', data);
  const handleStop = (e, data) => console.log('Drag stopped', data);

  return (
    <Draggable onStart={handleStart} onDrag={handleDrag} onStop={handleStop}>
      <div>Drag me and check the console</div>
    </Draggable>
  );
}

Getting Started

  1. Install the package:

    npm install react-draggable
    
  2. Import and use in your React component:

    import React from 'react';
    import Draggable from 'react-draggable';
    
    function MyComponent() {
      return (
        <Draggable>
          <div>Drag me!</div>
        </Draggable>
      );
    }
    
    export default MyComponent;
    
  3. Customize as needed using props and event handlers.

Competitor Comparisons

A draggable and resizable grid layout with responsive breakpoints, for React.

Pros of react-grid-layout

  • Provides a complete grid layout system with resizing and dragging capabilities
  • Offers responsive breakpoints for different screen sizes
  • Includes built-in collision detection and prevention

Cons of react-grid-layout

  • More complex API and setup compared to react-draggable
  • Heavier in terms of bundle size and performance impact
  • May be overkill for simple draggable requirements

Code Comparison

react-grid-layout:

import GridLayout from 'react-grid-layout';

<GridLayout
  className="layout"
  layout={layout}
  cols={12}
  rowHeight={30}
  width={1200}
>
  <div key="a">Item A</div>
  <div key="b">Item B</div>
</GridLayout>

react-draggable:

import Draggable from 'react-draggable';

<Draggable
  axis="both"
  handle=".handle"
  defaultPosition={{x: 0, y: 0}}
  grid={[25, 25]}
  scale={1}
>
  <div>
    <div className="handle">Drag from here</div>
    <div>This content will be draggable</div>
  </div>
</Draggable>

react-grid-layout offers a more comprehensive solution for creating complex, responsive grid layouts with draggable and resizable elements. It's ideal for dashboard-like interfaces or applications requiring precise control over element positioning. However, it comes with a steeper learning curve and higher complexity.

react-draggable, on the other hand, focuses solely on making elements draggable. It's simpler to implement and lighter in weight, making it a better choice for basic dragging functionality or when you need more control over the dragging behavior of individual elements.

Beautiful and accessible drag and drop for lists with React

Pros of react-beautiful-dnd

  • Provides a more natural and fluid drag-and-drop experience
  • Offers better accessibility features out of the box
  • Includes built-in animations and visual feedback during drag operations

Cons of react-beautiful-dnd

  • Less flexible for custom layouts or grid-based positioning
  • May have a steeper learning curve due to its specific API and concepts
  • Limited to vertical lists and horizontal lists, not suited for free-form dragging

Code Comparison

react-beautiful-dnd:

<DragDropContext onDragEnd={onDragEnd}>
  <Droppable droppableId="list">
    {(provided) => (
      <ul {...provided.droppableProps} ref={provided.innerRef}>
        {items.map((item, index) => (
          <Draggable key={item.id} draggableId={item.id} index={index}>
            {(provided) => (
              <li ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
                {item.content}
              </li>
            )}
          </Draggable>
        ))}
        {provided.placeholder}
      </ul>
    )}
  </Droppable>
</DragDropContext>

react-draggable:

<Draggable
  axis="both"
  handle=".handle"
  defaultPosition={{x: 0, y: 0}}
  position={null}
  grid={[25, 25]}
  scale={1}
  onStart={handleStart}
  onDrag={handleDrag}
  onStop={handleStop}>
  <div>
    <div className="handle">Drag from here</div>
    <div>This content will be draggable</div>
  </div>
</Draggable>
21,594

Drag and Drop for React

Pros of react-dnd

  • More flexible and powerful for complex drag-and-drop scenarios
  • Supports touch devices and keyboard interactions out of the box
  • Provides a higher level of abstraction with drag sources and drop targets

Cons of react-dnd

  • Steeper learning curve due to its more complex API
  • Requires more setup and boilerplate code for basic functionality
  • May be overkill for simple drag-and-drop requirements

Code Comparison

react-dnd:

import { useDrag, useDrop } from 'react-dnd';

const [{ isDragging }, drag] = useDrag(() => ({
  type: 'ITEM',
  item: { id: props.id },
  collect: (monitor) => ({
    isDragging: !!monitor.isDragging(),
  }),
}));

react-draggable:

import Draggable from 'react-draggable';

<Draggable
  axis="x"
  handle=".handle"
  defaultPosition={{x: 0, y: 0}}
  position={null}
  grid={[25, 25]}
  scale={1}
>
  <div>Draggable content</div>
</Draggable>

A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️

Pros of react-sortable-hoc

  • Specialized for sortable lists and grids
  • Supports both vertical and horizontal sorting
  • Provides animation and auto-scrolling capabilities

Cons of react-sortable-hoc

  • Less flexible for general dragging tasks
  • May have a steeper learning curve for simple use cases
  • Limited to sorting within a container

Code Comparison

react-sortable-hoc:

import { SortableContainer, SortableElement } from 'react-sortable-hoc';

const SortableItem = SortableElement(({value}) => <li>{value}</li>);

const SortableList = SortableContainer(({items}) => (
  <ul>
    {items.map((value, index) => (
      <SortableItem key={`item-${index}`} index={index} value={value} />
    ))}
  </ul>
));

react-draggable:

import Draggable from 'react-draggable';

const DraggableComponent = () => (
  <Draggable>
    <div>I can be dragged anywhere!</div>
  </Draggable>
);

react-sortable-hoc is more suited for creating sortable lists or grids, while react-draggable offers more general-purpose dragging functionality. The choice between them depends on the specific requirements of your project.

🖱 A resizable and draggable component for React.

Pros of react-rnd

  • Combines dragging and resizing functionality in a single component
  • Supports both controlled and uncontrolled modes for more flexibility
  • Includes built-in touch support for mobile devices

Cons of react-rnd

  • Less focused on grid-based layouts compared to react-grid-layout
  • May have a steeper learning curve due to more configuration options
  • Smaller community and fewer contributors compared to react-draggable

Code Comparison

react-rnd:

<Rnd
  default={{
    x: 0, y: 0,
    width: 320, height: 200
  }}
>
  Resizable and draggable content
</Rnd>

react-draggable:

<Draggable>
  <div>Draggable content</div>
</Draggable>

react-rnd combines dragging and resizing in a single component, while react-draggable focuses solely on dragging functionality. react-rnd requires more configuration but offers more built-in features. react-draggable is simpler to use for basic dragging needs but may require additional components or libraries for resizing capabilities.

Both libraries are well-maintained and offer good performance, but react-draggable has a larger community and more frequent updates. The choice between them depends on specific project requirements, such as the need for combined dragging and resizing or preference for simplicity versus feature richness.

10,644

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!

Pros of Moveable

  • More versatile, supporting not just dragging but also resizing, rotating, and other transformations
  • Framework-agnostic, can be used with various JavaScript libraries or vanilla JS
  • Extensive set of events and hooks for fine-grained control over interactions

Cons of Moveable

  • Steeper learning curve due to its more comprehensive feature set
  • Potentially higher performance overhead for simpler use cases
  • Less React-specific optimizations compared to React Draggable

Code Comparison

React Draggable:

import Draggable from 'react-draggable';

<Draggable>
  <div>I can be dragged anywhere</div>
</Draggable>

Moveable:

import Moveable from "moveable";

const moveable = new Moveable(document.body, {
  target: document.querySelector(".target"),
  draggable: true,
});

moveable.on("drag", ({ target, transform }) => {
  target.style.transform = transform;
});

Both libraries offer drag functionality, but Moveable provides a more low-level API that can be used in various contexts. React Draggable is more tightly integrated with React and offers a simpler API for basic dragging needs. Moveable's approach allows for more complex interactions and transformations beyond just dragging.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

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

VersionReact Version
4.x16.3+
3.x15 - 16
2.x0.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,
};
PropTypeDefaultDescription
allowAnyClickbooleanfalseAllow dragging on non-left-button clicks
allowMobileScrollbooleanfalseDon't prevent touchstart, allowing scrolling inside containers
axis'both' | 'x' | 'y' | 'none''both'Axis to allow dragging on
boundsobject | string-Restrict movement. Use 'parent', a CSS selector, or {left, top, right, bottom}
cancelstring-CSS selector for elements that should not initiate drag
defaultClassNamestring'react-draggable'Class name applied to the element
defaultClassNameDraggingstring'react-draggable-dragging'Class name applied while dragging
defaultClassNameDraggedstring'react-draggable-dragged'Class name applied after drag
defaultPosition{x: number, y: number}{x: 0, y: 0}Starting position
disabledbooleanfalseDisable dragging
enableUserSelectHackbooleantrueAdd user-select: none while dragging
grid[number, number]-Snap to grid [x, y]
handlestring-CSS selector for the drag handle
nodeRefReact.RefObject-Ref to the DOM element. Required for React Strict Mode
offsetParentHTMLElement-Custom offsetParent for drag calculations
onDragDraggableEventHandler-Called while dragging
onMouseDown(e: MouseEvent) => void-Called on mouse down
onStartDraggableEventHandler-Called when dragging starts. Return false to cancel
onStopDraggableEventHandler-Called when dragging stops
position{x: number, y: number}-Controlled position
positionOffset{x: number | string, y: number | string}-Position offset (supports percentages)
scalenumber1Scale 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

NPM DownloadsLast 30 Days