diff --git a/packages/fiori/cypress/specs/IllustratedMessage.cy.tsx b/packages/fiori/cypress/specs/IllustratedMessage.cy.tsx index df9a91b81f8a..2ca9da895f90 100644 --- a/packages/fiori/cypress/specs/IllustratedMessage.cy.tsx +++ b/packages/fiori/cypress/specs/IllustratedMessage.cy.tsx @@ -12,12 +12,12 @@ describe("Accessibility", () => { cy.get("[ui5-illustrated-message]") .shadow() - .find("svg") + .find(".ui5-illustrated-message-illustration") .should("have.attr", "role", "presentation"); cy.get("[ui5-illustrated-message]") .shadow() - .find("svg") + .find(".ui5-illustrated-message-illustration") .should("have.attr", "aria-hidden", "true"); }); @@ -30,10 +30,133 @@ describe("Accessibility", () => { cy.get("[ui5-illustrated-message]") .shadow() - .find("svg") + .find(".ui5-illustrated-message-illustration") .should("not.have.attr", "aria-label"); }); + + it("should have role=img and aria-label with illustration name when decorative is false", () => { + cy.mount( + + + ); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-illustration") + .should("have.attr", "role", "img"); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-illustration") + .should("have.attr", "aria-label", "UnableToUpload"); + }); + + it("should have role=img and aria-label with illustration name by default (when decorative is not set)", () => { + cy.mount( + + + ); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-illustration") + .should("have.attr", "role", "img"); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-illustration") + .should("have.attr", "aria-label", "NoData"); + }); + + it("should have proper role and aria-label on the root container", () => { + cy.mount( + + + ); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-root") + .should("have.attr", "role", "region"); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-root") + .should("have.attr", "aria-label", "Illustrated Message"); + }); + + it("should have aria-describedby pointing to the title element", () => { + cy.mount( + + + ); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-root") + .should("have.attr", "aria-describedby") + .and("match", /-im-title$/); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-title") + .should("have.attr", "id") + .and("match", /-im-title$/); + + // Verify that aria-describedby points to the correct title element + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-root") + .invoke("attr", "aria-describedby") + .then((ariaDescribedBy) => { + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-title") + .should("have.attr", "id", ariaDescribedBy); + }); + }); + + it("should maintain accessibility attributes when title is present", () => { + cy.mount( + + + ); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-root") + .should("have.attr", "role", "region") + .and("have.attr", "aria-label", "Illustrated Message") + .and("have.attr", "aria-describedby"); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-title") + .should("exist") + .and("have.attr", "id"); + }); + + it("should maintain accessibility attributes when title is slotted", () => { + cy.mount( + +
Slotted Title
+
+ ); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-root") + .should("have.attr", "role", "region") + .and("have.attr", "aria-label", "Illustrated Message") + .and("have.attr", "aria-describedby"); + + cy.get("[ui5-illustrated-message]") + .shadow() + .find(".ui5-illustrated-message-title") + .should("exist") + .and("have.attr", "id"); + }); }); describe("design", () => { diff --git a/packages/fiori/src/IllustratedMessage.ts b/packages/fiori/src/IllustratedMessage.ts index 0b119df2ce0d..89f32b2a0d19 100644 --- a/packages/fiori/src/IllustratedMessage.ts +++ b/packages/fiori/src/IllustratedMessage.ts @@ -421,30 +421,6 @@ class IllustratedMessage extends UI5Element { } } - _setSVGAccAttrs() { - const svg = this.shadowRoot!.querySelector(".ui5-illustrated-message-illustration svg"); - - if (!svg) { - return; - } - - if (this.decorative) { - svg.setAttribute("role", "presentation"); - svg.setAttribute("aria-hidden", "true"); - svg.removeAttribute("aria-label"); - } else { - svg.removeAttribute("role"); - svg.removeAttribute("aria-hidden"); - - // Set aria-label only when not decorative and text exists - if (this.ariaLabelText) { - svg.setAttribute("aria-label", this.ariaLabelText); - } else { - svg.removeAttribute("aria-label"); - } - } - } - _adjustHeightToFitContainer() { const illustrationWrapper = this.shadowRoot!.querySelector(".ui5-illustrated-message-illustration"), illustration = illustrationWrapper.querySelector("svg"); @@ -458,10 +434,6 @@ class IllustratedMessage extends UI5Element { } } - onAfterRendering() { - this._setSVGAccAttrs(); - } - /** * Modifies the IM styles in accordance to the `size` property's value. * Note: The resize handler has no effect when size is different than "Auto". diff --git a/packages/fiori/src/IllustratedMessageTemplate.tsx b/packages/fiori/src/IllustratedMessageTemplate.tsx index 82789694e895..1ebced333629 100644 --- a/packages/fiori/src/IllustratedMessageTemplate.tsx +++ b/packages/fiori/src/IllustratedMessageTemplate.tsx @@ -3,14 +3,20 @@ import type IllustratedMessage from "./IllustratedMessage.js"; export default function IllustratedMessageTemplate(this: IllustratedMessage) { return ( -
+
-
+
{renderIllustration.call(this)}
{this.hasTitle && -
+
{this.hasFormattedTitle ? :