@@ -5,70 +5,56 @@ sidebar_label: React Beautiful DND
5
5
slug : /react-beautiful-dnd/
6
6
---
7
7
8
- The example below integrates React Virtuoso with [ React Beautiful DND] ( https://github.com/atlassian/react-beautiful-dnd ) .
8
+ The example below integrates React Virtuoso with the maintained fork of [ React Beautiful DND] ( https://github.com/atlassian/react-beautiful-dnd ) , [ hello-pangea/dnd] ( https://github.com/hello-pangea/dnd ) .
9
+ The example works with Beautiful DND too, but causes warnings with StrictMode.
9
10
10
11
``` jsx live import=react-beautiful-dnd
11
- import React , { useCallback , useEffect , useState } from ' react'
12
- import ReactDOM from ' react-dom'
13
- import { Virtuoso } from ' react-virtuoso'
14
- import { DragDropContext , Droppable , Draggable } from ' react-beautiful-dnd'
12
+ import React , { useEffect , useState } from " react" ;
13
+ import ReactDOM from " react-dom" ;
14
+ import { Virtuoso } from " react-virtuoso" ;
15
+ // Works with react-beautiful-dnd, too, but causes issues with StrictMode
16
+ import { DragDropContext , Droppable , Draggable } from " @hello-pangea/dnd" ;
15
17
16
18
// Virtuoso's resize observer can this error,
17
19
// which is caught by DnD and aborts dragging.
18
- window .addEventListener (' error' , (e ) => {
19
- if (e .message === ' ResizeObserver loop completed with undelivered notifications.' || e .message === ' ResizeObserver loop limit exceeded' ) {
20
- e .stopImmediatePropagation ()
20
+ window .addEventListener (" error" , (e ) => {
21
+ if (
22
+ e .message ===
23
+ " ResizeObserver loop completed with undelivered notifications." ||
24
+ e .message === " ResizeObserver loop limit exceeded"
25
+ ) {
26
+ e .stopImmediatePropagation ();
21
27
}
22
- })
28
+ });
23
29
24
30
// Generate our initial big data set
25
31
const initial = Array .from ({ length: 1000 }, (_ , k ) => ({
26
32
id: ` id:${ k} ` ,
27
- text: ` item ${ k} ` ,
28
- }))
33
+ text: ` item ${ k} `
34
+ }));
29
35
30
36
function reorder (list , startIndex , endIndex ) {
31
- const result = Array .from (list)
32
- const [removed ] = result .splice (startIndex, 1 )
33
- result .splice (endIndex, 0 , removed)
37
+ const result = Array .from (list);
38
+ const [removed ] = result .splice (startIndex, 1 );
39
+ result .splice (endIndex, 0 , removed);
34
40
35
- return result
41
+ return result;
36
42
}
37
43
38
44
function Item ({ provided, item, isDragging }) {
39
45
return (
40
- < div style= {{ paddingBottom: ' 8px' }}>
46
+ < div style= {{ paddingBottom: " 8px" }}>
41
47
< div
42
48
{... provided .draggableProps }
43
49
{... provided .dragHandleProps }
44
50
ref= {provided .innerRef }
45
51
style= {provided .draggableProps .style }
46
- className= {` item ${ isDragging ? ' is-dragging' : ' ' } ` }
52
+ className= {` item ${ isDragging ? " is-dragging" : " " } ` }
47
53
>
48
54
{item .text }
49
55
< / div>
50
56
< / div>
51
- )
52
- }
53
-
54
- const HeightPreservingItem = ({ children, ... props }) => {
55
- const [size , setSize ] = useState (0 )
56
- const knownSize = props[' data-known-size' ]
57
- useEffect (() => {
58
- setSize ((prevSize ) => {
59
- return knownSize == 0 ? prevSize : knownSize
60
- })
61
- }, [knownSize])
62
- return (
63
- < div
64
- {... props}
65
- className= " height-preserving-container"
66
- // check styling in the style tag below
67
- style= {{ ' --child-height' : ` ${ size} px` , }}
68
- >
69
- {children}
70
- < / div>
71
- )
57
+ );
72
58
}
73
59
74
60
export default function App () {
@@ -89,46 +75,67 @@ export default function App() {
89
75
[setItems]
90
76
)
91
77
78
+ const HeightPreservingItem = React .useCallback (({ children, ... props }) => {
79
+ const [size , setSize ] = useState (0 );
80
+ const knownSize = props[" data-known-size" ];
81
+ useEffect (() => {
82
+ setSize ((prevSize ) => {
83
+ return knownSize == 0 ? prevSize : knownSize;
84
+ });
85
+ }, [knownSize]);
86
+ return (
87
+ < div
88
+ {... props}
89
+ className= " height-preserving-container"
90
+ style= {{
91
+ " --child-height" : ` ${ size} px`
92
+ }}
93
+ >
94
+ {children}
95
+ < / div>
96
+ );
97
+ }, []);
98
+
92
99
return (
93
100
< div style= {{ padding: ' 1rem' }}>
94
101
< style>
95
- {`
96
- .height-preserving-container:empty {
97
- min-height: calc(var(--child-height));
98
- box-sizing: border-box;
99
- }
100
- ` }
101
- < / style>
102
- < DragDropContext onDragEnd= {onDragEnd}>
103
- < Droppable
104
- droppableId= " droppable"
105
- mode= " virtual"
106
- renderClone= {(provided , snapshot , rubric ) => (
107
- < Item provided= {provided} isDragging= {snapshot .isDragging } item= {items[rubric .source .index ]} / >
108
- )}
109
- >
102
+ {`
103
+ .height-preserving-container:empty {
104
+ min-height: calc(var(--child-height));
105
+ box-sizing: border-box;
106
+ }
107
+ ` }
108
+ < / style>
109
+ < DragDropContext onDragEnd= {onDragEnd}>
110
+ < Droppable
111
+ droppableId= " droppable"
112
+ mode= " virtual"
113
+ renderClone= {(provided , snapshot , rubric ) => (
114
+ < Item provided= {provided} isDragging= {snapshot .isDragging } item= {items[rubric .source .index ]} / >
115
+ )}
116
+ >
110
117
{(provided ) => {
111
118
return (
112
119
< Virtuoso
113
120
components= {{
114
- Item: HeightPreservingItem,
121
+ Item: HeightPreservingItem
115
122
}}
116
123
scrollerRef= {provided .innerRef }
117
124
data= {items}
118
125
style= {{ width: 300 , height: 500 }}
119
126
itemContent= {(index , item ) => {
120
127
return (
121
- < Draggable draggableId= {item .id } index= {index} key= {item .id }>
122
- {(provided ) => < Item provided= {provided} item= {item} isDragging= {false } / > }
128
+ < Draggable draggableId= {item .id } index= {index} key= {item .id } >
129
+ {(provided ) => ( < Item provided= {provided} item= {item} isDragging= {false } / > ) }
123
130
< / Draggable>
124
- )
131
+ );
125
132
}}
126
133
/ >
127
- )
134
+ );
128
135
}}
129
136
< / Droppable>
130
137
< / DragDropContext>
131
138
< / div>
132
- )
139
+ );
133
140
}
134
141
```
0 commit comments