From 474155b39328a6d0be4ce5a877a23acd0809d0c5 Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Fri, 29 Aug 2025 14:16:20 +0300 Subject: [PATCH 1/2] fix(ui5-toolbar): prevent flickering on item state changes --- packages/main/src/Toolbar.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/main/src/Toolbar.ts b/packages/main/src/Toolbar.ts index 12a26824d191..ca47ab8f520d 100644 --- a/packages/main/src/Toolbar.ts +++ b/packages/main/src/Toolbar.ts @@ -150,8 +150,8 @@ class Toolbar extends UI5Element { /** * Defines the items of the component. - * - * **Note:** Currently only `ui5-toolbar-button`, `ui5-toolbar-select`, `ui5-toolbar-separator` and `ui5-toolbar-spacer` are allowed here. + * + * **Note:** Currently only `ui5-toolbar-button`, `ui5-toolbar-select`, `ui5-toolbar-separator` and `ui5-toolbar-spacer` are allowed here. * @public */ @slot({ @@ -281,8 +281,11 @@ class Toolbar extends UI5Element { } onInvalidation(changeInfo: ChangeInfo) { - if (changeInfo.reason === "childchange" && changeInfo.child === this.itemsToOverflow[0]) { - this.onToolbarItemChange(); + if (changeInfo.reason === "childchange") { + const currentItemsWidth = this.items.reduce((total, item) => total + this.getItemWidth(item), 0); + if (currentItemsWidth !== this.itemsWidth) { + this.onToolbarItemChange(); + } } } @@ -301,7 +304,7 @@ class Toolbar extends UI5Element { this.storeItemsWidth(); this.processOverflowLayout(); this.items.forEach(item => { - item.isOverflowed = this.overflowItems.map(overflowItem => overflowItem).indexOf(item) !== -1; + item.isOverflowed = this.overflowItems.map(overflowItem => overflowItem).indexOf(item) !== -1; }); } From 7c12c14edf3bd19d0d79d88857a29c34ad95f5dd Mon Sep 17 00:00:00 2001 From: Nikola Anachkov Date: Fri, 12 Sep 2025 10:54:10 +0300 Subject: [PATCH 2/2] chore: add test --- packages/main/cypress/specs/Toolbar.cy.tsx | 45 ++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/packages/main/cypress/specs/Toolbar.cy.tsx b/packages/main/cypress/specs/Toolbar.cy.tsx index 45da94b0a372..60ec91dfa2bd 100644 --- a/packages/main/cypress/specs/Toolbar.cy.tsx +++ b/packages/main/cypress/specs/Toolbar.cy.tsx @@ -619,4 +619,49 @@ describe("Toolbar Button", () => { cy.get("ui5-toolbar-button:not([disabled])").realClick(); cy.get("#value-input").should("have.value", "1"); }); + + it("Should not recalculate overflow when button state changes without affecting width", () => { + cy.mount( + + + + + + + + ); + + cy.viewport(800, 600); + cy.get("[ui5-toolbar]").as("toolbar"); + + cy.get("@toolbar") + .shadow() + .find(".ui5-tb-overflow-btn") + .should("have.class", "ui5-tb-overflow-btn-hidden"); + + cy.viewport(300, 600); + + cy.get("@toolbar") + .shadow() + .find(".ui5-tb-overflow-btn") + .should("not.have.class", "ui5-tb-overflow-btn-hidden"); + + cy.get("@toolbar").then($toolbar => { + const toolbar = $toolbar[0] as Toolbar; + const addButton = document.getElementById("add-btn") as ToolbarButton; + + expect(toolbar.itemsToOverflow.includes(addButton)).to.be.true; + + const initialOverflowCount = toolbar.itemsToOverflow.length; + const initialItemsWidth = toolbar.itemsWidth; + + addButton.disabled = !addButton.disabled; + + cy.get("@toolbar").then($toolbarAfter => { + const toolbarAfter = $toolbarAfter[0] as Toolbar; + expect(toolbarAfter.itemsToOverflow.length).to.equal(initialOverflowCount); + expect(toolbarAfter.itemsWidth).to.equal(initialItemsWidth); + }); + }); + }); });