diff --git a/src/vaadin-board-row.html b/src/vaadin-board-row.html index fa7ae36..d01cada 100644 --- a/src/vaadin-board-row.html +++ b/src/vaadin-board-row.html @@ -228,9 +228,7 @@ _recalculateFlexBasis(forceResize) { const width = this.getBoundingClientRect().width; const breakpoints = this._measureBreakpointsInPx(); - if (forceResize || width != this._oldWidth - || breakpoints.smallSize != this._oldBreakpoints.smallSize - || breakpoints.mediumSize != this._oldBreakpoints.mediumSize) { + if (forceResize || this._shouldRecalculate(width, breakpoints)) { const nodes = this.$.insertionPoint.assignedNodes({ flatten: true }); const isElementNode = function (node) { return !((node.nodeType === node.TEXT_NODE) @@ -253,6 +251,37 @@ } } + /** @private */ + _shouldRecalculate(width, breakpoints) { + // Should not recalculate if row is invisible + if (this._isElementHidden()) { + return false; + } + return ( + width !== this._oldWidth || + breakpoints.smallSize !== this._oldBreakpoints.smallSize || + breakpoints.mediumSize !== this._oldBreakpoints.mediumSize + ); + } + + /** @private */ + _isElementHidden() { + // `offsetParent` is `null` when the element itself + // or one of its ancestors is hidden with `display: none`. + // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent + // However `offsetParent` is also null when the element is using fixed + // positioning, so additionally check if the element takes up layout space. + if (this.offsetParent === null && this.clientWidth === 0 && this.clientHeight === 0) { + return true; + } + // Check inline style first to save a re-flow. + if (this.style.visibility === 'hidden' || this.style.display === 'none') { + return true; + } + const computedStyle = window.getComputedStyle(this); + return computedStyle.visibility === 'hidden' || computedStyle.display === 'none'; + } + /** * Measure the breakpoints in pixels. * diff --git a/test/vaadin-board_redraw_test.html b/test/vaadin-board_redraw_test.html index 2632b6d..a7811d0 100644 --- a/test/vaadin-board_redraw_test.html +++ b/test/vaadin-board_redraw_test.html @@ -124,6 +124,44 @@ assert.approximately(rect.top, (Math.floor(i / 2) * rowRect.height / 2) + rowRect.top, 1); } }); + + test("Resize event should not trigger recalculating flex basis for a directly hidden row", function () { + const board = fixture("board-1-row-4-items"); + const row = board.querySelector("#top"); + + const initialClassName = row.className; + + row.style.display = "none"; + row.style.width = "100px"; + row.fire("resize"); + + assert.equal(initialClassName, row.className); + }); + + test("Resize event should not trigger recalculating flex basis for a row hidden through an ancestor", function () { + const board = fixture("board-1-row-4-items"); + const row = board.querySelector("#top"); + + const initialClassName = row.className; + + board.style.display = "none"; + row.style.width = "100px"; + row.fire("resize"); + + assert.equal(initialClassName, row.className); + }); + + test("Resize event should trigger recalculating flex basis for a visible row", function () { + const board = fixture("board-1-row-4-items"); + const row = board.querySelector("#top"); + + const initialClassName = row.className; + + row.style.width = "100px"; + row.fire("resize"); + + assert.notEqual(initialClassName, row.className); + }); });