Skip to content

Commit 0c06817

Browse files
committed
Add animations when the element appears and disappears
1 parent 1673476 commit 0c06817

File tree

3 files changed

+101
-9
lines changed

3 files changed

+101
-9
lines changed

ts/WoltLabSuite/Core/Component/Snackbar.ts

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,26 +88,44 @@ class Snackbar extends EventTarget {
8888

8989
#setHideTimeout(): void {
9090
window.setTimeout(() => {
91-
//this.hide();
92-
}, 5000);
91+
this.close();
92+
}, 3_000);
9393
}
9494

9595
isProgress(): boolean {
9696
return this.#type == SnackbarType.Progress;
9797
}
9898

9999
isVisible(): boolean {
100-
return this.#snackbarElement.parentElement !== null;
100+
if (this.#snackbarElement.parentElement === null) {
101+
return false;
102+
}
103+
104+
if (this.#snackbarElement.classList.contains("snackbar--closing")) {
105+
return false;
106+
}
107+
108+
return true;
101109
}
102110

103111
close(): void {
104112
if (!this.isVisible()) {
105113
return;
106114
}
107115

108-
this.#snackbarElement.remove();
109-
110116
this.dispatchEvent(new CustomEvent("close"));
117+
118+
// The animation to move the element vertically relative to its height
119+
// requires the value to be computed first.
120+
const height = Math.trunc(
121+
getSnackbarContainer().getGapValue() + this.#snackbarElement.getBoundingClientRect().height,
122+
);
123+
this.#snackbarElement.style.setProperty("--height", `${height}px`);
124+
125+
this.#snackbarElement.classList.add("snackbar--closing");
126+
this.#snackbarElement.addEventListener("animationend", () => {
127+
this.#snackbarElement.remove();
128+
});
111129
}
112130

113131
get element(): HTMLElement {
@@ -166,6 +184,16 @@ class SnackbarContainer {
166184
}
167185
});
168186
}
187+
188+
getGapValue(): number {
189+
const gap = window.getComputedStyle(this.#element).gap;
190+
const match = gap.match(/^(\d+)px$/);
191+
if (match === null) {
192+
return 0;
193+
}
194+
195+
return parseInt(match[1]);
196+
}
169197
}
170198

171199
export function showSuccessSnackbar(message: string): Snackbar {

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

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

wcfsetup/install/files/style/ui/snackbar.scss

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,45 @@
77
gap: 10px;
88
}
99

10+
@keyframes snackbarIn {
11+
0% {
12+
opacity: 0;
13+
transform: translateX(-100%);
14+
}
15+
50% {
16+
opacity: 1;
17+
transform: translateX(-50%);
18+
}
19+
100% {
20+
opacity: 1;
21+
transform: translateX(0);
22+
}
23+
}
24+
25+
@keyframes snackbarOut {
26+
0% {
27+
opacity: 1;
28+
transform: translateX(0);
29+
margin-bottom: 0;
30+
}
31+
25% {
32+
opacity: 1;
33+
transform: translateX(-50%);
34+
}
35+
50% {
36+
margin-bottom: 0;
37+
opacity: 0;
38+
transform: translateX(-100%);
39+
}
40+
100% {
41+
margin-bottom: calc(var(--height) * -1);
42+
opacity: 0;
43+
transform: translateX(-100%);
44+
}
45+
}
46+
1047
.snackbar {
48+
animation: snackbarIn 0.12s ease-in-out;
1149
color: #fff;
1250
background-color: rgb(50, 50, 50);
1351
display: flex;
@@ -22,6 +60,11 @@
2260
min-width: 200px;
2361
}
2462

63+
.snackbar.snackbar--closing {
64+
animation-name: snackbarOut;
65+
animation-duration: .24s;
66+
}
67+
2568
.snackbar__icon {
2669
border-right: 2px solid transparent;
2770
display: flex;

0 commit comments

Comments
 (0)