You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Aug 18, 2025. It is now read-only.
Copy file name to clipboardExpand all lines: README.md
+39-32Lines changed: 39 additions & 32 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -406,7 +406,7 @@ So how do you use the library?
406
406
407
407
In order to use drag and drop, you need to have the part of your `React` tree that you want to be able to use drag and drop in wrapped in a `DragDropContext`. It is advised to just wrap your entire application in a `DragDropContext`. Having nested `DragDropContext`'s is *not* supported. You will be able to achieve your desired conditional dragging and dropping using the props of `Droppable` and `Draggable`. You can think of `DragDropContext` as having a similar purpose to the [react-redux Provider component](https://github.com/reactjs/react-redux/blob/master/docs/api.md#provider-store)
408
408
409
-
### Prop type information
409
+
### Props
410
410
411
411
```js
412
412
type Hooks = {|
@@ -449,7 +449,6 @@ class App extends React.Component {
449
449
450
450
These are top level application events that you can use to perform your own state updates.
451
451
452
-
453
452
### `onDragStart` (optional)
454
453
455
454
This function will get notified when a drag starts. You are provided with the following details:
@@ -462,7 +461,7 @@ This function will get notified when a drag starts. You are provided with the fo
462
461
463
462
This function is *optional* and therefore does not need to be provided. It is **highly recommended** that you use this function to block updates to all `Draggable` and `Droppable` components during a drag. (See [*Best practices for `hooks`*](https://github.com/atlassian/react-beautiful-dnd#best-practices-for-hooks))
464
463
465
-
**Type information**
464
+
### `onDragStart` type information
466
465
467
466
```js
468
467
onDragStart?: (initial:DragStart) =>void
@@ -511,7 +510,7 @@ Because this library does not control your state, it is up to you to *synchronou
511
510
512
511
If you need to persist a reorder to a remote data store - update the list synchronously on the client and fire off a request in the background to persist the change. If the remote save fails it is up to you how to communicate that to the user and update, or not update, the list.
513
512
514
-
### Type information
513
+
### `onDragEnd` type information
515
514
516
515
```js
517
516
onDragEnd: (result:DropResult) =>void
@@ -572,9 +571,7 @@ When an item is moved from one list to a different list, it loses browser focus
572
571
- In the `componentDidMount` lifecycle call back check if the item needs to gain focus based on its props (such as an `autoFocus` prop)
573
572
- If focus is required - call `.focus` on the node. You can obtain the node by using `ReactDOM.findDOMNode` or monkey patching the `provided.innerRef` callback.
574
573
575
-
### Other `hooks` information
576
-
577
-
**`onDragStart` and `onDragEnd` pairing**
574
+
### `onDragStart` and `onDragEnd` pairing
578
575
579
576
We try very hard to ensure that each `onDragStart` event is paired with a single `onDragEnd` event. However, there maybe a rogue situation where this is not the case. If that occurs - it is a bug. Currently there is no mechanism to tell the library to cancel a current drag externally.
580
577
@@ -608,7 +605,7 @@ import { Droppable } from 'react-beautiful-dnd';
608
605
609
606
### Children function
610
607
611
-
The `React` children of a `Droppable` must be a function that returns a `ReactElement`.
608
+
The `React` children of a `Droppable` must be a function that returns a [`ReactElement`](https://tylermcginnis.com/react-elements-vs-react-components/).
612
609
613
610
```js
614
611
<Droppable droppableId="droppable-1">
@@ -684,13 +681,17 @@ This library supports dragging within scroll containers (DOM elements that have
684
681
1. The `Droppable` can itself be a scroll container with **no scrollable parents**
685
682
2. The `Droppable` has **one scrollable parent**
686
683
687
-
**Auto scrolling is not provided (yet!)**
684
+
### Empty `Droppable`s
685
+
686
+
It is recommended that you put a `min-height` on a vertical `Droppable` or a `min-width` on a horizontal `Droppable`. Otherwise when the `Droppable` is empty there may not be enough of a target for `Draggable` being dragged with touch or mouse inputs to be *over* the `Droppable`.
687
+
688
+
### Auto scrolling is not provided (yet!)
688
689
689
690
Currently auto scrolling of scroll containers is not part of this library. Auto scrolling is where the container automatically scrolls to make room for the dragging item as you drag near the edge of a scroll container. You are welcome to build your own auto scrolling list, or if you would you really like it as part of this library we could provide a auto scrolling `Droppable`.
690
691
691
692
Users will be able to scroll a scroll container while dragging by using their trackpad or mouse wheel.
692
693
693
-
**Keyboard dragging limitation**
694
+
### Keyboard dragging limitation
694
695
695
696
Getting keyboard dragging to work with scroll containers is quite difficult. Currently there is a limitation: you cannot drag with a keyboard beyond the visible edge of a scroll container. This limitation could be removed if we introduced auto scrolling. Scrolling a container with a mouse during a keyboard drag will cancel the drag.
696
697
@@ -769,24 +770,14 @@ Everything within the *provided* object must be applied for the `Draggable` to f
769
770
</Draggable>;
770
771
```
771
772
772
-
**Type information**
773
+
### Type information
773
774
774
775
```js
775
776
innerRef: (HTMLElement) =>void
776
777
```
777
778
778
779
- `provided.draggableStyle (?DraggableStyle)`: This is an `Object` or `null` that contains an a number of styles that needs to be applied to the `Draggable`. This 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 this object – but please do not remove or replace any of the properties.
779
780
780
-
**Ownership**
781
-
782
-
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.
783
-
784
-
**Warning: `position: fixed`**
785
-
786
-
`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`](http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/) (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. We may look into creating a portal solution where we attach the dragging element to the body rather than leave it in place. However, leaving it in place is a really nice experience for everyone. For now we will leave it as is, but feel free to raise an issue if you this is important to you.
787
-
788
-
**Usage of `draggableStyle`**
789
-
790
781
```js
791
782
<Draggable draggableId="draggable-1">
792
783
{(provided, snapshot) => (
@@ -799,11 +790,22 @@ It is a contract of this library that it owns the positioning logic of the dragg
799
790
</Draggable>;
800
791
```
801
792
802
-
**Extending with your own styles**
793
+
### Positioning ownership
794
+
795
+
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.
796
+
797
+
### Warning: `position: fixed`
798
+
799
+
`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`](http://meyerweb.com/eric/thoughts/2011/09/12/un-fixing-fixed-elements-with-css-transforms/) (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. We may look into creating a portal solution where we attach the dragging element to the body rather than leave it in place. However, leaving it in place is a really nice experience for everyone. For now we will leave it as is, but feel free to raise an issue if you this is important to you.
800
+
801
+
### Extending `draggableStyle`
802
+
803
+
If you are using inline styles you are welcome to extend the `draggableStyle` object. You are also welcome to apply the `draggableStyle` object using inline styles and use your own styling solution for the component itself - such as [styled-components](https://github.com/styled-components/styled-components).
803
804
804
805
```js
805
806
<Draggable draggable="draggable-1">
806
807
{(provided, snapshot) => {
808
+
// extending the draggableStyle with our own inline styles
@@ -820,7 +822,7 @@ It is a contract of this library that it owns the positioning logic of the dragg
820
822
</Draggable>;
821
823
```
822
824
823
-
**Type information**
825
+
### Type information
824
826
825
827
```js
826
828
type DraggableStyle = DraggingStyle | NotDraggingStyle;
@@ -880,7 +882,7 @@ type NotDraggingStyle = {|
880
882
881
883
- `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](https://davidwalsh.name/monkey-patching) these props if you also need to respond to them. DragHandleProps will be `null` when `isDragDisabled` is set to `true`.
882
884
883
-
**Type information**
885
+
### Type information
884
886
885
887
```js
886
888
type DragHandleProps = {|
@@ -895,7 +897,7 @@ type DragHandleProps = {|
895
897
|};
896
898
```
897
899
898
-
**Standard example**
900
+
### Example: standard
899
901
900
902
```js
901
903
<Draggable draggableId="draggable-1">
@@ -914,7 +916,9 @@ type DragHandleProps = {|
914
916
</Draggable>;
915
917
```
916
918
917
-
**Custom drag handle**
919
+
### Example: custom drag handle
920
+
921
+
Controlling a whole draggable by just a part of it
918
922
919
923
```js
920
924
<Draggable draggableId="draggable-1">
@@ -930,9 +934,9 @@ type DragHandleProps = {|
930
934
</Draggable>;
931
935
```
932
936
933
-
**Monkey patching**
937
+
### Monkey patching
934
938
935
-
> If you want to also use one of the props in `DragHandleProps`
939
+
You can override some of the `dragHandleProvided` props with your own behavior if you need to.
@@ -1010,7 +1014,8 @@ The `children` function is also provided with a small amount of state relating t
1010
1014
1011
1015
It is possible for your `Draggable` to be an interactive element such as a `<button>` or an `<a>`. However, there may be a situation where you want your `Draggable` element be the parent of an interactive element such as a `<button>` or an `<input>`. By default the child interactive element **will not be interactive**. Interacting with these nested interactive elements will be used as part of the calculation to start a drag. This is because we call `event.preventDefault()` on the `mousedown` event for the `Draggable`. Calling `preventDefault` will prevent the nested interactive element from performing its standard actions and interactions. What you will need to do is *opt out* of our standard calling of `event.preventDefault()`. By doing this the nested interactive element will not be able to be used to start a drag - but will allow the user to interact with it directly. Keep in mind - that by doing this the user will not be able to drag the `Draggable` by dragging on the interactive child element - which is probably what you want anyway. There are a few ways you can get around the standard `preventDefault` behavior. Here are some suggestions:
1012
1016
1013
-
**1. Call `event.stopPropagation()` on the interactive element `mousedown`**
1017
+
#### 1. Call `event.stopPropagation()` on the interactive element `mousedown`
1018
+
1014
1019
*This is the simpler solution*
1015
1020
1016
1021
On the child element, call `event.stopPropagation()` for the `onMouseDown` function. This will stop the event bubbling up to the `Draggable` and having `event.preventDefault()` called on it. The `Draggable` will not be aware that a `mousedown` has even occurred.
@@ -1022,7 +1027,8 @@ On the child element, call `event.stopPropagation()` for the `onMouseDown` funct
1022
1027
/>
1023
1028
```
1024
1029
1025
-
**2. Patch the `onMouseDown` event in `provided`**
1030
+
#### 2. Patch the `onMouseDown` event in `provided`
1031
+
1026
1032
*This is the more complex solution*
1027
1033
1028
1034
If you cannot use the first solution, then you can consider patching the `provided` > `onMouseDown` function. The main idea of this approach is to add additional behavior to the existing `onMouseDown` function - only calling it when it should be called.
@@ -1078,7 +1084,7 @@ class DraggableWithSelect extends Component {
1078
1084
}
1079
1085
```
1080
1086
1081
-
**3. Patch the `onKeyDown` event in `provided`**
1087
+
#### 3. Patch the `onKeyDown` event in `provided`
1082
1088
1083
1089
Similar to #2, this patch should be used on inputs inside a `Draggable`
1084
1090
@@ -1256,7 +1262,7 @@ While code coverage is [not a guarantee of code health](https://stackoverflow.co
1256
1262
1257
1263
This codebase is designed to be extremely performant - it is part of its DNA. It builds on prior investigations into `React` performance that you can read about [here](https://medium.com/@alexandereardon/performance-optimisations-for-react-applications-b453c597b191) and [here](https://medium.com/@alexandereardon/performance-optimisations-for-react-applications-round-2-2042e5c9af97). It is designed to perform the minimum number of renders required for each task.
1258
1264
1259
-
**Highlights**
1265
+
#### Highlights
1260
1266
1261
1267
- using connected-components with memoization to ensure the only components that render are the ones that need to - thanks [`react-redux`](https://github.com/reactjs/react-redux), [`reselect`](https://github.com/reactjs/reselect) and [`memoize-one`](https://github.com/alexreardon/memoize-one)
1262
1268
- all movements are throttled with a [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) - thanks [`raf-schd`](https://github.com/alexreardon/raf-schd)
@@ -1289,6 +1295,7 @@ This library supports the standard [Atlassian supported browsers](https://conflu
1289
1295
## Translations
1290
1296
1291
1297
The documentation for this library is also available in other languages:
These translations are maintained by the community and are not reviewed or maintained by the maintainers of this library. Please raise issues on the respective translations if you would like to have them updated.
0 commit comments