-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Removed dynamic stylesheet and migrated to CSS vars #2854
base: master
Are you sure you want to change the base?
Changes from 11 commits
bfa84fa
cf62b1d
bf7a96a
aab0fb2
9cb7ef5
db2615e
6bad283
b5624d9
60c75bb
9b013fa
57d75a3
d618ef5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,10 +51,6 @@ export interface CellPosition { | |
y: number; | ||
} | ||
|
||
interface GridCSSStyleSheet extends CSSStyleSheet { | ||
_max?: number; // internal tracker of the max # of rows we created | ||
} | ||
|
||
// extend with internal fields we need - TODO: move other items in here | ||
interface InternalGridStackOptions extends GridStackOptions { | ||
_alwaysShowResizeHandle?: true | false | 'mobile'; // so we can restore for save | ||
|
@@ -247,8 +243,6 @@ export class GridStack { | |
protected _ignoreLayoutsNodeChange: boolean; | ||
/** @internal */ | ||
public _gsEventHandler = {}; | ||
/** @internal */ | ||
protected _styles: GridCSSStyleSheet; | ||
/** @internal flag to keep cells square during resize */ | ||
protected _isAutoCellHeight: boolean; | ||
/** @internal limit auto cell resizing method */ | ||
|
@@ -395,8 +389,6 @@ export class GridStack { | |
float: opts.float, | ||
maxRow: opts.maxRow, | ||
onChange: (cbNodes) => { | ||
let maxH = 0; | ||
this.engine.nodes.forEach(n => { maxH = Math.max(maxH, n.y + n.h) }); | ||
cbNodes.forEach(n => { | ||
const el = n.el; | ||
if (!el) return; | ||
|
@@ -407,12 +399,12 @@ export class GridStack { | |
this._writePosAttr(el, n); | ||
} | ||
}); | ||
this._updateStyles(false, maxH); // false = don't recreate, just append if need be | ||
this._updateStyles(); | ||
} | ||
}); | ||
|
||
// create initial global styles BEFORE loading children so resizeToContent margin can be calculated correctly | ||
this._updateStyles(false, 0); | ||
this._updateStyles(); | ||
|
||
if (opts.auto) { | ||
this.batchUpdate(); // prevent in between re-layout #1535 TODO: this only set float=true, need to prevent collision check... | ||
|
@@ -862,7 +854,7 @@ export class GridStack { | |
this.resizeToContentCheck(); | ||
|
||
if (update) { | ||
this._updateStyles(true); // true = force re-create for current # of rows | ||
this._updateStyles(); | ||
} | ||
return this; | ||
} | ||
|
@@ -979,7 +971,6 @@ export class GridStack { | |
} else { | ||
this.el.parentNode.removeChild(this.el); | ||
} | ||
this._removeStylesheet(); | ||
if (this.parentGridNode) delete this.parentGridNode.subGrid; | ||
delete this.parentGridNode; | ||
delete this.opts; | ||
|
@@ -1317,7 +1308,7 @@ export class GridStack { | |
// restore any sub-grid back | ||
if (n.subGrid?.el) { | ||
itemContent.appendChild(n.subGrid.el); | ||
if (!n.subGrid.opts.styleInHead) n.subGrid._updateStyles(true); // force create | ||
n.subGrid._updateStyles(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. again if we skipped redoing styles that were global, then most likely we don't need to do anything... need to go though all calls and only call when what we upate changes... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above, since my changes are quite conservative, I don't feel that the performances are hurting so much in removing the line. Probably better to split _updateStyles and extract _updateContainerHeight from it? |
||
} | ||
} | ||
delete w.content; | ||
|
@@ -1467,7 +1458,7 @@ export class GridStack { | |
this.opts.marginTop = this.opts.marginBottom = this.opts.marginLeft = this.opts.marginRight = undefined; | ||
this._initMargin(); | ||
|
||
this._updateStyles(true); // true = force re-create | ||
this._updateStyles(); | ||
|
||
return this; | ||
} | ||
|
@@ -1547,78 +1538,31 @@ export class GridStack { | |
return this; | ||
} | ||
|
||
/** @internal called to delete the current dynamic style sheet used for our layout */ | ||
protected _removeStylesheet(): GridStack { | ||
|
||
if (this._styles) { | ||
const styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode as HTMLElement; | ||
Utils.removeStylesheet(this._styleSheetClass, styleLocation); | ||
delete this._styles; | ||
} | ||
return this; | ||
private setVar(el: HTMLElement, varName: string, varValue: string) { | ||
el.style.setProperty(varName, varValue); | ||
} | ||
|
||
/** @internal updated/create the CSS styles for row based layout and initial margin setting */ | ||
protected _updateStyles(forceUpdate = false, maxH?: number): GridStack { | ||
// call to delete existing one if we change cellHeight / margin | ||
if (forceUpdate) { | ||
this._removeStylesheet(); | ||
} | ||
|
||
if (maxH === undefined) maxH = this.getRow(); | ||
/** | ||
* Updates the CSS variables (used in CSS and inline style) for row based layout and initial margin setting, | ||
* Variables are scoped in DOM so they works for nested grids as well | ||
* @internal | ||
*/ | ||
protected _updateStyles(): GridStack { | ||
this._updateContainerHeight(); | ||
|
||
// if user is telling us they will handle the CSS themselves by setting heights to 0. Do we need this opts really ?? | ||
if (this.opts.cellHeight === 0) { | ||
return this; | ||
} | ||
|
||
const cellHeight = this.opts.cellHeight as number; | ||
const cellHeightUnit = this.opts.cellHeightUnit; | ||
const prefix = `.${this._styleSheetClass} > .${this.opts.itemClass}`; | ||
|
||
// create one as needed | ||
if (!this._styles) { | ||
// insert style to parent (instead of 'head' by default) to support WebComponent | ||
const styleLocation = this.opts.styleInHead ? undefined : this.el.parentNode as HTMLElement; | ||
this._styles = Utils.createStylesheet(this._styleSheetClass, styleLocation, { | ||
lmartorella marked this conversation as resolved.
Show resolved
Hide resolved
|
||
nonce: this.opts.nonce, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nonce: does that need to be done elsewhere now ? |
||
}); | ||
if (!this._styles) return this; | ||
this._styles._max = 0; | ||
|
||
// these are done once only | ||
Utils.addCSSRule(this._styles, prefix, `height: ${cellHeight}${cellHeightUnit}`); | ||
lmartorella marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// content margins | ||
const top: string = this.opts.marginTop + this.opts.marginUnit; | ||
const bottom: string = this.opts.marginBottom + this.opts.marginUnit; | ||
const right: string = this.opts.marginRight + this.opts.marginUnit; | ||
const left: string = this.opts.marginLeft + this.opts.marginUnit; | ||
const content = `${prefix} > .grid-stack-item-content`; | ||
const placeholder = `.${this._styleSheetClass} > .grid-stack-placeholder > .placeholder-content`; | ||
Utils.addCSSRule(this._styles, content, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`); | ||
Utils.addCSSRule(this._styles, placeholder, `top: ${top}; right: ${right}; bottom: ${bottom}; left: ${left};`); | ||
// resize handles offset (to match margin) | ||
Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-n`, `top: ${top};`); | ||
Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-s`, `bottom: ${bottom}`); | ||
Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-ne`, `right: ${right}`); | ||
Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-e`, `right: ${right}`); | ||
Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-se`, `right: ${right}; bottom: ${bottom}`); | ||
Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-nw`, `left: ${left}`); | ||
Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-w`, `left: ${left}`); | ||
Utils.addCSSRule(this._styles, `${prefix} > .ui-resizable-sw`, `left: ${left}; bottom: ${bottom}`); | ||
} | ||
|
||
// now update the height specific fields | ||
maxH = maxH || this._styles._max; | ||
if (maxH > this._styles._max) { | ||
const getHeight = (rows: number): string => (cellHeight * rows) + cellHeightUnit; | ||
for (let i = this._styles._max + 1; i <= maxH; i++) { // start at 1 | ||
Utils.addCSSRule(this._styles, `${prefix}[gs-y="${i}"]`, `top: ${getHeight(i)}`); | ||
Utils.addCSSRule(this._styles, `${prefix}[gs-h="${i + 1}"]`, `height: ${getHeight(i + 1)}`); // start at 2 | ||
} | ||
this._styles._max = maxH; | ||
} | ||
// Set CSS var of cell height | ||
this.setVar(this.el, "--gs-cell-height", `${this.opts.cellHeight}${this.opts.cellHeightUnit}`); | ||
// content margins | ||
this.setVar(this.el, "--gs-item-margin-top", `${this.opts.marginTop}${this.opts.marginUnit}`); | ||
this.setVar(this.el, "--gs-item-margin-bottom", `${this.opts.marginBottom}${this.opts.marginUnit}`); | ||
this.setVar(this.el, "--gs-item-margin-right", `${this.opts.marginRight}${this.opts.marginUnit}`); | ||
this.setVar(this.el, "--gs-item-margin-left", `${this.opts.marginLeft}${this.opts.marginUnit}`); | ||
|
||
return this; | ||
} | ||
|
||
|
@@ -1677,17 +1621,32 @@ export class GridStack { | |
return this; | ||
} | ||
|
||
/** @internal call to write position x,y,w,h attributes back to element */ | ||
protected _writePosAttr(el: HTMLElement, n: GridStackPosition): GridStack { | ||
/** | ||
* Call to write position x,y,w,h attributes back to element | ||
* In addition, updates the inline top/height inline style as well | ||
* @internal | ||
*/ | ||
protected _writePosAttr(el: HTMLElement, n: GridStackNode): GridStack { | ||
if (n.x !== undefined && n.x !== null) { el.setAttribute('gs-x', String(n.x)); } | ||
if (n.y !== undefined && n.y !== null) { el.setAttribute('gs-y', String(n.y)); } | ||
n.w > 1 ? el.setAttribute('gs-w', String(n.w)) : el.removeAttribute('gs-w'); | ||
n.h > 1 ? el.setAttribute('gs-h', String(n.h)) : el.removeAttribute('gs-h'); | ||
// Avoid overwriting the inline style of the element during drag/resize, but always update the placeholder | ||
if ((!n._moving && !n._resizing) || this._placeholder === el) { | ||
// Set inline style, refer CSS variables | ||
lmartorella marked this conversation as resolved.
Show resolved
Hide resolved
|
||
el.style.top = `calc(${n.y} * var(--gs-cell-height))`; | ||
if (n.h !== 1) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. n.h > 1 ? el.style.height = to match above case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will trigger the
sonar lint issue, part of the recommended TS set. |
||
el.style.height = `calc(${n.h} * var(--gs-cell-height))`; | ||
} else { | ||
// height is set to --gs-cell-height by default | ||
delete el.style.height; | ||
} | ||
} | ||
return this; | ||
} | ||
|
||
/** @internal call to write any default attributes back to element */ | ||
protected _writeAttr(el: HTMLElement, node: GridStackWidget): GridStack { | ||
protected _writeAttr(el: HTMLElement, node: GridStackNode): GridStack { | ||
if (!node) return this; | ||
this._writePosAttr(el, node); | ||
|
||
|
@@ -2306,7 +2265,7 @@ export class GridStack { | |
this.resizeToContentCheck(false, node); | ||
if (subGrid) { | ||
subGrid.parentGridNode = node; | ||
if (!subGrid.opts.styleInHead) subGrid._updateStyles(true); // re-create sub-grid styles now that we've moved | ||
subGrid._updateStyles(); // re-create sub-grid styles now that we've moved | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might not be needed. all _updateStyles() need to be verified if needed to be called actually... sicne the external file isn't used now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, my changes are quite conservative, I don't have the full knowledge about the side effects expected by this call (i.e. _updateContainerHeight) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fair enough. but if there was a condition styleInHead then that means it's location based and therefore entire thing doesn't apply. |
||
} | ||
this._updateContainerHeight(); | ||
} | ||
|
@@ -2395,6 +2354,7 @@ export class GridStack { | |
const onEndMoving = (event: Event) => { | ||
this.placeholder.remove(); | ||
delete node._moving; | ||
delete node._resizing; | ||
delete node._event; | ||
delete node._lastTried; | ||
const widthChanged = node.w !== node._orig.w; | ||
|
@@ -2494,6 +2454,7 @@ export class GridStack { | |
node._lastUiPosition = ui.position; | ||
node._prevYPix = ui.position.top; | ||
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) | ||
node._resizing = (event.type === 'resizestart'); | ||
delete node._lastTried; | ||
|
||
if (event.type === 'dropover' && node._temporaryRemoved) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that conflicts with 95. need to figure out why I have 0 while you have '5' - either way we don't want 2 rules...
same with rest below...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comes from the old code:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep ok, so replace my 0 with your var then (just one css rule). all your resize should merge into my existing rules.