Skip to content
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

fix: do not recalculate flex basis for hidden rows #159

Merged
merged 12 commits into from
May 15, 2023
35 changes: 32 additions & 3 deletions src/vaadin-board-row.html
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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.
*
Expand Down
38 changes: 38 additions & 0 deletions test/vaadin-board_redraw_test.html
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
</script>
</body>
Expand Down