Top Related Projects
Drag and Drop for React
A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️
Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.
Infinite responsive, sortable, filterable and draggable layouts
:ok_hand: Drag and drop so simple it hurts
🖱 A resizable and draggable component for React.
Quick Overview
React Beautiful DnD is a powerful and flexible drag and drop library for React applications. It provides a natural and intuitive drag and drop experience with smooth animations, while maintaining high performance and accessibility.
Pros
- Highly customizable and flexible
- Excellent performance, even with large lists
- Strong focus on accessibility
- Comprehensive documentation and examples
Cons
- Limited to vertical lists and horizontal lists (no free-form dragging)
- Learning curve can be steep for complex implementations
- No built-in touch support for mobile devices
- Relatively large bundle size
Code Examples
Basic list with drag and drop:
import React from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
const MyList = ({ items, onDragEnd }) => (
<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>
);
Multiple drag and drop lists:
import React from 'react';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
const MultipleList = ({ lists, onDragEnd }) => (
<DragDropContext onDragEnd={onDragEnd}>
{Object.entries(lists).map(([listId, list]) => (
<Droppable key={listId} droppableId={listId}>
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef}>
{list.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
{item.content}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
))}
</DragDropContext>
);
Getting Started
-
Install the package:
npm install react-beautiful-dnd
-
Import the necessary components:
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
-
Wrap your app or component with
DragDropContext
:<DragDropContext onDragEnd={this.onDragEnd}> {/* Your app content */} </DragDropContext>
-
Use
Droppable
for drop targets andDraggable
for draggable items:<Droppable droppableId="list"> {(provided) => ( <ul {...provided.droppableProps} ref={provided.innerRef}> <Draggable draggableId="item1" index={0}> {(provided) => ( <li ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} > Item 1 </li> )} </Draggable> {provided.placeholder} </ul>
Competitor Comparisons
Drag and Drop for React
Pros of react-dnd
- More flexible and customizable, allowing for complex drag and drop scenarios
- Supports touch events and works well on mobile devices
- Provides a lower-level API, giving developers more control over the implementation
Cons of react-dnd
- Steeper learning curve due to its flexibility and lower-level API
- Requires more setup and configuration to get started
- Less out-of-the-box styling and animations compared to react-beautiful-dnd
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-beautiful-dnd:
import { Draggable } from 'react-beautiful-dnd';
<Draggable draggableId={props.id} index={props.index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
{props.children}
</div>
)}
</Draggable>
The code comparison shows that react-dnd requires more setup and uses hooks for implementation, while react-beautiful-dnd provides a more declarative approach with less boilerplate code.
A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️
Pros of react-sortable-hoc
- More flexible and customizable, allowing for complex sorting scenarios
- Supports both vertical and horizontal sorting out of the box
- Lighter weight and potentially better performance for simpler use cases
Cons of react-sortable-hoc
- Less polished animations and visual feedback during drag operations
- Requires more setup and configuration for advanced features
- Documentation is not as comprehensive or well-maintained
Code Comparison
react-sortable-hoc:
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
const SortableItem = SortableElement(({value}) => <li>{value}</li>);
const SortableList = SortableContainer(({items}) => {
return (
<ul>
{items.map((value, index) => (
<SortableItem key={`item-${index}`} index={index} value={value} />
))}
</ul>
);
});
react-beautiful-dnd:
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
const List = ({items}) => (
<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>
);
Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.
Pros of Sortable
- Framework-agnostic, works with vanilla JavaScript and various frameworks
- Supports more features out-of-the-box, like multi-drag and swap animations
- Smaller bundle size, potentially better performance for simpler use cases
Cons of Sortable
- Less React-specific optimizations and integrations
- Documentation and examples are not as comprehensive for React use cases
- May require more manual setup for advanced React-specific functionality
Code Comparison
react-beautiful-dnd:
import { DragDropContext, Droppable, Draggable } from '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>
Sortable:
import Sortable from 'sortablejs';
const el = document.getElementById('items');
const sortable = Sortable.create(el, {
animation: 150,
ghostClass: 'blue-background-class',
onEnd: (evt) => {
// Handle drag end
}
});
Infinite responsive, sortable, filterable and draggable layouts
Pros of Muuri
- Framework-agnostic: Works with any JavaScript framework or vanilla JS
- Supports both grid and list layouts with advanced sorting and filtering
- Highly customizable with extensive API and event system
Cons of Muuri
- Steeper learning curve due to more complex API
- Less React-specific optimizations and integrations
- Requires more manual setup for accessibility features
Code Comparison
Muuri:
const grid = new Muuri('.grid', {
dragEnabled: true,
dragSort: true
});
grid.on('dragEnd', (item) => {
console.log('Item moved:', item);
});
react-beautiful-dnd:
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="list">
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef}>
{items.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided) => (
<div ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
{item.content}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
:ok_hand: Drag and drop so simple it hurts
Pros of Dragula
- Lightweight and framework-agnostic, making it versatile for various projects
- Simple API and easy setup, requiring minimal configuration
- Supports touch events out of the box for mobile compatibility
Cons of Dragula
- Less feature-rich compared to React Beautiful DnD, lacking advanced functionalities
- Not specifically optimized for React, which may result in less seamless integration
- Limited built-in animations and visual feedback options
Code Comparison
React Beautiful DnD:
import { DragDropContext, Droppable, Draggable } from '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>
Dragula:
import dragula from 'dragula';
dragula([document.querySelector('#left'), document.querySelector('#right')])
.on('drag', function(el) {
el.className += ' is-moving';
})
.on('drop', function(el) {
el.className = el.className.replace('is-moving', '');
});
🖱 A resizable and draggable component for React.
Pros of react-rnd
- Supports both resizing and dragging of elements
- Allows for more flexible positioning and sizing of components
- Provides fine-grained control over resize and drag behavior
Cons of react-rnd
- Less optimized for complex list reordering scenarios
- May require more manual setup for accessibility features
- Doesn't provide built-in animations for drag and drop operations
Code Comparison
react-rnd:
<Rnd
default={{
x: 0,
y: 0,
width: 320,
height: 200,
}}
>
Resizable and draggable component
</Rnd>
react-beautiful-dnd:
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="list">
{(provided) => (
<div {...provided.droppableProps} ref={provided.innerRef}>
{items.map((item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
{item.content}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
</DragDropContext>
react-beautiful-dnd is more focused on list reordering and provides a more structured API for handling drag and drop within lists. react-rnd offers a simpler API for individual element manipulation but requires more setup for complex scenarios.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
â ï¸ Maintenance & support
This library continues to be relied upon heavily by Atlassian products, but we are focused on other priorities right now and have no current plans for further feature development or improvements.
It will continue to be here on GitHub and we will still make critical updates (e.g. security fixes, if any) as required, but will not be actively monitoring or replying to issues and pull requests.
We recommend that you donât raise issues or pull requests, as they will not be reviewed or actioned until further notice.
[!IMPORTANT]
Update: 3rd April 2024
react-beautiful-dnd (rbd)
Core characteristics
- Beautiful and natural movement of items ð
- Accessible: powerful keyboard and screen reader support â¿ï¸
- Extremely performant ð
- Clean and powerful api which is simple to get started with
- Plays extremely well with standard browser interactions
- Unopinionated styling
- No creation of additional wrapper dom nodes - flexbox and focus management friendly!
Get started ð©âð«
We have created a free course on egghead.io
ð¥ to help you get started with react-beautiful-dnd
as quickly as possible.
Currently supported feature set â
- Vertical lists â
- Horizontal lists â
- Movement between lists (⤠â â¤)
- Virtual list support ð¾ - unlocking 10,000 items @ 60fps
- Combining items
- Mouse ð, keyboard ð¹â¿ï¸ and touch ðð± (mobile, tablet and so on) support
- Multi drag support
- Incredible screen reader support â¿ï¸ - we provide an amazing experience for english screen readers out of the box ð¦. We also provide complete customisation control and internationalisation support for those who need it ð
- Conditional dragging and conditional dropping
- Multiple independent lists on the one page
- Flexible item sizes - the draggable items can have different heights (vertical lists) or widths (horizontal lists)
- Add and remove items during a drag
- Compatible with semantic
<table>
reordering - table pattern - Auto scrolling - automatically scroll containers and the window as required during a drag (even with keyboard ð¥)
- Custom drag handles - you can drag a whole item by just a part of it
- Able to move the dragging item to another element while dragging (clone, portal) - Reparenting your
<Draggable />
- Create scripted drag and drop experiences ð®
- Allows extensions to support for any input type you like ð¹
- ð² Tree support through the
@atlaskit/tree
package - A
<Droppable />
list can be a scroll container (without a scrollable parent) or be the child of a scroll container (that also does not have a scrollable parent) - Independent nested lists - a list can be a child of another list, but you cannot drag items from the parent list into a child list
- Server side rendering (SSR) compatible - see resetServerContext()
- Plays well with nested interactive elements by default
Motivation ð¤
react-beautiful-dnd
exists to create beautiful drag and drop for lists that anyone can use - even people who cannot see. For a good overview of the history and motivations of the project you can take a look at these external resources:
Not for everyone âï¸
There are a lot of libraries out there that allow for drag and drop interactions within React. Most notable of these is the amazing react-dnd
. It does an incredible job at providing a great set of drag and drop primitives which work especially well with the wildly inconsistent html5 drag and drop feature. react-beautiful-dnd
is a higher level abstraction specifically built for lists (vertical, horizontal, movement between lists, nested lists and so on). Within that subset of functionality react-beautiful-dnd
offers a powerful, natural and beautiful drag and drop experience. However, it does not provide the breadth of functionality offered by react-dnd
. So react-beautiful-dnd
might not be for you depending on what your use case is.
Documentation ð
About ð
- Installation
- Examples and samples
- Get started
- Design principles
- Animations
- Accessibility
- Browser support
Sensors ð
The ways in which somebody can start and control a drag
- Mouse dragging ð
- Touch dragging ðð±
- Keyboard dragging ð¹â¿ï¸
- Create your own sensor (allows for any input type as well as scripted experiences)
API ðï¸â
<DragDropContext />
- Wraps the part of your application you want to have drag and drop enabled for<Droppable />
- An area that can be dropped into. Contains<Draggable />
s<Draggable />
- What can be dragged aroundresetServerContext()
- Utility for server side rendering (SSR)
Guides ðº
<DragDropContext />
responders -onDragStart
,onDragUpdate
,onDragEnd
andonBeforeDragStart
- Combining
<Draggable />
s - Common setup issues
- Using
innerRef
- Setup problem detection and error recovery
- Rules for
draggableId
anddroppableId
s - Browser focus retention
- Customising or skipping the drop animation
- Auto scrolling
- Controlling the screen reader
- Use the html5
doctype
TypeScript
andflow
: type information- Dragging
<svg>
s - Avoiding image flickering
- Non-visible preset styles
- How we detect scroll containers
- How we use dom events - Useful if you need to build on top of
react-beautiful-dnd
- Adding
<Draggable />
s during a drag (11.x behaviour) - â ï¸ Advanced - Setting up Content Security Policy
Patterns ð·â
- Virtual lists ð¾
- Multi drag
- Tables
- Reparenting a
<Draggable />
- Using our cloning API or your own portal
Support ð©ââï¸
Read this in other languages ð
- íê¸/Korean
- Ðа ÑÑÑÑком/Russian
- Português/Portuguese
- Îλληνικά/Greek
- æ¥æ¬èª/Japanese
Creator âï¸
Alex Reardon @alexandereardon
Alex is no longer personally maintaning this project. The other wonderful maintainers are carrying this project forward.
Maintainers
- Daniel Del Core
- Many other @Atlassian's!
Collaborators ð¤
- Bogdan Chadkin @IAmTrySound
Top Related Projects
Drag and Drop for React
A set of higher-order components to turn any list into an animated, accessible and touch-friendly sortable list✌️
Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.
Infinite responsive, sortable, filterable and draggable layouts
:ok_hand: Drag and drop so simple it hurts
🖱 A resizable and draggable component for React.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot