Skip to content

Commit 20de5ae

Browse files
authored
feat(ui5-li-notification*): full-fill accessibility spec (#2578)
We identified gaps in the accessibility implementation, that this change aims to address as follows: **NotificationListItem** - More Button: added aria-label="More" - Close Button: added aria-label="Close" **NotificationListGroupItem** - Invisible text reading: added "read" or "unread", based on the "read" property. - Root: added aria-expanded="true"/"false", based on the "collapsed" property - More Button: added aria-label="More" - Close Button: added aria-label="Close All" - Toggle Button added title="Collapse Group" ("Expand Group") and aria-label="Collapse Group" ("Expand Group") - based on the "collapsed" property **NotificationListGroupItem** - new property "read" (previously available in the NotificationListItem only)
1 parent f3c4748 commit 20de5ae

10 files changed

+111
-37
lines changed

packages/fiori/src/NotificationListGroupItem.hbs

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
role="option"
77
tabindex="{{_tabIndex}}"
88
dir="{{effectiveDir}}"
9+
aria-expanded="{{ariaExpanded}}"
910
aria-labelledby="{{ariaLabelledBy}}"
1011
style="list-style-type: none;"
1112
>
@@ -15,6 +16,8 @@
1516
design="Transparent"
1617
@click="{{_onBtnToggleClick}}"
1718
class="ui5-nli-group-toggle-btn"
19+
title="{{toggleBtnAccessibleName}}"
20+
aria-label="{{toggleBtnAccessibleName}}"
1821
></ui5-button>
1922

2023
{{#if hasPriority}}
@@ -41,7 +44,8 @@
4144
design="Transparent"
4245
@click="{{_onBtnOverflowClick}}"
4346
class="ui5-nli-overflow-btn"
44-
title="{{overflowBtnTitle}}"
47+
title="{{overflowBtnAccessibleName}}"
48+
aria-label="{{overflowBtnAccessibleName}}"
4549
></ui5-button>
4650
{{else}}
4751
{{#each standardActions}}
@@ -64,7 +68,8 @@
6468
icon="decline"
6569
design="Transparent"
6670
@click="{{_onBtnCloseClick}}"
67-
title="{{closeBtnTitle}}"
71+
title="{{closeBtnAccessibleName}}"
72+
aria-label="{{closeBtnAccessibleName}}"
6873
close-btn
6974
></ui5-button>
7075
{{/if}}

packages/fiori/src/NotificationListGroupItem.js

+37-9
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@ import NotificationListItemBase from "./NotificationListItemBase.js";
1111
import {
1212
NOTIFICATION_LIST_GROUP_ITEM_TXT,
1313
NOTIFICATION_LIST_GROUP_ITEM_COUNTER_TXT,
14+
NOTIFICATION_LIST_ITEM_READ,
15+
NOTIFICATION_LIST_ITEM_UNREAD,
1416
NOTIFICATION_LIST_ITEM_HIGH_PRIORITY_TXT,
1517
NOTIFICATION_LIST_ITEM_MEDIUM_PRIORITY_TXT,
1618
NOTIFICATION_LIST_ITEM_LOW_PRIORITY_TXT,
1719
NOTIFICATION_LIST_ITEM_OVERLOW_BTN_TITLE,
18-
NOTIFICATION_LIST_ITEM_CLOSE_BTN_TITLE,
20+
NOTIFICATION_LIST_GROUP_ITEM_CLOSE_BTN_TITLE,
21+
NOTIFICATION_LIST_GROUP_ITEM_TOGGLE_BTN_COLLAPSE_TITLE,
22+
NOTIFICATION_LIST_GROUP_ITEM_TOGGLE_BTN_EXPAND_TITLE,
1923
} from "./generated/i18n/i18n-defaults.js";
2024

2125
// Templates
@@ -161,12 +165,20 @@ class NotificationListGroupItem extends NotificationListItemBase {
161165
return this.items.length;
162166
}
163167

164-
get overflowBtnTitle() {
168+
get overflowBtnAccessibleName() {
165169
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_OVERLOW_BTN_TITLE);
166170
}
167171

168-
get closeBtnTitle() {
169-
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_CLOSE_BTN_TITLE);
172+
get closeBtnAccessibleName() {
173+
return this.i18nBundle.getText(NOTIFICATION_LIST_GROUP_ITEM_CLOSE_BTN_TITLE);
174+
}
175+
176+
get toggleBtnAccessibleName() {
177+
if (this.collapsed) {
178+
return this.i18nBundle.getText(NOTIFICATION_LIST_GROUP_ITEM_TOGGLE_BTN_EXPAND_TITLE);
179+
}
180+
181+
return this.i18nBundle.getText(NOTIFICATION_LIST_GROUP_ITEM_TOGGLE_BTN_COLLAPSE_TITLE);
170182
}
171183

172184
get priorityText() {
@@ -186,12 +198,24 @@ class NotificationListGroupItem extends NotificationListItemBase {
186198
}
187199

188200
get accInvisibleText() {
189-
const groupTxt = this.i18nBundle.getText(NOTIFICATION_LIST_GROUP_ITEM_TXT);
190-
const counterTxt = this.i18nBundle.getText(NOTIFICATION_LIST_GROUP_ITEM_COUNTER_TXT);
191-
const counter = this.showCounter ? `${counterTxt} ${this.itemsCount}` : "";
192-
const priorityText = this.priorityText;
201+
return `${this.groupText} ${this.readText} ${this.priorityText} ${this.counterText}`;
202+
}
203+
204+
get readText() {
205+
if (this.read) {
206+
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_READ);
207+
}
193208

194-
return `${groupTxt} ${priorityText} ${counter}`;
209+
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_UNREAD);
210+
}
211+
212+
get groupText() {
213+
return this.i18nBundle.getText(NOTIFICATION_LIST_GROUP_ITEM_TXT);
214+
}
215+
216+
get counterText() {
217+
const text = this.i18nBundle.getText(NOTIFICATION_LIST_GROUP_ITEM_COUNTER_TXT);
218+
return this.showCounter ? `${text} ${this.itemsCount}` : "";
195219
}
196220

197221
get ariaLabelledBy() {
@@ -207,6 +231,10 @@ class NotificationListGroupItem extends NotificationListItemBase {
207231
return ids.join(" ");
208232
}
209233

234+
get ariaExpanded() {
235+
return !this.collapsed;
236+
}
237+
210238
/**
211239
* Event handlers
212240
*

packages/fiori/src/NotificationListItem.hbs

+5-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
design="Transparent"
1919
@click="{{_onBtnOverflowClick}}"
2020
class="ui5-nli-overflow-btn"
21-
title="{{overflowBtnTitle}}"
21+
title="{{overflowBtnAccessibleName}}"
22+
aria-label="{{overflowBtnAccessibleName}}"
2223
></ui5-button>
2324
{{else}}
2425
{{#each standardActions}}
@@ -40,7 +41,8 @@
4041
icon="decline"
4142
design="Transparent"
4243
@click="{{_onBtnCloseClick}}"
43-
title="{{closeBtnTitle}}"
44+
title="{{closeBtnAccessibleName}}"
45+
aria-label="{{closeBtnAccessibleName}}"
4446
close-btn
4547
></ui5-button>
4648
{{/if}}
@@ -55,7 +57,7 @@
5557
</ui5-icon>
5658
{{/if}}
5759

58-
<div id="{{_id}}-heading" class="ui5-nli-title" part="heading">
60+
<div id="{{_id}}-heading" class="ui5-nli-heading" part="heading">
5961
{{heading}}
6062
</div>
6163
</div>

packages/fiori/src/NotificationListItem.js

+3-16
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,6 @@ const metadata = {
5757
type: Boolean,
5858
},
5959

60-
/**
61-
* Defines if the <code>notification</code> is new or has been already read.
62-
* <br><br>
63-
* <b>Note:</b> if set to <code>false</code> the <code>heading</code> has bold font,
64-
* if set to true - it has a normal font.
65-
* @type {boolean}
66-
* @defaultvalue false
67-
* @public
68-
*/
69-
read: {
70-
type: Boolean,
71-
},
72-
7360
/**
7461
* Defines the state of the <code>heading</code> and <code>description</code>,
7562
* if less or more information is displayed.
@@ -236,11 +223,11 @@ class NotificationListItem extends NotificationListItemBase {
236223
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_SHOW_MORE);
237224
}
238225

239-
get overflowBtnTitle() {
226+
get overflowBtnAccessibleName() {
240227
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_OVERLOW_BTN_TITLE);
241228
}
242229

243-
get closeBtnTitle() {
230+
get closeBtnAccessibleName() {
244231
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_CLOSE_BTN_TITLE);
245232
}
246233

@@ -257,7 +244,7 @@ class NotificationListItem extends NotificationListItemBase {
257244
}
258245

259246
get headingDOM() {
260-
return this.shadowRoot.querySelector(".ui5-nli-title");
247+
return this.shadowRoot.querySelector(".ui5-nli-heading");
261248
}
262249

263250
get headingHeight() {

packages/fiori/src/NotificationListItemBase.js

+13
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ const metadata = {
5555
type: Boolean,
5656
},
5757

58+
/**
59+
* Defines if the <code>notification</code> is new or has been already read.
60+
* <br><br>
61+
* <b>Note:</b> if set to <code>false</code> the <code>heading</code> has bold font,
62+
* if set to true - it has a normal font.
63+
* @type {boolean}
64+
* @defaultvalue false
65+
* @public
66+
*/
67+
read: {
68+
type: Boolean,
69+
},
70+
5871
/**
5972
* Defines if a busy indicator would be displayed over the item.
6073
* @type {boolean}

packages/fiori/src/i18n/messagebundle.properties

+9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ NOTIFICATION_LIST_GROUP_ITEM_TXT=Notification group
5454
#XTXT: Text for the NotificationListGroupItem counter
5555
NOTIFICATION_LIST_GROUP_ITEM_COUNTER_TXT=Counter
5656

57+
#XBUT: accessible name for 'Close All' button in the NotificationListGroupItem
58+
NOTIFICATION_LIST_GROUP_ITEM_CLOSE_BTN_TITLE=Close All
59+
60+
#XBUT: accessible name for 'Toggle' button in the NotificationListGroupItem
61+
NOTIFICATION_LIST_GROUP_ITEM_TOGGLE_BTN_COLLAPSE_TITLE=Collapse Group
62+
63+
#XBUT: accessible name for 'Toggle' button in the NotificationListGroupItem
64+
NOTIFICATION_LIST_GROUP_ITEM_TOGGLE_BTN_EXPAND_TITLE=Expand Group
65+
5766
#XACT: ARIA announcement for timeline label
5867
TIMELINE_ARIA_LABEL=Timeline
5968

packages/fiori/src/themes/NotificationListGroupItem.css

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
display: none;
1010
}
1111

12+
:host([read]) .ui5-nli-group-heading {
13+
font-weight: normal;
14+
}
15+
1216
.ui5-nli-group-root {
1317
display: flex;
1418
flex-direction: column;
@@ -36,6 +40,7 @@
3640
color: var(--sapGroup_TitleTextColor);
3741
font-family: "72override", var(--sapFontFamily);
3842
font-size: var(--sapFontHeader6Size);
43+
font-weight: bold;
3944
white-space: nowrap;
4045
overflow: hidden;
4146
text-overflow: ellipsis;

packages/fiori/src/themes/NotificationListItem.css

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@import "./NotificationListItemBase.css";
22
@import "./NotificationPrioIcon.css";
33

4-
:host(:not([wrap])) .ui5-nli-title {
4+
:host(:not([wrap])) .ui5-nli-heading {
55
display: -webkit-box;
66
-webkit-line-clamp: 2;
77
-webkit-box-orient: vertical;
@@ -15,15 +15,15 @@
1515
overflow: hidden;
1616
}
1717

18-
:host([_show-more-pressed]) .ui5-nli-title {
18+
:host([_show-more-pressed]) .ui5-nli-heading {
1919
-webkit-line-clamp: unset;
2020
}
2121

2222
:host([_show-more-pressed]) .ui5-nli-description {
2323
-webkit-line-clamp: unset;
2424
}
2525

26-
:host([read]) .ui5-nli-title {
26+
:host([read]) .ui5-nli-heading {
2727
font-weight: normal;
2828
}
2929

@@ -32,11 +32,11 @@
3232
max-height: 32px;
3333
}
3434

35-
:host(:not([wrap])) .ui5-nli-content--ie .ui5-nli-title {
35+
:host(:not([wrap])) .ui5-nli-content--ie .ui5-nli-heading {
3636
max-height: 32px;
3737
}
3838

39-
:host([_show-more-pressed]) .ui5-nli-content--ie .ui5-nli-title {
39+
:host([_show-more-pressed]) .ui5-nli-content--ie .ui5-nli-heading {
4040
max-height: inherit;
4141
}
4242

@@ -71,7 +71,7 @@
7171
box-sizing: border-box;
7272
}
7373

74-
.ui5-nli-title {
74+
.ui5-nli-heading {
7575
color: var(--sapGroup_TitleTextColor);
7676
font-weight: bold;
7777
font-size: var(--sapFontHeader6Size);

packages/fiori/test/pages/NotificationListGroupItem.html

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ <h3>Properties</h3>
2727
<li>collapsed (default: "false")</li>
2828
<li>show-close (default: "false")</li>
2929
<li>show-counter (default: "false")</li>
30+
<li>read (default: "false")</li>
3031
</ul>
3132

3233
<h3>Slots</h3>
@@ -155,6 +156,7 @@ <h3>Events on ui5-list level</h3>
155156
id="busyGroup"
156157
show-close
157158
show-counter
159+
read
158160
priority="High"
159161
heading="Meetings With a very long title - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent feugiat, turpis vel scelerisque pharetra, tellus odio vehicula dolor, nec elementum lectus turpis at nunc."
160162
>

packages/fiori/test/specs/NotificationList.spec.js

+24-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ describe("Notification List Item Tests", () => {
113113
});
114114

115115
it("tests List Group Item ACC invisible text", () => {
116-
const EXPECTED_RESULT = "Notification group High Priority Counter 2";
116+
const EXPECTED_RESULT = "Notification group unread High Priority Counter 2";
117117
const firstGroupItem = $("#nlgi1");
118118
const invisibleText = firstGroupItem.shadow$(".ui5-hidden-text");
119119

@@ -122,6 +122,29 @@ describe("Notification List Item Tests", () => {
122122
"The invisible text is correct.");
123123
});
124124

125+
it("tests List Group Item aria-expanded aria-label when collapsed and expanded", () => {
126+
const groupItem = browser.$("#nlgi3");
127+
const goupItemRoot = groupItem.shadow$(".ui5-nli-group-root");
128+
const goupItemToggleBtn = groupItem.shadow$(".ui5-nli-group-toggle-btn");
129+
const TOGGLE_BUTTON_EXPAND_GROUP = "Expand Group";
130+
const TOGGLE_BUTTON_COLLAPSE_GROUP = "Collapse Group";
131+
132+
// assert
133+
assert.strictEqual(goupItemRoot.getAttribute("aria-expanded"), "false",
134+
"The aria-expanded value is correct.");
135+
assert.strictEqual(goupItemToggleBtn.getAttribute("aria-label"), TOGGLE_BUTTON_EXPAND_GROUP,
136+
"The aria-label value is correct.");
137+
138+
// act
139+
goupItemToggleBtn.click();
140+
141+
// assert
142+
assert.strictEqual(goupItemRoot.getAttribute("aria-expanded"), "true",
143+
"The aria-expanded value is correct.");
144+
assert.strictEqual(goupItemToggleBtn.getAttribute("aria-label"), TOGGLE_BUTTON_COLLAPSE_GROUP,
145+
"The aria-label value is correct.");
146+
});
147+
125148
it("tests List Group Item ACC ariaLabelledBy", () => {
126149
const firstGroupItem = $("#nlgi1");
127150
const firstGroupItemRoot = firstGroupItem.shadow$(".ui5-nli-group-root");

0 commit comments

Comments
 (0)