8
8
import { GridStackEngine } from './gridstack-engine' ;
9
9
import { Utils , HeightData , obsolete } from './utils' ;
10
10
import { 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' ;
12
12
13
13
// export all dependent file as well to make it easier for users to just import the main file
14
14
export * from './types' ;
@@ -35,8 +35,7 @@ export interface CellPosition {
35
35
}
36
36
37
37
interface 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
40
39
}
41
40
42
41
/**
@@ -164,6 +163,9 @@ export class GridStack {
164
163
protected _isNested ?: GridStackNode ;
165
164
/** @internal unique class name for our generated CSS style sheet */
166
165
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
+
167
169
168
170
/** @internal create placeholder DIV as needed */
169
171
public get placeholder ( ) : HTMLElement {
@@ -295,7 +297,7 @@ export class GridStack {
295
297
this . opts . alwaysShowResizeHandle = isTouch ;
296
298
}
297
299
298
- this . _styleSheetClass = 'grid-stack-instance-' + ( Math . random ( ) * 10000 ) . toFixed ( 0 )
300
+ this . _styleSheetClass = 'grid-stack-instance-' + GridStackEngine . _idSeq ++ ;
299
301
this . el . classList . add ( this . _styleSheetClass ) ;
300
302
301
303
this . _setStaticClass ( ) ;
@@ -351,7 +353,7 @@ export class GridStack {
351
353
delete this . opts . dragInOptions ;
352
354
353
355
// 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 ;
355
357
if ( this . opts . draggable ?. pause !== undefined ) DDManager . pauseDrag = this . opts . draggable . pause ;
356
358
357
359
this . _setupRemoveDrop ( ) ;
@@ -440,15 +442,17 @@ export class GridStack {
440
442
* @param el gridItem element to convert
441
443
* @param ops (optional) sub-grid options, else default to node, then parent settings, else defaults
442
444
* @param nodeToAdd (optional) node to add to the newly created sub grid (used when dragging over existing regular item)
445
+ * @returns newly created grid
443
446
*/
444
- public makeSubGrid ( el : GridItemHTMLElement , ops ?: GridStackSubOptions , nodeToAdd ?: GridStackNode , saveContent = true ) : GridStack {
447
+ public makeSubGrid ( el : GridItemHTMLElement , ops ?: GridStackOptions , nodeToAdd ?: GridStackNode , saveContent = true ) : GridStack {
445
448
let node = el . gridstackNode ;
446
449
if ( ! node ) {
447
450
node = this . makeWidget ( el ) . gridstackNode ;
448
451
}
449
452
if ( ( node . subGrid as GridStack ) ?. el ) return node . subGrid as GridStack ; // already done
450
453
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
452
456
node . subGrid = ops ;
453
457
454
458
// if column special case it set, remember that flag and set default
@@ -486,27 +490,51 @@ export class GridStack {
486
490
style . transition = 'none' ; // show up instantly so we don't see scrollbar with nodeToAdd
487
491
this . update ( node . el , { w, h} ) ;
488
492
setTimeout ( ( ) => style . transition = null ) ; // recover animation
489
- ops . isTemp = true ; // prevent re-nesting as we add over
490
493
}
491
494
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 ;
494
498
495
499
// add the original content back as a child of hte newly created grid
496
500
if ( saveContent ) {
497
- grid . addWidget ( newItem , newItemOpt ) ;
501
+ subGrid . addWidget ( newItem , newItemOpt ) ;
498
502
}
499
503
500
504
// now add any additional node
501
505
if ( nodeToAdd ) {
502
506
if ( nodeToAdd . _moving ) {
503
507
// 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 ) ;
505
509
} else {
506
- grid . addWidget ( node . el , node ) ;
510
+ subGrid . addWidget ( node . el , node ) ;
507
511
}
508
512
}
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
+ }
510
538
}
511
539
512
540
/**
@@ -712,7 +740,7 @@ export class GridStack {
712
740
this . opts . cellHeight = data . h ;
713
741
714
742
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
716
744
}
717
745
return this ;
718
746
}
@@ -1218,7 +1246,7 @@ export class GridStack {
1218
1246
protected _removeStylesheet ( ) : GridStack {
1219
1247
1220
1248
if ( this . _styles ) {
1221
- Utils . removeStylesheet ( this . _styles . _id ) ;
1249
+ Utils . removeStylesheet ( this . _styleSheetClass ) ;
1222
1250
delete this . _styles ;
1223
1251
}
1224
1252
return this ;
@@ -1231,6 +1259,7 @@ export class GridStack {
1231
1259
this . _removeStylesheet ( ) ;
1232
1260
}
1233
1261
1262
+ if ( ! maxH ) maxH = this . getRow ( ) ;
1234
1263
this . _updateContainerHeight ( ) ;
1235
1264
1236
1265
// 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 {
1244
1273
1245
1274
// create one as needed
1246
1275
if ( ! this . _styles ) {
1247
- let id = 'gridstack-style-' + ( Math . random ( ) * 100000 ) . toFixed ( ) ;
1248
1276
// insert style to parent (instead of 'head' by default) to support WebComponent
1249
1277
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 ) ;
1251
1279
if ( ! this . _styles ) return this ;
1252
- this . _styles . _id = id ;
1253
1280
this . _styles . _max = 0 ;
1254
1281
1255
1282
// these are done once only
0 commit comments