Skip to content

Commit ef62f81

Browse files
authored
feat(ui5-li-notification, ui5-li-notification-group): introduce new components (#1576)
The component covers the main functionaly of the sap.m.NotificationListItem. It is meant to display a notification and has a rich set of properties and slots to do it. Fixes: #1478
1 parent b898cd3 commit ef62f81

36 files changed

+3205
-8
lines changed

docs/Public Module Imports.md

+3
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ For API documentation and samples, please check the [UI5 Web Components Playgrou
136136
| Shell Bar Item | `ui5-shellbar-item` | `import "@ui5/webcomponents-fiori/dist/ShellBarItem.js";` |
137137
| Product Switch | `ui5-product-switch` | `import "@ui5/webcomponents-fiori/dist/ProductSwitch.js";` |
138138
| Product Switch Item | `ui5-product-switch-item` | `import "@ui5/webcomponents-fiori/dist/ProductSwitchItem.js";` |
139+
| Notification List Item | `ui5-li-notifcation` | `import "@ui5/webcomponents-fiori/dist/NotifcationListItem.js";` |
140+
| Notification Group List Item|`ui5-li-notification-group`| `import "@ui5/webcomponents-fiori/dist/NotifcationListGroupItem.js";`|
141+
| Notification Overflow Action| `ui5-notification-overflow-action` | `import "@ui5/webcomponents-fiori/dist/NotificationOverflowAction.js";`|
139142

140143
### 2. Assets
141144

packages/base/src/util/TabbableElements.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ const getLastTabbableElement = node => {
1212
const getTabbables = (nodes, tabbables) => {
1313
const tabbablesNodes = tabbables || [];
1414

15+
if (!nodes) {
16+
return tabbablesNodes;
17+
}
18+
1519
Array.from(nodes).forEach(currentNode => {
16-
if (currentNode.nodeType === Node.TEXT_NODE) {
20+
if (currentNode.nodeType === Node.TEXT_NODE || currentNode.nodeType === Node.COMMENT_NODE) {
1721
return;
1822
}
1923

packages/fiori/bundle.esm.js

+3
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ import ShellBar from "./dist/ShellBar.js";
1313
import ShellBarItem from "./dist/ShellBarItem.js";
1414
import UploadCollection from "./dist/UploadCollection.js";
1515
import UploadCollectionItem from "./dist/UploadCollectionItem.js";
16+
import NotificationListItem from "./dist/NotificationListItem.js"
17+
import NotificationListGroupItem from "./dist/NotificationListGroupItem.js";
18+
import NotificationOverflowAction from "./dist/NotificationOverflowAction.js";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<ui5-popover
2+
class="ui5-notification-overflow-popover"
3+
placement-type="Bottom"
4+
horizontal-align="Right"
5+
no-arrow
6+
>
7+
<div class="ui5-notification-overflow-list">
8+
{{#each overflowActions}}
9+
<ui5-button
10+
icon="{{this.icon}}"
11+
design="Transparent"
12+
@click="{{this.press}}"
13+
?disabled="{{this.disabled}}"
14+
design="{{this.design}}"
15+
data-ui5-external-action-item-id="{{this.refItemid}}"
16+
>{{this.text}}
17+
</ui5-button>
18+
{{/each}}
19+
</div>
20+
</ui5-popover>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<li
2+
class="ui5-nli-group-root ui5-nli-focusable"
3+
@focusin="{{_onfocusin}}"
4+
@focusout="{{_onfocusout}}"
5+
@keydown="{{_onkeydown}}"
6+
role="option"
7+
tabindex="{{_tabIndex}}"
8+
dir="{{rtl}}"
9+
aria-labelledby="{{ariaLabelledBy}}"
10+
>
11+
<div class="ui5-nli-group-header">
12+
<ui5-button
13+
icon="navigation-right-arrow"
14+
design="Transparent"
15+
@click="{{_onBtnToggleClick}}"
16+
class="ui5-nli-group-toggle-btn"
17+
></ui5-button>
18+
19+
{{#if hasPriority}}
20+
<ui5-icon
21+
class="ui5-prio-icon ui5-prio-icon--{{priorityIcon}}"
22+
name="{{priorityIcon}}">
23+
</ui5-icon>
24+
{{/if}}
25+
26+
<div id="{{_id}}-heading" class="ui5-nli-group-heading" part="heading">
27+
{{heading}}
28+
</div>
29+
30+
{{#if showCounter}}
31+
<span class="ui5-nli-group-counter">({{itemsCount}})</span>
32+
{{/if}}
33+
34+
<div class="ui5-nli-group-divider"></div>
35+
36+
{{#unless collapsed}}
37+
{{#if showOverflow}}
38+
<ui5-button
39+
icon="overflow"
40+
design="Transparent"
41+
@click="{{_onBtnOverflowClick}}"
42+
class="ui5-nli-overflow-btn"
43+
title="{{overflowBtnTitle}}"
44+
></ui5-button>
45+
{{else}}
46+
{{#each standardActions}}
47+
<ui5-button
48+
icon="{{this.icon}}"
49+
class="ui5-nli-action"
50+
?disabled="{{this.disabled}}"
51+
design="{{this.design}}"
52+
@click="{{this.press}}"
53+
data-ui5-external-action-item-id="{{this.refItemid}}"
54+
>
55+
{{this.text}}
56+
</ui5-button>
57+
{{/each}}
58+
{{/if}}
59+
{{/unless}}
60+
61+
{{#if showClose}}
62+
<ui5-button
63+
icon="decline"
64+
design="Transparent"
65+
@click="{{_onBtnCloseClick}}"
66+
title="{{closeBtnTitle}}"
67+
close-btn
68+
></ui5-button>
69+
{{/if}}
70+
71+
<span id="{{_id}}-invisibleText" class="ui5-hidden-text">{{accInvisibleText}}</span>
72+
</div>
73+
74+
<ui5-list class="ui5-nli-group-items">
75+
<slot></slot>
76+
</ui5-list>
77+
</li>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
2+
import { fetchI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
3+
import Priority from "@ui5/webcomponents/dist/types/Priority.js";
4+
import List from "@ui5/webcomponents/dist/List.js";
5+
import Button from "@ui5/webcomponents/dist/Button.js";
6+
import Icon from "@ui5/webcomponents/dist/Icon.js";
7+
import Popover from "@ui5/webcomponents/dist/Popover.js";
8+
import NotificationListItemBase from "./NotificationListItemBase.js";
9+
10+
// Texts
11+
import {
12+
NOTIFICATION_LIST_GROUP_ITEM_TXT,
13+
NOTIFICATION_LIST_GROUP_ITEM_COUNTER_TXT,
14+
NOTIFICATION_LIST_ITEM_HIGH_PRIORITY_TXT,
15+
NOTIFICATION_LIST_ITEM_MEDIUM_PRIORITY_TXT,
16+
NOTIFICATION_LIST_ITEM_LOW_PRIORITY_TXT,
17+
NOTIFICATION_LIST_ITEM_OVERLOW_BTN_TITLE,
18+
NOTIFICATION_LIST_ITEM_CLOSE_BTN_TITLE,
19+
} from "./generated/i18n/i18n-defaults.js";
20+
21+
// Templates
22+
import NotificationListGroupItemTemplate from "./generated/templates/NotificationListGroupItemTemplate.lit.js";
23+
24+
// Styles
25+
import NotificationListGroupItemCss from "./generated/themes/NotificationListGroupItem.css.js";
26+
27+
/**
28+
* @public
29+
*/
30+
const metadata = {
31+
tag: "ui5-li-notification-group",
32+
managedSlots: true,
33+
properties: /** @lends sap.ui.webcomponents.fiori.NotificationListGroupItem.prototype */ {
34+
35+
/**
36+
* Defines if the group is collapsed or expanded.
37+
* @type {boolean}
38+
* @defaultvalue false
39+
* @public
40+
*/
41+
collapsed: {
42+
type: Boolean,
43+
},
44+
45+
/**
46+
* Defines if the items <code>counter</code> would be displayed.
47+
* @type {boolean}
48+
* @defaultvalue false
49+
* @public
50+
*/
51+
showCounter: {
52+
type: Boolean,
53+
},
54+
},
55+
slots: /** @lends sap.ui.webcomponents.fiori.NotificationListGroupItem.prototype */ {
56+
57+
/**
58+
* Defines the items of the <code>ui5-li-notification-group</code>,
59+
* usually <code>ui5-li-notification</code> items.
60+
*
61+
* @type {HTMLElement[]}
62+
* @slot
63+
* @public
64+
*/
65+
"default": {
66+
propertyName: "items",
67+
type: HTMLElement,
68+
},
69+
},
70+
events: /** @lends sap.ui.webcomponents.fiori.NotificationListGroupItem.prototype */ {
71+
72+
/**
73+
* Fired when the <code>ui5-li-notification-group</code> is expanded/collapsed by user interaction.
74+
*
75+
* @event
76+
* @public
77+
*/
78+
toggle: {},
79+
},
80+
};
81+
82+
/**
83+
* @class
84+
*
85+
* <h3 class="comment-api-title">Overview</h3>
86+
* The <code>ui5-li-notification-group</code> is a special type of list item,
87+
* that unlike others can group items within self, usually <code>ui5-li-notification</code> items.
88+
* <br>
89+
*
90+
* The component consists of:
91+
* <ul>
92+
* <li><code>Toggle</code> button to expand and collapse the group</li>
93+
* <li><code>Priority</code> icon to display the priority of the group</li>
94+
* <li><code>Heading</code> to entitle the group</li>
95+
* <li>Custom actions - with the use of <code>ui5-notification-overflow-action</code></li>
96+
* <li>Items of the group</li>
97+
* </ul>
98+
*
99+
* <h3>Usage</h3>
100+
* The component can be used in a standard <code>ui5-list</code>.
101+
*
102+
* <h3>ES6 Module Import</h3>
103+
*
104+
* <code>import @ui5/webcomponents/dist/NotificationListGroupItem.js";</code>
105+
* <br>
106+
* <code>import @ui5/webcomponents/dist/NotificationOverflowAction.js";</code> (optional)
107+
* @constructor
108+
* @author SAP SE
109+
* @alias sap.ui.webcomponents.fiori.NotificationListGroupItem
110+
* @extends NotificationListItemBase
111+
* @tagname ui5-li-notification-group
112+
* @since 1.0.0-rc.8
113+
* @appenddocs NotificationOverflowAction
114+
* @public
115+
*/
116+
class NotificationListGroupItem extends NotificationListItemBase {
117+
static get metadata() {
118+
return metadata;
119+
}
120+
121+
static get render() {
122+
return litRender;
123+
}
124+
125+
static get styles() {
126+
return NotificationListGroupItemCss;
127+
}
128+
129+
static get template() {
130+
return NotificationListGroupItemTemplate;
131+
}
132+
133+
static async onDefine() {
134+
await Promise.all([
135+
List.define(),
136+
Button.define(),
137+
Icon.define(),
138+
Popover.define(),
139+
fetchI18nBundle("@ui5/webcomponents-fiori"),
140+
]);
141+
}
142+
143+
get itemsCount() {
144+
return this.items.length;
145+
}
146+
147+
get overflowBtnTitle() {
148+
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_OVERLOW_BTN_TITLE);
149+
}
150+
151+
get closeBtnTitle() {
152+
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_CLOSE_BTN_TITLE);
153+
}
154+
155+
get priorityText() {
156+
if (this.priority === Priority.High) {
157+
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_HIGH_PRIORITY_TXT);
158+
}
159+
160+
if (this.priority === Priority.Medium) {
161+
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_MEDIUM_PRIORITY_TXT);
162+
}
163+
164+
if (this.priority === Priority.Low) {
165+
return this.i18nBundle.getText(NOTIFICATION_LIST_ITEM_LOW_PRIORITY_TXT);
166+
}
167+
168+
return "";
169+
}
170+
171+
get accInvisibleText() {
172+
const groupTxt = this.i18nBundle.getText(NOTIFICATION_LIST_GROUP_ITEM_TXT);
173+
const counterTxt = this.i18nBundle.getText(NOTIFICATION_LIST_GROUP_ITEM_COUNTER_TXT);
174+
const counter = this.showCounter ? `${counterTxt} ${this.itemsCount}` : "";
175+
const priorityText = this.priorityText;
176+
177+
return `${groupTxt} ${priorityText} ${counter}`;
178+
}
179+
180+
get ariaLabelledBy() {
181+
const id = this._id;
182+
const ids = [];
183+
184+
if (this.hasHeading) {
185+
ids.push(`${id}-heading`);
186+
}
187+
188+
ids.push(`${id}-invisibleText`);
189+
190+
return ids.join(" ");
191+
}
192+
193+
/**
194+
* Event handlers
195+
*
196+
*/
197+
_onBtnToggleClick() {
198+
this.collapsed = !this.collapsed;
199+
this.fireEvent("toggle", { item: this });
200+
}
201+
}
202+
203+
NotificationListGroupItem.define();
204+
205+
export default NotificationListGroupItem;

0 commit comments

Comments
 (0)