Skip to content

Commit 1673476

Browse files
committed
Use an event instead of a promise when closing an element
1 parent 6ff5686 commit 1673476

File tree

2 files changed

+52
-28
lines changed

2 files changed

+52
-28
lines changed

ts/WoltLabSuite/Core/Component/Snackbar.ts

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,18 @@ enum SnackbarType {
66
Progress,
77
}
88

9-
class Snackbar {
9+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
10+
class Snackbar extends EventTarget {
1011
#message: string = "";
1112
readonly #type: SnackbarType;
1213
#snackbarElement: HTMLElement;
13-
readonly #hidden: Promise<void>;
14-
#hiddenResolve: () => void;
1514

1615
constructor(message: string, type: SnackbarType) {
16+
super();
17+
1718
this.#message = message;
1819
this.#type = type;
1920

20-
this.#hidden = new Promise<void>((resolve) => {
21-
this.#hiddenResolve = resolve;
22-
});
2321
this.#render();
2422
}
2523

@@ -58,14 +56,17 @@ class Snackbar {
5856

5957
const message = document.createElement("div");
6058
message.classList.add("snackbar__message");
59+
if (this.isProgress()) {
60+
message.setAttribute("aria-live", "polite");
61+
}
6162
message.append(this.message);
6263

6364
const dismissButton = document.createElement("button");
6465
dismissButton.type = "button";
6566
dismissButton.classList.add("snackbar__dismissButton");
6667
dismissButton.setAttribute("aria-label", getPhrase("wcf.global.button.close"));
6768
dismissButton.addEventListener("click", () => {
68-
this.hide();
69+
this.close();
6970
});
7071

7172
const dismissIcon = document.createElement("fa-icon");
@@ -95,20 +96,40 @@ class Snackbar {
9596
return this.#type == SnackbarType.Progress;
9697
}
9798

98-
hide(): void {
99-
this.#snackbarElement.remove();
100-
this.#hiddenResolve();
99+
isVisible(): boolean {
100+
return this.#snackbarElement.parentElement !== null;
101101
}
102102

103-
get hidden(): Promise<void> {
104-
return this.#hidden;
103+
close(): void {
104+
if (!this.isVisible()) {
105+
return;
106+
}
107+
108+
this.#snackbarElement.remove();
109+
110+
this.dispatchEvent(new CustomEvent("close"));
105111
}
106112

107113
get element(): HTMLElement {
108114
return this.#snackbarElement;
109115
}
110116
}
111117

118+
interface SnackbarEventMap {
119+
close: CustomEvent<void>;
120+
}
121+
122+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
123+
interface Snackbar extends EventTarget {
124+
addEventListener: {
125+
<T extends keyof SnackbarEventMap>(
126+
type: T,
127+
listener: (this: Snackbar, ev: SnackbarEventMap[T]) => any,
128+
options?: boolean | AddEventListenerOptions,
129+
): void;
130+
} & HTMLElement["addEventListener"];
131+
}
132+
112133
let snackbarContainer: SnackbarContainer;
113134

114135
function getSnackbarContainer(): SnackbarContainer {
@@ -132,13 +153,13 @@ class SnackbarContainer {
132153
addSnackbar(snackbar: Snackbar): void {
133154
if (this.#snackbars.length > 2) {
134155
const oldSnackbar = this.#snackbars.shift();
135-
oldSnackbar?.hide();
156+
oldSnackbar?.close();
136157
}
137158

138159
this.#snackbars.push(snackbar);
139160
this.#element.prepend(snackbar.element);
140161

141-
void snackbar.hidden.then(() => {
162+
void snackbar.addEventListener("close", () => {
142163
const i = this.#snackbars.indexOf(snackbar);
143164
if (i !== -1) {
144165
this.#snackbars = this.#snackbars.splice(i, 1);

wcfsetup/install/files/js/WoltLabSuite/Core/Component/Snackbar.js

Lines changed: 17 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)