Skip to content

Commit

Permalink
fix: postpone menu-bar initial render to prevent re-layout
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan committed Apr 9, 2024
1 parent 9808c68 commit 48d0e76
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
16 changes: 14 additions & 2 deletions integration/tests/component-relayout-page.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { expect } from '@esm-bundle/chai';
import { fixtureSync, nextRender } from '@vaadin/testing-helpers';
import { ContextMenu } from '@vaadin/context-menu';

[{ tagName: ContextMenu.is }].forEach(({ tagName }) => {
import { MenuBar } from '@vaadin/menu-bar';

[
{ tagName: ContextMenu.is },
{
tagName: MenuBar.is,
callback: (el) => {
el.items = [{ text: 'Item' }];
},
},
].forEach(({ tagName, callback }) => {
describe(`${tagName} re-layout`, () => {
let wrapper;

Expand All @@ -16,6 +25,9 @@ import { ContextMenu } from '@vaadin/context-menu';
}

wrapper.appendChild(document.createElement(tagName));
if (callback) {
callback(wrapper.firstElementChild);
}

for (let i = 0; i < 100; i++) {
const btn = document.createElement('button');
Expand Down
11 changes: 10 additions & 1 deletion packages/menu-bar/src/vaadin-menu-bar-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,12 @@ export const MenuBarMixin = (superClass) =>
container.addEventListener('click', this.__onButtonClick.bind(this));
container.addEventListener('mouseover', (e) => this._onMouseOver(e));

this._container = container;
// Delay setting container to avoid rendering buttons immediately,
// which would also trigger detecting overflow and force re-layout
// See https://github.com/vaadin/web-components/issues/7271
queueMicrotask(() => {
this._container = container;
});
}

/**
Expand Down Expand Up @@ -468,6 +473,10 @@ export const MenuBarMixin = (superClass) =>

/** @private */
__detectOverflow() {
if (!this._container) {
return;
}

const overflow = this._overflow;
const buttons = this._buttons.filter((btn) => btn !== overflow);
const oldOverflowCount = this.__getOverflowCount(overflow);
Expand Down

0 comments on commit 48d0e76

Please sign in to comment.