Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 126 additions & 3 deletions packages/fiori/cypress/specs/IllustratedMessage.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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");
});

Expand All @@ -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(
<IllustratedMessage name="UnableToUpload" decorative={false}>
</IllustratedMessage>
);

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(
<IllustratedMessage name="NoData">
</IllustratedMessage>
);

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(
<IllustratedMessage name="UnableToUpload">
</IllustratedMessage>
);

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(
<IllustratedMessage name="UnableToUpload">
</IllustratedMessage>
);

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(
<IllustratedMessage name="UnableToUpload" titleText="Custom Title">
</IllustratedMessage>
);

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(
<IllustratedMessage name="UnableToUpload">
<div slot="title">Slotted Title</div>
</IllustratedMessage>
);

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", () => {
Expand Down
28 changes: 0 additions & 28 deletions packages/fiori/src/IllustratedMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <HTMLElement> this.shadowRoot!.querySelector(".ui5-illustrated-message-illustration"),
illustration = illustrationWrapper.querySelector("svg");
Expand All @@ -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".
Expand Down
12 changes: 9 additions & 3 deletions packages/fiori/src/IllustratedMessageTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ import type IllustratedMessage from "./IllustratedMessage.js";

export default function IllustratedMessageTemplate(this: IllustratedMessage) {
return (
<div class="ui5-illustrated-message-root">
<div role="region"
aria-label="Illustrated Message"
aria-describedby={`${this._id}-im-title`}
class="ui5-illustrated-message-root">
<div class="ui5-illustrated-message-inner">
<div class="ui5-illustrated-message-illustration">
<div class="ui5-illustrated-message-illustration"
role={this.decorative ? "presentation" : "img"}
aria-hidden={this.decorative}
aria-label={!this.decorative ? this.name : undefined}>
{renderIllustration.call(this)}
</div>
<div class="ui5-illustrated-message-text-and-actions-container">
{this.hasTitle &&
<div part="title" class="ui5-illustrated-message-title">
<div part="title" id={`${this._id}-im-title`} class="ui5-illustrated-message-title">
{this.hasFormattedTitle ?
<slot name="title"></slot>
:
Expand Down
Loading