@@ -163,6 +163,15 @@ export default class Draggable extends React.Component {
163
163
isElementSVG : false
164
164
} ;
165
165
166
+ componentWillMount ( ) {
167
+ if ( this . props . position && ! ( this . props . onDrag || this . props . onStop ) ) {
168
+ // eslint-disable-next-line
169
+ console . warn ( 'A `position` was applied to this <Draggable>, without drag handlers. This will make this ' +
170
+ 'component effectively undraggable. Please attach `onDrag` or `onStop` handlers so you can adjust the ' +
171
+ '`position` of this element.' ) ;
172
+ }
173
+ }
174
+
166
175
componentDidMount ( ) {
167
176
// Check to see if the element passed is an instanceof SVGElement
168
177
if ( ReactDOM . findDOMNode ( this ) instanceof SVGElement ) {
@@ -250,30 +259,40 @@ export default class Draggable extends React.Component {
250
259
251
260
log ( 'Draggable: onDragStop: %j' , coreData ) ;
252
261
253
- this . setState ( {
262
+ const newState : $Shape < DraggableState > = {
254
263
dragging : false ,
255
264
slackX : 0 ,
256
265
slackY : 0
257
- } ) ;
266
+ } ;
267
+
268
+ // If this is a controlled component, the result of this operation will be to
269
+ // revert back to the old position. We expect a handler on `onDragStop`, at the least.
270
+ const controlled = Boolean(this.props.position);
271
+ if (controlled) {
272
+ const { x, y} = this . props . position ;
273
+ newState . x = x ;
274
+ newState . y = y ;
275
+ }
276
+
277
+ this . setState ( newState ) ;
258
278
} ;
259
279
260
280
render ( ) : React . Element {
261
281
let style = { } , svgTransform = null ;
262
282
263
- // Add a CSS transform to move the element around. This allows us to move the element around
264
- // without worrying about whether or not it is relatively or absolutely positioned.
265
- // If the item you are dragging already has a transform set, wrap it in a <span> so <Draggable>
266
- // has a clean slate.
283
+ // If this is controlled, we don't want to move it - unless it's dragging.
267
284
const controlled = Boolean ( this . props . position ) ;
285
+ const draggable = ! controlled || this . state . dragging ;
286
+
268
287
const position = this . props . position || this . props . defaultPosition ;
269
288
const transformOpts = {
270
289
// Set left if horizontal drag is enabled
271
- x : canDragX ( this ) && ! controlled ?
290
+ x : canDragX ( this ) && draggable ?
272
291
this . state . x :
273
292
position . x ,
274
293
275
294
// Set top if vertical drag is enabled
276
- y : canDragY ( this ) && ! controlled ?
295
+ y : canDragY ( this ) && draggable ?
277
296
this . state . y :
278
297
position . y
279
298
} ;
@@ -282,6 +301,10 @@ export default class Draggable extends React.Component {
282
301
if ( this . state . isElementSVG ) {
283
302
svgTransform = createSVGTransform ( transformOpts ) ;
284
303
} else {
304
+ // Add a CSS transform to move the element around. This allows us to move the element around
305
+ // without worrying about whether or not it is relatively or absolutely positioned.
306
+ // If the item you are dragging already has a transform set, wrap it in a <span> so <Draggable>
307
+ // has a clean slate.
285
308
style = createCSSTransform ( transformOpts ) ;
286
309
}
287
310
0 commit comments