@@ -4,14 +4,14 @@ import dropRight from 'lodash/dropRight';
4
4
import isEmpty from 'lodash/isEmpty' ;
5
5
import isEqual from 'lodash/isEqual' ;
6
6
import values from 'lodash/values' ;
7
- import React from 'react' ;
7
+ import React , { useContext } from 'react' ;
8
8
import {
9
9
ConnectDragPreview ,
10
10
ConnectDragSource ,
11
11
ConnectDropTarget ,
12
- DragSource ,
13
- DragSourceMonitor ,
14
- DropTarget ,
12
+ DropTargetMonitor ,
13
+ useDrag ,
14
+ useDrop ,
15
15
} from 'react-dnd' ;
16
16
17
17
import { DEFAULT_CONTROLS_WITHOUT_CREATION , DEFAULT_CONTROLS_WITH_CREATION } from './buttons/defaultToolbarControls' ;
@@ -245,84 +245,78 @@ export class InternalMosaicWindow<T extends MosaicKey> extends React.Component<
245
245
} ;
246
246
}
247
247
248
- const dragSource = {
249
- beginDrag : (
250
- props : InternalMosaicWindowProps < any > ,
251
- _monitor : DragSourceMonitor ,
252
- component : InternalMosaicWindow < any > ,
253
- ) : MosaicDragItem => {
254
- if ( props . onDragStart ) {
255
- props . onDragStart ( ) ;
256
- }
257
- // TODO: Actually just delete instead of hiding
258
- // The defer is necessary as the element must be present on start for HTML DnD to not cry
259
- const hideTimer = defer ( ( ) => component . context . mosaicActions . hide ( component . props . path ) ) ;
260
- return {
261
- mosaicId : component . context . mosaicId ,
262
- hideTimer,
263
- } ;
264
- } ,
265
- endDrag : (
266
- props : InternalMosaicWindowProps < any > ,
267
- monitor : DragSourceMonitor ,
268
- component : InternalMosaicWindow < any > ,
269
- ) => {
270
- const { hideTimer } = monitor . getItem ( ) as MosaicDragItem ;
271
- // If the hide call hasn't happened yet, cancel it
272
- window . clearTimeout ( hideTimer ) ;
273
-
274
- const ownPath = component . props . path ;
275
- const dropResult : MosaicDropData = ( monitor . getDropResult ( ) || { } ) as MosaicDropData ;
276
- const { mosaicActions } = component . context ;
277
- const { position, path : destinationPath } = dropResult ;
278
- if ( position != null && destinationPath != null && ! isEqual ( destinationPath , ownPath ) ) {
279
- mosaicActions . updateTree ( createDragToUpdates ( mosaicActions . getRoot ( ) , ownPath , destinationPath , position ) ) ;
280
- if ( props . onDragEnd ) {
281
- props . onDragEnd ( 'drop' ) ;
248
+ function ConnectedInternalMosaicWindow < T extends MosaicKey = string > ( props : InternalMosaicWindowProps < T > ) {
249
+ const { mosaicActions, mosaicId } = useContext ( MosaicContext ) ;
250
+
251
+ const [ , connectDragSource , connectDragPreview ] = useDrag < MosaicDragItem > ( {
252
+ type : MosaicDragType . WINDOW ,
253
+ item : ( _monitor ) : MosaicDragItem | null => {
254
+ if ( props . onDragStart ) {
255
+ props . onDragStart ( ) ;
282
256
}
283
- } else {
284
- // TODO: restore node from captured state
285
- mosaicActions . updateTree ( [
286
- {
287
- path : dropRight ( ownPath ) ,
288
- spec : {
289
- splitPercentage : {
290
- $set : null ,
257
+ // TODO: Actually just delete instead of hiding
258
+ // The defer is necessary as the element must be present on start for HTML DnD to not cry
259
+ const hideTimer = defer ( ( ) => mosaicActions . hide ( props . path ) ) ;
260
+ return {
261
+ mosaicId : mosaicId ,
262
+ hideTimer,
263
+ } ;
264
+ } ,
265
+ end : ( item , monitor ) => {
266
+ const { hideTimer } = item ;
267
+ // If the hide call hasn't happened yet, cancel it
268
+ window . clearTimeout ( hideTimer ) ;
269
+
270
+ const ownPath = props . path ;
271
+ const dropResult : MosaicDropData = ( monitor . getDropResult ( ) || { } ) as MosaicDropData ;
272
+ const { position, path : destinationPath } = dropResult ;
273
+ if ( position != null && destinationPath != null && ! isEqual ( destinationPath , ownPath ) ) {
274
+ mosaicActions . updateTree ( createDragToUpdates ( mosaicActions . getRoot ( ) ! , ownPath , destinationPath , position ) ) ;
275
+ if ( props . onDragEnd ) {
276
+ props . onDragEnd ( 'drop' ) ;
277
+ }
278
+ } else {
279
+ // TODO: restore node from captured state
280
+ mosaicActions . updateTree ( [
281
+ {
282
+ path : dropRight ( ownPath ) ,
283
+ spec : {
284
+ splitPercentage : {
285
+ $set : undefined ,
286
+ } ,
291
287
} ,
292
288
} ,
293
- } ,
294
- ] ) ;
295
- if ( props . onDragEnd ) {
296
- props . onDragEnd ( 'reset' ) ;
289
+ ] ) ;
290
+ if ( props . onDragEnd ) {
291
+ props . onDragEnd ( 'reset' ) ;
292
+ }
297
293
}
298
- }
299
- } ,
300
- } ;
301
-
302
- const dropTarget = { } ;
303
-
304
- // Each step exported here just to keep react-hot-loader happy
305
- export const SourceConnectedInternalMosaicWindow = DragSource (
306
- MosaicDragType . WINDOW ,
307
- dragSource ,
308
- ( connect , _monitor ) : InternalDragSourceProps => ( {
309
- connectDragSource : connect . dragSource ( ) ,
310
- connectDragPreview : connect . dragPreview ( ) ,
311
- } ) ,
312
- ) ( InternalMosaicWindow ) ;
313
-
314
- export const SourceDropConnectedInternalMosaicWindow = DropTarget (
315
- MosaicDragType . WINDOW ,
316
- dropTarget ,
317
- ( connect , monitor ) : InternalDropTargetProps => ( {
318
- connectDropTarget : connect . dropTarget ( ) ,
319
- isOver : monitor . isOver ( ) ,
320
- draggedMosaicId : ( ( monitor . getItem ( ) || { } ) as MosaicDragItem ) . mosaicId ,
321
- } ) ,
322
- ) ( SourceConnectedInternalMosaicWindow as any ) ;
294
+ } ,
295
+ } ) ;
296
+
297
+ const [ { isOver, draggedMosaicId } , connectDropTarget ] = useDrop ( {
298
+ accept : MosaicDragType . WINDOW ,
299
+ collect ( monitor : DropTargetMonitor < MosaicDragItem > ) {
300
+ return {
301
+ isOver : monitor . isOver ( ) ,
302
+ draggedMosaicId : ( monitor . getItem ( ) || { } ) . mosaicId ,
303
+ } ;
304
+ } ,
305
+ } ) ;
306
+ return (
307
+ < InternalMosaicWindow
308
+ { ...props }
309
+ connectDragPreview = { connectDragPreview }
310
+ connectDragSource = { connectDragSource }
311
+ connectDropTarget = { connectDropTarget }
312
+ isOver = { isOver }
313
+ draggedMosaicId = { draggedMosaicId }
314
+ />
315
+ ) ;
316
+ }
323
317
324
318
export class MosaicWindow < T extends MosaicKey = string > extends React . PureComponent < MosaicWindowProps < T > > {
325
319
render ( ) {
326
- return < SourceDropConnectedInternalMosaicWindow { ...( this . props as InternalMosaicWindowProps < T > ) } /> ;
320
+ return < ConnectedInternalMosaicWindow < T > { ...( this . props as InternalMosaicWindowProps < T > ) } /> ;
327
321
}
328
322
}
0 commit comments