@@ -51,10 +51,6 @@ export interface CellPosition {
5151 y : number ;
5252}
5353
54- interface GridHTMLStyleElement extends HTMLStyleElement {
55- _max ?: number ; // internal tracker of the max # of rows we created
56- }
57-
5854// extend with internal fields we need - TODO: move other items in here
5955interface InternalGridStackOptions extends GridStackOptions {
6056 _alwaysShowResizeHandle ?: true | false | 'mobile' ; // so we can restore for save
@@ -247,8 +243,6 @@ export class GridStack {
247243 protected _ignoreLayoutsNodeChange : boolean ;
248244 /** @internal */
249245 public _gsEventHandler = { } ;
250- /** @internal */
251- protected _styles : GridHTMLStyleElement ;
252246 /** @internal flag to keep cells square during resize */
253247 protected _isAutoCellHeight : boolean ;
254248 /** @internal limit auto cell resizing method */
@@ -396,8 +390,6 @@ export class GridStack {
396390 float : opts . float ,
397391 maxRow : opts . maxRow ,
398392 onChange : ( cbNodes ) => {
399- let maxH = 0 ;
400- this . engine . nodes . forEach ( n => { maxH = Math . max ( maxH , n . y + n . h ) } ) ;
401393 cbNodes . forEach ( n => {
402394 const el = n . el ;
403395 if ( ! el ) return ;
@@ -408,12 +400,12 @@ export class GridStack {
408400 this . _writePosAttr ( el , n ) ;
409401 }
410402 } ) ;
411- this . _updateStyles ( false , maxH ) ; // false = don't recreate, just append if need be
403+ this . _updateStyles ( ) ;
412404 }
413405 } ) ;
414406
415407 // create initial global styles BEFORE loading children so resizeToContent margin can be calculated correctly
416- this . _updateStyles ( false , 0 ) ;
408+ this . _updateStyles ( ) ;
417409
418410 if ( opts . auto ) {
419411 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 {
894886 this . resizeToContentCheck ( ) ;
895887
896888 if ( update ) {
897- this . _updateStyles ( true ) ; // true = force re-create for current # of rows
889+ this . _updateStyles ( ) ;
898890 }
899891 return this ;
900892 }
@@ -1014,8 +1006,7 @@ export class GridStack {
10141006 } else {
10151007 this . el . parentNode . removeChild ( this . el ) ;
10161008 }
1017- this . _removeStylesheet ( ) ;
1018- delete this . parentGridNode ?. subGrid ;
1009+ if ( this . parentGridNode ) delete this . parentGridNode . subGrid ;
10191010 delete this . parentGridNode ;
10201011 delete this . opts ;
10211012 delete this . _placeholder ?. gridstackNode ;
@@ -1369,7 +1360,7 @@ export class GridStack {
13691360 // restore any sub-grid back
13701361 if ( n . subGrid ?. el ) {
13711362 itemContent . appendChild ( n . subGrid . el ) ;
1372- if ( ! n . subGrid . opts . styleInHead ) n . subGrid . _updateStyles ( true ) ; // force create
1363+ n . subGrid . _updateStyles ( ) ;
13731364 }
13741365 }
13751366 delete w . content ;
@@ -1527,7 +1518,7 @@ export class GridStack {
15271518 this . opts . marginTop = this . opts . marginBottom = this . opts . marginLeft = this . opts . marginRight = undefined ;
15281519 this . _initMargin ( ) ;
15291520
1530- this . _updateStyles ( true ) ; // true = force re-create
1521+ this . _updateStyles ( ) ;
15311522
15321523 return this ;
15331524 }
@@ -1607,78 +1598,31 @@ export class GridStack {
16071598 return this ;
16081599 }
16091600
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 ) ;
16191603 }
16201604
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 {
16291611 this . _updateContainerHeight ( ) ;
16301612
16311613 // if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ??
16321614 if ( this . opts . cellHeight === 0 ) {
16331615 return this ;
16341616 }
16351617
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+
16821626 return this ;
16831627 }
16841628
@@ -1738,17 +1682,28 @@ export class GridStack {
17381682 return this ;
17391683 }
17401684
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 {
17431691 if ( n . x !== undefined && n . x !== null ) { el . setAttribute ( 'gs-x' , String ( n . x ) ) ; }
17441692 if ( n . y !== undefined && n . y !== null ) { el . setAttribute ( 'gs-y' , String ( n . y ) ) ; }
17451693 n . w > 1 ? el . setAttribute ( 'gs-w' , String ( n . w ) ) : el . removeAttribute ( 'gs-w' ) ;
17461694 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+ }
17471702 return this ;
17481703 }
17491704
17501705 /** @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 {
17521707 if ( ! node ) return this ;
17531708 this . _writePosAttr ( el , node ) ;
17541709
@@ -2400,7 +2355,7 @@ export class GridStack {
24002355 this . resizeToContentCheck ( false , node ) ;
24012356 if ( subGrid ) {
24022357 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
24042359 }
24052360 this . _updateContainerHeight ( ) ;
24062361 }
@@ -2498,6 +2453,7 @@ export class GridStack {
24982453 this . placeholder . remove ( ) ;
24992454 delete this . placeholder . gridstackNode ;
25002455 delete node . _moving ;
2456+ delete node . _resizing ;
25012457 delete node . _event ;
25022458 delete node . _lastTried ;
25032459 const widthChanged = node . w !== node . _orig . w ;
@@ -2597,6 +2553,7 @@ export class GridStack {
25972553 node . _lastUiPosition = ui . position ;
25982554 node . _prevYPix = ui . position . top ;
25992555 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' ) ;
26002557 delete node . _lastTried ;
26012558
26022559 if ( event . type === 'dropover' && node . _temporaryRemoved ) {
0 commit comments