2
2
< html >
3
3
4
4
< head >
5
- < meta charset ="UTF-8 " />
6
- < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
7
- < title > Gridstack.js React integration example</ title >
8
- < link rel ="stylesheet " href ="demo.css " />
9
- < script src ="../dist/gridstack-all.js "> </ script >
10
-
11
- <!-- Scripts to use react inside html -->
12
- < script src ="https://unpkg.com/react@16/umd/react.production.min.js "> </ script >
13
- < script src ="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js "> </ script >
14
- < script src ="https://unpkg.com/babel-standalone@6.15.0/babel.min.js "> </ script >
5
+ < meta charset ="UTF-8 " />
6
+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
7
+ < title > Gridstack.js React integration example</ title >
8
+ < link rel ="stylesheet " href ="demo.css " />
9
+ < script src ="../dist/gridstack-all.js "> </ script >
10
+
11
+ <!-- Scripts to use react inside html -->
12
+ < script src ="https://unpkg.com/react@16/umd/react.production.min.js "> </ script >
13
+ < script src ="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js "> </ script >
14
+ < script src ="https://unpkg.com/babel-standalone@6.15.0/babel.min.js "> </ script >
15
15
</ head >
16
16
17
17
< body >
18
-
19
- < div >
20
- < h2 > Controlled stack</ h2 >
21
- < div id ="controlled-stack "> </ div >
22
- </ div >
23
-
18
+ < div >
19
+ < h2 > Controlled stack</ h2 >
20
+ < div id ="controlled-stack "> </ div >
21
+ </ div >
24
22
</ body >
25
23
26
24
< script type ="text/babel ">
27
- const { useState, useEffect, useLayoutEffect, createRef, useRef } = React
28
-
29
- const Item = ( { id } ) => < div > I am item: { id } </ div >
30
-
31
- //
32
- // Controlled example
33
- //
34
- const ControlledStack = ( { items, addItem, removeItem, id } ) => {
35
- const refs = useRef ( { } )
36
- const gridRef = useRef ( )
37
- refs . current = { }
38
-
39
- if ( Object . keys ( refs . current ) . length !== items . length ) {
40
- items . forEach ( ( { id } ) => {
41
- refs . current [ id ] = refs . current [ id ] || createRef ( )
42
- } )
43
- }
44
-
45
-
46
- useLayoutEffect ( ( ) => {
47
-
48
- gridRef . current =
49
- // gridRef.current ||
50
- GridStack . init (
51
- {
52
- float : true ,
53
- acceptWidgets : true ,
54
- } ,
55
- `.controlled-${ id } `
56
- )
57
-
58
- const grid = gridRef . current
59
-
60
- grid . on ( 'removed' , ( e , el ) => {
61
- const elId = Array . isArray ( el ) ? el [ el . length - 1 ] . id : el . id ;
62
- removeItem ( elId . split ( ':' ) [ 1 ] )
63
- } )
64
-
65
- grid . on ( 'dropped' , ( e , p , n ) => {
66
- console . log ( 'dropped' , p , n )
67
-
68
- // Remove "placeholder" item
69
- // Gridstack creates a DOM element for dropped items, those need to be removed
70
- // as they are rendered by React
71
- grid . getGridItems ( ) . forEach ( ( item ) => {
72
- const ids = item . getAttribute ( 'gs-id' ) . split ( ':' )
73
- if ( ids [ 0 ] !== id ) {
74
- grid . removeWidget ( item , true , false ) ;
75
- }
76
- } ) ;
77
- addItem ( { id : n . id . split ( ':' ) [ 1 ] , x : n . x , y : n . y , w : n . w , h : n . h } )
78
- } )
79
-
80
- grid . batchUpdate ( )
81
-
82
-
83
- items . forEach ( ( a ) => {
84
- // remove existing widgets
85
- if ( refs . current [ a . id ] && refs . current [ a . id ] . current ) {
86
- grid . removeWidget ( refs . current [ a . id ] . current , false , false )
87
- }
88
-
89
- grid . makeWidget ( refs . current [ a . id ] . current )
90
- } )
91
- grid . batchUpdate ( false )
92
-
93
-
94
-
95
- } , [ items ] )
96
-
97
- useEffect ( ( ) => {
98
- return ( ) => {
99
- // console.log('cleanup', id)
100
- // gridRef.current.destroy(false, false)
101
- // gridRef.current = null
102
- }
103
- } )
104
-
105
-
106
-
107
-
108
- return (
109
- < div style = { { width : '100%' } } >
110
- < div className = { `grid-stack controlled-${ id } ` } >
111
- { items . map ( ( item , i ) => {
112
- // console.log('render', id, item.id)
113
- return (
114
- < div ref = { refs . current [ item . id ] } key = { `${ id } -${ item . id } ` } className = { 'grid-stack-item' } gs-id = { `${ id } :${ item . id } ` } gs-w = { item . w } gs-h = { item . h } gs-x = { item . x } gs-y = { item . y } >
115
- < div className = "grid-stack-item-content" >
116
- < Item { ...item } />
117
- </ div >
118
- </ div >
119
- )
120
- } ) }
121
- </ div >
122
- < code >
123
- < pre > { JSON . stringify ( items , null , 2 ) } </ pre >
124
- </ code >
125
- </ div >
126
- )
25
+ const { useState, useEffect, useLayoutEffect, createRef, useRef } = React
26
+ const Item = ( { id } ) => < div > I am item: { id } </ div >
27
+
28
+ //
29
+ // Controlled example
30
+ //
31
+ const ControlledStack = ( { items, addItem, removeItem, id } ) => {
32
+ const refs = useRef ( { } )
33
+ const gridRef = useRef ( )
34
+ refs . current = { }
35
+
36
+ if ( Object . keys ( refs . current ) . length !== items . length ) {
37
+ items . forEach ( ( { id } ) => {
38
+ refs . current [ id ] = refs . current [ id ] || createRef ( )
39
+ } )
127
40
}
128
41
129
- const ControlledExample = ( ) => {
130
- const [ items1 , setItems1 ] = useState ( [ { id : 'item-1-1' , x : 0 , y : 0 , w : 2 , h : 2 } , { id : 'item-1-2' , x : 2 , y : 0 , w : 2 , h : 2 } ] )
131
- 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 } ] )
132
-
133
- return (
134
- < div style = { {
135
- display : 'flex'
136
- } } >
137
- < div style = { { display : 'flex' , width : '50%' } } >
138
- < ControlledStack
139
- id = 'gs1'
140
- items = { items1 }
141
- addItem = { ( item ) => {
142
- setItems1 ( [ ...items1 , item ] )
143
- } }
144
- removeItem = { ( id ) => {
145
- setItems1 ( items1 . filter ( i => i . id !== id ) )
146
- } }
147
- />
148
- </ div >
149
- < div style = { { display : 'flex' , width : '50%' } } >
150
- < ControlledStack
151
- id = 'gs2'
152
- items = { items2 }
153
- addItem = { ( item ) => {
154
- setItems2 ( [ ...items2 , item ] )
155
- } }
156
- removeItem = { ( id ) => {
157
- setItems2 ( items2 . filter ( i => i . id !== id ) )
158
- } }
159
- />
160
-
161
- </ div >
162
-
163
- </ div >
42
+ useLayoutEffect ( ( ) => {
43
+ gridRef . current =
44
+ // gridRef.current ||
45
+ GridStack . init (
46
+ {
47
+ float : true ,
48
+ acceptWidgets : true ,
49
+ } ,
50
+ `.controlled-${ id } `
164
51
)
165
- }
166
-
167
-
168
-
169
- ReactDOM . render ( < ControlledExample /> , document . getElementById ( 'controlled-stack' ) )
170
-
52
+ const grid = gridRef . current
53
+
54
+ grid . on ( 'removed' , ( e , el ) => {
55
+ const elId = Array . isArray ( el ) ? el [ el . length - 1 ] . id : el . id ;
56
+ removeItem ( elId . split ( ':' ) [ 1 ] )
57
+ } )
58
+
59
+ grid . on ( 'dropped' , ( e , p , n ) => {
60
+ console . log ( 'dropped' , p , n )
61
+ // Remove "placeholder" item
62
+ // Gridstack creates a DOM element for dropped items, those need to be removed
63
+ // as they are rendered by React
64
+ grid . getGridItems ( ) . forEach ( ( item ) => {
65
+ const ids = item . getAttribute ( 'gs-id' ) . split ( ':' )
66
+ if ( ids [ 0 ] !== id ) {
67
+ grid . removeWidget ( item , true , false ) ;
68
+ }
69
+ } ) ;
70
+ addItem ( { id : n . id . split ( ':' ) [ 1 ] , x : n . x , y : n . y , w : n . w , h : n . h } )
71
+ } )
72
+
73
+ grid . batchUpdate ( )
74
+ items . forEach ( ( a ) => {
75
+ // remove existing widgets
76
+ if ( refs . current [ a . id ] && refs . current [ a . id ] . current ) {
77
+ grid . removeWidget ( refs . current [ a . id ] . current , false , false )
78
+ }
79
+ grid . makeWidget ( refs . current [ a . id ] . current )
80
+ } )
81
+ grid . batchUpdate ( false )
82
+
83
+ } , [ items ] )
84
+
85
+ useEffect ( ( ) => {
86
+ return ( ) => {
87
+ // console.log('cleanup', id)
88
+ // gridRef.current.destroy(false, false)
89
+ // gridRef.current = null
90
+ }
91
+ } )
92
+
93
+ return (
94
+ < div style = { { width : '100%' } } >
95
+ < div className = { `grid-stack controlled-${ id } ` } >
96
+ { items . map ( ( item , i ) => {
97
+ // console.log('render', id, item.id)
98
+ return (
99
+ < div ref = { refs . current [ item . id ] } key = { `${ id } -${ item . id } ` } className = { 'grid-stack-item' } gs-id = { `${ id } :${ item . id } ` } gs-w = { item . w } gs-h = { item . h } gs-x = { item . x } gs-y = { item . y } >
100
+ < div className = "grid-stack-item-content" >
101
+ < Item { ...item } />
102
+ </ div >
103
+ </ div >
104
+ )
105
+ } ) }
106
+ </ div >
107
+ < code >
108
+ < pre > { JSON . stringify ( items , null , 2 ) } </ pre >
109
+ </ code >
110
+ </ div >
111
+ )
112
+ }
113
+
114
+ const ControlledExample = ( ) => {
115
+ const [ items1 , setItems1 ] = useState ( [ { id : 'item-1-1' , x : 0 , y : 0 , w : 2 , h : 2 } , { id : 'item-1-2' , x : 2 , y : 0 , w : 2 , h : 2 } ] )
116
+ 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 } ] )
117
+
118
+ return (
119
+ < div style = { { display : 'flex' } } >
120
+ < div style = { { display : 'flex' , width : '50%' } } >
121
+ < ControlledStack
122
+ id = 'gs1'
123
+ items = { items1 }
124
+ addItem = { ( item ) => {
125
+ setItems1 ( [ ...items1 , item ] )
126
+ } }
127
+ removeItem = { ( id ) => {
128
+ setItems1 ( items1 . filter ( i => i . id !== id ) )
129
+ } }
130
+ />
131
+ </ div >
132
+ < div style = { { display : 'flex' , width : '50%' } } >
133
+ < ControlledStack
134
+ id = 'gs2'
135
+ items = { items2 }
136
+ addItem = { ( item ) => {
137
+ setItems2 ( [ ...items2 , item ] )
138
+ } }
139
+ removeItem = { ( id ) => {
140
+ setItems2 ( items2 . filter ( i => i . id !== id ) )
141
+ } }
142
+ />
143
+ </ div >
144
+ </ div >
145
+ )
146
+ }
147
+
148
+ ReactDOM . render ( < ControlledExample /> , document . getElementById ( 'controlled-stack' ) )
171
149
</ script >
172
-
173
150
</ html >
0 commit comments