From 0bba39bc28f5614c535532af21255c57219f1e95 Mon Sep 17 00:00:00 2001 From: PetyaMarkovaBogdanova Date: Fri, 23 Jan 2026 15:48:42 +0200 Subject: [PATCH] fix(ui5-illustrated-message): flickering fix using throttling --- .../cypress/specs/IllustratedMessage.cy.tsx | 63 ++++++++++++++++++- packages/fiori/src/IllustratedMessage.ts | 18 +++++- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/packages/fiori/cypress/specs/IllustratedMessage.cy.tsx b/packages/fiori/cypress/specs/IllustratedMessage.cy.tsx index 0f2165948be3..359c5fe154f4 100644 --- a/packages/fiori/cypress/specs/IllustratedMessage.cy.tsx +++ b/packages/fiori/cypress/specs/IllustratedMessage.cy.tsx @@ -1,5 +1,6 @@ import IllustratedMessage from "../../src/IllustratedMessage.js"; import Label from "@ui5/webcomponents/dist/Label.js"; +import Dialog from "@ui5/webcomponents/dist/Dialog.js"; import "@ui5/webcomponents-fiori/dist/illustrations/AllIllustrations.js" import Panel from "@ui5/webcomponents/dist/Panel.js"; @@ -124,7 +125,7 @@ describe('SVG CSP Compliance', () => { const violationReport = invalidFiles .map(v => `${v.file}: has violations`) .join('\n') - + throw new Error(`Found ${invalidFiles.length} SVG files with CSP violations:\n${violationReport}`) } @@ -199,7 +200,7 @@ describe("Vertical responsiveness", () => { expect(scrollHeight).to.be.lessThan(500); expect(scrollHeight).to.equal(offsetHeight); }); - + cy.get("[ui5-illustrated-message]") .should("have.prop", "media", expectedMedia); }); @@ -272,6 +273,64 @@ describe("Vertical responsiveness", () => { expect(scrollHeight).to.not.equal(0); }); }); + it("IllustratedMessage variations in a dialog with resizing", () => { + cy.mount( + +
+ +
+
+ ); + + // Ensure the dialog is rendered and open + cy.get("[ui5-dialog]").as("Dialog").should("exist").and("have.attr", "open"); + + // Validate the first IllustratedMessage + cy.get("#illustration1") + .shadow() + .find(".ui5-illustrated-message-illustration svg") + .should(($illustration) => { + const scrollHeight = $illustration[0].scrollHeight; + expect(scrollHeight).to.not.equal(0); + }); + + // Resize the dialog and validate the media property for each IllustratedMessage + cy.get("[ui5-dialog]").then(($dialog) => { + // Resize the dialog to a smaller size + $dialog[0].style.width = "300px"; + $dialog[0].style.height = "300px"; + }); + // Validate the media property for the first IllustratedMessage + cy.get("#illustration1") + .invoke("prop", "media") + .should("equal", "spot"); + + cy.get("[ui5-dialog]").then(($dialog) => { + // Resize the dialog to a larger size + $dialog[0].style.width = "800px"; + $dialog[0].style.height = "600px"; + }); + + // Validate the media property for the first IllustratedMessage + cy.get("#illustration1") + .invoke("prop", "media") + .should("equal", "scene"); + + cy.get("[ui5-dialog]").then(($dialog) => { + // Resize the dialog to a smallest size + $dialog[0].style.width = "200px"; + $dialog[0].style.height = "200px"; + }); + + // Validate the media property for the first IllustratedMessage + cy.get("#illustration1") + .invoke("prop", "media") + .should("equal", "dot"); + + }); }); describe("Dot design resource handling", () => { diff --git a/packages/fiori/src/IllustratedMessage.ts b/packages/fiori/src/IllustratedMessage.ts index 0b119df2ce0d..523f9c13c6fc 100644 --- a/packages/fiori/src/IllustratedMessage.ts +++ b/packages/fiori/src/IllustratedMessage.ts @@ -13,6 +13,7 @@ import executeTemplate from "@ui5/webcomponents-base/dist/renderer/executeTempla import type { IButton } from "@ui5/webcomponents/dist/Button.js"; import IllustrationMessageDesign from "./types/IllustrationMessageDesign.js"; import IllustrationMessageType from "./types/IllustrationMessageType.js"; +import throttle from "@ui5/webcomponents-base/dist/util/throttle.js"; import "./illustrations/BeforeSearch.js"; // Styles @@ -278,6 +279,7 @@ class IllustratedMessage extends UI5Element { _lastKnownOffsetHeightForMedia: Record; _lastKnownMedia: string; _handleResize: ResizeObserverCallback; + _throttledApplyMedia: (() => void); constructor() { super(); @@ -288,6 +290,7 @@ class IllustratedMessage extends UI5Element { this._lastKnownOffsetHeightForMedia = {}; // this will store the last known media, in order to detect if IllustratedMessage has been hidden by expand/collapse container this._lastKnownMedia = "base"; + this._throttledApplyMedia = () => {}; } static get BREAKPOINTS() { @@ -383,7 +386,7 @@ class IllustratedMessage extends UI5Element { return; } - this._applyMedia(); + this._applyMediaThrottled(); window.requestAnimationFrame(this._adjustHeightToFitContainer.bind(this)); } @@ -445,6 +448,15 @@ class IllustratedMessage extends UI5Element { } } + _applyMediaThrottled(heightChange?: boolean) { + this._throttledApplyMedia = throttle(() => { + this._applyMedia(heightChange); + }, 1000); // Adjust the delay (in milliseconds) as needed + + // Call the throttled version + this._throttledApplyMedia(); + } + _adjustHeightToFitContainer() { const illustrationWrapper = this.shadowRoot!.querySelector(".ui5-illustrated-message-illustration"), illustration = illustrationWrapper.querySelector("svg"); @@ -453,7 +465,9 @@ class IllustratedMessage extends UI5Element { illustrationWrapper.classList.toggle("ui5-illustrated-message-illustration-fit-content", false); if (this.getDomRef()!.scrollHeight > this.getDomRef()!.offsetHeight) { illustrationWrapper.classList.toggle("ui5-illustrated-message-illustration-fit-content", true); - this._applyMedia(true /* height change */); + + // Use the throttled version of _applyMedia + this._applyMediaThrottled(true /* height change */); } } }