@@ -6,6 +6,7 @@ import classNames from "classnames";
66import {
77 autoBindHandlers ,
88 bottom ,
9+ nodesCollide ,
910 childrenEqual ,
1011 cloneLayoutItem ,
1112 compact ,
@@ -38,7 +39,8 @@ type State = {
3839 mounted : boolean ,
3940 oldDragItem : ?LayoutItem ,
4041 oldLayout : ?Layout ,
41- oldResizeItem : ?LayoutItem
42+ oldResizeItem : ?LayoutItem ,
43+ draggingOverToolbox : boolean
4244} ;
4345
4446export type Props = {
@@ -58,6 +60,7 @@ export type Props = {
5860 maxRows : number ,
5961 isDraggable : boolean ,
6062 isResizable : boolean ,
63+ toolbox : ReactElement < any > ,
6164 preventCollision : boolean ,
6265 useCSSTransforms : boolean ,
6366
@@ -69,6 +72,7 @@ export type Props = {
6972 onResize : EventCallback ,
7073 onResizeStart : EventCallback ,
7174 onResizeStop : EventCallback ,
75+ onPutItem : EventCallback ,
7276 children : ReactChildrenArray < ReactElement < any >>
7377} ;
7478// End Types
@@ -196,7 +200,9 @@ export default class ReactGridLayout extends React.Component<Props, State> {
196200 }
197201 keys [ child . key ] = true ;
198202 } ) ;
199- }
203+ } ,
204+
205+ toolbox : PropTypes . element
200206 } ;
201207
202208 static defaultProps = {
@@ -238,9 +244,12 @@ export default class ReactGridLayout extends React.Component<Props, State> {
238244 mounted : false ,
239245 oldDragItem : null ,
240246 oldLayout : null ,
241- oldResizeItem : null
247+ oldResizeItem : null ,
248+ draggingOverToolbox : false
242249 } ;
243250
251+ toolboxRef : ?HTMLDivElement = null ;
252+
244253 constructor ( props : Props , context : any ) : void {
245254 super ( props , context ) ;
246255 autoBindHandlers ( this , [
@@ -372,6 +381,15 @@ export default class ReactGridLayout extends React.Component<Props, State> {
372381 cols
373382 ) ;
374383
384+ if ( this . toolboxRef ) {
385+ let draggingOverToolbox = false ;
386+ if ( nodesCollide ( node , this . toolboxRef ) ) {
387+ placeholder = null ;
388+ draggingOverToolbox = true ;
389+ }
390+ this . setState ( { draggingOverToolbox } ) ;
391+ }
392+
375393 this . props . onDrag ( layout , oldDragItem , l , placeholder , e , node ) ;
376394
377395 this . setState ( {
@@ -408,6 +426,15 @@ export default class ReactGridLayout extends React.Component<Props, State> {
408426 cols
409427 ) ;
410428
429+ if ( this . toolboxRef ) {
430+ if ( nodesCollide ( node , this . toolboxRef ) ) {
431+ layout = layout . filter ( ( { i } ) => i !== l . i ) ;
432+ if ( this . props . onPutItem ) {
433+ this . props . onPutItem ( layout , oldDragItem , l , null , e , node ) ;
434+ }
435+ }
436+ }
437+
411438 this . props . onDragStop ( layout , oldDragItem , l , null , e , node ) ;
412439
413440 // Set state
@@ -417,7 +444,8 @@ export default class ReactGridLayout extends React.Component<Props, State> {
417444 activeDrag : null ,
418445 layout : newLayout ,
419446 oldDragItem : null ,
420- oldLayout : null
447+ oldLayout : null ,
448+ draggingOverToolbox : false
421449 } ) ;
422450
423451 this . onLayoutMaybeChanged ( newLayout , oldLayout ) ;
@@ -453,14 +481,17 @@ export default class ReactGridLayout extends React.Component<Props, State> {
453481 // to find collisions faster
454482 let hasCollisions ;
455483 if ( preventCollision ) {
456- const collisions = getAllCollisions ( layout , { ...l , w, h } ) . filter ( ( layoutItem ) => layoutItem . i !== l . i ) ;
484+ const collisions = getAllCollisions ( layout , { ...l , w, h } ) . filter (
485+ layoutItem => layoutItem . i !== l . i
486+ ) ;
457487 hasCollisions = collisions . length > 0 ;
458488
459489 // If we're colliding, we need adjust the placeholder.
460490 if ( hasCollisions ) {
461491 // adjust w && h to maximum allowed space
462- let leastX = Infinity , leastY = Infinity ;
463- collisions . forEach ( ( layoutItem ) => {
492+ let leastX = Infinity ,
493+ leastY = Infinity ;
494+ collisions . forEach ( layoutItem => {
464495 if ( layoutItem . x > l . x ) leastX = Math . min ( leastX , layoutItem . x ) ;
465496 if ( layoutItem . y > l . y ) leastY = Math . min ( leastY , layoutItem . y ) ;
466497 } ) ;
@@ -625,20 +656,35 @@ export default class ReactGridLayout extends React.Component<Props, State> {
625656 }
626657
627658 render ( ) {
628- const { className, style } = this . props ;
629-
630- const mergedClassName = classNames ( "react-grid-layout" , className ) ;
631- const mergedStyle = {
632- height : this . containerHeight ( ) ,
633- ...style
634- } ;
659+ const mergedClassName = classNames (
660+ "react-grid-layout" ,
661+ this . props . className
662+ ) ;
635663
636664 return (
637- < div className = { mergedClassName } style = { mergedStyle } >
638- { React . Children . map ( this . props . children , child =>
639- this . processGridItem ( child )
640- ) }
641- { this . placeholder ( ) }
665+ < div className = { mergedClassName } style = { this . props . style } >
666+ { this . props . toolbox ? (
667+ < div
668+ className = { classNames ( "react-grid-layout__toolbox" , {
669+ "is-active" : this . state . draggingOverToolbox
670+ } ) }
671+ ref = { elem => ( this . toolboxRef = elem ) }
672+ >
673+ { this . props . toolbox }
674+ </ div >
675+ ) : null }
676+ < div
677+ className = "react-grid-layout__grid-items"
678+ style = { {
679+ position : "relative" ,
680+ height : this . containerHeight ( )
681+ } }
682+ >
683+ { React . Children . map ( this . props . children , child =>
684+ this . processGridItem ( child )
685+ ) }
686+ { this . placeholder ( ) }
687+ </ div >
642688 </ div >
643689 ) ;
644690 }
0 commit comments