@@ -20,10 +20,15 @@ import PropTypes from 'prop-types';
20
20
import GndFormElementEditor from './gnd-form-element-editor' ;
21
21
import GndFormWarning from './gnd-form-warning' ;
22
22
import update from 'immutability-helper' ;
23
- import { Add } from '@material-ui/icons' ;
23
+ import { Add , DragHandle } from '@material-ui/icons' ;
24
24
import Button from '@material-ui/core/Button' ;
25
25
import { withStyles } from '@material-ui/core/styles' ;
26
26
import DeleteForeverIcon from '@material-ui/icons/DeleteForever' ;
27
+ import {
28
+ sortableContainer ,
29
+ sortableElement ,
30
+ sortableHandle ,
31
+ } from 'react-sortable-hoc' ;
27
32
28
33
const styles = ( theme ) => ( {
29
34
button : {
@@ -46,6 +51,19 @@ const styles = (theme) => ({
46
51
display : 'block' ,
47
52
width : '100%' ,
48
53
} ,
54
+ sortableElement : {
55
+ zIndex : 1300 ,
56
+ '&:hover div[name=sortableHandle]' : {
57
+ visibility : 'visible' ,
58
+ }
59
+ } ,
60
+ sortableHandle : {
61
+ textAlign : 'center' ,
62
+ visibility : 'hidden' ,
63
+ '&:hover' : {
64
+ cursor : 'move' ,
65
+ }
66
+ }
49
67
} ) ;
50
68
51
69
class GndFormEditor extends React . Component {
@@ -102,21 +120,65 @@ class GndFormEditor extends React.Component {
102
120
onChange ( { id : form . id , defn : undefined } ) ;
103
121
} ;
104
122
123
+ onSortEnd = ( { oldIndex, newIndex} ) => {
124
+ const { form, onChange} = this . props ;
125
+ const oldIndexElement = form . defn . elements [ oldIndex ] ;
126
+ const newIndexElement = form . defn . elements [ newIndex ] ;
127
+ onChange (
128
+ update ( form , {
129
+ defn : {
130
+ elements : {
131
+ [ oldIndex ] : { $set : newIndexElement } ,
132
+ [ newIndex ] : { $set : oldIndexElement }
133
+ }
134
+ } ,
135
+ } )
136
+ ) ;
137
+ } ;
138
+
105
139
render ( ) {
106
140
const { form, classes} = this . props ;
107
141
if ( ! form || ! form . defn || ! form . defn . elements ) {
108
142
return null ;
109
143
}
110
- const formElements = form . defn . elements . map ( ( element , idx ) => (
111
- < GndFormElementEditor
112
- key = { element . id }
113
- element = { element }
114
- onChange = { ( el ) => this . handleElementChange ( el , idx ) }
115
- />
116
- ) ) ;
144
+
145
+ const SortableHandle = sortableHandle ( ( ) =>
146
+ < div className = { classes . sortableHandle } name = "sortableHandle" >
147
+ < DragHandle fontSize = "inherit" />
148
+ </ div >
149
+ ) ;
150
+
151
+ const SortableElement = sortableElement ( ( { element, onChange} ) =>
152
+ < div className = { classes . sortableElement } >
153
+ < SortableHandle />
154
+ < GndFormElementEditor
155
+ key = { element . id }
156
+ element = { element }
157
+ onChange = { onChange }
158
+ />
159
+ </ div >
160
+ ) ;
161
+
162
+ const SortableContainer = sortableContainer ( ( { children} ) =>
163
+ < div > { children } </ div >
164
+ ) ;
165
+
117
166
return (
118
167
< React . Fragment >
119
- { formElements }
168
+ < SortableContainer
169
+ onSortEnd = { this . onSortEnd }
170
+ lockAxis = 'y'
171
+ useDragHandle
172
+ >
173
+ { form . defn . elements . map ( ( element , index ) => (
174
+ < SortableElement
175
+ key = { `item-${ index } ` }
176
+ index = { index }
177
+ element = { element }
178
+ onChange = { ( el ) => this . handleElementChange ( el , index ) }
179
+ />
180
+ ) ) }
181
+ </ SortableContainer >
120
182
< div className = { classes . bottomControls } >
121
183
< span className = { classes . bottomLeftControls } >
122
184
< Button
0 commit comments