Skip to content

Commit 2f4fd6e

Browse files
authored
fix(ui5-toast): keep toast open when hovered (#1294)
Fixes: #1292
1 parent 0c408d2 commit 2f4fd6e

File tree

4 files changed

+79
-56
lines changed

4 files changed

+79
-56
lines changed

packages/main/src/Toast.hbs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<div class="ui5-toast-root"
2-
dir="{{rtl}}">
3-
<div class="ui5-toast-content"
4-
role="alert"
5-
style="{{styles.root}}"
6-
@transitionend="{{_ontransitionend}}">
7-
<bdi>
8-
<slot></slot>
9-
</bdi>
10-
</div>
2+
role="alert"
3+
style="{{styles.root}}"
4+
dir="{{rtl}}"
5+
@mouseover="{{_onmouseover}}"
6+
@mouseleave="{{_onmouseleave}}"
7+
@transitionend="{{_ontransitionend}}">
8+
<bdi>
9+
<slot></slot>
10+
</bdi>
1111
</div>

packages/main/src/Toast.js

+21-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ const metadata = {
6868
open: {
6969
type: Boolean,
7070
},
71+
72+
/**
73+
* Indicates whether <code>ui5-toast</code> is hovered.
74+
* @type {boolean}
75+
* @private
76+
*/
77+
hover: {
78+
type: Boolean,
79+
},
7180
},
7281
slots: /** @lends sap.ui.webcomponents.main.Toast.prototype */ {
7382
/**
@@ -196,7 +205,7 @@ class Toast extends UI5Element {
196205
"transition-delay": this.open ? `${this.duration - transitionDuration}ms` : "",
197206

198207
// We alter the opacity property, in order to trigger transition
199-
"opacity": this.open ? "0" : "",
208+
"opacity": this.open && !this.hover ? "0" : "",
200209
},
201210
};
202211
}
@@ -208,8 +217,19 @@ class Toast extends UI5Element {
208217
}
209218

210219
_ontransitionend() {
220+
if (this.hover) {
221+
return;
222+
}
211223
this.open = false;
212224
}
225+
226+
_onmouseover() {
227+
this.hover = true;
228+
}
229+
230+
_onmouseleave() {
231+
this.hover = false;
232+
}
213233
}
214234

215235
Toast.define();

packages/main/src/themes/Toast.css

+44-38
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,12 @@
44
font-size: var(--sapFontMediumSize);
55
}
66

7-
.ui5-toast-root {
8-
position: fixed;
9-
left: 0;
10-
right: 0;
11-
top: 0;
12-
bottom: 0;
13-
width: 100%;
14-
display: none;
15-
height: 100%;
16-
pointer-events: none;
17-
overflow: hidden;
18-
z-index: 999;
19-
justify-content: center;
20-
align-items: flex-end;
7+
:host([open]) .ui5-toast-root {
8+
display: block;
219
}
2210

23-
.ui5-toast-content {
11+
.ui5-toast-root {
12+
display: none;
2413
box-sizing: border-box;
2514
max-width: 15rem;
2615
overflow: hidden;
@@ -41,48 +30,65 @@
4130
text-align: center;
4231
text-overflow: ellipsis;
4332
white-space: pre-line;
33+
z-index: 999;
4434
}
4535

46-
:host([open]) .ui5-toast-root {
47-
display: flex;
36+
.ui5-toast-root {
37+
position: fixed;
38+
}
39+
40+
:host(:not([placement])) .ui5-toast-root {
41+
bottom: 2rem;
42+
left: 50%;
43+
transform: translateX(-50%);
4844
}
4945

5046
:host([placement="TopStart"]) .ui5-toast-root {
51-
justify-content: flex-start;
52-
align-items: flex-start;
47+
top: 2rem;
48+
left: 2rem;
5349
}
5450

55-
:host([placement="TopCenter"]) .ui5-toast-root {
56-
justify-content: center;
57-
align-items: flex-start;
51+
:host([placement="MiddleStart"]) .ui5-toast-root {
52+
left: 2rem;
53+
top: 50%;
54+
transform: translateY(-50%);
5855
}
5956

60-
:host([placement="TopEnd"]) .ui5-toast-root {
61-
justify-content: flex-end;
62-
align-items: flex-start;
57+
:host([placement="BottomStart"]) .ui5-toast-root {
58+
left: 2rem;
59+
bottom: 2rem;
6360
}
6461

65-
:host([placement="MiddleStart"]) .ui5-toast-root {
66-
justify-content: flex-start;
67-
align-items: center;
62+
:host([placement="TopCenter"]) .ui5-toast-root {
63+
top: 2rem;
64+
left: 50%;
65+
transform: translateX(-50%);
6866
}
6967

7068
:host([placement="MiddleCenter"]) .ui5-toast-root {
71-
justify-content: center;
72-
align-items: center;
69+
left: 50%;
70+
top: 50%;
71+
transform: translate(-50%, -50%);
7372
}
7473

75-
:host([placement="MiddleEnd"]) .ui5-toast-root {
76-
justify-content: flex-end;
77-
align-items: center;
74+
:host([placement="BottomCenter"]) .ui5-toast-root {
75+
bottom: 2rem;
76+
left: 50%;
77+
transform: translateX(-50%);
7878
}
7979

80-
:host([placement="BottomStart"]) .ui5-toast-root {
81-
justify-content: flex-start;
82-
align-items: flex-end;
80+
:host([placement="TopEnd"]) .ui5-toast-root {
81+
right: 2rem;
82+
top: 2rem;
83+
}
84+
85+
:host([placement="MiddleEnd"]) .ui5-toast-root {
86+
right: 2rem;
87+
top: 50%;
88+
transform: translateY(-50%);
8389
}
8490

8591
:host([placement="BottomEnd"]) .ui5-toast-root {
86-
justify-content: flex-end;
87-
align-items: flex-end;
92+
right: 2rem;
93+
bottom: 2rem;
8894
}

packages/main/test/specs/Toast.spec.js

+5-8
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,27 @@ describe("Toast general interaction", () => {
4545
});
4646

4747
it("tests shadow content div role", () => {
48-
const toastShadowContent = browser.$("#wcToastBE").shadow$(".ui5-toast-content");
48+
const toastShadowContent = browser.$("#wcToastBE").shadow$(".ui5-toast-root");
4949

5050
assert.strictEqual(toastShadowContent.getAttribute("role"), "alert",
5151
"The role of the shadow ui5-toast-content div should be alert");
5252
});
5353

5454
it("tests shadow content div inline styles with default duration", () => {
5555
const button = browser.$("#wcBtnShowToastBE");
56-
const toastShadowContent = browser.$("#wcToastBE").shadow$(".ui5-toast-content");
56+
const toastShadowContent = browser.$("#wcToastBE").shadow$(".ui5-toast-root");
5757

5858
button.click();
5959

6060
assert.strictEqual(toastShadowContent.getAttribute("style"),
6161
"transition-duration: 1000ms; transition-delay: 2000ms; opacity: 0;",
62-
"The correct default inline styles are applied to the shadow ui5-toast-content");
62+
"The correct default inline styles are applied to the shadow ui5-toast-root");
6363
});
6464

6565
it("tests shadow content div inline styles with long duration", () => {
6666
const button = browser.$("#wcBtnShowToastBS");
6767
const toast = browser.$("#wcToastBS");
68-
const toastShadowContent = toast.shadow$(".ui5-toast-content");
68+
const toastShadowContent = toast.shadow$(".ui5-toast-root");
6969
const maximumAllowedTransition = 1000;
7070
const durationProperty = toast.getProperty("duration");
7171
let calculatedDelay;
@@ -83,7 +83,7 @@ describe("Toast general interaction", () => {
8383
it("tests shadow content div inline styles with short duration", () => {
8484
const button = browser.$("#wcBtnShowToastME");
8585
const toast = browser.$("#wcToastME");
86-
const toastShadowContent = toast.shadow$(".ui5-toast-content");
86+
const toastShadowContent = toast.shadow$(".ui5-toast-root");
8787
const durationProperty = toast.getProperty("duration");
8888
let calculatedTransition, calculatedDelay;
8989

@@ -101,7 +101,6 @@ describe("Toast general interaction", () => {
101101
it("tests closing of toast", () => {
102102
const button = browser.$("#wcBtnShowToastMS");
103103
const toast = browser.$("#wcToastMS");
104-
const toastShadowContent = toast.shadow$(".ui5-toast-content");
105104

106105
button.click();
107106

@@ -110,8 +109,6 @@ describe("Toast general interaction", () => {
110109

111110
assert.notOk(toast.getProperty("open"),
112111
"Open property should be false after Toast is closed");
113-
assert.notOk(toastShadowContent.isDisplayedInViewport(),
114-
"Toast's content div shouldn't be displayed in the viewport after its closing.")
115112
});
116113

117114
it("tests minimum allowed duration", () => {

0 commit comments

Comments
 (0)