Skip to content

Commit

Permalink
fix(ui5-card): correctly set aria-labelledby (#3692)
Browse files Browse the repository at this point in the history
Now card doesn't reference element ID in another shadow DOM with aria-labelledby. The header is labelled by its own title instead.

Fixes #3643
  • Loading branch information
dimovpetar committed Aug 19, 2021
1 parent 3afe78a commit 1e57b00
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 35 deletions.
8 changes: 4 additions & 4 deletions packages/main/src/Card.hbs
Expand Up @@ -2,14 +2,14 @@
class="{{classes}}"
dir="{{effectiveDir}}"
role="region"
aria-labelledby="{{ariaLabelledByCard}}">
{{#if hasHeader}}
aria-labelledby="{{_id}}-desc">
{{#if _hasHeader}}
<div class="ui5-card-header-root">
<slot name="header"></slot>
</div>
{{/if}}
<div role="group" aria-label="{{ariaCardContentLabel}}">
<div role="group" aria-label="{{_ariaCardContentLabel}}">
<slot></slot>
</div>
<span id="{{_id}}-desc" class="ui5-hidden-text">{{ariaCardRoleDescription}}</span>
<span id="{{_id}}-desc" class="ui5-hidden-text">{{_ariaCardRoleDescription}}</span>
</div>
16 changes: 3 additions & 13 deletions packages/main/src/Card.js
Expand Up @@ -111,28 +111,18 @@ class Card extends UI5Element {
};
}

get hasHeader() {
get _hasHeader() {
return !!this.header.length;
}

get ariaCardRoleDescription() {
get _ariaCardRoleDescription() {
return this.i18nBundle.getText(ARIA_ROLEDESCRIPTION_CARD);
}

get ariaCardContentLabel() {
get _ariaCardContentLabel() {
return this.i18nBundle.getText(ARIA_LABEL_CARD_CONTENT);
}

get ariaLabelledByCard() {
let labels;
if (this.hasHeader) {
labels = this.header[0].hasAttribute("title-text") ? `${this._id}--header-title ${this._id}-desc` : `${this._id}-desc`;
} else {
labels = `${this._id}-desc`;
}
return labels;
}

static get dependencies() {
return [Icon];
}
Expand Down
4 changes: 4 additions & 0 deletions packages/main/src/CardHeader.js
Expand Up @@ -195,6 +195,10 @@ class CardHeader extends UI5Element {
get ariaLabelledByHeader() {
const labels = [];

if (this.titleText) {
labels.push(`${this._id}-title`);
}

if (this.subtitleText) {
labels.push(`${this._id}-subtitle`);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/main/test/pages/Card.html
Expand Up @@ -29,7 +29,7 @@
slot="header"
status="4 of 10"
title-text="Quick Links"
subtitle-text="quick links"
subtitle-text="quick links sub title"
interactive>
</ui5-card-header>
<ui5-list id="myList3" separators="Inner">
Expand Down
48 changes: 31 additions & 17 deletions packages/main/test/specs/Card.spec.js
Expand Up @@ -36,27 +36,41 @@ describe("Card general interaction", () => {
assert.strictEqual(field.getProperty("value"), "3", "The events count should remain 3 as the header is not interactive.");
});

it("Tests internal aria-labelledby labeling", () => {
const card1 = $("#textAreaAriaLabel").shadow$(".ui5-card-root");
const card1Id = $("#textAreaAriaLabel").getProperty("_id");
it("tests aria-labelledby", () => {
const card = $("#textAreaAriaLabel").shadow$(".ui5-card-root");
const cardId = $("#textAreaAriaLabel").getProperty("_id");
const EXPECTED_ARIA_LABELLEDBY_CARD = `${cardId}-desc`;

assert.strictEqual(card.getAttribute("aria-labelledby"), EXPECTED_ARIA_LABELLEDBY_CARD,
"The aria-labelledby of card is correctly set.");
})

it("tests ARIA attributes of the content", () => {
const card = $("#card");
const content = card.shadow$(".ui5-card-root div:nth-child(2)");

assert.strictEqual(content.getAttribute("aria-label"), card.getProperty("_ariaCardContentLabel"));
assert.strictEqual(content.getAttribute("role"), "group");
});
});

describe("CardHeader", () => {
before(() => {
browser.url(`http://localhost:${PORT}/test-resources/pages/Card.html`);
});

it("tests header aria-labelledby", () => {
const header = $("#header").shadow$(".ui5-card-header");
const headerId = $("#header").getProperty("_id");
const card2 = $("#textAreaAriaLabelledBy").shadow$(".ui5-card-root");
const card2Id = $("#textAreaAriaLabelledBy").getProperty("_id");
const header2 = $("#header2").shadow$(".ui5-card-header");
const headerId = $("#header").getProperty("_id");
const headerId2 = $("#header2").getProperty("_id");
const EXPECTED_ARIA_LABELLEDBY_CARD = `${card1Id}--header-title ${card1Id}-desc`;
const EXPECTED_ARIA_LABELLEDBY_HEADER = `${headerId}-subtitle ${headerId}-status`;
const EXPECTED_ARIA_LABELLEDBY_CARD2 = `${card2Id}--header-title ${card2Id}-desc`;
const EXPECTED_ARIA_LABELLEDBY_HEADER2 = `${headerId2}-subtitle`;
const EXPECTED_ARIA_LABELLEDBY_HEADER = `${headerId}-title ${headerId}-subtitle ${headerId}-status`;
const EXPECTED_ARIA_LABELLEDBY_HEADER2 = `${headerId2}-title ${headerId2}-subtitle`;

assert.strictEqual(card1.getAttribute("aria-labelledby"), EXPECTED_ARIA_LABELLEDBY_CARD,
"The aria-labelledby of card is correctly set internally.");
assert.strictEqual(header.getAttribute("aria-labelledby"), EXPECTED_ARIA_LABELLEDBY_HEADER,
"The aria-labelledby is correctly set internally.");
assert.strictEqual(card2.getAttribute("aria-labelledby"), EXPECTED_ARIA_LABELLEDBY_CARD2,
"The aria-labelledby of card is correctly set internally.3");
"The aria-labelledby is correctly set.");
assert.strictEqual(header2.getAttribute("aria-labelledby"), EXPECTED_ARIA_LABELLEDBY_HEADER2,
"The aria-labelledby is correctly set internally.");
});
"The aria-labelledby is correctly set.");
})

});

0 comments on commit 1e57b00

Please sign in to comment.