88import { GridStackEngine } from './gridstack-engine' ;
99import { Utils , HeightData , obsolete } from './utils' ;
1010import { gridDefaults , ColumnOptions , GridItemHTMLElement , GridStackElement , GridStackEventHandlerCallback ,
11- GridStackNode , GridStackOptions , GridStackWidget , numberOrString , DDUIData , DDDragInOpt , GridStackPosition , GridStackSubOptions } from './types' ;
11+ GridStackNode , GridStackWidget , numberOrString , DDUIData , DDDragInOpt , GridStackPosition , GridStackOptions } from './types' ;
1212
1313// export all dependent file as well to make it easier for users to just import the main file
1414export * from './types' ;
@@ -35,8 +35,7 @@ export interface CellPosition {
3535}
3636
3737interface GridCSSStyleSheet extends CSSStyleSheet {
38- _id ?: string ; // random id we will use to style us
39- _max ?: number ; // internal tracker of the max # of rows we created\
38+ _max ?: number ; // internal tracker of the max # of rows we created
4039}
4140
4241/**
@@ -164,6 +163,9 @@ export class GridStack {
164163 protected _isNested ?: GridStackNode ;
165164 /** @internal unique class name for our generated CSS style sheet */
166165 protected _styleSheetClass ?: string ;
166+ /** @internal true if we got created by drag over gesture, so we can removed on drag out (temporary) */
167+ public _isTemp ?: boolean ;
168+
167169
168170 /** @internal create placeholder DIV as needed */
169171 public get placeholder ( ) : HTMLElement {
@@ -295,7 +297,7 @@ export class GridStack {
295297 this . opts . alwaysShowResizeHandle = isTouch ;
296298 }
297299
298- this . _styleSheetClass = 'grid-stack-instance-' + ( Math . random ( ) * 10000 ) . toFixed ( 0 )
300+ this . _styleSheetClass = 'grid-stack-instance-' + GridStackEngine . _idSeq ++ ;
299301 this . el . classList . add ( this . _styleSheetClass ) ;
300302
301303 this . _setStaticClass ( ) ;
@@ -351,7 +353,7 @@ export class GridStack {
351353 delete this . opts . dragInOptions ;
352354
353355 // dynamic grids require pausing during drag to detect over to nest vs push
354- if ( this . opts . subGrid ?. createDynamic && ! DDManager . pauseDrag ) DDManager . pauseDrag = true ;
356+ if ( this . opts . subGridDynamic && ! DDManager . pauseDrag ) DDManager . pauseDrag = true ;
355357 if ( this . opts . draggable ?. pause !== undefined ) DDManager . pauseDrag = this . opts . draggable . pause ;
356358
357359 this . _setupRemoveDrop ( ) ;
@@ -440,15 +442,17 @@ export class GridStack {
440442 * @param el gridItem element to convert
441443 * @param ops (optional) sub-grid options, else default to node, then parent settings, else defaults
442444 * @param nodeToAdd (optional) node to add to the newly created sub grid (used when dragging over existing regular item)
445+ * @returns newly created grid
443446 */
444- public makeSubGrid ( el : GridItemHTMLElement , ops ?: GridStackSubOptions , nodeToAdd ?: GridStackNode , saveContent = true ) : GridStack {
447+ public makeSubGrid ( el : GridItemHTMLElement , ops ?: GridStackOptions , nodeToAdd ?: GridStackNode , saveContent = true ) : GridStack {
445448 let node = el . gridstackNode ;
446449 if ( ! node ) {
447450 node = this . makeWidget ( el ) . gridstackNode ;
448451 }
449452 if ( ( node . subGrid as GridStack ) ?. el ) return node . subGrid as GridStack ; // already done
450453
451- ops = Utils . cloneDeep ( ops || node . subGrid as GridStackOptions || this . opts . subGrid || this . opts ) ;
454+ ops = Utils . cloneDeep ( ops || node . subGrid as GridStackOptions || { ...this . opts . subGrid , children : undefined } ) ;
455+ ops . subGrid = Utils . cloneDeep ( ops ) ; // carry nesting settings to next one down
452456 node . subGrid = ops ;
453457
454458 // if column special case it set, remember that flag and set default
@@ -486,27 +490,51 @@ export class GridStack {
486490 style . transition = 'none' ; // show up instantly so we don't see scrollbar with nodeToAdd
487491 this . update ( node . el , { w, h} ) ;
488492 setTimeout ( ( ) => style . transition = null ) ; // recover animation
489- ops . isTemp = true ; // prevent re-nesting as we add over
490493 }
491494
492- let grid = node . subGrid = GridStack . addGrid ( content , ops ) ;
493- if ( autoColumn ) node . subGrid . _autoColumn = true ;
495+ let subGrid = node . subGrid = GridStack . addGrid ( content , ops ) ;
496+ if ( nodeToAdd ?. _moving ) subGrid . _isTemp = true ; // prevent re-nesting as we add over
497+ if ( autoColumn ) subGrid . _autoColumn = true ;
494498
495499 // add the original content back as a child of hte newly created grid
496500 if ( saveContent ) {
497- grid . addWidget ( newItem , newItemOpt ) ;
501+ subGrid . addWidget ( newItem , newItemOpt ) ;
498502 }
499503
500504 // now add any additional node
501505 if ( nodeToAdd ) {
502506 if ( nodeToAdd . _moving ) {
503507 // create an artificial event even for the just created grid to receive this item
504- window . setTimeout ( ( ) => Utils . simulateMouseEvent ( nodeToAdd . _event , 'mouseenter' , grid . el ) , 0 ) ;
508+ window . setTimeout ( ( ) => Utils . simulateMouseEvent ( nodeToAdd . _event , 'mouseenter' , subGrid . el ) , 0 ) ;
505509 } else {
506- grid . addWidget ( node . el , node ) ;
510+ subGrid . addWidget ( node . el , node ) ;
507511 }
508512 }
509- return grid ;
513+ return subGrid ;
514+ }
515+
516+ /**
517+ * called when an item was converted into a nested grid to accommodate a dragged over item, but then item leaves - return back
518+ * to the original grid-item. Also called to remove empty sub-grids when last item is dragged out (since re-creating is simple)
519+ */
520+ public removeAsSubGrid ( nodeThatRemoved ?: GridStackNode ) : void {
521+ let parentGrid = this . _isNested ?. grid ;
522+ if ( ! parentGrid ) return ;
523+
524+ parentGrid . batchUpdate ( ) ;
525+ parentGrid . removeWidget ( this . _isNested . el , true , true ) ;
526+ this . engine . nodes . forEach ( n => {
527+ // migrate any children over and offsetting by our location
528+ n . x += this . _isNested . x ;
529+ n . y += this . _isNested . y ;
530+ parentGrid . addWidget ( n . el , n ) ;
531+ } ) ;
532+ parentGrid . batchUpdate ( false ) ;
533+
534+ // create an artificial event for the original grid now that this one is gone (got a leave, but won't get enter)
535+ if ( nodeThatRemoved ) {
536+ window . setTimeout ( ( ) => Utils . simulateMouseEvent ( nodeThatRemoved . _event , 'mouseenter' , parentGrid . el ) , 0 ) ;
537+ }
510538 }
511539
512540 /**
@@ -712,7 +740,7 @@ export class GridStack {
712740 this . opts . cellHeight = data . h ;
713741
714742 if ( update ) {
715- this . _updateStyles ( true , this . getRow ( ) ) ; // true = force re-create, for that # of rows
743+ this . _updateStyles ( true ) ; // true = force re-create for current # of rows
716744 }
717745 return this ;
718746 }
@@ -1218,7 +1246,7 @@ export class GridStack {
12181246 protected _removeStylesheet ( ) : GridStack {
12191247
12201248 if ( this . _styles ) {
1221- Utils . removeStylesheet ( this . _styles . _id ) ;
1249+ Utils . removeStylesheet ( this . _styleSheetClass ) ;
12221250 delete this . _styles ;
12231251 }
12241252 return this ;
@@ -1231,6 +1259,7 @@ export class GridStack {
12311259 this . _removeStylesheet ( ) ;
12321260 }
12331261
1262+ if ( ! maxH ) maxH = this . getRow ( ) ;
12341263 this . _updateContainerHeight ( ) ;
12351264
12361265 // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??
@@ -1244,12 +1273,10 @@ export class GridStack {
12441273
12451274 // create one as needed
12461275 if ( ! this . _styles ) {
1247- let id = 'gridstack-style-' + ( Math . random ( ) * 100000 ) . toFixed ( ) ;
12481276 // insert style to parent (instead of 'head' by default) to support WebComponent
12491277 let styleLocation = this . opts . styleInHead ? undefined : this . el . parentNode as HTMLElement ;
1250- this . _styles = Utils . createStylesheet ( id , styleLocation ) ;
1278+ this . _styles = Utils . createStylesheet ( this . _styleSheetClass , styleLocation ) ;
12511279 if ( ! this . _styles ) return this ;
1252- this . _styles . _id = id ;
12531280 this . _styles . _max = 0 ;
12541281
12551282 // these are done once only
0 commit comments