@@ -51,10 +51,6 @@ export interface CellPosition {
51
51
y : number ;
52
52
}
53
53
54
- interface GridHTMLStyleElement extends HTMLStyleElement {
55
- _max ?: number ; // internal tracker of the max # of rows we created
56
- }
57
-
58
54
// extend with internal fields we need - TODO: move other items in here
59
55
interface InternalGridStackOptions extends GridStackOptions {
60
56
_alwaysShowResizeHandle ?: true | false | 'mobile' ; // so we can restore for save
@@ -247,8 +243,6 @@ export class GridStack {
247
243
protected _ignoreLayoutsNodeChange : boolean ;
248
244
/** @internal */
249
245
public _gsEventHandler = { } ;
250
- /** @internal */
251
- protected _styles : GridHTMLStyleElement ;
252
246
/** @internal flag to keep cells square during resize */
253
247
protected _isAutoCellHeight : boolean ;
254
248
/** @internal limit auto cell resizing method */
@@ -396,8 +390,6 @@ export class GridStack {
396
390
float : opts . float ,
397
391
maxRow : opts . maxRow ,
398
392
onChange : ( cbNodes ) => {
399
- let maxH = 0 ;
400
- this . engine . nodes . forEach ( n => { maxH = Math . max ( maxH , n . y + n . h ) } ) ;
401
393
cbNodes . forEach ( n => {
402
394
const el = n . el ;
403
395
if ( ! el ) return ;
@@ -408,12 +400,12 @@ export class GridStack {
408
400
this . _writePosAttr ( el , n ) ;
409
401
}
410
402
} ) ;
411
- this . _updateStyles ( false , maxH ) ; // false = don't recreate, just append if need be
403
+ this . _updateStyles ( ) ;
412
404
}
413
405
} ) ;
414
406
415
407
// create initial global styles BEFORE loading children so resizeToContent margin can be calculated correctly
416
- this . _updateStyles ( false , 0 ) ;
408
+ this . _updateStyles ( ) ;
417
409
418
410
if ( opts . auto ) {
419
411
this . batchUpdate ( ) ; // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check...
@@ -894,7 +886,7 @@ export class GridStack {
894
886
this . resizeToContentCheck ( ) ;
895
887
896
888
if ( update ) {
897
- this . _updateStyles ( true ) ; // true = force re-create for current # of rows
889
+ this . _updateStyles ( ) ;
898
890
}
899
891
return this ;
900
892
}
@@ -1014,8 +1006,7 @@ export class GridStack {
1014
1006
} else {
1015
1007
this . el . parentNode . removeChild ( this . el ) ;
1016
1008
}
1017
- this . _removeStylesheet ( ) ;
1018
- delete this . parentGridNode ?. subGrid ;
1009
+ if ( this . parentGridNode ) delete this . parentGridNode . subGrid ;
1019
1010
delete this . parentGridNode ;
1020
1011
delete this . opts ;
1021
1012
delete this . _placeholder ?. gridstackNode ;
@@ -1369,7 +1360,7 @@ export class GridStack {
1369
1360
// restore any sub-grid back
1370
1361
if ( n . subGrid ?. el ) {
1371
1362
itemContent . appendChild ( n . subGrid . el ) ;
1372
- if ( ! n . subGrid . opts . styleInHead ) n . subGrid . _updateStyles ( true ) ; // force create
1363
+ n . subGrid . _updateStyles ( ) ;
1373
1364
}
1374
1365
}
1375
1366
delete w . content ;
@@ -1527,7 +1518,7 @@ export class GridStack {
1527
1518
this . opts . marginTop = this . opts . marginBottom = this . opts . marginLeft = this . opts . marginRight = undefined ;
1528
1519
this . _initMargin ( ) ;
1529
1520
1530
- this . _updateStyles ( true ) ; // true = force re-create
1521
+ this . _updateStyles ( ) ;
1531
1522
1532
1523
return this ;
1533
1524
}
@@ -1607,78 +1598,31 @@ export class GridStack {
1607
1598
return this ;
1608
1599
}
1609
1600
1610
- /** @internal called to delete the current dynamic style sheet used for our layout */
1611
- protected _removeStylesheet ( ) : GridStack {
1612
-
1613
- if ( this . _styles ) {
1614
- const styleLocation = this . opts . styleInHead ? undefined : this . el . parentNode as HTMLElement ;
1615
- Utils . removeStylesheet ( this . _styleSheetClass , styleLocation ) ;
1616
- delete this . _styles ;
1617
- }
1618
- return this ;
1601
+ private setVar ( el : HTMLElement , varName : string , varValue : string ) {
1602
+ el . style . setProperty ( varName , varValue ) ;
1619
1603
}
1620
1604
1621
- /** @internal updated/create the CSS styles for row based layout and initial margin setting */
1622
- protected _updateStyles ( forceUpdate = false , maxH ?: number ) : GridStack {
1623
- // call to delete existing one if we change cellHeight / margin
1624
- if ( forceUpdate ) {
1625
- this . _removeStylesheet ( ) ;
1626
- }
1627
-
1628
- if ( maxH === undefined ) maxH = this . getRow ( ) ;
1605
+ /**
1606
+ * Updates the CSS variables (used in CSS and inline style) for row based layout and initial margin setting,
1607
+ * Variables are scoped in DOM so they works for nested grids as well
1608
+ * @internal
1609
+ */
1610
+ protected _updateStyles ( ) : GridStack {
1629
1611
this . _updateContainerHeight ( ) ;
1630
1612
1631
1613
// if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??
1632
1614
if ( this . opts . cellHeight === 0 ) {
1633
1615
return this ;
1634
1616
}
1635
1617
1636
- const cellHeight = this . opts . cellHeight as number ;
1637
- const cellHeightUnit = this . opts . cellHeightUnit ;
1638
- const prefix = `.${ this . _styleSheetClass } > .${ this . opts . itemClass } ` ;
1639
-
1640
- // create one as needed
1641
- if ( ! this . _styles ) {
1642
- // insert style to parent (instead of 'head' by default) to support WebComponent
1643
- const styleLocation = this . opts . styleInHead ? undefined : this . el . parentNode as HTMLElement ;
1644
- this . _styles = Utils . createStylesheet ( this . _styleSheetClass , styleLocation , {
1645
- nonce : this . opts . nonce ,
1646
- } ) ;
1647
- if ( ! this . _styles ) return this ;
1648
- this . _styles . _max = 0 ;
1649
-
1650
- // these are done once only
1651
- Utils . addCSSRule ( this . _styles , prefix , `height: ${ cellHeight } ${ cellHeightUnit } ` ) ;
1652
- // content margins
1653
- const top : string = this . opts . marginTop + this . opts . marginUnit ;
1654
- const bottom : string = this . opts . marginBottom + this . opts . marginUnit ;
1655
- const right : string = this . opts . marginRight + this . opts . marginUnit ;
1656
- const left : string = this . opts . marginLeft + this . opts . marginUnit ;
1657
- const content = `${ prefix } > .grid-stack-item-content` ;
1658
- const placeholder = `.${ this . _styleSheetClass } > .grid-stack-placeholder > .placeholder-content` ;
1659
- Utils . addCSSRule ( this . _styles , content , `top: ${ top } ; right: ${ right } ; bottom: ${ bottom } ; left: ${ left } ;` ) ;
1660
- Utils . addCSSRule ( this . _styles , placeholder , `top: ${ top } ; right: ${ right } ; bottom: ${ bottom } ; left: ${ left } ;` ) ;
1661
- // resize handles offset (to match margin)
1662
- Utils . addCSSRule ( this . _styles , `${ prefix } > .ui-resizable-n` , `top: ${ top } ;` ) ;
1663
- Utils . addCSSRule ( this . _styles , `${ prefix } > .ui-resizable-s` , `bottom: ${ bottom } ` ) ;
1664
- Utils . addCSSRule ( this . _styles , `${ prefix } > .ui-resizable-ne` , `right: ${ right } ; top: ${ top } ` ) ;
1665
- Utils . addCSSRule ( this . _styles , `${ prefix } > .ui-resizable-e` , `right: ${ right } ` ) ;
1666
- Utils . addCSSRule ( this . _styles , `${ prefix } > .ui-resizable-se` , `right: ${ right } ; bottom: ${ bottom } ` ) ;
1667
- Utils . addCSSRule ( this . _styles , `${ prefix } > .ui-resizable-nw` , `left: ${ left } ; top: ${ top } ` ) ;
1668
- Utils . addCSSRule ( this . _styles , `${ prefix } > .ui-resizable-w` , `left: ${ left } ` ) ;
1669
- Utils . addCSSRule ( this . _styles , `${ prefix } > .ui-resizable-sw` , `left: ${ left } ; bottom: ${ bottom } ` ) ;
1670
- }
1671
-
1672
- // now update the height specific fields
1673
- maxH = maxH || this . _styles . _max ;
1674
- if ( maxH > this . _styles . _max ) {
1675
- const getHeight = ( rows : number ) : string => ( cellHeight * rows ) + cellHeightUnit ;
1676
- for ( let i = this . _styles . _max + 1 ; i <= maxH ; i ++ ) { // start at 1
1677
- Utils . addCSSRule ( this . _styles , `${ prefix } [gs-y="${ i } "]` , `top: ${ getHeight ( i ) } ` ) ;
1678
- Utils . addCSSRule ( this . _styles , `${ prefix } [gs-h="${ i + 1 } "]` , `height: ${ getHeight ( i + 1 ) } ` ) ; // start at 2
1679
- }
1680
- this . _styles . _max = maxH ;
1681
- }
1618
+ // Set CSS var of cell height
1619
+ this . setVar ( this . el , "--gs-cell-height" , `${ this . opts . cellHeight } ${ this . opts . cellHeightUnit } ` ) ;
1620
+ // content margins
1621
+ this . setVar ( this . el , "--gs-item-margin-top" , `${ this . opts . marginTop } ${ this . opts . marginUnit } ` ) ;
1622
+ this . setVar ( this . el , "--gs-item-margin-bottom" , `${ this . opts . marginBottom } ${ this . opts . marginUnit } ` ) ;
1623
+ this . setVar ( this . el , "--gs-item-margin-right" , `${ this . opts . marginRight } ${ this . opts . marginUnit } ` ) ;
1624
+ this . setVar ( this . el , "--gs-item-margin-left" , `${ this . opts . marginLeft } ${ this . opts . marginUnit } ` ) ;
1625
+
1682
1626
return this ;
1683
1627
}
1684
1628
@@ -1738,17 +1682,28 @@ export class GridStack {
1738
1682
return this ;
1739
1683
}
1740
1684
1741
- /** @internal call to write position x,y,w,h attributes back to element */
1742
- protected _writePosAttr ( el : HTMLElement , n : GridStackPosition ) : GridStack {
1685
+ /**
1686
+ * Call to write position x,y,w,h attributes back to element
1687
+ * In addition, updates the inline top/height inline style as well
1688
+ * @internal
1689
+ */
1690
+ protected _writePosAttr ( el : HTMLElement , n : GridStackNode ) : GridStack {
1743
1691
if ( n . x !== undefined && n . x !== null ) { el . setAttribute ( 'gs-x' , String ( n . x ) ) ; }
1744
1692
if ( n . y !== undefined && n . y !== null ) { el . setAttribute ( 'gs-y' , String ( n . y ) ) ; }
1745
1693
n . w > 1 ? el . setAttribute ( 'gs-w' , String ( n . w ) ) : el . removeAttribute ( 'gs-w' ) ;
1746
1694
n . h > 1 ? el . setAttribute ( 'gs-h' , String ( n . h ) ) : el . removeAttribute ( 'gs-h' ) ;
1695
+ // Avoid overwriting the inline style of the element during drag/resize, but always update the placeholder
1696
+ if ( ( ! n . _moving && ! n . _resizing ) || this . _placeholder === el ) {
1697
+ // Set inline style, refer CSS variables
1698
+ el . style . top = `calc(${ n . y } * var(--gs-cell-height))` ;
1699
+ // height is set to --gs-cell-height by default in the main CSS, so no need to set inline style when h = 1
1700
+ el . style . height = n . h > 1 ? `calc(${ n . h } * var(--gs-cell-height))` : undefined ;
1701
+ }
1747
1702
return this ;
1748
1703
}
1749
1704
1750
1705
/** @internal call to write any default attributes back to element */
1751
- protected _writeAttr ( el : HTMLElement , node : GridStackWidget ) : GridStack {
1706
+ protected _writeAttr ( el : HTMLElement , node : GridStackNode ) : GridStack {
1752
1707
if ( ! node ) return this ;
1753
1708
this . _writePosAttr ( el , node ) ;
1754
1709
@@ -2400,7 +2355,7 @@ export class GridStack {
2400
2355
this . resizeToContentCheck ( false , node ) ;
2401
2356
if ( subGrid ) {
2402
2357
subGrid . parentGridNode = node ;
2403
- if ( ! subGrid . opts . styleInHead ) subGrid . _updateStyles ( true ) ; // re-create sub-grid styles now that we've moved
2358
+ subGrid . _updateStyles ( ) ; // re-create sub-grid styles now that we've moved
2404
2359
}
2405
2360
this . _updateContainerHeight ( ) ;
2406
2361
}
@@ -2498,6 +2453,7 @@ export class GridStack {
2498
2453
this . placeholder . remove ( ) ;
2499
2454
delete this . placeholder . gridstackNode ;
2500
2455
delete node . _moving ;
2456
+ delete node . _resizing ;
2501
2457
delete node . _event ;
2502
2458
delete node . _lastTried ;
2503
2459
const widthChanged = node . w !== node . _orig . w ;
@@ -2597,6 +2553,7 @@ export class GridStack {
2597
2553
node . _lastUiPosition = ui . position ;
2598
2554
node . _prevYPix = ui . position . top ;
2599
2555
node . _moving = ( event . type === 'dragstart' ) ; // 'dropover' are not initially moving so they can go exactly where they enter (will push stuff out of the way)
2556
+ node . _resizing = ( event . type === 'resizestart' ) ;
2600
2557
delete node . _lastTried ;
2601
2558
2602
2559
if ( event . type === 'dropover' && node . _temporaryRemoved ) {
0 commit comments