Skip to content

Commit

Permalink
feat(ui5-panel): support aria-label and aria-labelledby (#1910)
Browse files Browse the repository at this point in the history
  • Loading branch information
nnaydenow committed Jul 9, 2020
1 parent 7da7a54 commit 8cb7c48
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 10 deletions.
5 changes: 5 additions & 0 deletions packages/main/src/Panel.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
role="{{accInfo.role}}"
aria-expanded="{{accInfo.ariaExpanded}}"
aria-controls="{{accInfo.ariaControls}}"
aria-label="{{accInfo.ariaLabel}}"
aria-labelledby="{{accInfo.ariaLabelledby}}"
>
{{#unless fixed}}
<div class="ui5-panel-header-button-root">
Expand All @@ -23,6 +25,8 @@
?non-focusable="{{nonFocusableButton}}"
@click="{{_toggleButtonClick}}"
._buttonAccInfo="{{accInfo.button}}"
aria-label="{{accInfo.ariaLabelButton}}"
aria-labelledby="{{accInfo.ariaLabelledbyButton}}"
></ui5-button>
</div>
{{/unless}}
Expand All @@ -31,6 +35,7 @@
<slot name="header"></slot>
{{else}}
<div
id="{{_id}}-header-title"
role="heading"
aria-level="{{headerAriaLevel}}"
class="ui5-panel-header-title"
Expand Down
53 changes: 45 additions & 8 deletions packages/main/src/Panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import slideDown from "@ui5/webcomponents-base/dist/animations/slideDown.js";
import slideUp from "@ui5/webcomponents-base/dist/animations/slideUp.js";
import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js";
import AnimationMode from "@ui5/webcomponents-base/dist/types/AnimationMode.js";
import getEffectiveAriaLabelText from "@ui5/webcomponents-base/dist/util/getEffectiveAriaLabelText.js";
import { getAnimationMode } from "@ui5/webcomponents-base/dist/config/AnimationMode.js";
import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
import "@ui5/webcomponents-icons/dist/icons/navigation-right-arrow.js";
Expand Down Expand Up @@ -117,7 +118,27 @@ const metadata = {
type: TitleLevel,
defaultValue: TitleLevel.H2,
},

/**
* @type {String}
* @defaultvalue ""
* @private
* @since 1.0.0-rc.8
*/
ariaLabel: {
type: String,
},
/**
* Receives id(or many ids) of the elements that label the panel
*
* @type {String}
* @defaultvalue ""
* @private
* @since 1.0.0-rc.8
*/
ariaLabelledby: {
type: String,
defaultValue: "",
},
/**
* @private
*/
Expand Down Expand Up @@ -342,10 +363,6 @@ class Panel extends UI5Element {
return !this.collapsed;
}

get ariaLabelledBy() {
return this.header.length ? "" : `${this._id}-header`;
}

get accRole() {
return this.accessibleRole.toLowerCase();
}
Expand All @@ -357,12 +374,28 @@ class Panel extends UI5Element {
"ariaControls": this._hasHeader ? `${this._id}-content` : undefined,
"title": this.toggleButtonTitle,
},
"ariaExpanded": !this._hasHeader ? this.expanded : undefined,
"ariaControls": !this._hasHeader ? `${this._id}-content` : undefined,
"role": !this._hasHeader ? "button" : undefined,
"ariaExpanded": this.nonFixedInternalHeader ? this.expanded : undefined,
"ariaControls": this.nonFixedInternalHeader ? `${this._id}-content` : undefined,
"ariaLabelledby": this.nonFocusableButton ? this.ariaLabelledbyReference : undefined,
"ariaLabel": this.nonFocusableButton ? this.ariaLabelTxt : undefined,
"ariaLabelledbyButton": this.nonFocusableButton ? undefined : this.ariaLabelledbyReference,
"ariaLabelButton": this.nonFocusableButton ? undefined : this.ariaLabelTxt,
"role": this.nonFixedInternalHeader ? "button" : undefined,
};
}

get ariaLabelledbyReference() {
if (this.ariaLabelledby || this.ariaLabel) {
return undefined;
}

return (this.nonFocusableButton && this.headerText) ? `${this._id}-header-title` : undefined;
}

get ariaLabelTxt() {
return getEffectiveAriaLabelText(this);
}

get headerAriaLevel() {
return this.headerLevel.slice(1);
}
Expand All @@ -371,6 +404,10 @@ class Panel extends UI5Element {
return (this.header.length || this.fixed) ? "-1" : "0";
}

get nonFixedInternalHeader() {
return !this._hasHeader && !this.fixed;
}

get nonFocusableButton() {
return !this.header.length;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/main/test/pages/Panel.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@
}
</style>

<ui5-panel id="p1" collapsed accessible-role="Complementary">
<ui5-panel id="p1" collapsed accessible-role="Complementary" aria-labelledby="p1-title">

<!-- Panel header -->
<div slot="header" class="header">
<ui5-title>Expandable but not expanded</ui5-title>
<ui5-title id="p1-title">Expandable but not expanded</ui5-title>
<ui5-button id="b1">Add child </ui5-button>
<ui5-label id="l1">No new children added yet.</ui5-label>
<ui5-button design="Reject" icon="cancel">Cancel</ui5-button>
Expand Down
25 changes: 25 additions & 0 deletions packages/main/test/specs/Panel.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,31 @@ describe("Panel general interaction", () => {
assert.strictEqual(title.getAttribute("aria-level"), "3", "title aria-level is set to 3 correctly");
});

it("tests aria-label and aria-labelledby attributes", () => {
const panelWithNativeHeader = $("#panel-expandable");
const nativeHeader = panelWithNativeHeader.shadow$(".ui5-panel-header");
const panelWithNativeHeaderId = panelWithNativeHeader.getProperty("_id");

assert.strictEqual(nativeHeader.getAttribute("aria-label"), null, "aria-label is not present");
assert.strictEqual(nativeHeader.getAttribute("aria-labelledby"),
`${panelWithNativeHeaderId}-header-title`, "aria-labelledby is correct");

const panelWithCustomHeader = $("#p1");
const headerButton = panelWithCustomHeader.shadow$(".ui5-panel-header-button");
const expectedText = "Expandable but not expanded";

assert.strictEqual(headerButton.getAttribute("aria-label"), expectedText,
"aria-labelledby is propagated correctly to the expand/collapse button");
});

it("tests whether aria attributes are set correctly with fixed header", () => {
const header = browser.$("#panel-fixed").shadow$(".ui5-panel-header");

assert.ok(!header.getAttribute("aria-expanded"), "aria-expanded shouldn't be set on the fixed header");
assert.ok(!header.getAttribute("aria-controls"), "aria-controls shouldn't be set on the fixed header");
assert.ok(!header.getAttribute("role"), "role shouldn't be set on the fixed header");
});

it("tests whether aria attributes are set correctly in case of custom header", () => {
const button = browser.$("#panel2").shadow$(".ui5-panel-header-button").shadow$(".ui5-button-root");
const header = browser.$("#panel2").shadow$(".ui5-panel-header");
Expand Down

0 comments on commit 8cb7c48

Please sign in to comment.