@tsirosgeorge/toastnotification 5.1.1 โ†’ 5.3.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 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@5.1.1/toast.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.3.0/toast.min.js"></script>
10
10
  ```
11
11
 
12
12
  ## ๐Ÿ“ฆ Include package via npm
@@ -63,6 +63,23 @@ if (ok) {
63
63
  }
64
64
  ```
65
65
 
66
+ - With Input Field
67
+ ```javascript
68
+ const name = await toast.confirm('Enter your name:', {
69
+ title: 'Welcome',
70
+ input: 'text', // 'text', 'email', 'password', 'number', 'textarea'
71
+ inputPlaceholder: 'Your name here...',
72
+ inputValue: '', // optional default value
73
+ confirmText: 'Submit',
74
+ cancelText: 'Cancel',
75
+ });
76
+ if (name) {
77
+ console.log('Hello', name);
78
+ } else {
79
+ console.log('Cancelled');
80
+ }
81
+ ```
82
+
66
83
  - Callback API
67
84
  ```javascript
68
85
  toast('Are you sure?', {
@@ -110,8 +127,8 @@ t.update('Done!', { type: 'success', duration: 2000 });
110
127
  | `cancelButtonBg` | `string` | `null` | Inline background color for cancel button. |
111
128
  | `cancelButtonColor` | `string` | `null` | Inline text color for cancel button. |
112
129
 
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).
130
+ ### ๐Ÿงช Live Demo
131
+ Open the online demo to try all options: https://tsirosgeorge.github.io/toast-notification/
115
132
 
116
133
 
117
134
  ## ๐Ÿ“ License
@@ -87,6 +87,8 @@
87
87
  border-radius: 12px;
88
88
  padding: 16px 20px;
89
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
+ /* Add transitions for overlay confirms */
91
+ transition: opacity 0.5s ease, transform 0.5s ease;
90
92
  }
91
93
 
92
94
  .ts-toast.ts-toast-confirm .ts-toast-content {
@@ -107,15 +109,33 @@
107
109
  margin-top: 12px;
108
110
  }
109
111
 
112
+ .ts-toast-input {
113
+ width: 100%;
114
+ padding: 8px 12px;
115
+ border: 1px solid var(--toast-border, #e5e7eb);
116
+ border-radius: 8px;
117
+ font-family: inherit;
118
+ font-size: 0.95rem;
119
+ margin-top: 12px;
120
+ background: var(--toast-bg, #fff);
121
+ color: var(--toast-color, #000);
122
+ outline: none;
123
+ transition: border-color 0.2s ease;
124
+ }
125
+
126
+ .ts-toast-input:focus {
127
+ border-color: #3b82f6;
128
+ }
129
+
110
130
  /* Show toast with animation */
111
- .ts-toast-container .ts-toast.show {
131
+ .ts-toast-container .ts-toast.ts-toast-show {
112
132
  opacity: 1;
113
133
  transform: translateY(0);
114
134
  /* Move to final position */
115
135
  }
116
136
 
117
137
  /* Animations for different effects */
118
- @keyframes slide-left {
138
+ @keyframes ts-toast-slide-left {
119
139
  from {
120
140
  transform: translateX(-100%);
121
141
  }
@@ -125,7 +145,7 @@
125
145
  }
126
146
  }
127
147
 
128
- @keyframes slide-right {
148
+ @keyframes ts-toast-slide-right {
129
149
  from {
130
150
  transform: translateX(100%);
131
151
  }
@@ -135,7 +155,7 @@
135
155
  }
136
156
  }
137
157
 
138
- @keyframes slide-top {
158
+ @keyframes ts-toast-slide-top {
139
159
  from {
140
160
  transform: translateY(-100%);
141
161
  }
@@ -145,7 +165,7 @@
145
165
  }
146
166
  }
147
167
 
148
- @keyframes slide-bottom {
168
+ @keyframes ts-toast-slide-bottom {
149
169
  from {
150
170
  transform: translateY(100%);
151
171
  }
@@ -155,7 +175,7 @@
155
175
  }
156
176
  }
157
177
 
158
- @keyframes zoom-in {
178
+ @keyframes ts-toast-zoom-in {
159
179
  from {
160
180
  transform: scale(0);
161
181
  }
@@ -165,7 +185,12 @@
165
185
  }
166
186
  }
167
187
 
168
- @keyframes flip {
188
+ @keyframes ts-toast-zoom-out {
189
+ from { transform: scale(1); }
190
+ to { transform: scale(0); }
191
+ }
192
+
193
+ @keyframes ts-toast-flip {
169
194
  from {
170
195
  transform: rotateY(90deg);
171
196
  }
@@ -200,12 +225,12 @@
200
225
  border: 3px solid #f3f3f3;
201
226
  border-top: 3px solid var(--toast-loader-color, #66ee78);
202
227
  border-radius: 50%;
203
- animation: spin 1s linear infinite;
228
+ animation: ts-toast-spin 1s linear infinite;
204
229
  /* Continuous spinning */
205
230
  }
206
231
 
207
232
  /* Keyframe for spinning effect */
208
- @keyframes spin {
233
+ @keyframes ts-toast-spin {
209
234
  0% {
210
235
  transform: rotate(0deg);
211
236
  }
@@ -230,7 +255,7 @@
230
255
  }
231
256
 
232
257
  /* Show the icon after the loader has completed */
233
- .ts-toast-container .ts-toast.show .ts-toast-icon {
258
+ .ts-toast-container .ts-toast.ts-toast-show .ts-toast-icon {
234
259
  opacity: 1;
235
260
  /* Fade in the icon */
236
261
  }
@@ -246,7 +271,7 @@
246
271
  }
247
272
 
248
273
  /* Reverse Slide-out Animations */
249
- @keyframes slide-top-reverse {
274
+ @keyframes ts-toast-slide-top-reverse {
250
275
  from {
251
276
  transform: translateY(0);
252
277
  }
@@ -256,7 +281,7 @@
256
281
  }
257
282
  }
258
283
 
259
- @keyframes slide-bottom-reverse {
284
+ @keyframes ts-toast-slide-bottom-reverse {
260
285
  from {
261
286
  transform: translateY(0);
262
287
  }
@@ -266,7 +291,7 @@
266
291
  }
267
292
  }
268
293
 
269
- @keyframes slide-left-reverse {
294
+ @keyframes ts-toast-slide-left-reverse {
270
295
  from {
271
296
  transform: translateX(0);
272
297
  }
@@ -276,7 +301,7 @@
276
301
  }
277
302
  }
278
303
 
279
- @keyframes slide-right-reverse {
304
+ @keyframes ts-toast-slide-right-reverse {
280
305
  from {
281
306
  transform: translateX(0);
282
307
  }
@@ -286,11 +311,9 @@
286
311
  }
287
312
  }
288
313
 
289
- /* Slide-out when removed */
290
- .ts-toast-container .ts-toast.slide-out {
291
- animation-duration: 0.5s;
292
- animation-timing-function: ease-in-out;
293
- animation-fill-mode: forwards;
314
+ /* Slide-out when removed: use the same opacity/transform transition */
315
+ .ts-toast.ts-toast-slide-out {
316
+ opacity: 0;
294
317
  }
295
318
 
296
319
  /* Overlay for confirm dialogs */
@@ -304,11 +327,17 @@
304
327
  z-index: 2147483646;
305
328
  }
306
329
 
330
+ /* Position-based overlay alignment */
331
+ .ts-toast-overlay.top-left { align-items: flex-start; justify-content: flex-start; padding: 1rem; }
332
+ .ts-toast-overlay.top-center { align-items: flex-start; justify-content: center; padding: 1rem; }
333
+ .ts-toast-overlay.top-right { align-items: flex-start; justify-content: flex-end; padding: 1rem; }
334
+ .ts-toast-overlay.bottom-left { align-items: flex-end; justify-content: flex-start; padding: 1rem; }
335
+ .ts-toast-overlay.bottom-center { align-items: flex-end; justify-content: center; padding: 1rem; }
336
+ .ts-toast-overlay.bottom-right { align-items: flex-end; justify-content: flex-end; padding: 1rem; }
337
+
307
338
  /* Tiny utility: flex icon container */
308
- .d-flex {
309
- display: inline-flex;
310
- align-items: center;
311
- }
339
+ /* Scoped utility to avoid conflicts */
340
+ .ts-toast-d-flex { display: inline-flex; align-items: center; }
312
341
 
313
342
  /* Prevent scroll behind confirm overlay */
314
343
  body.ts-toast-no-scroll {
@@ -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.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}
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));transition:opacity .5s ease,transform .5s ease}.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-input{width:100%;padding:8px 12px;border:1px solid var(--toast-border,#e5e7eb);border-radius:8px;font-family:inherit;font-size:.95rem;margin-top:12px;background:var(--toast-bg,#fff);color:var(--toast-color,#000);outline:0;transition:border-color .2s ease}.ts-toast-input:focus{border-color:#3b82f6}.ts-toast-container .ts-toast.ts-toast-show{opacity:1;transform:translateY(0)}@keyframes ts-toast-slide-left{from{transform:translateX(-100%)}to{transform:translateX(0)}}@keyframes ts-toast-slide-right{from{transform:translateX(100%)}to{transform:translateX(0)}}@keyframes ts-toast-slide-top{from{transform:translateY(-100%)}to{transform:translateY(0)}}@keyframes ts-toast-slide-bottom{from{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes ts-toast-zoom-in{from{transform:scale(0)}to{transform:scale(1)}}@keyframes ts-toast-zoom-out{from{transform:scale(1)}to{transform:scale(0)}}@keyframes ts-toast-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:ts-toast-spin 1s linear infinite}@keyframes ts-toast-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.ts-toast-show .ts-toast-icon{opacity:1}@keyframes progress-bar{0%{width:0%}100%{width:100%}}@keyframes ts-toast-slide-top-reverse{from{transform:translateY(0)}to{transform:translateY(-100%)}}@keyframes ts-toast-slide-bottom-reverse{from{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes ts-toast-slide-left-reverse{from{transform:translateX(0)}to{transform:translateX(-100%)}}@keyframes ts-toast-slide-right-reverse{from{transform:translateX(0)}to{transform:translateX(100%)}}.ts-toast.ts-toast-slide-out{opacity:0}.ts-toast-overlay{position:fixed;inset:0;background:rgba(0,0,0,.5);display:flex;align-items:center;justify-content:center;z-index:2147483646}.ts-toast-overlay.top-left{align-items:flex-start;justify-content:flex-start;padding:1rem}.ts-toast-overlay.top-center{align-items:flex-start;justify-content:center;padding:1rem}.ts-toast-overlay.top-right{align-items:flex-start;justify-content:flex-end;padding:1rem}.ts-toast-overlay.bottom-left{align-items:flex-end;justify-content:flex-start;padding:1rem}.ts-toast-overlay.bottom-center{align-items:flex-end;justify-content:center;padding:1rem}.ts-toast-overlay.bottom-right{align-items:flex-end;justify-content:flex-end;padding:1rem}.ts-toast-d-flex{display:inline-flex;align-items:center}body.ts-toast-no-scroll{overflow:hidden}
package/package.json CHANGED
@@ -1,8 +1,15 @@
1
1
  {
2
2
  "name": "@tsirosgeorge/toastnotification",
3
- "version": "5.1.1",
3
+ "version": "5.3.0",
4
4
  "description": "a toast notification plugin",
5
5
  "main": "toast.min.js",
6
+ "module": "toast.module.js",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./toast.module.js",
10
+ "require": "./toast.min.js"
11
+ }
12
+ },
6
13
  "scripts": {
7
14
  "test": "echo \"Error: no test specified\" && exit 1",
8
15
  "build:css": "cleancss -o assets/css/toast.min.css assets/css/toast.css",
@@ -14,9 +21,10 @@
14
21
  "files": [
15
22
  "toast.js",
16
23
  "toast.min.js",
24
+ "toast.module.js",
17
25
  "assets/css/toast.css",
18
- "assets/css/toast.min.css",
19
- "assets/img/"
26
+ "assets/css/toast.min.css",
27
+ "assets/img/"
20
28
  ],
21
29
  "repository": {
22
30
  "type": "git",
package/toast.js CHANGED
@@ -1,13 +1,12 @@
1
- (function () {
2
- "use strict";
1
+ "use strict";
3
2
 
4
- // Dynamically load the external CSS file
5
- const link = document.createElement("link");
6
- link.rel = "stylesheet";
7
- link.href = "https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/assets/css/toast.min.css";// Pinned to current release
8
- document.head.appendChild(link);
3
+ // Dynamically load the external CSS file
4
+ const link = document.createElement("link");
5
+ link.rel = "stylesheet";
6
+ link.href = "./assets/css/toast.css"; // Local for testing
7
+ document.head.appendChild(link);
9
8
 
10
- // Inject minimal styles for confirm actions and overlay (kept tiny to avoid breaking existing CSS)
9
+ // Inject minimal styles for confirm actions and overlay (kept tiny to avoid breaking existing CSS)
11
10
  (function injectInlineStyles() {
12
11
  const STYLE_ID = 'ts-toast-inline-extras';
13
12
  if (document.getElementById(STYLE_ID)) return;
@@ -39,7 +38,7 @@
39
38
  document.head.appendChild(style);
40
39
  })();
41
40
 
42
- const toast = function (message, options = {}) {
41
+ const toast = function (message, options = {}) {
43
42
  const {
44
43
  position = 'top-right',
45
44
  animation = 'slide-right', // Default fallback animation
@@ -53,6 +52,10 @@
53
52
  title = null,
54
53
  confirmText = 'Yes',
55
54
  cancelText = 'No',
55
+ // input field options
56
+ input = false, // 'text', 'email', 'password', 'number', 'textarea', or false
57
+ inputPlaceholder = '',
58
+ inputValue = '',
56
59
  // confirm button color customization (optional)
57
60
  confirmButtonBg = null,
58
61
  confirmButtonColor = null,
@@ -75,39 +78,52 @@
75
78
 
76
79
  // Pick an animation intelligently when one wasn't explicitly provided
77
80
  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
81
+ ? (function mapAnim(a){
82
+ const m = {
83
+ 'slide-top':'ts-toast-slide-top',
84
+ 'slide-bottom':'ts-toast-slide-bottom',
85
+ 'slide-left':'ts-toast-slide-left',
86
+ 'slide-right':'ts-toast-slide-right',
87
+ 'zoom-in':'ts-toast-zoom-in',
88
+ 'zoom-out':'ts-toast-zoom-out',
89
+ 'flip':'ts-toast-flip'
90
+ };
91
+ return m[a] || a;
92
+ })(options.animation.trim())
93
+ : (isConfirm ? 'ts-toast-zoom-in' : (position.startsWith('top') ? 'ts-toast-slide-top'
94
+ : position.startsWith('bottom') ? 'ts-toast-slide-bottom'
95
+ : position.endsWith('left') ? 'ts-toast-slide-left'
96
+ : 'ts-toast-slide-right'));
97
+
98
+ // helper: remove with smooth CSS transition and cleanup (used by alerts)
85
99
  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';
100
+ const anim = el.dataset && el.dataset.anim ? el.dataset.anim : (el.style.animation || '');
101
+ let transform = '';
102
+ if (anim.includes('ts-toast-slide-top')) {
103
+ // Entered from top, exit upwards
104
+ transform = 'translateY(-100%)';
105
+ } else if (anim.includes('ts-toast-slide-bottom')) {
106
+ // Entered from bottom, exit upwards
107
+ transform = 'translateY(100%)';
108
+ } else if (anim.includes('ts-toast-slide-left')) {
109
+ // Entered from left, exit to right
110
+ transform = 'translateX(100%)';
111
+ } else if (anim.includes('ts-toast-slide-right')) {
112
+ // Entered from right, exit to right
113
+ transform = 'translateX(100%)';
101
114
  }
102
115
 
103
- // Apply the reverse animation dynamically
104
- el.classList.add('slide-out');
105
- el.style.animation = `${reverseAnimation} 0.5s ease`;
116
+ el.classList.add('ts-toast-slide-out');
117
+ el.classList.remove('ts-toast-show');
118
+ // Stop any running keyframe animation and drive exit via CSS transition
119
+ el.style.animation = '';
120
+ if (transform) {
121
+ el.style.transform = transform;
122
+ }
123
+ el.style.opacity = '0';
106
124
 
107
- // Wait for the reverse animation to finish before removing the toast
108
125
  setTimeout(() => {
109
- el.classList.remove('show', 'slide-out');
110
- el.style.animation = '';
126
+ el.classList.remove('ts-toast-slide-out');
111
127
  if (el.parentNode) el.parentNode.removeChild(el);
112
128
  if (typeof callback === 'function') callback();
113
129
  }, 500);
@@ -115,6 +131,7 @@
115
131
 
116
132
  const toastElement = document.createElement('div');
117
133
  toastElement.className = `ts-toast ts-toast-${type}${isConfirm ? ' ts-toast-confirm' : ''}`;
134
+ toastElement.dataset.anim = resolvedAnimation;
118
135
  toastElement.style.animation = `${resolvedAnimation} 0.5s ease`;
119
136
  // In confirm mode, we stack content vertically; in alert mode keep original layout
120
137
  if (!isConfirm) {
@@ -135,7 +152,7 @@
135
152
  img.style.height = '30px';
136
153
  img.style.objectFit = 'contain';
137
154
 
138
- const baseUrl = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/assets/img/';
155
+ const baseUrl = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.3.0/assets/img/';
139
156
  const timestamp = new Date().getTime(); // ๐Ÿ”„ force refresh
140
157
 
141
158
  if (type === 'success') {
@@ -174,6 +191,22 @@
174
191
  toastElement.appendChild(toastBody);
175
192
  }
176
193
 
194
+ // Input field (for confirm mode with input)
195
+ let inputElement = null;
196
+ if (isConfirm && input) {
197
+ if (input === 'textarea') {
198
+ inputElement = document.createElement('textarea');
199
+ inputElement.rows = 3;
200
+ } else {
201
+ inputElement = document.createElement('input');
202
+ inputElement.type = input === 'text' || input === 'email' || input === 'password' || input === 'number' ? input : 'text';
203
+ }
204
+ inputElement.className = 'ts-toast-input';
205
+ inputElement.placeholder = inputPlaceholder;
206
+ inputElement.value = inputValue;
207
+ toastElement.appendChild(inputElement);
208
+ }
209
+
177
210
  // Actions (for confirm mode)
178
211
  let actionsContainer = null;
179
212
  let resultResolver = null;
@@ -203,10 +236,12 @@
203
236
  toastElement.result = new Promise((resolve) => { resultResolver = resolve; });
204
237
 
205
238
  const resolveAndClose = (value) => {
206
- if (resultResolver) resultResolver(value);
207
- if (value && typeof onConfirm === 'function') onConfirm(toastElement);
239
+ const result = (value && inputElement !== null) ? inputElement.value : value;
240
+ if (resultResolver) resultResolver(result);
241
+ if (value && typeof onConfirm === 'function') onConfirm((inputElement !== null) ? inputElement.value : value, toastElement);
208
242
  if (!value && typeof onCancel === 'function') onCancel(toastElement);
209
- if (typeof onResult === 'function') onResult(value, toastElement);
243
+ if (typeof onResult === 'function') onResult(result, toastElement);
244
+ // Use the same slide+fade removal as alerts
210
245
  removeWithAnimation(toastElement, () => {
211
246
  if (onDismiss && typeof onDismiss === 'function') onDismiss(toastElement);
212
247
  // Remove overlay if present
@@ -230,7 +265,7 @@
230
265
  let overlay = null;
231
266
  if (isConfirm && useOverlay) {
232
267
  overlay = document.createElement('div');
233
- overlay.className = 'ts-toast-overlay';
268
+ overlay.className = `ts-toast-overlay ${position}`;
234
269
  document.body.appendChild(overlay);
235
270
  overlay.appendChild(toastElement);
236
271
  if (showClose) {
@@ -282,7 +317,7 @@
282
317
 
283
318
  // Show Toast with animation
284
319
  setTimeout(() => {
285
- toastElement.classList.add('show');
320
+ toastElement.classList.add('ts-toast-show');
286
321
  }, 100);
287
322
 
288
323
  // Handle Loader and Icon
@@ -403,13 +438,13 @@
403
438
  img.style.objectFit = 'contain';
404
439
 
405
440
  if (type === 'success') {
406
- img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/assets/img/success.gif';
441
+ img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/success.gif';
407
442
  } else if (type === 'error') {
408
- img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/assets/img/error.gif';
443
+ img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/error.gif';
409
444
  } else if (type === 'info') {
410
- img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/assets/img/info.gif';
445
+ img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/info.gif';
411
446
  } else if (type === 'warning') {
412
- img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/assets/img/warning.gif';
447
+ img.src = 'https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/warning.gif';
413
448
  }
414
449
 
415
450
  iconElement.appendChild(img);
@@ -435,21 +470,12 @@
435
470
 
436
471
  // Set the auto-remove timer again to ensure toast disappears after the duration
437
472
  const autoRemove = setTimeout(() => {
438
- // Use the same helper removal used above
439
- // Re-create the helper here in case update() is used alone
440
473
  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`;
474
+ el.classList.add('ts-toast-slide-out');
475
+ el.classList.remove('ts-toast-show');
476
+ el.style.animation = '';
450
477
  setTimeout(() => {
451
- el.classList.remove('show', 'slide-out');
452
- el.style.animation = '';
478
+ el.classList.remove('ts-toast-slide-out');
453
479
  if (el.parentNode) el.parentNode.removeChild(el);
454
480
  if (typeof cb === 'function') cb();
455
481
  }, 500);
@@ -474,7 +500,7 @@
474
500
 
475
501
  // Force reflow and add animation after DOM insert
476
502
  requestAnimationFrame(() => {
477
- toastElement.classList.add('show');
503
+ toastElement.classList.add('ts-toast-show');
478
504
  });
479
505
 
480
506
  const loader = toastElement.querySelector('.ts-toast-loader');
@@ -510,18 +536,11 @@
510
536
  },
511
537
  close: () => {
512
538
  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`;
539
+ toastElement.classList.add('ts-toast-slide-out');
540
+ toastElement.classList.remove('ts-toast-show');
541
+ toastElement.style.animation = '';
522
542
  setTimeout(() => {
523
- toastElement.classList.remove('show', 'slide-out');
524
- toastElement.style.animation = '';
543
+ toastElement.classList.remove('ts-toast-slide-out');
525
544
  if (toastElement.parentNode) toastElement.parentNode.removeChild(toastElement);
526
545
  }, 500);
527
546
  }
@@ -537,7 +556,7 @@
537
556
  mode: 'confirm',
538
557
  duration: 0, // prevent auto-dismiss
539
558
  dismissOnClick: false,
540
- onResult: (val) => resolve(!!val)
559
+ onResult: (val) => resolve(val)
541
560
  });
542
561
  // If consumer needs the element, it is returned by toast() but we ignore here.
543
562
  // They can still call toast(...) with mode: 'confirm' to get the element and read el.result
@@ -545,6 +564,12 @@
545
564
  });
546
565
  };
547
566
 
548
- // Expose globally
567
+ // Expose globally for CDN / browser usage
568
+ if (typeof window !== 'undefined') {
549
569
  window.toast = toast;
550
- })();
570
+ }
571
+
572
+ // CommonJS export for Node/bundlers (safe no-op in browsers)
573
+ if (typeof module !== 'undefined' && module.exports) {
574
+ module.exports = toast;
575
+ }
package/toast.min.js CHANGED
@@ -1 +1 @@
1
- !function(){"use strict";const t=document.createElement("link");t.rel="stylesheet",t.href="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/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.1/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="&times;",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.1/assets/img/success.gif":"error"===s?t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/assets/img/error.gif":"info"===s?t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/assets/img/info.gif":"warning"===s&&(t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.1.1/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}();
1
+ "use strict";const link=document.createElement("link");link.rel="stylesheet",link.href="./assets/css/toast.css",document.head.appendChild(link),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 toast=function(t,e={}){const{position:o="top-right",animation:s="slide-right",type:n="info",duration:a=3e3,icon:i=null,showLoader:l=!1,mode:c="alert",title:r=null,confirmText:d="Yes",cancelText:m="No",input:u=!1,inputPlaceholder:p="",inputValue:f="",confirmButtonBg:g=null,confirmButtonColor:h=null,cancelButtonBg:y=null,cancelButtonColor:x=null,onConfirm:v=null,onCancel:b=null,onResult:C=null,useOverlay:w=!0,closeOnOverlayClick:L=!0,showClose:E=!1,dismissOnClick:N=!0,onClick:k=null,onShow:T=null,onDismiss:$=null}=e,_="confirm"===c||"swal"===c,j="string"==typeof e.animation&&e.animation.trim()?{"slide-top":"ts-toast-slide-top","slide-bottom":"ts-toast-slide-bottom","slide-left":"ts-toast-slide-left","slide-right":"ts-toast-slide-right","zoom-in":"ts-toast-zoom-in","zoom-out":"ts-toast-zoom-out",flip:"ts-toast-flip"}[R=e.animation.trim()]||R:_?"ts-toast-zoom-in":o.startsWith("top")?"ts-toast-slide-top":o.startsWith("bottom")?"ts-toast-slide-bottom":o.endsWith("left")?"ts-toast-slide-left":"ts-toast-slide-right";var R;const B=(t,e)=>{const o=t.dataset&&t.dataset.anim?t.dataset.anim:t.style.animation||"";let s="";o.includes("ts-toast-slide-top")?s="translateY(-100%)":o.includes("ts-toast-slide-bottom")?s="translateY(100%)":(o.includes("ts-toast-slide-left")||o.includes("ts-toast-slide-right"))&&(s="translateX(100%)"),t.classList.add("ts-toast-slide-out"),t.classList.remove("ts-toast-show"),t.style.animation="",s&&(t.style.transform=s),t.style.opacity="0",setTimeout((()=>{t.classList.remove("ts-toast-slide-out"),t.parentNode&&t.parentNode.removeChild(t),"function"==typeof e&&e()}),500)},S=document.createElement("div");S.className=`ts-toast ts-toast-${n}${_?" ts-toast-confirm":""}`,S.dataset.anim=j,S.style.animation=`${j} 0.5s ease`,_||(S.style.flexDirection="row-reverse",S.style.justifyContent="flex-end");const z=document.createElement("span");if(z.className="ts-toast-icon",z.style.display="flex",i)z.textContent=i;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.3.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}`),z.appendChild(t)}const q=document.createElement("div");q.className="ts-toast-body",q.innerHTML=t;let P=null;if(_){if(P=document.createElement("div"),P.className="ts-toast-content",P.appendChild(z),r){const t=document.createElement("div");t.className="ts-toast-title",t.textContent=r,P.appendChild(t)}P.appendChild(q),S.appendChild(P)}else S.appendChild(q);let O=null;_&&u&&("textarea"===u?(O=document.createElement("textarea"),O.rows=3):(O=document.createElement("input"),O.type="text"===u||"email"===u||"password"===u||"number"===u?u:"text"),O.className="ts-toast-input",O.placeholder=p,O.value=f,S.appendChild(O));let X=null,D=null;if(_){X=document.createElement("div"),X.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,y&&(t.style.background=y),x&&(t.style.color=x),g&&(e.style.background=g),h&&(e.style.color=h),X.appendChild(t),X.appendChild(e),S.appendChild(X),S.result=new Promise((t=>{D=t}));const o=t=>{const e=t&&null!==O?O.value:t;D&&D(e),t&&"function"==typeof v&&v(null!==O?O.value:t,S),t||"function"!=typeof b||b(S),"function"==typeof C&&C(e,S),B(S,(()=>{$&&"function"==typeof $&&$(S),F&&F.parentNode&&F.parentNode.removeChild(F)}))};t.addEventListener("click",(t=>{t.stopPropagation(),o(!1)})),e.addEventListener("click",(t=>{t.stopPropagation(),o(!0)}))}let M=null;l&&(M=document.createElement("div"),M.className="ts-toast-loader",S.appendChild(M));let F=null;if(_&&w){if(F=document.createElement("div"),F.className=`ts-toast-overlay ${o}`,document.body.appendChild(F),F.appendChild(S),E){const t=document.createElement("button");t.className="ts-toast-close",t.setAttribute("aria-label","Close"),t.innerHTML="&times;",t.addEventListener("click",(t=>{t.stopPropagation(),B(S,(()=>{$&&"function"==typeof $&&$(S),F&&F.parentNode&&F.parentNode.removeChild(F)}))})),S.appendChild(t)}L&&F.addEventListener("click",(t=>{t.target===F&&(S.result&&"function"==typeof D&&D(!1),B(S,(()=>{$&&"function"==typeof $&&$(S),F&&F.parentNode&&F.parentNode.removeChild(F)})))}))}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(S)}if(T&&"function"==typeof T&&T(S),setTimeout((()=>{S.classList.add("ts-toast-show")}),100),l&&M&&setTimeout((()=>{S._managedByLoading||(M.classList.add("done"),M.remove(),S.contains(z)||(_&&P?P.appendChild(z):S.appendChild(z)))}),2e3),l||_||S.contains(z)||S.appendChild(z),!_&&a>0){const t=setTimeout((()=>{B(S,(()=>{$&&"function"==typeof $&&$(S)}))}),a);S._autoRemove=t}if(!_&&N&&S.addEventListener("click",(()=>{S._autoRemove&&clearTimeout(S._autoRemove),B(S,(()=>{k&&"function"==typeof k&&k(S),$&&"function"==typeof $&&$(S)}))})),!_){let t=0,e=0;S.addEventListener("touchstart",(e=>{t=e.changedTouches[0].screenX})),S.addEventListener("touchend",(o=>{e=o.changedTouches[0].screenX,Math.abs(t-e)>50&&(S._autoRemove&&clearTimeout(S._autoRemove),B(S,(()=>{$&&"function"==typeof $&&$(S)})))}))}return S};toast.success=function(t,e){toast(t,{...e,type:"success"})},toast.error=function(t,e){toast(t,{...e,type:"error"})},toast.update=function(t,e,o={}){const{type:s=null,icon:n=null,showLoader:a=!1,duration:i=3e3,position:l="top-right",onClick:c=null,onShow:r=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.2.0/assets/img/success.gif":"error"===s?t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/error.gif":"info"===s?t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/info.gif":"warning"===s&&(t.src="https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/warning.gif"),f.appendChild(t)}if(t.appendChild(f),a){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((()=>{var e,o;o=()=>{d&&"function"==typeof d&&d(t)},(e=t).classList.add("ts-toast-slide-out"),e.classList.remove("ts-toast-show"),e.style.animation="",setTimeout((()=>{e.classList.remove("ts-toast-slide-out"),e.parentNode&&e.parentNode.removeChild(e),"function"==typeof o&&o()}),500)}),i);t._autoRemove=g},toast.loading=function(t,e={}){const o=toast(t,{...e,type:e.type||"info",duration:0,showLoader:!0,icon:null});requestAnimationFrame((()=>{o.classList.add("ts-toast-show")}));const s=o.querySelector(".ts-toast-loader");let n=o.querySelector(".ts-toast-icon");return n||(n=document.createElement("span"),n.className="ts-toast-icon",n.style.display="flex",o.appendChild(n)),o._managedByLoading=!0,s&&setTimeout((()=>{o._managedByLoading||s.classList.add("done")}),2e3),{update:(t,e={})=>{o._managedByLoading=!1,toast.update(o,t,{...e,showLoader:!1})},close:()=>{o._autoRemove&&clearTimeout(o._autoRemove),o.classList.add("ts-toast-slide-out"),o.classList.remove("ts-toast-show"),o.style.animation="",setTimeout((()=>{o.classList.remove("ts-toast-slide-out"),o.parentNode&&o.parentNode.removeChild(o)}),500)}}},toast.confirm=function(t,e={}){return new Promise((o=>{toast(t,{...e,mode:"confirm",duration:0,dismissOnClick:!1,onResult:t=>o(t)})}))},"undefined"!=typeof window&&(window.toast=toast),"undefined"!=typeof module&&module.exports&&(module.exports=toast);
@@ -0,0 +1,542 @@
1
+ "use strict";
2
+
3
+ // Dynamically load the external CSS file (same as toast.js)
4
+ const link = document.createElement("link");
5
+ link.rel = "stylesheet";
6
+ link.href = "./assets/css/toast.css"; // Local for testing
7
+ document.head.appendChild(link);
8
+
9
+ // Inject minimal styles for confirm actions and overlay (same as toast.js)
10
+ (function injectInlineStyles() {
11
+ const STYLE_ID = "ts-toast-inline-extras";
12
+ if (document.getElementById(STYLE_ID)) return;
13
+ const style = document.createElement("style");
14
+ style.id = STYLE_ID;
15
+ style.textContent = `
16
+ /* Ensure center positions exist even if external CSS lacks them */
17
+ .ts-toast-container.top-center { top: 1rem; left: 50%; transform: translateX(-50%); align-items: center; }
18
+ .ts-toast-container.bottom-center { bottom: 1rem; left: 50%; transform: translateX(-50%); align-items: center; }
19
+ .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; }
20
+ .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; }
21
+ .ts-toast.ts-toast-confirm .ts-toast-content { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; }
22
+ .ts-toast-actions { display: flex; gap: 10px; justify-content: center; margin-top: 12px; }
23
+ .ts-toast-btn { appearance: none; border: 0; padding: 8px 12px; border-radius: 8px; font-weight: 600; cursor: pointer; }
24
+ .ts-toast-btn.cancel { background: #e9ecef; color: #1f2937; }
25
+ .ts-toast-btn.confirm { background: #3b82f6; color: #fff; }
26
+ .ts-toast.ts-toast-error .ts-toast-btn.confirm,
27
+ .ts-toast.ts-toast-warning .ts-toast-btn.confirm { background: #ef4444; color: #fff; }
28
+ .ts-toast.ts-toast-confirm .ts-toast-title { font-weight: 700; font-size: 1.05rem; margin-top: 4px; }
29
+ .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; }
30
+ .ts-toast.ts-toast-confirm .ts-toast-close:hover { background: rgba(0,0,0,0.06); }
31
+ .ts-toast.ts-toast-confirm .ts-toast-icon { width: 64px; height: 64px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; }
32
+ .ts-toast.ts-toast-confirm .ts-toast-icon img { width: 36px; height: 36px; }
33
+ .ts-toast.ts-toast-confirm.ts-toast-success .ts-toast-icon { background: #dcfce7; }
34
+ .ts-toast.ts-toast-confirm.ts-toast-info .ts-toast-icon { background: #dbeafe; }
35
+ .ts-toast.ts-toast-confirm.ts-toast-warning .ts-toast-icon { background: #fef3c7; }
36
+ .ts-toast.ts-toast-confirm.ts-toast-error .ts-toast-icon { background: #fee2e2; }
37
+ `;
38
+ document.head.appendChild(style);
39
+ })();
40
+
41
+ // Full implementation copied from toast.js but exposed as ES module
42
+ const toast = function (message, options = {}) {
43
+ const {
44
+ position = "top-right",
45
+ animation = "slide-right",
46
+ type = "info",
47
+ duration = 3000,
48
+ icon = null,
49
+ showLoader = false,
50
+ mode = "alert",
51
+ title = null,
52
+ confirmText = "Yes",
53
+ cancelText = "No",
54
+ input = false,
55
+ inputPlaceholder = "",
56
+ inputValue = "",
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
+ dismissOnClick = true,
68
+ onClick = null,
69
+ onShow = null,
70
+ onDismiss = null,
71
+ } = options;
72
+
73
+ const isConfirm = mode === "confirm" || mode === "swal";
74
+
75
+ const resolvedAnimation =
76
+ typeof options.animation === "string" && options.animation.trim()
77
+ ? (function mapAnim(a) {
78
+ const m = {
79
+ "slide-top": "ts-toast-slide-top",
80
+ "slide-bottom": "ts-toast-slide-bottom",
81
+ "slide-left": "ts-toast-slide-left",
82
+ "slide-right": "ts-toast-slide-right",
83
+ "zoom-in": "ts-toast-zoom-in",
84
+ "zoom-out": "ts-toast-zoom-out",
85
+ flip: "ts-toast-flip",
86
+ };
87
+ return m[a] || a;
88
+ })(options.animation.trim())
89
+ : isConfirm
90
+ ? "ts-toast-zoom-in"
91
+ : position.startsWith("top")
92
+ ? "ts-toast-slide-top"
93
+ : position.startsWith("bottom")
94
+ ? "ts-toast-slide-bottom"
95
+ : position.endsWith("left")
96
+ ? "ts-toast-slide-left"
97
+ : "ts-toast-slide-right";
98
+
99
+ // helper: remove with smooth CSS transition and cleanup (used by alerts and confirms)
100
+ const removeWithAnimation = (el, callback) => {
101
+ const anim = el.dataset && el.dataset.anim ? el.dataset.anim : (el.style.animation || "");
102
+ let transform = "";
103
+ if (anim.includes("ts-toast-slide-top")) {
104
+ // Entered from top, exit upwards
105
+ transform = "translateY(-100%)";
106
+ } else if (anim.includes("ts-toast-slide-bottom")) {
107
+ // Entered from bottom, exit upwards
108
+ transform = "translateY(100%)";
109
+ } else if (anim.includes("ts-toast-slide-left")) {
110
+ // Entered from left, exit to right
111
+ transform = "translateX(100%)";
112
+ } else if (anim.includes("ts-toast-slide-right")) {
113
+ // Entered from right, exit to right
114
+ transform = "translateX(100%)";
115
+ }
116
+
117
+ el.classList.add("ts-toast-slide-out");
118
+ el.classList.remove("ts-toast-show");
119
+ el.style.animation = "";
120
+ if (transform) {
121
+ el.style.transform = transform;
122
+ }
123
+ el.style.opacity = "0";
124
+
125
+ setTimeout(() => {
126
+ el.classList.remove("ts-toast-slide-out");
127
+ if (el.parentNode) el.parentNode.removeChild(el);
128
+ if (typeof callback === "function") callback();
129
+ }, 500);
130
+ };
131
+
132
+ const toastElement = document.createElement("div");
133
+ toastElement.className = `ts-toast ts-toast-${type}${isConfirm ? " ts-toast-confirm" : ""}`;
134
+ toastElement.dataset.anim = resolvedAnimation;
135
+ toastElement.style.animation = `${resolvedAnimation} 0.5s ease`;
136
+ if (!isConfirm) {
137
+ toastElement.style.flexDirection = "row-reverse";
138
+ toastElement.style.justifyContent = "flex-end";
139
+ }
140
+
141
+ const iconElement = document.createElement("span");
142
+ iconElement.className = "ts-toast-icon";
143
+ iconElement.style.display = "flex";
144
+ if (icon) {
145
+ iconElement.textContent = icon;
146
+ } else {
147
+ const img = document.createElement("img");
148
+ img.src = "";
149
+ img.style.width = "30px";
150
+ img.style.height = "30px";
151
+ img.style.objectFit = "contain";
152
+
153
+ const baseUrl =
154
+ "https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.3.0/assets/img/";
155
+ const timestamp = new Date().getTime();
156
+
157
+ if (type === "success") {
158
+ img.src = `${baseUrl}success.gif?t=${timestamp}`;
159
+ } else if (type === "error") {
160
+ img.src = `${baseUrl}error.gif?t=${timestamp}`;
161
+ } else if (type === "info") {
162
+ img.src = `${baseUrl}info.gif?t=${timestamp}`;
163
+ } else if (type === "warning") {
164
+ img.src = `${baseUrl}warning.gif?t=${timestamp}`;
165
+ }
166
+
167
+ iconElement.appendChild(img);
168
+ }
169
+
170
+ const toastBody = document.createElement("div");
171
+ toastBody.className = "ts-toast-body";
172
+ toastBody.innerHTML = message;
173
+
174
+ let contentRow = null;
175
+ if (isConfirm) {
176
+ contentRow = document.createElement("div");
177
+ contentRow.className = "ts-toast-content";
178
+ contentRow.appendChild(iconElement);
179
+ if (title) {
180
+ const titleEl = document.createElement("div");
181
+ titleEl.className = "ts-toast-title";
182
+ titleEl.textContent = title;
183
+ contentRow.appendChild(titleEl);
184
+ }
185
+ contentRow.appendChild(toastBody);
186
+ toastElement.appendChild(contentRow);
187
+ } else {
188
+ toastElement.appendChild(toastBody);
189
+ }
190
+
191
+ // Input field (for confirm mode with input)
192
+ let inputElement = null;
193
+ if (isConfirm && input) {
194
+ if (input === "textarea") {
195
+ inputElement = document.createElement("textarea");
196
+ inputElement.rows = 3;
197
+ } else {
198
+ inputElement = document.createElement("input");
199
+ inputElement.type = input === "text" || input === "email" || input === "password" || input === "number" ? input : "text";
200
+ }
201
+ inputElement.className = "ts-toast-input";
202
+ inputElement.placeholder = inputPlaceholder;
203
+ inputElement.value = inputValue;
204
+ toastElement.appendChild(inputElement);
205
+ }
206
+
207
+ let actionsContainer = null;
208
+ let resultResolver = null;
209
+ if (isConfirm) {
210
+ actionsContainer = document.createElement("div");
211
+ actionsContainer.className = "ts-toast-actions";
212
+
213
+ const cancelBtn = document.createElement("button");
214
+ cancelBtn.className = "ts-toast-btn cancel";
215
+ cancelBtn.textContent = cancelText;
216
+
217
+ const confirmBtn = document.createElement("button");
218
+ confirmBtn.className = "ts-toast-btn confirm";
219
+ confirmBtn.textContent = confirmText;
220
+
221
+ if (cancelButtonBg) cancelBtn.style.background = cancelButtonBg;
222
+ if (cancelButtonColor) cancelBtn.style.color = cancelButtonColor;
223
+ if (confirmButtonBg) confirmBtn.style.background = confirmButtonBg;
224
+ if (confirmButtonColor) confirmBtn.style.color = confirmButtonColor;
225
+
226
+ actionsContainer.appendChild(cancelBtn);
227
+ actionsContainer.appendChild(confirmBtn);
228
+ toastElement.appendChild(actionsContainer);
229
+
230
+ toastElement.result = new Promise((resolve) => {
231
+ resultResolver = resolve;
232
+ });
233
+
234
+ const resolveAndClose = (value) => {
235
+ const result = (value && inputElement !== null) ? inputElement.value : value;
236
+ if (resultResolver) resultResolver(result);
237
+ if (value && typeof onConfirm === "function") onConfirm((inputElement !== null) ? inputElement.value : value, toastElement);
238
+ if (!value && typeof onCancel === "function") onCancel(toastElement);
239
+ if (typeof onResult === "function") onResult(result, toastElement);
240
+ // Use the same slide+fade removal as alerts
241
+ removeWithAnimation(toastElement, () => {
242
+ if (onDismiss && typeof onDismiss === "function") onDismiss(toastElement);
243
+ if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
244
+ });
245
+ };
246
+
247
+ cancelBtn.addEventListener("click", (e) => {
248
+ e.stopPropagation();
249
+ resolveAndClose(false);
250
+ });
251
+ confirmBtn.addEventListener("click", (e) => {
252
+ e.stopPropagation();
253
+ resolveAndClose(true);
254
+ });
255
+ }
256
+
257
+ let loader = null;
258
+ if (showLoader) {
259
+ loader = document.createElement("div");
260
+ loader.className = "ts-toast-loader";
261
+ toastElement.appendChild(loader);
262
+ }
263
+
264
+ let overlay = null;
265
+ if (isConfirm && useOverlay) {
266
+ overlay = document.createElement("div");
267
+ overlay.className = `ts-toast-overlay ${position}`;
268
+ document.body.appendChild(overlay);
269
+ overlay.appendChild(toastElement);
270
+ if (showClose) {
271
+ const closeBtn = document.createElement("button");
272
+ closeBtn.className = "ts-toast-close";
273
+ closeBtn.setAttribute("aria-label", "Close");
274
+ closeBtn.innerHTML = "&times;";
275
+ closeBtn.addEventListener("click", (e) => {
276
+ e.stopPropagation();
277
+ removeWithAnimation(toastElement, () => {
278
+ if (onDismiss && typeof onDismiss === "function") onDismiss(toastElement);
279
+ if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
280
+ });
281
+ });
282
+ toastElement.appendChild(closeBtn);
283
+ }
284
+ if (closeOnOverlayClick) {
285
+ overlay.addEventListener("click", (e) => {
286
+ if (e.target === overlay) {
287
+ if (toastElement.result) {
288
+ if (typeof resultResolver === "function") {
289
+ resultResolver(false);
290
+ }
291
+ }
292
+ removeWithAnimation(toastElement, () => {
293
+ if (onDismiss && typeof onDismiss === "function") onDismiss(toastElement);
294
+ if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
295
+ });
296
+ }
297
+ });
298
+ }
299
+ } else {
300
+ let container = document.querySelector(`.ts-toast-container.${position}`);
301
+ if (!container) {
302
+ container = document.createElement("div");
303
+ container.className = `ts-toast-container ${position}`;
304
+ document.body.appendChild(container);
305
+ }
306
+ container.appendChild(toastElement);
307
+ }
308
+
309
+ if (onShow && typeof onShow === "function") {
310
+ onShow(toastElement);
311
+ }
312
+
313
+ setTimeout(() => {
314
+ toastElement.classList.add("ts-toast-show");
315
+ }, 100);
316
+
317
+ if (showLoader && loader) {
318
+ setTimeout(() => {
319
+ if (toastElement._managedByLoading) return;
320
+ loader.classList.add("done");
321
+ loader.remove();
322
+ if (!toastElement.contains(iconElement)) {
323
+ if (isConfirm && contentRow) contentRow.appendChild(iconElement);
324
+ else toastElement.appendChild(iconElement);
325
+ }
326
+ }, 2000);
327
+ }
328
+ if (!showLoader) {
329
+ if (!isConfirm && !toastElement.contains(iconElement)) {
330
+ toastElement.appendChild(iconElement);
331
+ }
332
+ }
333
+
334
+ if (!isConfirm && duration > 0) {
335
+ const autoRemove = setTimeout(() => {
336
+ removeWithAnimation(toastElement, () => {
337
+ if (onDismiss && typeof onDismiss === "function") onDismiss(toastElement);
338
+ });
339
+ }, duration);
340
+ toastElement._autoRemove = autoRemove;
341
+ }
342
+
343
+ if (!isConfirm && dismissOnClick) {
344
+ toastElement.addEventListener("click", () => {
345
+ if (toastElement._autoRemove) clearTimeout(toastElement._autoRemove);
346
+ removeWithAnimation(toastElement, () => {
347
+ if (onClick && typeof onClick === "function") onClick(toastElement);
348
+ if (onDismiss && typeof onDismiss === "function") onDismiss(toastElement);
349
+ });
350
+ });
351
+ }
352
+
353
+ if (!isConfirm) {
354
+ let touchStartX = 0;
355
+ let touchEndX = 0;
356
+
357
+ toastElement.addEventListener("touchstart", (e) => {
358
+ touchStartX = e.changedTouches[0].screenX;
359
+ });
360
+
361
+ toastElement.addEventListener("touchend", (e) => {
362
+ touchEndX = e.changedTouches[0].screenX;
363
+ if (Math.abs(touchStartX - touchEndX) > 50) {
364
+ if (toastElement._autoRemove) clearTimeout(toastElement._autoRemove);
365
+ removeWithAnimation(toastElement, () => {
366
+ if (onDismiss && typeof onDismiss === "function") onDismiss(toastElement);
367
+ });
368
+ }
369
+ });
370
+ }
371
+
372
+ return toastElement;
373
+ };
374
+
375
+ toast.success = function (message, options) {
376
+ toast(message, { ...options, type: "success" });
377
+ };
378
+
379
+ toast.error = function (message, options) {
380
+ toast(message, { ...options, type: "error" });
381
+ };
382
+
383
+ toast.update = function (toastElement, message, options = {}) {
384
+ const {
385
+ type = null,
386
+ icon = null,
387
+ showLoader = false,
388
+ duration = 3000,
389
+ position = "top-right",
390
+ onClick = null,
391
+ onShow = null,
392
+ onDismiss = null,
393
+ } = options;
394
+
395
+ const oldLoader = toastElement.querySelector(".ts-toast-loader");
396
+ const oldIcon = toastElement.querySelector(".ts-toast-icon");
397
+ if (oldLoader) oldLoader.remove();
398
+
399
+ if (type) {
400
+ toastElement.className = `ts-toast ts-toast-${type} show ${position}`;
401
+ }
402
+ const toastBody = toastElement.querySelector(".ts-toast-body");
403
+ if (toastBody) {
404
+ toastBody.innerHTML = message;
405
+ }
406
+
407
+ if (oldIcon) {
408
+ oldIcon.remove();
409
+ }
410
+
411
+ const iconElement = document.createElement("span");
412
+ iconElement.className = "ts-toast-icon";
413
+ iconElement.style.display = "flex";
414
+
415
+ if (icon) {
416
+ iconElement.textContent = icon;
417
+ } else {
418
+ const img = document.createElement("img");
419
+ img.style.width = "30px";
420
+ img.style.height = "30px";
421
+ img.style.objectFit = "contain";
422
+
423
+ if (type === "success") {
424
+ img.src =
425
+ "https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/success.gif";
426
+ } else if (type === "error") {
427
+ img.src =
428
+ "https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/error.gif";
429
+ } else if (type === "info") {
430
+ img.src =
431
+ "https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/info.gif";
432
+ } else if (type === "warning") {
433
+ img.src =
434
+ "https://cdn.jsdelivr.net/npm/@tsirosgeorge/toastnotification@5.2.0/assets/img/warning.gif";
435
+ }
436
+
437
+ iconElement.appendChild(img);
438
+ }
439
+
440
+ toastElement.appendChild(iconElement);
441
+
442
+ if (showLoader) {
443
+ const loader = document.createElement("div");
444
+ loader.className = "ts-toast-loader";
445
+ toastElement.appendChild(loader);
446
+ setTimeout(() => {
447
+ loader.classList.add("done");
448
+ }, 2000);
449
+ }
450
+
451
+ if (toastElement._autoRemove) {
452
+ clearTimeout(toastElement._autoRemove);
453
+ }
454
+
455
+ const autoRemove = setTimeout(() => {
456
+ const removeWithAnimation = (el, cb) => {
457
+ el.classList.add("ts-toast-slide-out");
458
+ el.classList.remove("ts-toast-show");
459
+ el.style.animation = "";
460
+ setTimeout(() => {
461
+ el.classList.remove("ts-toast-slide-out");
462
+ if (el.parentNode) el.parentNode.removeChild(el);
463
+ if (typeof cb === "function") cb();
464
+ }, 500);
465
+ };
466
+
467
+ removeWithAnimation(toastElement, () => {
468
+ if (onDismiss && typeof onDismiss === "function") onDismiss(toastElement);
469
+ });
470
+ }, duration);
471
+
472
+ toastElement._autoRemove = autoRemove;
473
+ };
474
+
475
+ toast.loading = function (message, options = {}) {
476
+ const toastElement = toast(message, {
477
+ ...options,
478
+ type: options.type || "info",
479
+ duration: 0,
480
+ showLoader: true,
481
+ icon: null,
482
+ });
483
+
484
+ requestAnimationFrame(() => {
485
+ toastElement.classList.add("ts-toast-show");
486
+ });
487
+
488
+ const loader = toastElement.querySelector(".ts-toast-loader");
489
+ let iconElement = toastElement.querySelector(".ts-toast-icon");
490
+
491
+ if (!iconElement) {
492
+ iconElement = document.createElement("span");
493
+ iconElement.className = "ts-toast-icon";
494
+ iconElement.style.display = "flex";
495
+ toastElement.appendChild(iconElement);
496
+ }
497
+
498
+ toastElement._managedByLoading = true;
499
+
500
+ if (loader) {
501
+ setTimeout(() => {
502
+ if (!toastElement._managedByLoading) loader.classList.add("done");
503
+ }, 2000);
504
+ }
505
+
506
+ return {
507
+ update: (newMessage, newOptions = {}) => {
508
+ toastElement._managedByLoading = false;
509
+ toast.update(toastElement, newMessage, {
510
+ ...newOptions,
511
+ showLoader: false,
512
+ });
513
+ },
514
+ close: () => {
515
+ if (toastElement._autoRemove) clearTimeout(toastElement._autoRemove);
516
+ toastElement.classList.add("ts-toast-slide-out");
517
+ toastElement.classList.remove("ts-toast-show");
518
+ toastElement.style.animation = "";
519
+ setTimeout(() => {
520
+ toastElement.classList.remove("ts-toast-slide-out");
521
+ if (toastElement.parentNode) toastElement.parentNode.removeChild(toastElement);
522
+ }, 500);
523
+ },
524
+ };
525
+ };
526
+
527
+ toast.confirm = function (message, options = {}) {
528
+ return new Promise((resolve) => {
529
+ const el = toast(message, {
530
+ ...options,
531
+ mode: "confirm",
532
+ duration: 0,
533
+ dismissOnClick: false,
534
+ onResult: (val) => resolve(val),
535
+ });
536
+ void el;
537
+ });
538
+ };
539
+
540
+ // ES module export
541
+ export default toast;
542
+ export { toast };