@dile/ui 2.27.0 → 2.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
|
2
|
+
import './button.js';
|
|
3
|
+
|
|
4
|
+
describe('dile-button', () => {
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
document.body.innerHTML = '';
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
async function renderButton(html) {
|
|
10
|
+
document.body.innerHTML = html;
|
|
11
|
+
const el = document.body.querySelector('dile-button');
|
|
12
|
+
await el.updateComplete;
|
|
13
|
+
return el;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
it('renders the slotted content inside a native button', async () => {
|
|
17
|
+
const el = await renderButton('<dile-button>Click me</dile-button>');
|
|
18
|
+
|
|
19
|
+
expect(el.shadowRoot.querySelector('button')).toBeTruthy();
|
|
20
|
+
expect(el.textContent.trim()).toBe('Click me');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('reflects the disabled property onto the native button', async () => {
|
|
24
|
+
const el = await renderButton('<dile-button disabled>Click me</dile-button>');
|
|
25
|
+
|
|
26
|
+
expect(el.shadowRoot.querySelector('button').disabled).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('dispatches a click event when enabled', async () => {
|
|
30
|
+
const el = await renderButton('<dile-button>Click me</dile-button>');
|
|
31
|
+
let clicked = false;
|
|
32
|
+
el.addEventListener('click', () => { clicked = true; });
|
|
33
|
+
|
|
34
|
+
el.shadowRoot.querySelector('button').click();
|
|
35
|
+
|
|
36
|
+
expect(clicked).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('shows a spinner icon while loading', async () => {
|
|
40
|
+
const el = await renderButton('<dile-button>Save</dile-button>');
|
|
41
|
+
expect(el.shadowRoot.querySelector('dile-spinner-icon')).toBeNull();
|
|
42
|
+
|
|
43
|
+
el.loading = true;
|
|
44
|
+
await el.updateComplete;
|
|
45
|
+
|
|
46
|
+
expect(el.shadowRoot.querySelector('dile-spinner-icon')).toBeTruthy();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LitElement, html, css } from "lit";
|
|
2
|
+
import { repeat } from "lit/directives/repeat.js";
|
|
2
3
|
|
|
3
4
|
export class DileToast extends LitElement {
|
|
4
5
|
static get properties() {
|
|
@@ -7,6 +8,8 @@ export class DileToast extends LitElement {
|
|
|
7
8
|
messages: { type: Array },
|
|
8
9
|
/* Miliseconds the feedback message remains on the screen */
|
|
9
10
|
duration: { type: Number },
|
|
11
|
+
/* If true, shows a close icon on each toast so the user can dismiss it manually */
|
|
12
|
+
showCloseIcon: { type: Boolean },
|
|
10
13
|
};
|
|
11
14
|
}
|
|
12
15
|
|
|
@@ -15,6 +18,8 @@ export class DileToast extends LitElement {
|
|
|
15
18
|
this.messages = [];
|
|
16
19
|
this.duration = 3000;
|
|
17
20
|
this.cleanTimeout = false;
|
|
21
|
+
this.showCloseIcon = false;
|
|
22
|
+
this._messageId = 0;
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
static get styles() {
|
|
@@ -31,11 +36,15 @@ export class DileToast extends LitElement {
|
|
|
31
36
|
|
|
32
37
|
render() {
|
|
33
38
|
return html`
|
|
34
|
-
${
|
|
39
|
+
${repeat(
|
|
40
|
+
this.messages,
|
|
41
|
+
(msg) => msg.id,
|
|
35
42
|
(msg) => html`
|
|
36
43
|
<dile-toast-item
|
|
37
44
|
.msg="${msg}"
|
|
45
|
+
.showCloseIcon="${this.showCloseIcon}"
|
|
38
46
|
duration="${this.duration}"
|
|
47
|
+
@dile-toast-item-closed="${(e) => this._closeMessage(e.detail.id)}"
|
|
39
48
|
></dile-toast-item>
|
|
40
49
|
`
|
|
41
50
|
)}
|
|
@@ -51,6 +60,7 @@ export class DileToast extends LitElement {
|
|
|
51
60
|
this.messages = [
|
|
52
61
|
...this.messages,
|
|
53
62
|
{
|
|
63
|
+
id: ++this._messageId,
|
|
54
64
|
text,
|
|
55
65
|
toastType,
|
|
56
66
|
hidden: false,
|
|
@@ -61,6 +71,27 @@ export class DileToast extends LitElement {
|
|
|
61
71
|
this._programMessageHide();
|
|
62
72
|
}
|
|
63
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Closes a specific message before its automatic duration elapses, triggered by the user
|
|
76
|
+
*/
|
|
77
|
+
_closeMessage(id) {
|
|
78
|
+
const message = this.messages.find((item) => item.id === id);
|
|
79
|
+
if (!message || message.hidden) return;
|
|
80
|
+
this.messages = this.messages.map((item) =>
|
|
81
|
+
item.id === id ? { ...item, hidden: true } : item
|
|
82
|
+
);
|
|
83
|
+
setTimeout(() => {
|
|
84
|
+
this.messages = this.messages.filter((item) => item.id !== id);
|
|
85
|
+
}, 500);
|
|
86
|
+
this.dispatchEvent(
|
|
87
|
+
new CustomEvent("dile-toast-closed-by-user", {
|
|
88
|
+
bubbles: true,
|
|
89
|
+
composed: true,
|
|
90
|
+
detail: { message },
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
64
95
|
/**
|
|
65
96
|
* Programs the hiding of the last message, after it's duration time
|
|
66
97
|
*/
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { LitElement, html, css } from "lit";
|
|
2
|
+
import { clearIcon } from "@dile/icons/index.js";
|
|
3
|
+
import "../../icon/icon.js";
|
|
2
4
|
|
|
3
5
|
export class DileToastItem extends LitElement {
|
|
4
6
|
static get properties() {
|
|
5
7
|
return {
|
|
6
8
|
msg: { type: Object },
|
|
9
|
+
showCloseIcon: { type: Boolean },
|
|
7
10
|
};
|
|
8
11
|
}
|
|
9
12
|
|
|
@@ -15,6 +18,7 @@ export class DileToastItem extends LitElement {
|
|
|
15
18
|
hidden: false,
|
|
16
19
|
opening: true,
|
|
17
20
|
};
|
|
21
|
+
this.showCloseIcon = false;
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
static get styles() {
|
|
@@ -26,6 +30,9 @@ export class DileToastItem extends LitElement {
|
|
|
26
30
|
display: block;
|
|
27
31
|
}
|
|
28
32
|
div {
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
justify-content: space-between;
|
|
29
36
|
color: var(--dile-toast-text-color, #fff);
|
|
30
37
|
padding: var(--dile-toast-padding, 10px 15px);
|
|
31
38
|
margin-top: 10px;
|
|
@@ -40,6 +47,16 @@ export class DileToastItem extends LitElement {
|
|
|
40
47
|
font-weight: var(--dile-toast-font-weight, normal);
|
|
41
48
|
border-radius: var(--dile-toast-border-radius, 0);
|
|
42
49
|
}
|
|
50
|
+
.text {
|
|
51
|
+
flex-grow: 1;
|
|
52
|
+
}
|
|
53
|
+
.closeicon {
|
|
54
|
+
cursor: pointer;
|
|
55
|
+
flex-shrink: 0;
|
|
56
|
+
margin-left: 10px;
|
|
57
|
+
--dile-icon-color: var(--dile-toast-close-icon-color, var(--dile-toast-text-color, #fff));
|
|
58
|
+
--dile-icon-size: var(--dile-toast-close-icon-size, 16px);
|
|
59
|
+
}
|
|
43
60
|
.hidden {
|
|
44
61
|
top: 20px;
|
|
45
62
|
opacity: 0;
|
|
@@ -68,11 +85,28 @@ export class DileToastItem extends LitElement {
|
|
|
68
85
|
? "opening"
|
|
69
86
|
: ""} ${this.getClassType(this.msg.toastType)}"
|
|
70
87
|
>
|
|
71
|
-
|
|
88
|
+
<span class="text">${this.msg.text}</span>
|
|
89
|
+
${this.showCloseIcon
|
|
90
|
+
? html`<dile-icon
|
|
91
|
+
.icon="${clearIcon}"
|
|
92
|
+
class="closeicon"
|
|
93
|
+
@click="${this.closeByUser}"
|
|
94
|
+
></dile-icon>`
|
|
95
|
+
: ""}
|
|
72
96
|
</div>
|
|
73
97
|
`;
|
|
74
98
|
}
|
|
75
99
|
|
|
100
|
+
closeByUser() {
|
|
101
|
+
this.dispatchEvent(
|
|
102
|
+
new CustomEvent("dile-toast-item-closed", {
|
|
103
|
+
bubbles: true,
|
|
104
|
+
composed: true,
|
|
105
|
+
detail: { id: this.msg.id, msg: this.msg },
|
|
106
|
+
})
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
76
110
|
firstUpdated() {
|
|
77
111
|
setTimeout(() => {
|
|
78
112
|
this.msg.opening = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dile/ui",
|
|
3
|
-
"version": "2.27.
|
|
3
|
+
"version": "2.27.1",
|
|
4
4
|
"description": "UI Core components from dile-components.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "fec5662d02ad55763620b92b5748e45217f31b11"
|
|
31
31
|
}
|