Skip to content

refactor(ui5-li-notification): change close event to non-bubbling #11905

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions packages/fiori/cypress/specs/base/Events.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import Dialog from "@ui5/webcomponents/dist/Dialog.js";
import NotificationListItem from "../../../src/NotificationListItem.js";
import NotificationList from "../../../src/NotificationList.js";
import { setAnimationMode } from "@ui5/webcomponents-base/dist/config/AnimationMode.js";
import AnimationMode from "@ui5/webcomponents-base/dist/types/AnimationMode.js";

describe("Event bubbling", () => {
before(() => {
cy.wrap({ setAnimationMode })
.invoke("setAnimationMode", AnimationMode.None);
})

it("test bubbling events", () => {
cy.mount(
<div id="app">
<Dialog id="myDialog" headerText="Dialog">
<NotificationList id="myNotList" header-text="Notifications">
<NotificationListItem id="myNotItem" show-close
title-text="Single line notification."
state="Information">
<span slot="footnotes">Office Notifications</span>
<span slot="footnotes">3 Days</span>
</NotificationListItem>
</NotificationList>
</Dialog>
</div>
);

cy.get("#app")
.as("app");

cy.get("[ui5-dialog]")
.as("dialog");

cy.get("[ui5-notification-list]")
.as("notificationList");

cy.get("[ui5-li-notification]")
.as("notificationListItem");

cy.get("@app")
.then(app => {
app.get(0).addEventListener("ui5-close", cy.stub().as("appClosed"));
});

cy.get("@dialog")
.then(dialog => {
dialog.get(0).addEventListener("ui5-close", cy.stub().as("dialogClosed"));
});

cy.get("@notificationList")
.then(notificationList => {
notificationList.get(0).addEventListener("ui5-close", cy.stub().as("notListClosed"));
});

cy.get("@notificationListItem")
.then(notificationListItem => {
notificationListItem.get(0).addEventListener("ui5-close", cy.stub().as("notListItemClosed"));
});

cy.get("@dialog").invoke("attr", "open", true);

// act - close NotificationListItem
cy.get("@notificationListItem")
.shadow()
.find(".ui5-nli-close-btn")
.realClick();

// assert - the close event of the NotificationListItem does not bubble
cy.get("@notListItemClosed")
.should("have.been.calledOnce");
cy.get("@notListClosed")
.should("have.been.not.called");
cy.get("@dialogClosed")
.should("have.been.not.called");
cy.get("@appClosed")
.should("have.been.not.called");
});
});
12 changes: 11 additions & 1 deletion packages/fiori/src/NotificationListItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,22 @@ const ICON_PER_STATUS_DESIGN = {
* @param {HTMLElement} item the closed item.
* @public
*/
@event("close", {
@event("close")

/**
* Fired when the `Close` button is pressed.
* @param {HTMLElement} item the closed item.
* @private
*/
@event("_close", {
bubbles: true,
})

class NotificationListItem extends NotificationListItemBase {
eventDetails!: NotificationListItemBase["eventDetails"] & {
_press: NotificationListItemPressEventDetail,
close: NotificationListItemCloseEventDetail,
_close: NotificationListItemCloseEventDetail,
}
/**
* Defines if the `titleText` and `description` should wrap,
Expand Down Expand Up @@ -499,6 +507,7 @@ class NotificationListItem extends NotificationListItemBase {

if (isDelete(e)) {
this.fireDecoratorEvent("close", { item: this });
this.fireDecoratorEvent("_close", { item: this });
}

if (isF10Shift(e)) {
Expand All @@ -512,6 +521,7 @@ class NotificationListItem extends NotificationListItemBase {

_onBtnCloseClick() {
this.fireDecoratorEvent("close", { item: this });
this.fireDecoratorEvent("_close", { item: this });
}

_onBtnMenuClick() {
Expand Down
58 changes: 58 additions & 0 deletions packages/fiori/test/pages/EventBubbling.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Event Bubbling for Fiori</title>
<script src="%VITE_BUNDLE_PATH%" type="module"></script>
</head>

<body>
<div id="app">
<ui5-dialog id="myDialog" header-text="Dialog With Dropdowns" open>
<ui5-notification-list id="myNotList" header-text="Notifications">
<ui5-li-notification id="myNotItem" show-close
title-text="Single line notification."
state="Information">
<span slot="footnotes">Office Notifications</span>
<span slot="footnotes">3 Days</span>
</ui5-li-notification>
</ui5-notification-list>
</ui5-dialog>
</div>
</body>

<script>
app.addEventListener("close", function(e) {
console.log("[X] App on close")
});

app.addEventListener("item-close", function(e) {
console.log("App on item-close")
});

myDialog.addEventListener("close", function(e) {
console.log("[X] Dialog on close")
});

myDialog.addEventListener("item-close", function(e) {
console.log("Dialog on item-close")
});

myNotList.addEventListener("close", function(e) {
console.log("[X] Notification List on close")
});

myNotList.addEventListener("item-close", function(e) {
console.log("Notification List on item-close")
});

myNotItem.addEventListener("close", function(e) {
console.log("Notification Item on close")
});

btnOpen.addEventListener("click", function(e) {
myMenu.open = true;
});
</script>
</html>
2 changes: 1 addition & 1 deletion packages/main/src/ListTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default function ListTemplate(this: List) {
onDrop={this._ondrop}
onDragLeave={this._ondragleave}
// events bubbling from slotted items
onui5-close={this.onItemClose}
onui5-_close={this.onItemClose}
onui5-toggle={this.onItemToggle}
onui5-request-tabindex-change={this.onItemTabIndexChange}
onui5-_focused={this.onItemFocused}
Expand Down
2 changes: 1 addition & 1 deletion packages/main/test/pages/EventBubbling.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Event Bubbling</title>
<title>Event Bubbling for Main</title>
<script src="%VITE_BUNDLE_PATH%" type="module"></script>
</head>

Expand Down
Loading