@tsirosgeorge/toastnotification 5.0.7 → 5.1.0
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.
- package/Readme.md +67 -3
- package/assets/css/toast.css +53 -0
- package/assets/css/toast.min.css +1 -1
- package/package.json +7 -6
- package/toast.js +333 -130
- package/toast.min.js +1 -1
package/Readme.md
CHANGED
|
@@ -6,7 +6,7 @@ A lightweight, customizable, and dependency-free toast notification system writt
|
|
|
6
6
|
|
|
7
7
|
## 📦 Include package via cdn
|
|
8
8
|
```html
|
|
9
|
-
<script src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@
|
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/toast.min.js"></script>
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
## 📦 Include package via npm
|
|
@@ -35,12 +35,58 @@ toast('Data saved successfully!', {
|
|
|
35
35
|
});
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
### ✅ Convenience helpers
|
|
39
|
+
```javascript
|
|
40
|
+
toast.success('Saved!');
|
|
41
|
+
toast.error('Failed!');
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### ⚠️ Confirm (SweetAlert-like)
|
|
45
|
+
- Promise API
|
|
46
|
+
```javascript
|
|
47
|
+
const ok = await toast.confirm('This will delete the file.', {
|
|
48
|
+
title: 'Are you sure?',
|
|
49
|
+
type: 'warning',
|
|
50
|
+
confirmText: 'Yes, delete',
|
|
51
|
+
cancelText: 'Cancel',
|
|
52
|
+
useOverlay: true,
|
|
53
|
+
closeOnOverlayClick: true,
|
|
54
|
+
showClose: true,
|
|
55
|
+
// optional custom button colors
|
|
56
|
+
confirmButtonBg: '#10b981',
|
|
57
|
+
confirmButtonColor: '#fff',
|
|
58
|
+
cancelButtonBg: '#e5e7eb',
|
|
59
|
+
cancelButtonColor: '#1f2937',
|
|
60
|
+
});
|
|
61
|
+
if (ok) {
|
|
62
|
+
// proceed
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- Callback API
|
|
67
|
+
```javascript
|
|
68
|
+
toast('Are you sure?', {
|
|
69
|
+
mode: 'confirm',
|
|
70
|
+
type: 'warning',
|
|
71
|
+
title: 'Confirm action',
|
|
72
|
+
onConfirm: () => console.log('YES'),
|
|
73
|
+
onCancel: () => console.log('NO'),
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### ⏳ Loading → Update
|
|
78
|
+
```javascript
|
|
79
|
+
const t = toast.loading('Uploading…', { type: 'info' });
|
|
80
|
+
// later
|
|
81
|
+
t.update('Done!', { type: 'success', duration: 2000 });
|
|
82
|
+
```
|
|
83
|
+
|
|
38
84
|
## 🛠️ Available Options
|
|
39
85
|
|
|
40
86
|
| Option | Type | Default | Description |
|
|
41
87
|
|--------------|------------|---------------|-----------------------------------------------------------------------------------------------|
|
|
42
|
-
| `position` | `string` | `'top-right'` |
|
|
43
|
-
| `animation` | `string` | `'slide-right'` |
|
|
88
|
+
| `position` | `string` | `'top-right'` | Container position. Values: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`, `'top-center'`, `'bottom-center'`. |
|
|
89
|
+
| `animation` | `string` | `'slide-right'` | Show animation. Examples: `'slide-right'`, `'slide-left'`, `'slide-top'`, `'slide-bottom'`, `'zoom-in'`. Hide uses reverse automatically. |
|
|
44
90
|
| `type` | `string` | `'info'` | Type of toast, controlling icon and styling. Possible values: `'info'`, `'success'`, `'error'`, `'warning'`. |
|
|
45
91
|
| `duration` | `number` | `3000` | Duration in milliseconds before the toast automatically dismisses. |
|
|
46
92
|
| `icon` | `string` or `null` | `null` | Optional custom icon displayed as text (e.g., emoji) before the toast message. If not set, a default GIF icon is used based on the `type`. |
|
|
@@ -49,6 +95,24 @@ toast('Data saved successfully!', {
|
|
|
49
95
|
| `onShow` | `function` or `null` | `null` | Callback function executed when the toast appears (after it's added to the DOM and shown). |
|
|
50
96
|
| `onDismiss` | `function` or `null` | `null` | Callback function executed when the toast is dismissed and removed from the DOM. |
|
|
51
97
|
|
|
98
|
+
### 🧩 Confirm-specific options
|
|
99
|
+
| Option | Type | Default | Description |
|
|
100
|
+
|-------|------|---------|-------------|
|
|
101
|
+
| `mode` | `"confirm" | "swal"` | — | Set to show a confirm dialog with Yes/No buttons. |
|
|
102
|
+
| `title` | `string` | `null` | Optional heading shown above the message. |
|
|
103
|
+
| `confirmText` | `string` | `"Yes"` | Confirm button label. |
|
|
104
|
+
| `cancelText` | `string` | `"No"` | Cancel button label. |
|
|
105
|
+
| `useOverlay` | `boolean` | `true` | Dim the background and center the dialog. |
|
|
106
|
+
| `closeOnOverlayClick` | `boolean` | `true` | Clicking the overlay cancels. |
|
|
107
|
+
| `showClose` | `boolean` | `false` | Show a top-right × button. |
|
|
108
|
+
| `confirmButtonBg` | `string` | `null` | Inline background color for confirm button. |
|
|
109
|
+
| `confirmButtonColor` | `string` | `null` | Inline text color for confirm button. |
|
|
110
|
+
| `cancelButtonBg` | `string` | `null` | Inline background color for cancel button. |
|
|
111
|
+
| `cancelButtonColor` | `string` | `null` | Inline text color for cancel button. |
|
|
112
|
+
|
|
113
|
+
### 🧪 Playground
|
|
114
|
+
Open `index.html` to experiment with all options (message, type, position, animation, duration, icon, loader, confirm title/texts, overlay, close, and button colors).
|
|
115
|
+
|
|
52
116
|
|
|
53
117
|
## 📝 License
|
|
54
118
|
|
package/assets/css/toast.css
CHANGED
|
@@ -76,6 +76,37 @@
|
|
|
76
76
|
width: auto!important;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/* When toast is used outside a container (e.g., confirm in overlay), keep card styles */
|
|
80
|
+
.ts-toast.ts-toast-confirm {
|
|
81
|
+
display: flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
justify-content: center;
|
|
84
|
+
background-color: var(--toast-bg, #fff);
|
|
85
|
+
color: var(--toast-color, #000);
|
|
86
|
+
border: 1px solid var(--toast-border, #e5e7eb);
|
|
87
|
+
border-radius: 12px;
|
|
88
|
+
padding: 16px 20px;
|
|
89
|
+
box-shadow: var(--toast-shadow, 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.ts-toast.ts-toast-confirm .ts-toast-content {
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
align-items: center;
|
|
96
|
+
justify-content: center;
|
|
97
|
+
gap: 12px;
|
|
98
|
+
text-align: center;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.ts-toast.ts-toast-confirm .ts-toast-body { text-align: center; }
|
|
102
|
+
|
|
103
|
+
.ts-toast-actions {
|
|
104
|
+
display: flex;
|
|
105
|
+
gap: 10px;
|
|
106
|
+
justify-content: center;
|
|
107
|
+
margin-top: 12px;
|
|
108
|
+
}
|
|
109
|
+
|
|
79
110
|
/* Show toast with animation */
|
|
80
111
|
.ts-toast-container .ts-toast.show {
|
|
81
112
|
opacity: 1;
|
|
@@ -260,4 +291,26 @@
|
|
|
260
291
|
animation-duration: 0.5s;
|
|
261
292
|
animation-timing-function: ease-in-out;
|
|
262
293
|
animation-fill-mode: forwards;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* Overlay for confirm dialogs */
|
|
297
|
+
.ts-toast-overlay {
|
|
298
|
+
position: fixed;
|
|
299
|
+
inset: 0;
|
|
300
|
+
background: rgba(0, 0, 0, 0.5); /* darker backdrop */
|
|
301
|
+
display: flex;
|
|
302
|
+
align-items: center;
|
|
303
|
+
justify-content: center;
|
|
304
|
+
z-index: 2147483646;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* Tiny utility: flex icon container */
|
|
308
|
+
.d-flex {
|
|
309
|
+
display: inline-flex;
|
|
310
|
+
align-items: center;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/* Prevent scroll behind confirm overlay */
|
|
314
|
+
body.ts-toast-no-scroll {
|
|
315
|
+
overflow: hidden;
|
|
263
316
|
}
|
package/assets/css/toast.min.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.ts-toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:10px;pointer-events:none;width:fit-content;max-width:calc(100% - 2rem)}.ts-toast-container>:not(:last-child){margin-bottom:0!important}.ts-toast-container.top-right{top:1rem;right:1rem;align-items:flex-end}.ts-toast-container.top-left{top:1rem;left:1rem;align-items:flex-start}.ts-toast-container.top-center{top:1rem;left:50%;transform:translateX(-50%);align-items:center}.ts-toast-container.bottom-right{bottom:1rem;right:1rem;align-items:flex-end}.ts-toast-container.bottom-left{bottom:1rem;left:1rem;align-items:flex-start}.ts-toast-container.bottom-center{bottom:1rem;left:50%;transform:translateX(-50%);align-items:center}.ts-toast-container .ts-toast{display:flex;align-items:center;gap:.75rem;background-color:var(--toast-bg,#fff);color:var(--toast-color,#000);padding:.75rem 1rem;border-radius:8px;border:1px solid var(--toast-border,#e5e7eb);box-shadow:var(--toast-shadow,0 10px 15px -3px rgba(0,0,0,.1));font-family:sans-serif;font-size:.95rem;pointer-events:all;position:relative;opacity:0;transform:translateY(20px);transition:opacity .5s ease,transform .5s ease;width:auto!important}.ts-toast-container .ts-toast.show{opacity:1;transform:translateY(0)}@keyframes slide-left{from{transform:translateX(-100%)}to{transform:translateX(0)}}@keyframes slide-right{from{transform:translateX(100%)}to{transform:translateX(0)}}@keyframes slide-top{from{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes slide-bottom{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes zoom-in{from{transform:scale(0)}to{transform:scale(1)}}@keyframes flip{from{transform:rotateY(90deg)}to{transform:rotateY(0)}}.ts-toast-container .ts-toast-icon{font-size:1.2rem}.ts-toast-container .ts-toast-success .ts-toast-icon{color:var(--toast-success-color,#66ee78)}.ts-toast-container .ts-toast-error .ts-toast-icon{color:var(--toast-error-color,#ef4444)}.ts-toast-container .ts-toast-loader{width:20px;height:20px;border:3px solid #f3f3f3;border-top:3px solid var(--toast-loader-color,#66ee78);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.ts-toast-container .ts-toast-loader.done{animation:none;opacity:0;transition:opacity .5s ease}.ts-toast-container .ts-toast-icon{font-size:1.2rem;opacity:0;transition:opacity .5s ease}.ts-toast-container .ts-toast.show .ts-toast-icon{opacity:1}@keyframes progress-bar{0%{width:0%}100%{width:100%}}@keyframes slide-top-reverse{from{transform:translateY(0)}to{transform:translateY(-100%)}}@keyframes slide-bottom-reverse{from{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes slide-left-reverse{from{transform:translateX(0)}to{transform:translateX(-100%)}}@keyframes slide-right-reverse{from{transform:translateX(0)}to{transform:translateX(100%)}}.ts-toast-container .ts-toast.slide-out{animation-duration:.5s;animation-timing-function:ease-in-out;animation-fill-mode:forwards}
|
|
1
|
+
.ts-toast-container{position:fixed;z-index:9999;display:flex;flex-direction:column;gap:10px;pointer-events:none;width:fit-content;max-width:calc(100% - 2rem)}.ts-toast-container>:not(:last-child){margin-bottom:0!important}.ts-toast-container.top-right{top:1rem;right:1rem;align-items:flex-end}.ts-toast-container.top-left{top:1rem;left:1rem;align-items:flex-start}.ts-toast-container.top-center{top:1rem;left:50%;transform:translateX(-50%);align-items:center}.ts-toast-container.bottom-right{bottom:1rem;right:1rem;align-items:flex-end}.ts-toast-container.bottom-left{bottom:1rem;left:1rem;align-items:flex-start}.ts-toast-container.bottom-center{bottom:1rem;left:50%;transform:translateX(-50%);align-items:center}.ts-toast-container .ts-toast{display:flex;align-items:center;gap:.75rem;background-color:var(--toast-bg,#fff);color:var(--toast-color,#000);padding:.75rem 1rem;border-radius:8px;border:1px solid var(--toast-border,#e5e7eb);box-shadow:var(--toast-shadow,0 10px 15px -3px rgba(0,0,0,.1));font-family:sans-serif;font-size:.95rem;pointer-events:all;position:relative;opacity:0;transform:translateY(20px);transition:opacity .5s ease,transform .5s ease;width:auto!important}.ts-toast.ts-toast-confirm{display:flex;align-items:center;justify-content:center;background-color:var(--toast-bg,#fff);color:var(--toast-color,#000);border:1px solid var(--toast-border,#e5e7eb);border-radius:12px;padding:16px 20px;box-shadow:var(--toast-shadow,0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1))}.ts-toast.ts-toast-confirm .ts-toast-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;text-align:center}.ts-toast.ts-toast-confirm .ts-toast-body{text-align:center}.ts-toast-actions{display:flex;gap:10px;justify-content:center;margin-top:12px}.ts-toast-container .ts-toast.show{opacity:1;transform:translateY(0)}@keyframes slide-left{from{transform:translateX(-100%)}to{transform:translateX(0)}}@keyframes slide-right{from{transform:translateX(100%)}to{transform:translateX(0)}}@keyframes slide-top{from{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes slide-bottom{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes zoom-in{from{transform:scale(0)}to{transform:scale(1)}}@keyframes flip{from{transform:rotateY(90deg)}to{transform:rotateY(0)}}.ts-toast-container .ts-toast-icon{font-size:1.2rem}.ts-toast-container .ts-toast-success .ts-toast-icon{color:var(--toast-success-color,#66ee78)}.ts-toast-container .ts-toast-error .ts-toast-icon{color:var(--toast-error-color,#ef4444)}.ts-toast-container .ts-toast-loader{width:20px;height:20px;border:3px solid #f3f3f3;border-top:3px solid var(--toast-loader-color,#66ee78);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.ts-toast-container .ts-toast-loader.done{animation:none;opacity:0;transition:opacity .5s ease}.ts-toast-container .ts-toast-icon{font-size:1.2rem;opacity:0;transition:opacity .5s ease}.ts-toast-container .ts-toast.show .ts-toast-icon{opacity:1}@keyframes progress-bar{0%{width:0%}100%{width:100%}}@keyframes slide-top-reverse{from{transform:translateY(0)}to{transform:translateY(-100%)}}@keyframes slide-bottom-reverse{from{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes slide-left-reverse{from{transform:translateX(0)}to{transform:translateX(-100%)}}@keyframes slide-right-reverse{from{transform:translateX(0)}to{transform:translateX(100%)}}.ts-toast-container .ts-toast.slide-out{animation-duration:.5s;animation-timing-function:ease-in-out;animation-fill-mode:forwards}.ts-toast-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:2147483646}.d-flex{display:inline-flex;align-items:center}body.ts-toast-no-scroll{overflow:hidden}
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsirosgeorge/toastnotification",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "a toast notification plugin",
|
|
5
5
|
"main": "toast.min.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
+
"build:css": "cleancss -o assets/css/toast.min.css assets/css/toast.css",
|
|
9
|
+
"build:js": "terser toast.js --compress --mangle --output toast.min.js",
|
|
10
|
+
"build": "npm run build:css && npm run build:js",
|
|
11
|
+
"prepublishOnly": "npm run build",
|
|
12
|
+
"release": "npm version && git push origin main --follow-tags && npm publish --access public"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
14
15
|
"toast.js",
|
package/toast.js
CHANGED
|
@@ -4,32 +4,128 @@
|
|
|
4
4
|
// Dynamically load the external CSS file
|
|
5
5
|
const link = document.createElement("link");
|
|
6
6
|
link.rel = "stylesheet";
|
|
7
|
-
link.href = "https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.0
|
|
7
|
+
link.href = "https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/css/toast.min.css";// Pinned to current release
|
|
8
8
|
document.head.appendChild(link);
|
|
9
9
|
|
|
10
|
+
// Inject minimal styles for confirm actions and overlay (kept tiny to avoid breaking existing CSS)
|
|
11
|
+
(function injectInlineStyles() {
|
|
12
|
+
const STYLE_ID = 'ts-toast-inline-extras';
|
|
13
|
+
if (document.getElementById(STYLE_ID)) return;
|
|
14
|
+
const style = document.createElement('style');
|
|
15
|
+
style.id = STYLE_ID;
|
|
16
|
+
style.textContent = `
|
|
17
|
+
/* Ensure center positions exist even if external CSS lacks them */
|
|
18
|
+
.ts-toast-container.top-center { top: 1rem; left: 50%; transform: translateX(-50%); align-items: center; }
|
|
19
|
+
.ts-toast-container.bottom-center { bottom: 1rem; left: 50%; transform: translateX(-50%); align-items: center; }
|
|
20
|
+
.ts-toast-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 2147483646; }
|
|
21
|
+
.ts-toast.ts-toast-confirm { max-width: min(92vw, 440px); width: max(320px, 60%); flex-direction: column; gap: 12px; padding: 16px 20px; background: var(--toast-bg, #fff); color: var(--toast-color, #000); border: 1px solid var(--toast-border, #e5e7eb); border-radius: 12px; box-shadow: var(--toast-shadow, 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)); text-align: center; }
|
|
22
|
+
.ts-toast.ts-toast-confirm .ts-toast-content { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; }
|
|
23
|
+
.ts-toast-actions { display: flex; gap: 10px; justify-content: center; margin-top: 12px; }
|
|
24
|
+
.ts-toast-btn { appearance: none; border: 0; padding: 8px 12px; border-radius: 8px; font-weight: 600; cursor: pointer; }
|
|
25
|
+
.ts-toast-btn.cancel { background: #e9ecef; color: #1f2937; }
|
|
26
|
+
.ts-toast-btn.confirm { background: #3b82f6; color: #fff; }
|
|
27
|
+
.ts-toast.ts-toast-error .ts-toast-btn.confirm,
|
|
28
|
+
.ts-toast.ts-toast-warning .ts-toast-btn.confirm { background: #ef4444; color: #fff; }
|
|
29
|
+
.ts-toast.ts-toast-confirm .ts-toast-title { font-weight: 700; font-size: 1.05rem; margin-top: 4px; }
|
|
30
|
+
.ts-toast.ts-toast-confirm .ts-toast-close { position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; border-radius: 999px; border: 0; background: transparent; color: #6b7280; font-size: 20px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
|
|
31
|
+
.ts-toast.ts-toast-confirm .ts-toast-close:hover { background: rgba(0,0,0,0.06); }
|
|
32
|
+
.ts-toast.ts-toast-confirm .ts-toast-icon { width: 64px; height: 64px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; }
|
|
33
|
+
.ts-toast.ts-toast-confirm .ts-toast-icon img { width: 36px; height: 36px; }
|
|
34
|
+
.ts-toast.ts-toast-confirm.ts-toast-success .ts-toast-icon { background: #dcfce7; }
|
|
35
|
+
.ts-toast.ts-toast-confirm.ts-toast-info .ts-toast-icon { background: #dbeafe; }
|
|
36
|
+
.ts-toast.ts-toast-confirm.ts-toast-warning .ts-toast-icon { background: #fef3c7; }
|
|
37
|
+
.ts-toast.ts-toast-confirm.ts-toast-error .ts-toast-icon { background: #fee2e2; }
|
|
38
|
+
`;
|
|
39
|
+
document.head.appendChild(style);
|
|
40
|
+
})();
|
|
41
|
+
|
|
10
42
|
const toast = function (message, options = {}) {
|
|
11
43
|
const {
|
|
12
44
|
position = 'top-right',
|
|
13
|
-
animation = 'slide-right', // Default animation
|
|
45
|
+
animation = 'slide-right', // Default fallback animation
|
|
14
46
|
type = 'info',
|
|
15
47
|
duration = 3000,
|
|
16
48
|
icon = null,
|
|
17
49
|
showLoader = false,
|
|
50
|
+
// behavior/mode: 'alert' (default) or 'confirm'/'swal'
|
|
51
|
+
mode = 'alert',
|
|
52
|
+
// confirm options (used when mode is 'confirm' or 'swal')
|
|
53
|
+
title = null,
|
|
54
|
+
confirmText = 'Yes',
|
|
55
|
+
cancelText = 'No',
|
|
56
|
+
// confirm button color customization (optional)
|
|
57
|
+
confirmButtonBg = null,
|
|
58
|
+
confirmButtonColor = null,
|
|
59
|
+
cancelButtonBg = null,
|
|
60
|
+
cancelButtonColor = null,
|
|
61
|
+
onConfirm = null,
|
|
62
|
+
onCancel = null,
|
|
63
|
+
onResult = null,
|
|
64
|
+
useOverlay = true,
|
|
65
|
+
closeOnOverlayClick = true,
|
|
66
|
+
showClose = false,
|
|
67
|
+
// interactions
|
|
68
|
+
dismissOnClick = true, // ignored if confirm-mode
|
|
18
69
|
onClick = null, // Custom onClick event listener
|
|
19
70
|
onShow = null, // Custom onShow event listener
|
|
20
71
|
onDismiss = null // Custom onDismiss event listener
|
|
21
72
|
} = options;
|
|
22
73
|
|
|
23
|
-
const
|
|
24
|
-
toastElement.className = `ts-toast ts-toast-${type}`;
|
|
25
|
-
toastElement.style.animation = `${animation} 0.5s ease`; // Default fade animation
|
|
26
|
-
toastElement.style.flexDirection = 'row-reverse';
|
|
27
|
-
toastElement.style.justifyContent = 'flex-end';
|
|
74
|
+
const isConfirm = (mode === 'confirm' || mode === 'swal');
|
|
28
75
|
|
|
29
|
-
//
|
|
30
|
-
const
|
|
31
|
-
|
|
76
|
+
// Pick an animation intelligently when one wasn't explicitly provided
|
|
77
|
+
const resolvedAnimation = (typeof options.animation === 'string' && options.animation.trim())
|
|
78
|
+
? options.animation.trim()
|
|
79
|
+
: (isConfirm ? 'zoom-in' : (position.startsWith('top') ? 'slide-top'
|
|
80
|
+
: position.startsWith('bottom') ? 'slide-bottom'
|
|
81
|
+
: position.endsWith('left') ? 'slide-left'
|
|
82
|
+
: 'slide-right'));
|
|
83
|
+
|
|
84
|
+
// helper: remove with reverse animation and cleanup
|
|
85
|
+
const removeWithAnimation = (el, callback) => {
|
|
86
|
+
// Get the current animation applied to the toast
|
|
87
|
+
const currentAnimation = el.style.animation || '';
|
|
88
|
+
|
|
89
|
+
// Determine the reverse animation based on the current animation
|
|
90
|
+
let reverseAnimation = '';
|
|
91
|
+
if (currentAnimation.includes('slide-top')) {
|
|
92
|
+
reverseAnimation = 'slide-top-reverse';
|
|
93
|
+
} else if (currentAnimation.includes('slide-bottom')) {
|
|
94
|
+
reverseAnimation = 'slide-bottom-reverse';
|
|
95
|
+
} else if (currentAnimation.includes('slide-left')) {
|
|
96
|
+
reverseAnimation = 'slide-left-reverse';
|
|
97
|
+
} else if (currentAnimation.includes('slide-right')) {
|
|
98
|
+
reverseAnimation = 'slide-right-reverse';
|
|
99
|
+
} else if (currentAnimation.includes('zoom-in')) {
|
|
100
|
+
reverseAnimation = 'zoom-out';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Apply the reverse animation dynamically
|
|
104
|
+
el.classList.add('slide-out');
|
|
105
|
+
el.style.animation = `${reverseAnimation} 0.5s ease`;
|
|
106
|
+
|
|
107
|
+
// Wait for the reverse animation to finish before removing the toast
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
el.classList.remove('show', 'slide-out');
|
|
110
|
+
el.style.animation = '';
|
|
111
|
+
if (el.parentNode) el.parentNode.removeChild(el);
|
|
112
|
+
if (typeof callback === 'function') callback();
|
|
113
|
+
}, 500);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const toastElement = document.createElement('div');
|
|
117
|
+
toastElement.className = `ts-toast ts-toast-${type}${isConfirm ? ' ts-toast-confirm' : ''}`;
|
|
118
|
+
toastElement.style.animation = `${resolvedAnimation} 0.5s ease`;
|
|
119
|
+
// In confirm mode, we stack content vertically; in alert mode keep original layout
|
|
120
|
+
if (!isConfirm) {
|
|
121
|
+
toastElement.style.flexDirection = 'row-reverse';
|
|
122
|
+
toastElement.style.justifyContent = 'flex-end';
|
|
123
|
+
}
|
|
32
124
|
|
|
125
|
+
// Create Icon Element
|
|
126
|
+
const iconElement = document.createElement('span');
|
|
127
|
+
iconElement.className = 'ts-toast-icon';
|
|
128
|
+
iconElement.style.display = 'flex';
|
|
33
129
|
if (icon) {
|
|
34
130
|
iconElement.textContent = icon;
|
|
35
131
|
} else {
|
|
@@ -39,7 +135,7 @@
|
|
|
39
135
|
img.style.height = '30px';
|
|
40
136
|
img.style.objectFit = 'contain';
|
|
41
137
|
|
|
42
|
-
const baseUrl = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@
|
|
138
|
+
const baseUrl = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/';
|
|
43
139
|
const timestamp = new Date().getTime(); // 🔄 force refresh
|
|
44
140
|
|
|
45
141
|
if (type === 'success') {
|
|
@@ -59,7 +155,68 @@
|
|
|
59
155
|
const toastBody = document.createElement('div');
|
|
60
156
|
toastBody.className = 'ts-toast-body';
|
|
61
157
|
toastBody.innerHTML = message; // Allow HTML content in message
|
|
62
|
-
|
|
158
|
+
|
|
159
|
+
// Content row for confirm (icon + text side-by-side)
|
|
160
|
+
let contentRow = null;
|
|
161
|
+
if (isConfirm) {
|
|
162
|
+
contentRow = document.createElement('div');
|
|
163
|
+
contentRow.className = 'ts-toast-content';
|
|
164
|
+
contentRow.appendChild(iconElement);
|
|
165
|
+
if (title) {
|
|
166
|
+
const titleEl = document.createElement('div');
|
|
167
|
+
titleEl.className = 'ts-toast-title';
|
|
168
|
+
titleEl.textContent = title;
|
|
169
|
+
contentRow.appendChild(titleEl);
|
|
170
|
+
}
|
|
171
|
+
contentRow.appendChild(toastBody);
|
|
172
|
+
toastElement.appendChild(contentRow);
|
|
173
|
+
} else {
|
|
174
|
+
toastElement.appendChild(toastBody);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Actions (for confirm mode)
|
|
178
|
+
let actionsContainer = null;
|
|
179
|
+
let resultResolver = null;
|
|
180
|
+
if (isConfirm) {
|
|
181
|
+
actionsContainer = document.createElement('div');
|
|
182
|
+
actionsContainer.className = 'ts-toast-actions';
|
|
183
|
+
|
|
184
|
+
const cancelBtn = document.createElement('button');
|
|
185
|
+
cancelBtn.className = 'ts-toast-btn cancel';
|
|
186
|
+
cancelBtn.textContent = cancelText;
|
|
187
|
+
|
|
188
|
+
const confirmBtn = document.createElement('button');
|
|
189
|
+
confirmBtn.className = 'ts-toast-btn confirm';
|
|
190
|
+
confirmBtn.textContent = confirmText;
|
|
191
|
+
|
|
192
|
+
// Apply custom button colors if provided (inline style overrides theme defaults)
|
|
193
|
+
if (cancelButtonBg) cancelBtn.style.background = cancelButtonBg;
|
|
194
|
+
if (cancelButtonColor) cancelBtn.style.color = cancelButtonColor;
|
|
195
|
+
if (confirmButtonBg) confirmBtn.style.background = confirmButtonBg;
|
|
196
|
+
if (confirmButtonColor) confirmBtn.style.color = confirmButtonColor;
|
|
197
|
+
|
|
198
|
+
actionsContainer.appendChild(cancelBtn);
|
|
199
|
+
actionsContainer.appendChild(confirmBtn);
|
|
200
|
+
toastElement.appendChild(actionsContainer);
|
|
201
|
+
|
|
202
|
+
// Create a Promise that resolves on user choice; expose via property
|
|
203
|
+
toastElement.result = new Promise((resolve) => { resultResolver = resolve; });
|
|
204
|
+
|
|
205
|
+
const resolveAndClose = (value) => {
|
|
206
|
+
if (resultResolver) resultResolver(value);
|
|
207
|
+
if (value && typeof onConfirm === 'function') onConfirm(toastElement);
|
|
208
|
+
if (!value && typeof onCancel === 'function') onCancel(toastElement);
|
|
209
|
+
if (typeof onResult === 'function') onResult(value, toastElement);
|
|
210
|
+
removeWithAnimation(toastElement, () => {
|
|
211
|
+
if (onDismiss && typeof onDismiss === 'function') onDismiss(toastElement);
|
|
212
|
+
// Remove overlay if present
|
|
213
|
+
if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
cancelBtn.addEventListener('click', (e) => { e.stopPropagation(); resolveAndClose(false); });
|
|
218
|
+
confirmBtn.addEventListener('click', (e) => { e.stopPropagation(); resolveAndClose(true); });
|
|
219
|
+
}
|
|
63
220
|
|
|
64
221
|
// Loader Element
|
|
65
222
|
let loader = null;
|
|
@@ -69,16 +226,55 @@
|
|
|
69
226
|
toastElement.appendChild(loader);
|
|
70
227
|
}
|
|
71
228
|
|
|
72
|
-
// Container
|
|
73
|
-
let
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
document.body.appendChild(
|
|
229
|
+
// Container/Overlay
|
|
230
|
+
let overlay = null;
|
|
231
|
+
if (isConfirm && useOverlay) {
|
|
232
|
+
overlay = document.createElement('div');
|
|
233
|
+
overlay.className = 'ts-toast-overlay';
|
|
234
|
+
document.body.appendChild(overlay);
|
|
235
|
+
overlay.appendChild(toastElement);
|
|
236
|
+
if (showClose) {
|
|
237
|
+
const closeBtn = document.createElement('button');
|
|
238
|
+
closeBtn.className = 'ts-toast-close';
|
|
239
|
+
closeBtn.setAttribute('aria-label', 'Close');
|
|
240
|
+
closeBtn.innerHTML = '×';
|
|
241
|
+
closeBtn.addEventListener('click', (e) => {
|
|
242
|
+
e.stopPropagation();
|
|
243
|
+
removeWithAnimation(toastElement, () => {
|
|
244
|
+
if (onDismiss && typeof onDismiss === 'function') onDismiss(toastElement);
|
|
245
|
+
if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
toastElement.appendChild(closeBtn);
|
|
249
|
+
}
|
|
250
|
+
if (closeOnOverlayClick) {
|
|
251
|
+
overlay.addEventListener('click', (e) => {
|
|
252
|
+
if (e.target === overlay) {
|
|
253
|
+
// Overlay background click -> cancel
|
|
254
|
+
if (toastElement.result) {
|
|
255
|
+
// let the confirm logic close and cleanup
|
|
256
|
+
if (typeof resultResolver === 'function') {
|
|
257
|
+
resultResolver(false);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
removeWithAnimation(toastElement, () => {
|
|
261
|
+
if (onDismiss && typeof onDismiss === 'function') onDismiss(toastElement);
|
|
262
|
+
if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
} else {
|
|
268
|
+
// Standard positioned container
|
|
269
|
+
let container = document.querySelector(`.ts-toast-container.${position}`);
|
|
270
|
+
if (!container) {
|
|
271
|
+
container = document.createElement('div');
|
|
272
|
+
container.className = `ts-toast-container ${position}`;
|
|
273
|
+
document.body.appendChild(container);
|
|
274
|
+
}
|
|
275
|
+
container.appendChild(toastElement);
|
|
78
276
|
}
|
|
79
277
|
|
|
80
|
-
container.appendChild(toastElement);
|
|
81
|
-
|
|
82
278
|
// Trigger the onShow event if provided
|
|
83
279
|
if (onShow && typeof onShow === 'function') {
|
|
84
280
|
onShow(toastElement);
|
|
@@ -92,88 +288,63 @@
|
|
|
92
288
|
// Handle Loader and Icon
|
|
93
289
|
if (showLoader && loader) {
|
|
94
290
|
setTimeout(() => {
|
|
291
|
+
// Skip auto-complete if controlled by toast.loading()
|
|
292
|
+
if (toastElement._managedByLoading) return;
|
|
95
293
|
loader.classList.add('done');
|
|
96
294
|
loader.remove();
|
|
97
|
-
if (!toastElement.
|
|
98
|
-
|
|
295
|
+
if (!toastElement.contains(iconElement)) {
|
|
296
|
+
if (isConfirm && contentRow) contentRow.appendChild(iconElement);
|
|
297
|
+
else toastElement.appendChild(iconElement); // Add icon only if not present
|
|
99
298
|
}
|
|
100
299
|
}, 2000); // Simulate a loading period of 2 seconds
|
|
101
300
|
}
|
|
102
301
|
if (!showLoader) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// Auto remove after the duration
|
|
107
|
-
const autoRemove = setTimeout(() => {
|
|
108
|
-
// Get the current animation applied to the toast
|
|
109
|
-
const currentAnimation = toastElement.style.animation || '';
|
|
110
|
-
|
|
111
|
-
// Determine the reverse animation based on the current animation
|
|
112
|
-
let reverseAnimation = '';
|
|
113
|
-
if (currentAnimation.includes('slide-top')) {
|
|
114
|
-
reverseAnimation = 'slide-top-reverse';
|
|
115
|
-
} else if (currentAnimation.includes('slide-bottom')) {
|
|
116
|
-
reverseAnimation = 'slide-bottom-reverse';
|
|
117
|
-
} else if (currentAnimation.includes('slide-left')) {
|
|
118
|
-
reverseAnimation = 'slide-left-reverse';
|
|
119
|
-
} else if (currentAnimation.includes('slide-right')) {
|
|
120
|
-
reverseAnimation = 'slide-right-reverse';
|
|
121
|
-
} else if (currentAnimation.includes('zoom-in')) {
|
|
122
|
-
reverseAnimation = 'zoom-out'; // You could define a zoom-out animation if needed
|
|
302
|
+
// For confirm, icon already added above inside contentRow; avoid moving it
|
|
303
|
+
if (!isConfirm && !toastElement.contains(iconElement)) {
|
|
304
|
+
toastElement.appendChild(iconElement);
|
|
123
305
|
}
|
|
306
|
+
}
|
|
124
307
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (onDismiss && typeof onDismiss === 'function') {
|
|
135
|
-
onDismiss(toastElement); // Trigger the onDismiss event if provided
|
|
136
|
-
}
|
|
137
|
-
}, 500); // Match the duration of the reverse animation
|
|
138
|
-
}, duration);
|
|
139
|
-
|
|
140
|
-
toastElement._autoRemove = autoRemove;
|
|
141
|
-
|
|
142
|
-
// Add event listener for closing the toast when clicked
|
|
143
|
-
toastElement.addEventListener('click', () => {
|
|
144
|
-
clearTimeout(toastElement._autoRemove); // Clear the auto-remove timeout
|
|
145
|
-
toastElement.classList.remove('show');
|
|
146
|
-
setTimeout(() => {
|
|
147
|
-
if (toastElement.parentNode) toastElement.parentNode.removeChild(toastElement);
|
|
148
|
-
}, 500); // Match the duration of the closing animation
|
|
308
|
+
// Auto remove after the duration (skip for confirm mode or when duration <= 0)
|
|
309
|
+
if (!isConfirm && duration > 0) {
|
|
310
|
+
const autoRemove = setTimeout(() => {
|
|
311
|
+
removeWithAnimation(toastElement, () => {
|
|
312
|
+
if (onDismiss && typeof onDismiss === 'function') onDismiss(toastElement);
|
|
313
|
+
});
|
|
314
|
+
}, duration);
|
|
315
|
+
toastElement._autoRemove = autoRemove;
|
|
316
|
+
}
|
|
149
317
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
318
|
+
// Add event listener for closing the toast when clicked (disabled in confirm mode)
|
|
319
|
+
if (!isConfirm && dismissOnClick) {
|
|
320
|
+
toastElement.addEventListener('click', () => {
|
|
321
|
+
if (toastElement._autoRemove) clearTimeout(toastElement._autoRemove); // Clear the auto-remove timeout
|
|
322
|
+
removeWithAnimation(toastElement, () => {
|
|
323
|
+
if (onClick && typeof onClick === 'function') onClick(toastElement);
|
|
324
|
+
if (onDismiss && typeof onDismiss === 'function') onDismiss(toastElement);
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
}
|
|
154
328
|
|
|
155
329
|
// Add swipe event listeners for mobile dismissal
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (onDismiss && typeof onDismiss === 'function') {
|
|
173
|
-
onDismiss(toastElement); // Trigger the onDismiss event if provided
|
|
330
|
+
if (!isConfirm) {
|
|
331
|
+
let touchStartX = 0;
|
|
332
|
+
let touchEndX = 0;
|
|
333
|
+
|
|
334
|
+
toastElement.addEventListener('touchstart', (e) => {
|
|
335
|
+
touchStartX = e.changedTouches[0].screenX;
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
toastElement.addEventListener('touchend', (e) => {
|
|
339
|
+
touchEndX = e.changedTouches[0].screenX;
|
|
340
|
+
if (Math.abs(touchStartX - touchEndX) > 50) { // Swipe distance threshold
|
|
341
|
+
if (toastElement._autoRemove) clearTimeout(toastElement._autoRemove);
|
|
342
|
+
removeWithAnimation(toastElement, () => {
|
|
343
|
+
if (onDismiss && typeof onDismiss === 'function') onDismiss(toastElement);
|
|
344
|
+
});
|
|
174
345
|
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
346
|
+
});
|
|
347
|
+
}
|
|
177
348
|
|
|
178
349
|
return toastElement;
|
|
179
350
|
};
|
|
@@ -205,7 +376,10 @@
|
|
|
205
376
|
if (oldLoader) oldLoader.remove();
|
|
206
377
|
|
|
207
378
|
// Update toast class and message
|
|
208
|
-
|
|
379
|
+
if (type) {
|
|
380
|
+
// keep ts- prefix consistent
|
|
381
|
+
toastElement.className = `ts-toast ts-toast-${type} show ${position}`;
|
|
382
|
+
}
|
|
209
383
|
const toastBody = toastElement.querySelector('.ts-toast-body');
|
|
210
384
|
if (toastBody) {
|
|
211
385
|
toastBody.innerHTML = message;
|
|
@@ -216,8 +390,9 @@
|
|
|
216
390
|
oldIcon.remove(); // Remove the old icon first
|
|
217
391
|
}
|
|
218
392
|
|
|
219
|
-
|
|
220
|
-
|
|
393
|
+
const iconElement = document.createElement('span');
|
|
394
|
+
iconElement.className = 'ts-toast-icon';
|
|
395
|
+
iconElement.style.display = 'flex';
|
|
221
396
|
|
|
222
397
|
if (icon) {
|
|
223
398
|
iconElement.textContent = icon;
|
|
@@ -228,13 +403,13 @@
|
|
|
228
403
|
img.style.objectFit = 'contain';
|
|
229
404
|
|
|
230
405
|
if (type === 'success') {
|
|
231
|
-
img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@
|
|
406
|
+
img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/success.gif';
|
|
232
407
|
} else if (type === 'error') {
|
|
233
|
-
img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@
|
|
408
|
+
img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/error.gif';
|
|
234
409
|
} else if (type === 'info') {
|
|
235
|
-
img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@
|
|
410
|
+
img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/info.gif';
|
|
236
411
|
} else if (type === 'warning') {
|
|
237
|
-
img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@
|
|
412
|
+
img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/warning.gif';
|
|
238
413
|
}
|
|
239
414
|
|
|
240
415
|
iconElement.appendChild(img);
|
|
@@ -246,7 +421,7 @@
|
|
|
246
421
|
// Handle loader if requested
|
|
247
422
|
if (showLoader) {
|
|
248
423
|
const loader = document.createElement('div');
|
|
249
|
-
loader.className = 'toast-loader';
|
|
424
|
+
loader.className = 'ts-toast-loader';
|
|
250
425
|
toastElement.appendChild(loader);
|
|
251
426
|
setTimeout(() => {
|
|
252
427
|
loader.classList.add('done');
|
|
@@ -260,36 +435,29 @@
|
|
|
260
435
|
|
|
261
436
|
// Set the auto-remove timer again to ensure toast disappears after the duration
|
|
262
437
|
const autoRemove = setTimeout(() => {
|
|
263
|
-
//
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
reverseAnimation = 'slide-
|
|
270
|
-
|
|
271
|
-
reverseAnimation = 'slide-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
toastElement.style.animation = `${reverseAnimation} 0.5s ease`; // Dynamically apply the reverse animation
|
|
438
|
+
// Use the same helper removal used above
|
|
439
|
+
// Re-create the helper here in case update() is used alone
|
|
440
|
+
const removeWithAnimation = (el, cb) => {
|
|
441
|
+
const currentAnimation = el.style.animation || '';
|
|
442
|
+
let reverseAnimation = '';
|
|
443
|
+
if (currentAnimation.includes('slide-top')) reverseAnimation = 'slide-top-reverse';
|
|
444
|
+
else if (currentAnimation.includes('slide-bottom')) reverseAnimation = 'slide-bottom-reverse';
|
|
445
|
+
else if (currentAnimation.includes('slide-left')) reverseAnimation = 'slide-left-reverse';
|
|
446
|
+
else if (currentAnimation.includes('slide-right')) reverseAnimation = 'slide-right-reverse';
|
|
447
|
+
else if (currentAnimation.includes('zoom-in')) reverseAnimation = 'zoom-out';
|
|
448
|
+
el.classList.add('slide-out');
|
|
449
|
+
el.style.animation = `${reverseAnimation} 0.5s ease`;
|
|
450
|
+
setTimeout(() => {
|
|
451
|
+
el.classList.remove('show', 'slide-out');
|
|
452
|
+
el.style.animation = '';
|
|
453
|
+
if (el.parentNode) el.parentNode.removeChild(el);
|
|
454
|
+
if (typeof cb === 'function') cb();
|
|
455
|
+
}, 500);
|
|
456
|
+
};
|
|
283
457
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
toastElement.style.animation = ''; // Reset the animation property
|
|
288
|
-
if (toastElement.parentNode) toastElement.parentNode.removeChild(toastElement);
|
|
289
|
-
if (onDismiss && typeof onDismiss === 'function') {
|
|
290
|
-
onDismiss(toastElement); // Trigger the onDismiss event if provided
|
|
291
|
-
}
|
|
292
|
-
}, 500); // Match the duration of the reverse animation
|
|
458
|
+
removeWithAnimation(toastElement, () => {
|
|
459
|
+
if (onDismiss && typeof onDismiss === 'function') onDismiss(toastElement);
|
|
460
|
+
});
|
|
293
461
|
}, duration);
|
|
294
462
|
|
|
295
463
|
toastElement._autoRemove = autoRemove; // Re-set the auto-remove timer
|
|
@@ -299,7 +467,7 @@
|
|
|
299
467
|
const toastElement = toast(message, {
|
|
300
468
|
...options,
|
|
301
469
|
type: options.type || 'info', // Default type is 'info'
|
|
302
|
-
duration:
|
|
470
|
+
duration: 0, // Sticky until manually updated/closed
|
|
303
471
|
showLoader: true, // Always show loader during loading
|
|
304
472
|
icon: null
|
|
305
473
|
});
|
|
@@ -316,32 +484,67 @@
|
|
|
316
484
|
if (!iconElement) {
|
|
317
485
|
iconElement = document.createElement('span');
|
|
318
486
|
iconElement.className = 'ts-toast-icon';
|
|
487
|
+
iconElement.style.display = 'flex';
|
|
319
488
|
toastElement.appendChild(iconElement);
|
|
320
489
|
}
|
|
321
490
|
|
|
491
|
+
// mark as managed by loading flow to avoid internal auto-complete
|
|
492
|
+
toastElement._managedByLoading = true;
|
|
493
|
+
|
|
322
494
|
// Ensure loader is handled properly
|
|
323
495
|
if (loader) {
|
|
324
496
|
setTimeout(() => {
|
|
325
|
-
|
|
497
|
+
// Keep spinning until update() decides otherwise
|
|
498
|
+
if (!toastElement._managedByLoading) loader.classList.add('done');
|
|
326
499
|
}, 2000); // Simulate a loading period of 2 seconds
|
|
327
500
|
}
|
|
328
501
|
|
|
329
502
|
return {
|
|
330
503
|
update: (newMessage, newOptions = {}) => {
|
|
504
|
+
// Let update manage completion: stop managing/finish loader
|
|
505
|
+
toastElement._managedByLoading = false;
|
|
331
506
|
toast.update(toastElement, newMessage, {
|
|
332
507
|
...newOptions,
|
|
333
508
|
showLoader: false // Disable loader when updating the message
|
|
334
509
|
});
|
|
335
510
|
},
|
|
336
511
|
close: () => {
|
|
337
|
-
toastElement.
|
|
512
|
+
if (toastElement._autoRemove) clearTimeout(toastElement._autoRemove);
|
|
513
|
+
const currentAnimation = toastElement.style.animation || '';
|
|
514
|
+
let reverseAnimation = '';
|
|
515
|
+
if (currentAnimation.includes('slide-top')) reverseAnimation = 'slide-top-reverse';
|
|
516
|
+
else if (currentAnimation.includes('slide-bottom')) reverseAnimation = 'slide-bottom-reverse';
|
|
517
|
+
else if (currentAnimation.includes('slide-left')) reverseAnimation = 'slide-left-reverse';
|
|
518
|
+
else if (currentAnimation.includes('slide-right')) reverseAnimation = 'slide-right-reverse';
|
|
519
|
+
else if (currentAnimation.includes('zoom-in')) reverseAnimation = 'zoom-out';
|
|
520
|
+
toastElement.classList.add('slide-out');
|
|
521
|
+
toastElement.style.animation = `${reverseAnimation} 0.5s ease`;
|
|
338
522
|
setTimeout(() => {
|
|
523
|
+
toastElement.classList.remove('show', 'slide-out');
|
|
524
|
+
toastElement.style.animation = '';
|
|
339
525
|
if (toastElement.parentNode) toastElement.parentNode.removeChild(toastElement);
|
|
340
526
|
}, 500);
|
|
341
527
|
}
|
|
342
528
|
};
|
|
343
529
|
};
|
|
344
530
|
|
|
531
|
+
// Convenience API: swal-like confirm dialog
|
|
532
|
+
// Usage: toast.confirm('Are you sure?', { type: 'warning', confirmText: 'Yes', cancelText: 'No' }).then(ok => {...})
|
|
533
|
+
toast.confirm = function (message, options = {}) {
|
|
534
|
+
return new Promise((resolve) => {
|
|
535
|
+
const el = toast(message, {
|
|
536
|
+
...options,
|
|
537
|
+
mode: 'confirm',
|
|
538
|
+
duration: 0, // prevent auto-dismiss
|
|
539
|
+
dismissOnClick: false,
|
|
540
|
+
onResult: (val) => resolve(!!val)
|
|
541
|
+
});
|
|
542
|
+
// If consumer needs the element, it is returned by toast() but we ignore here.
|
|
543
|
+
// They can still call toast(...) with mode: 'confirm' to get the element and read el.result
|
|
544
|
+
void el; // no-op
|
|
545
|
+
});
|
|
546
|
+
};
|
|
547
|
+
|
|
345
548
|
// Expose globally
|
|
346
549
|
window.toast = toast;
|
|
347
550
|
})();
|
package/toast.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(){"use strict";const e=document.createElement("link");e.rel="stylesheet",e.href="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.0.7/assets/css/toast.min.css",document.head.appendChild(e);const t=function(e,t={}){const{position:s="top-right",animation:o="slide-right",type:n="info",duration:i=3e3,icon:a=null,showLoader:l=!1,onClick:c=null,onShow:r=null,onDismiss:d=null}=t,m=document.createElement("div");m.className=`ts-toast ts-toast-${n}`,m.style.animation=`${o} 0.5s ease`,m.style.flexDirection="row-reverse",m.style.justifyContent="flex-end";const u=document.createElement("span");if(u.className="ts-toast-icon",a)u.textContent=a;else{const e=document.createElement("img");e.src="",e.style.width="30px",e.style.height="30px",e.style.objectFit="contain";const t="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@latest/assets/img/",s=(new Date).getTime();"success"===n?e.src=`${t}success.gif?t=${s}`:"error"===n?e.src=`${t}error.gif?t=${s}`:"info"===n?e.src=`${t}info.gif?t=${s}`:"warning"===n&&(e.src=`${t}warning.gif?t=${s}`),u.appendChild(e)}const p=document.createElement("div");p.className="ts-toast-body",p.innerHTML=e,m.appendChild(p);let h=null;l&&(h=document.createElement("div"),h.className="ts-toast-loader",m.appendChild(h));let f=document.querySelector(`.ts-toast-container.${s}`);f||(f=document.createElement("div"),f.className=`ts-toast-container ${s}`,document.body.appendChild(f)),f.appendChild(m),r&&"function"==typeof r&&r(m),setTimeout((()=>{m.classList.add("show")}),100),l&&h&&setTimeout((()=>{h.classList.add("done"),h.remove(),m.querySelector(".ts-toast-icon img")||m.appendChild(u)}),2e3),l||m.appendChild(u);const g=setTimeout((()=>{const e=m.style.animation||"";let t="";e.includes("slide-top")?t="slide-top-reverse":e.includes("slide-bottom")?t="slide-bottom-reverse":e.includes("slide-left")?t="slide-left-reverse":e.includes("slide-right")?t="slide-right-reverse":e.includes("zoom-in")&&(t="zoom-out"),m.classList.add("slide-out"),m.style.animation=`${t} 0.5s ease`,setTimeout((()=>{m.classList.remove("show","slide-out"),m.style.animation="",m.parentNode&&m.parentNode.removeChild(m),d&&"function"==typeof d&&d(m)}),500)}),i);m._autoRemove=g,m.addEventListener("click",(()=>{clearTimeout(m._autoRemove),m.classList.remove("show"),setTimeout((()=>{m.parentNode&&m.parentNode.removeChild(m)}),500),c&&"function"==typeof c&&c(m)}));let v=0,y=0;return m.addEventListener("touchstart",(e=>{v=e.changedTouches[0].screenX})),m.addEventListener("touchend",(e=>{y=e.changedTouches[0].screenX,Math.abs(v-y)>50&&(clearTimeout(m._autoRemove),m.classList.remove("show"),setTimeout((()=>{m.parentNode&&m.parentNode.removeChild(m)}),500),d&&"function"==typeof d&&d(m))})),m};t.success=function(e,s){t(e,{...s,type:"success"})},t.error=function(e,s){t(e,{...s,type:"error"})},t.update=function(e,t,s={}){const{type:o=null,icon:n=null,showLoader:i=!1,duration:a=3e3,position:l="top-right",onClick:c=null,onShow:r=null,onDismiss:d=null}=s,m=e.querySelector(".ts-toast-loader"),u=e.querySelector(".ts-toast-icon");m&&m.remove(),e.className=`toast toast-${o} show ${l}`;const p=e.querySelector(".ts-toast-body");p&&(p.innerHTML=t),u&&u.remove();const h=document.createElement("span");if(h.className="toast-icon",n)h.textContent=n;else{const e=document.createElement("img");e.style.width="30px",e.style.height="30px",e.style.objectFit="contain","success"===o?e.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@latest/assets/img/success.gif":"error"===o?e.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@latest/assets/img/error.gif":"info"===o?e.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@latest/assets/img/info.gif":"warning"===o&&(e.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@latest/assets/img/warning.gif"),h.appendChild(e)}if(e.appendChild(h),i){const t=document.createElement("div");t.className="toast-loader",e.appendChild(t),setTimeout((()=>{t.classList.add("done")}),2e3)}e._autoRemove&&clearTimeout(e._autoRemove);const f=setTimeout((()=>{const t=e.style.animation||"";let s="";t.includes("slide-top")?s="slide-top-reverse":t.includes("slide-bottom")?s="slide-bottom-reverse":t.includes("slide-left")?s="slide-left-reverse":t.includes("slide-right")?s="slide-right-reverse":t.includes("zoom-in")&&(s="zoom-out"),e.classList.add("slide-out"),e.style.animation=`${s} 0.5s ease`,setTimeout((()=>{e.classList.remove("show","slide-out"),e.style.animation="",e.parentNode&&e.parentNode.removeChild(e),d&&"function"==typeof d&&d(e)}),500)}),a);e._autoRemove=f},t.loading=function(e,s={}){const o=t(e,{...s,type:s.type||"info",duration:1e3,showLoader:!0,icon:null});requestAnimationFrame((()=>{o.classList.add("show")}));const n=o.querySelector(".ts-toast-loader");let i=o.querySelector(".ts-toast-icon");return i||(i=document.createElement("span"),i.className="ts-toast-icon",o.appendChild(i)),n&&setTimeout((()=>{n.classList.add("done")}),2e3),{update:(e,s={})=>{t.update(o,e,{...s,showLoader:!1})},close:()=>{o.classList.remove("show"),setTimeout((()=>{o.parentNode&&o.parentNode.removeChild(o)}),500)}}},window.toast=t}();
|
|
1
|
+
!function(){"use strict";const t=document.createElement("link");t.rel="stylesheet",t.href="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/css/toast.min.css",document.head.appendChild(t),function(){const t="ts-toast-inline-extras";if(document.getElementById(t))return;const e=document.createElement("style");e.id=t,e.textContent="\n /* Ensure center positions exist even if external CSS lacks them */\n .ts-toast-container.top-center { top: 1rem; left: 50%; transform: translateX(-50%); align-items: center; }\n .ts-toast-container.bottom-center { bottom: 1rem; left: 50%; transform: translateX(-50%); align-items: center; }\n .ts-toast-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 2147483646; }\n .ts-toast.ts-toast-confirm { max-width: min(92vw, 440px); width: max(320px, 60%); flex-direction: column; gap: 12px; padding: 16px 20px; background: var(--toast-bg, #fff); color: var(--toast-color, #000); border: 1px solid var(--toast-border, #e5e7eb); border-radius: 12px; box-shadow: var(--toast-shadow, 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)); text-align: center; }\n .ts-toast.ts-toast-confirm .ts-toast-content { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; }\n .ts-toast-actions { display: flex; gap: 10px; justify-content: center; margin-top: 12px; }\n .ts-toast-btn { appearance: none; border: 0; padding: 8px 12px; border-radius: 8px; font-weight: 600; cursor: pointer; }\n .ts-toast-btn.cancel { background: #e9ecef; color: #1f2937; }\n .ts-toast-btn.confirm { background: #3b82f6; color: #fff; }\n .ts-toast.ts-toast-error .ts-toast-btn.confirm,\n .ts-toast.ts-toast-warning .ts-toast-btn.confirm { background: #ef4444; color: #fff; }\n .ts-toast.ts-toast-confirm .ts-toast-title { font-weight: 700; font-size: 1.05rem; margin-top: 4px; }\n .ts-toast.ts-toast-confirm .ts-toast-close { position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; border-radius: 999px; border: 0; background: transparent; color: #6b7280; font-size: 20px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }\n .ts-toast.ts-toast-confirm .ts-toast-close:hover { background: rgba(0,0,0,0.06); }\n .ts-toast.ts-toast-confirm .ts-toast-icon { width: 64px; height: 64px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; }\n .ts-toast.ts-toast-confirm .ts-toast-icon img { width: 36px; height: 36px; }\n .ts-toast.ts-toast-confirm.ts-toast-success .ts-toast-icon { background: #dcfce7; }\n .ts-toast.ts-toast-confirm.ts-toast-info .ts-toast-icon { background: #dbeafe; }\n .ts-toast.ts-toast-confirm.ts-toast-warning .ts-toast-icon { background: #fef3c7; }\n .ts-toast.ts-toast-confirm.ts-toast-error .ts-toast-icon { background: #fee2e2; }\n ",document.head.appendChild(e)}();const e=function(t,e={}){const{position:o="top-right",animation:s="slide-right",type:n="info",duration:i=3e3,icon:a=null,showLoader:l=!1,mode:r="alert",title:c=null,confirmText:d="Yes",cancelText:m="No",confirmButtonBg:u=null,confirmButtonColor:p=null,cancelButtonBg:f=null,cancelButtonColor:g=null,onConfirm:h=null,onCancel:y=null,onResult:v=null,useOverlay:x=!0,closeOnOverlayClick:b=!0,showClose:C=!1,dismissOnClick:w=!0,onClick:L=null,onShow:N=null,onDismiss:E=null}=e,k="confirm"===r||"swal"===r,T="string"==typeof e.animation&&e.animation.trim()?e.animation.trim():k?"zoom-in":o.startsWith("top")?"slide-top":o.startsWith("bottom")?"slide-bottom":o.endsWith("left")?"slide-left":"slide-right",$=(t,e)=>{const o=t.style.animation||"";let s="";o.includes("slide-top")?s="slide-top-reverse":o.includes("slide-bottom")?s="slide-bottom-reverse":o.includes("slide-left")?s="slide-left-reverse":o.includes("slide-right")?s="slide-right-reverse":o.includes("zoom-in")&&(s="zoom-out"),t.classList.add("slide-out"),t.style.animation=`${s} 0.5s ease`,setTimeout((()=>{t.classList.remove("show","slide-out"),t.style.animation="",t.parentNode&&t.parentNode.removeChild(t),"function"==typeof e&&e()}),500)},j=document.createElement("div");j.className=`ts-toast ts-toast-${n}${k?" ts-toast-confirm":""}`,j.style.animation=`${T} 0.5s ease`,k||(j.style.flexDirection="row-reverse",j.style.justifyContent="flex-end");const _=document.createElement("span");if(_.className="ts-toast-icon",_.style.display="flex",a)_.textContent=a;else{const t=document.createElement("img");t.src="",t.style.width="30px",t.style.height="30px",t.style.objectFit="contain";const e="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/",o=(new Date).getTime();"success"===n?t.src=`${e}success.gif?t=${o}`:"error"===n?t.src=`${e}error.gif?t=${o}`:"info"===n?t.src=`${e}info.gif?t=${o}`:"warning"===n&&(t.src=`${e}warning.gif?t=${o}`),_.appendChild(t)}const R=document.createElement("div");R.className="ts-toast-body",R.innerHTML=t;let B=null;if(k){if(B=document.createElement("div"),B.className="ts-toast-content",B.appendChild(_),c){const t=document.createElement("div");t.className="ts-toast-title",t.textContent=c,B.appendChild(t)}B.appendChild(R),j.appendChild(B)}else j.appendChild(R);let z=null,S=null;if(k){z=document.createElement("div"),z.className="ts-toast-actions";const t=document.createElement("button");t.className="ts-toast-btn cancel",t.textContent=m;const e=document.createElement("button");e.className="ts-toast-btn confirm",e.textContent=d,f&&(t.style.background=f),g&&(t.style.color=g),u&&(e.style.background=u),p&&(e.style.color=p),z.appendChild(t),z.appendChild(e),j.appendChild(z),j.result=new Promise((t=>{S=t}));const o=t=>{S&&S(t),t&&"function"==typeof h&&h(j),t||"function"!=typeof y||y(j),"function"==typeof v&&v(t,j),$(j,(()=>{E&&"function"==typeof E&&E(j),O&&O.parentNode&&O.parentNode.removeChild(O)}))};t.addEventListener("click",(t=>{t.stopPropagation(),o(!1)})),e.addEventListener("click",(t=>{t.stopPropagation(),o(!0)}))}let q=null;l&&(q=document.createElement("div"),q.className="ts-toast-loader",j.appendChild(q));let O=null;if(k&&x){if(O=document.createElement("div"),O.className="ts-toast-overlay",document.body.appendChild(O),O.appendChild(j),C){const t=document.createElement("button");t.className="ts-toast-close",t.setAttribute("aria-label","Close"),t.innerHTML="×",t.addEventListener("click",(t=>{t.stopPropagation(),$(j,(()=>{E&&"function"==typeof E&&E(j),O&&O.parentNode&&O.parentNode.removeChild(O)}))})),j.appendChild(t)}b&&O.addEventListener("click",(t=>{t.target===O&&(j.result&&"function"==typeof S&&S(!1),$(j,(()=>{E&&"function"==typeof E&&E(j),O&&O.parentNode&&O.parentNode.removeChild(O)})))}))}else{let t=document.querySelector(`.ts-toast-container.${o}`);t||(t=document.createElement("div"),t.className=`ts-toast-container ${o}`,document.body.appendChild(t)),t.appendChild(j)}if(N&&"function"==typeof N&&N(j),setTimeout((()=>{j.classList.add("show")}),100),l&&q&&setTimeout((()=>{j._managedByLoading||(q.classList.add("done"),q.remove(),j.contains(_)||(k&&B?B.appendChild(_):j.appendChild(_)))}),2e3),l||k||j.contains(_)||j.appendChild(_),!k&&i>0){const t=setTimeout((()=>{$(j,(()=>{E&&"function"==typeof E&&E(j)}))}),i);j._autoRemove=t}if(!k&&w&&j.addEventListener("click",(()=>{j._autoRemove&&clearTimeout(j._autoRemove),$(j,(()=>{L&&"function"==typeof L&&L(j),E&&"function"==typeof E&&E(j)}))})),!k){let t=0,e=0;j.addEventListener("touchstart",(e=>{t=e.changedTouches[0].screenX})),j.addEventListener("touchend",(o=>{e=o.changedTouches[0].screenX,Math.abs(t-e)>50&&(j._autoRemove&&clearTimeout(j._autoRemove),$(j,(()=>{E&&"function"==typeof E&&E(j)})))}))}return j};e.success=function(t,o){e(t,{...o,type:"success"})},e.error=function(t,o){e(t,{...o,type:"error"})},e.update=function(t,e,o={}){const{type:s=null,icon:n=null,showLoader:i=!1,duration:a=3e3,position:l="top-right",onClick:r=null,onShow:c=null,onDismiss:d=null}=o,m=t.querySelector(".ts-toast-loader"),u=t.querySelector(".ts-toast-icon");m&&m.remove(),s&&(t.className=`ts-toast ts-toast-${s} show ${l}`);const p=t.querySelector(".ts-toast-body");p&&(p.innerHTML=e),u&&u.remove();const f=document.createElement("span");if(f.className="ts-toast-icon",f.style.display="flex",n)f.textContent=n;else{const t=document.createElement("img");t.style.width="30px",t.style.height="30px",t.style.objectFit="contain","success"===s?t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/success.gif":"error"===s?t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/error.gif":"info"===s?t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/info.gif":"warning"===s&&(t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.0/assets/img/warning.gif"),f.appendChild(t)}if(t.appendChild(f),i){const e=document.createElement("div");e.className="ts-toast-loader",t.appendChild(e),setTimeout((()=>{e.classList.add("done")}),2e3)}t._autoRemove&&clearTimeout(t._autoRemove);const g=setTimeout((()=>{((t,e)=>{const o=t.style.animation||"";let s="";o.includes("slide-top")?s="slide-top-reverse":o.includes("slide-bottom")?s="slide-bottom-reverse":o.includes("slide-left")?s="slide-left-reverse":o.includes("slide-right")?s="slide-right-reverse":o.includes("zoom-in")&&(s="zoom-out"),t.classList.add("slide-out"),t.style.animation=`${s} 0.5s ease`,setTimeout((()=>{t.classList.remove("show","slide-out"),t.style.animation="",t.parentNode&&t.parentNode.removeChild(t),"function"==typeof e&&e()}),500)})(t,(()=>{d&&"function"==typeof d&&d(t)}))}),a);t._autoRemove=g},e.loading=function(t,o={}){const s=e(t,{...o,type:o.type||"info",duration:0,showLoader:!0,icon:null});requestAnimationFrame((()=>{s.classList.add("show")}));const n=s.querySelector(".ts-toast-loader");let i=s.querySelector(".ts-toast-icon");return i||(i=document.createElement("span"),i.className="ts-toast-icon",i.style.display="flex",s.appendChild(i)),s._managedByLoading=!0,n&&setTimeout((()=>{s._managedByLoading||n.classList.add("done")}),2e3),{update:(t,o={})=>{s._managedByLoading=!1,e.update(s,t,{...o,showLoader:!1})},close:()=>{s._autoRemove&&clearTimeout(s._autoRemove);const t=s.style.animation||"";let e="";t.includes("slide-top")?e="slide-top-reverse":t.includes("slide-bottom")?e="slide-bottom-reverse":t.includes("slide-left")?e="slide-left-reverse":t.includes("slide-right")?e="slide-right-reverse":t.includes("zoom-in")&&(e="zoom-out"),s.classList.add("slide-out"),s.style.animation=`${e} 0.5s ease`,setTimeout((()=>{s.classList.remove("show","slide-out"),s.style.animation="",s.parentNode&&s.parentNode.removeChild(s)}),500)}}},e.confirm=function(t,o={}){return new Promise((s=>{e(t,{...o,mode:"confirm",duration:0,dismissOnClick:!1,onResult:t=>s(!!t)})}))},window.toast=e}();
|