@@ -33,9 +33,10 @@ <h2>Controlled stack</h2>
33
33
//
34
34
// Controlled example
35
35
//
36
- const ControlledStack = ( { items, addItem, removeItem, id } ) => {
36
+ const ControlledStack = ( { items, addItem, removeItem, changeItems } ) => {
37
37
const refs = useRef ( { } )
38
38
const gridRef = useRef ( )
39
+ const gridContainerRef = useRef ( null )
39
40
refs . current = { }
40
41
41
42
if ( Object . keys ( refs . current ) . length !== items . length ) {
@@ -49,13 +50,13 @@ <h2>Controlled stack</h2>
49
50
// no need to init twice (would will return same grid) or register dup events
50
51
const grid = gridRef . current = GridStack . init (
51
52
{
52
- float : true ,
53
+ float : false ,
53
54
acceptWidgets : true ,
54
55
disableOneColumnMode : true , // side-by-side and fever columns to fit smaller screens
55
56
column : 6 ,
56
57
minRow : 1 ,
57
58
} ,
58
- `.controlled- ${ id } `
59
+ gridContainerRef . current
59
60
)
60
61
. on ( 'added' , ( ev , gsItems ) => {
61
62
if ( grid . _ignoreCB ) return ;
@@ -68,45 +69,35 @@ <h2>Controlled stack</h2>
68
69
} ) ;
69
70
} )
70
71
. on ( 'removed' , ( ev , gsItems ) => {
72
+ /* Looks like a bug in GridStack */
73
+ const dirtyNodes = grid . engine . getDirtyNodes ( ) ;
74
+ if ( dirtyNodes !== undefined && dirtyNodes . length !== 0 ) {
75
+ const newItems = grid . save ( false ) ;
76
+ changeItems ( newItems ) ;
77
+ }
78
+
71
79
if ( grid . _ignoreCB ) return ;
72
80
gsItems . forEach ( n => removeItem ( n . id ) ) ;
73
81
} )
74
-
82
+ . on ( 'change' , ( ev , gsItems ) => {
83
+ const newItems = grid . save ( false ) ;
84
+ changeItems ( newItems ) ;
85
+ } )
75
86
} else {
76
87
//
77
88
// update existing grid layout, which is optimized to updates only diffs (will add new/delete items for examples)
78
89
//
79
90
const grid = gridRef . current ;
80
- const layout = [ ] ;
81
- items . forEach ( ( a ) => layout . push (
91
+ const layout = items . map ( ( a ) =>
82
92
refs . current [ a . id ] . current . gridstackNode || { ...a , el : refs . current [ a . id ] . current }
83
- ) ) ;
93
+ ) ;
84
94
grid . _ignoreCB = true ; // hack: ignore added/removed since we're the one doing the update
85
95
grid . load ( layout ) ;
86
96
delete grid . _ignoreCB ;
87
97
}
88
98
89
- // NOTE: old code is incorrect as it re-does the GS binding, but dragged item is left behind so you get dup DOM elements with same ids
90
- // grid.batchUpdate()
91
- // items.forEach((a) => {
92
- // // remove existing widgets
93
- // if (refs.current[a.id] && refs.current[a.id].current) {
94
- // grid.removeWidget(refs.current[a.id].current, false, false)
95
- // }
96
- // grid.makeWidget(refs.current[a.id].current)
97
- // })
98
- // grid.batchUpdate(false)
99
-
100
99
} , [ items ] )
101
100
102
- useEffect ( ( ) => {
103
- return ( ) => {
104
- // console.log('cleanup', id)
105
- // gridRef.current.destroy(false, false)
106
- // gridRef.current = null
107
- }
108
- } )
109
-
110
101
return (
111
102
// ********************
112
103
// NOTE: constructing DOM grid items in template when gridstack is also allowed editing (dragging between grids, or adding/removing from say a toolbar)
@@ -119,10 +110,10 @@ <h2>Controlled stack</h2>
119
110
// is not robust as things get added, and pollutes the DOM attr for default/missing entries, vs optimized code in GS.
120
111
// ********************
121
112
< div style = { { width : '100%' , marginRight : '10px' } } >
122
- < div className = { ` grid-stack controlled- ${ id } ` } >
113
+ < div className = " grid-stack" ref = { gridContainerRef } >
123
114
{ items . map ( ( item , i ) => {
124
115
return (
125
- < div ref = { refs . current [ item . id ] } key = { ` ${ id } - ${ item . id } ` } className = { ' grid-stack-item' } gs-id = { item . id } gs-w = { item . w } gs-h = { item . h } gs-x = { item . x } gs-y = { item . y } >
116
+ < div ref = { refs . current [ item . id ] } key = { item . id } className = " grid-stack-item" gs-id = { item . id } gs-w = { item . w } gs-h = { item . h } gs-x = { item . x } gs-y = { item . y } >
126
117
< div className = "grid-stack-item-content" >
127
118
< Item { ...item } />
128
119
</ div >
@@ -142,32 +133,42 @@ <h2>Controlled stack</h2>
142
133
const [ items2 , setItems2 ] = useState ( [ { id : 'item-2-1' , x : 0 , y : 0 , w : 1 , h : 1 } , { id : 'item-2-2' , x : 0 , y : 1 , w : 1 , h : 1 } , { id : 'item-2-3' , x : 1 , y : 0 , w : 1 , h : 1 } ] )
143
134
144
135
return (
145
- < div style = { { display : 'flex' } } >
146
- < div style = { { display : 'flex' , width : '50%' } } >
147
- < ControlledStack
148
- id = 'gs1'
149
- items = { items1 }
150
- addItem = { ( item ) => {
151
- setItems1 ( items => [ ...items , item ] )
152
- } }
153
- removeItem = { ( id ) => {
154
- setItems1 ( items => items . filter ( i => i . id !== id ) )
155
- } }
156
- />
157
- </ div >
158
- < div style = { { display : 'flex' , width : '50%' } } >
159
- < ControlledStack
160
- id = 'gs2'
161
- items = { items2 }
162
- addItem = { ( item ) => {
163
- setItems2 ( items => [ ...items , item ] )
164
- } }
165
- removeItem = { ( id ) => {
166
- setItems2 ( items => items . filter ( i => i . id !== id ) )
167
- } }
168
- />
136
+ < div >
137
+ < div style = { { display : 'flex' , gap : '16px' , marginBottom : '16px' } } >
138
+ < div > </ div >
139
+ </ div >
140
+
141
+ < div style = { { display : 'flex' , gap : '16px' , marginBottom : '16px' } } >
142
+ < button onClick = { ( ) => setItems1 ( items => [ ...items , { id : `item-1-${ Date . now ( ) } ` , x : 2 , y : 0 , w : 2 , h : 2 } ] ) } > Add Item to 1 grid</ button >
143
+ < button onClick = { ( ) => setItems2 ( items => [ ...items , { id : `item-2-${ Date . now ( ) } ` , x : 2 , y : 0 , w : 2 , h : 2 } ] ) } > Add Item to 2 grid</ button >
169
144
</ div >
170
- </ div >
145
+ < div style = { { display : 'flex' } } >
146
+ < div style = { { display : 'flex' , width : '50%' } } >
147
+ < ControlledStack
148
+ items = { items1 }
149
+ addItem = { ( item ) => {
150
+ setItems1 ( items => [ ...items , item ] )
151
+ } }
152
+ removeItem = { ( id ) => {
153
+ setItems1 ( items => items . filter ( i => i . id !== id ) )
154
+ } }
155
+ changeItems = { ( items ) => setItems1 ( items ) }
156
+ />
157
+ </ div >
158
+ < div style = { { display : 'flex' , width : '50%' } } >
159
+ < ControlledStack
160
+ items = { items2 }
161
+ addItem = { ( item ) => {
162
+ setItems2 ( items => [ ...items , item ] )
163
+ } }
164
+ removeItem = { ( id ) => {
165
+ setItems2 ( items => items . filter ( i => i . id !== id ) )
166
+ } }
167
+ changeItems = { ( items ) => setItems2 ( items ) }
168
+ />
169
+ </ div >
170
+ </ div >
171
+ </ div >
171
172
)
172
173
}
173
174
0 commit comments