react-beautiful-dnd-iframe - npm explorer
)}

`

The function is provided with two arguments:

#### 1. provided: (DraggableProvided)

`js
type DraggableProvided = {|
innerRef: HTMLElement => void,
draggableProps: DraggableProps,
// will be null if the draggable is disabled
dragHandleProps: ?DragHandleProps,
|};
`

Everything within the _provided_ object must be applied for the Draggable to function correctly.

- provided.innerRef (innerRef: (HTMLElement) => void): In order for the Droppable to function correctly, you must bind the innerRef function to the ReactElement that you want to be considered the Draggable node. We do this in order to avoid needing to use ReactDOM to look up your DOM node.

> For more information on using innerRef see our using innerRef guide

##### innerRef Example

`js

{(provided, snapshot) =>

Drag me!
}

`

- provided.draggableProps (DraggableProps): This is an Object that contains a data attribute and an inline style. This Object needs to be applied to the same node that you apply provided.innerRef to. This controls the movement of the draggable when it is dragging and not dragging. You are welcome to add your own styles to DraggableProps.style – but please do not remove or replace any of the properties.

##### draggableProps Type information

`js
// Props that can be spread onto the element directly
export type DraggableProps = {|
// inline style
style: ?DraggableStyle,
// used for shared global styles
'data-react-beautiful-dnd-draggable': string,
|};

type DraggableStyle = DraggingStyle | NotDraggingStyle;
type DraggingStyle = {|
position: 'fixed',
width: number,
height: number,
boxSizing: 'border-box',
pointerEvents: 'none',
top: number,
left: number,
transition: 'none',
transform: ?string,
zIndex: ZIndex,
|};
type NotDraggingStyle = {|
transform: ?string,
transition: null | 'none',
|};
`

##### draggableProps Example

`js

{(provided, snapshot) => (


Drag me!

)}

`

##### Positioning ownership

It is a contract of this library that it owns the positioning logic of the dragging element. This includes properties such as top, right, bottom, left and transform. The library may change how it positions things and which properties it uses without performing a major version bump. It is also recommended that you do not apply your own transition property to the dragging element.

##### Warning: position: fixed

react-beautiful-dnd uses position: fixed to position the dragging element. This is quite robust and allows for you to have position: relative | absolute | fixed parents. However, unfortunately position:fixed is impacted by transform (such as transform: rotate(10deg);). This means that if you have a transform: * on one of the parents of a Draggable then the positioning logic will be incorrect while dragging. Lame! For most consumers this will not be an issue.

To get around this you can use React.Portal. We do not enable this functionality by default as it has performance problems. We have a using a portal guide explaining the performance problem in more detail and how you can set up your own React.Portal if you want to.

##### Focus retention when moving between lists

When moving a Draggable from one list to another the default browser behaviour is for the _drag handle_ element to loose focus. This is because the old element is being destroyed and a new one is being created. The loss of focus is not good when dragging with a keyboard as the user is then unable to continue to interact with the element. To improve this user experience we automatically give a _drag handle_ focus when:

- It was unmounted at the end of a drag
- It had focus
- It is enabled when mounted
- No other elements have gained browser focus before the drag handle has mounted

##### Extending DraggableProps.style

If you are using inline styles you are welcome to extend the DraggableProps.style object. You are also welcome to apply the DraggableProps.style object using inline styles and use your own styling solution for the component itself - such as styled-components.

If you are overriding inline styles be sure to do it after you spread the provided.draggableProps or the spread will override your inline style.

`js

{(provided, snapshot) => {
// extending the DraggableStyle with our own inline styles
const style = {
backgroundColor: snapshot.isDragging ? 'blue' : 'white',
fontSize: 18,
...provided.draggableProps.style,
};
return (


Drag me!

);
}}

`

##### Avoid margin collapsing between Draggables

margin collapsing is one of those really hard parts of CSS. For our purposes, if you have one Draggable with a margin-bottom: 10px and the next Draggable has a margin-top: 12px these margins will _collapse_ and the resulting margin will be the greater of the two: 12px. When we do our calculations we are currently not accounting for margin collapsing. If you do want to have a margin on the siblings, wrap them both in a div and apply the margin to the inner div so they are not direct siblings.

##### Draggables should be visible siblings

It is an assumption that Draggables are _visible siblings_ of one another. There can be other elements in between, but these elements should not take up any additional space. You probably will not do this anyway, but just calling it out to be super clear.

`js
// Direct siblings ✅

{() => {}}


{() => {}}

// Not direct siblings, but are visible siblings ✅



{() => {}}




{() => {}}

// Spacer elements ❌

{() => {}}

I will break things!



{() => {}}

// Spacing on non sibling wrappers ❌



{() => {}}




{() => {}}


`

- provided.dragHandleProps (?DragHandleProps) every Draggable has a _drag handle_. This is what is used to drag the whole Draggable. Often this will be the same node as the Draggable, but sometimes it can be a child of the Draggable. DragHandleProps need to be applied to the node that you want to be the drag handle. This is a number of props that need to be applied to the Draggable node. The simplest approach is to spread the props onto the draggable node ({...provided.dragHandleProps}). However, you are also welcome to monkey patch these props if you also need to respond to them. DragHandleProps will be null when isDragDisabled is set to true.

##### dragHandleProps Type information

`js
type DragHandleProps = {|
onFocus: () => void,
onBlur: () => void,
onMouseDown: (event: MouseEvent) => void,
onKeyDown: (event: KeyboardEvent) => void,
onTouchStart: (event: TouchEvent) => void,
'data-react-beautiful-dnd-drag-handle': string,
'aria-roledescription': string,
tabIndex: number,
draggable: boolean,
onDragStart: (event: DragEvent) => void,
|};
`

##### dragHandleProps Example: standard

`js

{(provided, snapshot) => (
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
Drag me!

)}

`

##### dragHandleProps Example: custom drag handle

Controlling a whole draggable by just a part of it

`js

{(provided, snapshot) => (


Hello there


Drag handle


)}

`

##### dragHandleProps monkey patching

You can override some of the dragHandleProps props with your own behavior if you need to.

`js
const myOnMouseDown = event => console.log('mouse down on', event.target);


{(provided, snapshot) => {
const onMouseDown = (() => {
// dragHandleProps might be null
if (!provided.dragHandleProps) {
return onMouseDown;
}

// creating a new onMouseDown function that calls myOnMouseDown as well as the drag handle one.
return event => {
provided.dragHandleProps.onMouseDown(event);
myOnMouseDown(event);
};
})();

return (
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
onMouseDown={onMouseDown}
>
Drag me!

);
}}
;
`

#### 2. Snapshot: (DraggableStateSnapshot)

`js
type DraggableStateSnapshot = {|
// Set to true if a Draggable is being actively dragged, or if it is drop animating
// Both active dragging and the drop animation are considered part of the drag
isDragging: boolean,
// Set to true if a Draggable is drop animating. Not every drag and drop interaction
// as a drop animation. There is no drop animation when a Draggable is already in its final
// position when dropped. This is commonly the case when dragging with a keyboard
isDropAnimating: boolean,
// What Droppable (if any) the Draggable is currently over
draggingOver: ?DroppableId,
|};
`

The children function is also provided with a small amount of state relating to the current drag state. This can be optionally used to enhance your component. A common use case is changing the appearance of a Draggable while it is being dragged. Note: if you want to change the cursor to something like grab you will need to add the style to the draggable. (See Extending DraggableProps.style above)

`js

{(provided, snapshot) => {
const style = {
backgroundColor: snapshot.isDragging ? 'blue' : 'grey',
...provided.draggableProps.style,
};

return (
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={style}
>
Drag me!

);
}}

`

$3

When dragging a Draggable we leave behind a _placeholder_ React.Element to maintain space in the Droppable in order to prevent it from collapsing. The placeholder mimics the styling and layout (including width, height, margin, tagName and display) to ensure the list dimensions remain unaffected while dragging. It will be inserted by react-beautiful-dnd as a direct sibling to the React.Node returned by the Draggable children function.

$3

You are welcome to add your own onClick handler to a Draggable or a _drag handle_ (which might be the same element). onClick events handlers will always be called if a click occurred. If we are preventing the click then we the event.defaultPrevented property will be set to true. We prevent click events from occurring when the user was dragging an item. See sloppy clicks and click prevention for more information.

$3

It is possible for your Draggable to contain interactive elements. By default we block dragging on these elements. By doing this we allow those elements to function in the usual way. Here is the list of interactive elements that we block dragging from by default:

- input
-
button
-
textarea
-
select
-
option
-
optgroup
-
video
-
audio
-
contenteditable (any elements that are contenteditable or are within a contenteditable container)

You can opt out of this behavior by adding the disableInteractiveElementBlocking prop to a Draggable. However, it is questionable as to whether you should be doing so because it will render the interactive element unusable. If you need to _conditionally_ block dragging from interactive elements you can add the disableInteractiveElementBlocking prop to opt out of the default blocking and monkey patch the dragHandleProps (DragHandleProps) event handlers to disable dragging as required.

resetServerContext

The resetServerContext function should be used when server side rendering (SSR). It ensures context state does not persist across multiple renders on the server which would result in client/server markup mismatches after multiple requests are rendered on the server.

Use it before calling the server side render method:

`js
import { resetServerContext } from 'react-beautiful-dnd';
import { renderToString } from 'react-dom/server';

...

resetServerContext();
renderToString(...);
`

Flow usage

react-beautiful-dnd is typed using flowtype. This greatly improves internal consistency within the codebase. We also expose a number of public types which will allow you to type your javascript if you would like to. If you are not using flowtype this will not inhibit you from using the library. It is just extra safety for those who want it.

$3

`js
// id's
type Id = string;
type TypeId = Id;
type DroppableId = Id;
type DraggableId = Id;

// hooks
type DragStart = {|
draggableId: DraggableId,
type: TypeId,
source: DraggableLocation,
|};

type DragUpdate = {|
...DragStart,
// may not have any destination (drag to nowhere)
destination: ?DraggableLocation,
|};

type DropResult = {|
...DragUpdate,
reason: DropReason,
|};

type DropReason = 'DROP' | 'CANCEL';

type DraggableLocation = {|
droppableId: DroppableId,
// the position of the droppable within a droppable
index: number,
|};

// Droppable
type DroppableProvided = {|
innerRef: (?HTMLElement) => void,
placeholder: ?ReactElement,
|};

type DroppableStateSnapshot = {|
isDraggingOver: boolean,
draggingOverWith: ?DraggableId,
|};

// Draggable
type DraggableProvided = {|
innerRef: (?HTMLElement) => void,
draggableProps: DraggableProps,
dragHandleProps: ?DragHandleProps,
|};

type DraggableStateSnapshot = {|
isDragging: boolean,
isDropAnimating: boolean,
draggingOver: ?DroppableId,
|};

export type DraggableProps = {|
style: ?DraggableStyle,
'data-react-beautiful-dnd-draggable': string,
|};
type DraggableStyle = DraggingStyle | NotDraggingStyle;
type DraggingStyle = {|
position: 'fixed',
width: number,
height: number,
boxSizing: 'border-box',
pointerEvents: 'none',
top: number,
left: number,
transition: 'none',
transform: ?string,
zIndex: ZIndex,
|};
type NotDraggingStyle = {|
transition: ?string,
transition: null | 'none',
|};

type DragHandleProps = {|
onFocus: () => void,
onBlur: () => void,
onMouseDown: (event: MouseEvent) => void,
onKeyDown: (event: KeyboardEvent) => void,
onTouchStart: (event: TouchEvent) => void,
'data-react-beautiful-dnd-drag-handle': string,
'aria-roledescription': string,
tabIndex: number,
draggable: boolean,
onDragStart: (event: DragEvent) => void,
|};
`

$3

The types are exported as part of the module so using them is as simple as:

`js
import type { DroppableProvided } from 'react-beautiful-dnd';
`

Typescript

If you are using TypeScript you can use the community maintained DefinitelyTyped type definitions. Installation instructions.

Here is an example written in typescript.

$3

We have created a sample application which exercises the flowtypes. It is a super simple React project based on react-create-app. You can use this as a reference to see how to set things up correctly.

Engineering health

$3

This codebase is typed with flowtype to promote greater internal consistency and more resilient code.

$3

This code base employs a number of different testing strategies including unit, performance and integration tests. Testing various aspects of the system helps to promote its quality and stability.

While code coverage is not a guarantee of code health, it is a good indicator. This code base currently sits at ~90% coverage.

$3

This codebase is designed to be extremely performant - it is part of its DNA. It is designed to perform the smallest amount of updates possible. You can have a read about performance work done for react-beautiful-dnd here:

- Rethinking drag and drop
- Dragging React performance forward

Size

Great care has been taken to keep the library as light as possible. It is currently ~38kb (gzip) in size. There could be a smaller net cost if you where already using one of the underlying dependencies.

Supported browsers

This library supports the standard Atlassian supported browsers for desktop:

| Desktop | Version |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Microsoft Internet Explorer(Windows) | Version 11 (Need to polyfill
Array.prototype.find`) |
| Microsoft Edge | Latest stable version supported |
| Mozilla Firefox (all platforms) | Latest stable version supported |
| Google Chrome (Windows and Mac) | Latest stable version supported |
| Safari (Mac) | Latest stable version on latest OS release supported |

| Mobile | Version |
| ------------------------ | --------------------------------------------------------- |
| Chrome (Android and iOS) | Latest stable version supported |
| Mobile Safari (iOS) | Latest stable version supported