Skip to content

Commit e54111f

Browse files
authored
feat(ui5-button): support aria-labelledby attribute(#1446)
1 parent 5920817 commit e54111f

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const findNodeOwner = node => {
2+
if (!(node instanceof HTMLElement)) {
3+
throw new Error("Argument node should be of type HTMLElement");
4+
}
5+
6+
const ownerTypes = [HTMLHtmlElement, HTMLIFrameElement];
7+
let currentShadowRootFlag = true;
8+
let currentCustomElementFlag = true;
9+
10+
while (node) {
11+
if (node.toString() === "[object ShadowRoot]") {
12+
// Web Component
13+
// or the shadow root of web component with attached shadow root
14+
if (currentShadowRootFlag) {
15+
currentShadowRootFlag = false;
16+
}
17+
if (!currentCustomElementFlag && !currentShadowRootFlag) {
18+
return node;
19+
}
20+
} else if (node.tagName && node.tagName.indexOf("-") > -1) {
21+
if (currentCustomElementFlag) {
22+
currentCustomElementFlag = false;
23+
} else {
24+
return node;
25+
}
26+
} else if (ownerTypes.indexOf(node.constructor) > -1) {
27+
// Document or Iframe reached
28+
return node;
29+
}
30+
31+
node = node.parentNode || node.host;
32+
}
33+
};
34+
35+
export default findNodeOwner;

packages/main/src/Button.hbs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
tabindex={{tabIndexValue}}
1616
aria-expanded="{{accInfo.ariaExpanded}}"
1717
aria-controls="{{accInfo.ariaControls}}"
18+
aria-label="{{ariaLabelledByText}}"
1819
title="{{accInfo.title}}"
1920
part="button"
2021
>

packages/main/src/Button.js

+34
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { isSpace, isEnter } from "@ui5/webcomponents-base/dist/Keys.js";
44
import { getRTL } from "@ui5/webcomponents-base/dist/config/RTL.js";
55
import { getFeature } from "@ui5/webcomponents-base/dist/FeaturesRegistry.js";
66
import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
7+
import findNodeOwner from "@ui5/webcomponents-base/dist/util/findNodeOwner.js";
78
import ButtonDesign from "./types/ButtonDesign.js";
89
import ButtonTemplate from "./generated/templates/ButtonTemplate.lit.js";
910
import Icon from "./Icon.js";
@@ -128,6 +129,18 @@ const metadata = {
128129
type: Boolean,
129130
},
130131

132+
/**
133+
* Receives id(or many ids) of the elements that label the button
134+
* @type {String}
135+
* @defaultvalue ""
136+
* @private
137+
* @since 1.0.0-rc.7
138+
*/
139+
ariaLabelledby: {
140+
type: String,
141+
defaultValue: "",
142+
},
143+
131144
/**
132145
* Indicates if the element if focusable
133146
* @private
@@ -315,6 +328,27 @@ class Button extends UI5Element {
315328
};
316329
}
317330

331+
get ariaLabelledByText() {
332+
if (!this.ariaLabelledby) {
333+
return undefined;
334+
}
335+
336+
const ids = this.ariaLabelledby.split(" ");
337+
const owner = findNodeOwner(this);
338+
let result = "";
339+
340+
ids.forEach((elementId, index) => {
341+
const element = owner.querySelector(`#${elementId}`);
342+
result += `${element ? element.textContent : ""}`;
343+
344+
if (index < ids.length - 1) {
345+
result += " ";
346+
}
347+
});
348+
349+
return result;
350+
}
351+
318352
static typeTextMappings() {
319353
return {
320354
"Positive": BUTTON_ARIA_TYPE_ACCEPT,

packages/main/test/pages/Button.html

+4-3
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@
6969
<br />
7070
<br />
7171

72-
<ui5-button icon="employee">Action Bar Button</ui5-button>
73-
<ui5-button icon="download"></ui5-button>
74-
<ui5-button icon="download"></ui5-button>
72+
<ui5-label id="download-text">Download Application</ui5-label>
73+
<ui5-label id="download-text2">From This Button</ui5-label>
74+
<ui5-button icon="employee" aria-labelledby="download-text download-text2">Action Bar Button</ui5-button>
75+
<ui5-button icon="download" aria-labelledby="download-text"></ui5-button>
7576

7677

7778
<br/>

0 commit comments

Comments
 (0)