Skip to content

Commit 669262b

Browse files
authored
fix(ui5-toolbar): prevent flickering on item state changes (#12222)
Only trigger overflow recalculation when item dimensions actually change, not on every child property update like pressed/disabled state. Fixes: #12209
1 parent f7f98d6 commit 669262b

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

packages/main/cypress/specs/Toolbar.cy.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,4 +571,49 @@ describe("Toolbar Button", () => {
571571
cy.get("ui5-toolbar-button:not([disabled])").realClick();
572572
cy.get("#value-input").should("have.value", "1");
573573
});
574+
575+
it("Should not recalculate overflow when button state changes without affecting width", () => {
576+
cy.mount(
577+
<Toolbar id="state-change-toolbar">
578+
<ToolbarButton text="Bold" icon="bold-text"></ToolbarButton>
579+
<ToolbarButton text="Italic" icon="italic-text"></ToolbarButton>
580+
<ToolbarButton text="Underline" icon="underline-text"></ToolbarButton>
581+
<ToolbarButton id="add-btn" text="Add" icon="add" disabled></ToolbarButton>
582+
<ToolbarButton text="More" icon="employee"></ToolbarButton>
583+
</Toolbar>
584+
);
585+
586+
cy.viewport(800, 600);
587+
cy.get("[ui5-toolbar]").as("toolbar");
588+
589+
cy.get("@toolbar")
590+
.shadow()
591+
.find(".ui5-tb-overflow-btn")
592+
.should("have.class", "ui5-tb-overflow-btn-hidden");
593+
594+
cy.viewport(300, 600);
595+
596+
cy.get("@toolbar")
597+
.shadow()
598+
.find(".ui5-tb-overflow-btn")
599+
.should("not.have.class", "ui5-tb-overflow-btn-hidden");
600+
601+
cy.get("@toolbar").then($toolbar => {
602+
const toolbar = $toolbar[0] as Toolbar;
603+
const addButton = document.getElementById("add-btn") as ToolbarButton;
604+
605+
expect(toolbar.itemsToOverflow.includes(addButton)).to.be.true;
606+
607+
const initialOverflowCount = toolbar.itemsToOverflow.length;
608+
const initialItemsWidth = toolbar.itemsWidth;
609+
610+
addButton.disabled = !addButton.disabled;
611+
612+
cy.get("@toolbar").then($toolbarAfter => {
613+
const toolbarAfter = $toolbarAfter[0] as Toolbar;
614+
expect(toolbarAfter.itemsToOverflow.length).to.equal(initialOverflowCount);
615+
expect(toolbarAfter.itemsWidth).to.equal(initialItemsWidth);
616+
});
617+
});
618+
});
574619
});

packages/main/src/Toolbar.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ class Toolbar extends UI5Element {
150150

151151
/**
152152
* Defines the items of the component.
153-
*
154-
* **Note:** Currently only `ui5-toolbar-button`, `ui5-toolbar-select`, `ui5-toolbar-separator` and `ui5-toolbar-spacer` are allowed here.
153+
*
154+
* **Note:** Currently only `ui5-toolbar-button`, `ui5-toolbar-select`, `ui5-toolbar-separator` and `ui5-toolbar-spacer` are allowed here.
155155
* @public
156156
*/
157157
@slot({
@@ -281,8 +281,11 @@ class Toolbar extends UI5Element {
281281
}
282282

283283
onInvalidation(changeInfo: ChangeInfo) {
284-
if (changeInfo.reason === "childchange" && changeInfo.child === this.itemsToOverflow[0]) {
285-
this.onToolbarItemChange();
284+
if (changeInfo.reason === "childchange") {
285+
const currentItemsWidth = this.items.reduce((total, item) => total + this.getItemWidth(item), 0);
286+
if (currentItemsWidth !== this.itemsWidth) {
287+
this.onToolbarItemChange();
288+
}
286289
}
287290
}
288291

@@ -301,7 +304,7 @@ class Toolbar extends UI5Element {
301304
this.storeItemsWidth();
302305
this.processOverflowLayout();
303306
this.items.forEach(item => {
304-
item.isOverflowed = this.overflowItems.map(overflowItem => overflowItem).indexOf(item) !== -1;
307+
item.isOverflowed = this.overflowItems.map(overflowItem => overflowItem).indexOf(item) !== -1;
305308
});
306309
}
307310

0 commit comments

Comments
 (0)