ga-toasts 1.0.0 → 2.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/LICENSE +21 -0
- package/README.md +327 -554
- package/dist/ga-toasts.css +608 -0
- package/dist/ga-toasts.global.js +2 -0
- package/dist/index.cjs +1242 -0
- package/dist/index.d.cts +247 -0
- package/dist/index.d.ts +247 -0
- package/dist/index.js +1235 -0
- package/package.json +85 -23
- package/.htaccess +0 -75
- package/REDIRECT_SETUP.md +0 -149
- package/ga-toasts.d.ts +0 -99
- package/images/gennie_logo.png +0 -0
- package/index.html +0 -1034
- package/robots.txt +0 -54
- package/sitemap.xml +0 -47
- package/src/demo.css +0 -698
- package/src/demo.js +0 -467
- package/src/toasts.css +0 -1644
- package/src/toasts.js +0 -1005
- package/src/variables.css +0 -480
- package/vercel.json +0 -50
package/README.md
CHANGED
|
@@ -1,554 +1,327 @@
|
|
|
1
|
-
# 🍞 GA Toasts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
![
|
|
6
|
-
![
|
|
7
|
-
![
|
|
8
|
-
![
|
|
9
|
-
|
|
10
|
-
**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- 🎨 **
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
###
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
--ga-text-sm: 14px;
|
|
329
|
-
--ga-text-base: 16px;
|
|
330
|
-
|
|
331
|
-
/* Animations */
|
|
332
|
-
--ga-duration-300: 300ms;
|
|
333
|
-
--ga-ease-out: cubic-bezier(0, 0, 0.2, 1);
|
|
334
|
-
}
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
### Themes
|
|
338
|
-
|
|
339
|
-
#### Light Theme (Default)
|
|
340
|
-
```html
|
|
341
|
-
<html data-ga-theme="light">
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
#### Dark Theme
|
|
345
|
-
```html
|
|
346
|
-
<html data-ga-theme="dark">
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
#### System Theme
|
|
350
|
-
```html
|
|
351
|
-
<html data-ga-theme="system">
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
### Custom Styling
|
|
355
|
-
|
|
356
|
-
```css
|
|
357
|
-
/* Custom toast styles */
|
|
358
|
-
.ga-toast.my-custom-toast {
|
|
359
|
-
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
360
|
-
border: 2px solid #fff;
|
|
361
|
-
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
.ga-toast.my-custom-toast .ga-toast-title {
|
|
365
|
-
color: white;
|
|
366
|
-
font-weight: 700;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
.ga-toast.my-custom-toast .ga-toast-body {
|
|
370
|
-
color: rgba(255, 255, 255, 0.9);
|
|
371
|
-
}
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
## 📱 Responsive Design
|
|
375
|
-
|
|
376
|
-
GA Toasts automatically adapts to different screen sizes:
|
|
377
|
-
|
|
378
|
-
- **Desktop**: Full-width toasts with all features
|
|
379
|
-
- **Tablet**: Optimized spacing and sizing
|
|
380
|
-
- **Mobile**: Full-width toasts with simplified layout
|
|
381
|
-
|
|
382
|
-
### Mobile Optimizations
|
|
383
|
-
|
|
384
|
-
- Touch-friendly close buttons
|
|
385
|
-
- Optimized spacing for small screens
|
|
386
|
-
- Simplified animations for better performance
|
|
387
|
-
- Stacked layout for multiple toasts
|
|
388
|
-
|
|
389
|
-
## ♿ Accessibility
|
|
390
|
-
|
|
391
|
-
GA Toasts is built with accessibility in mind:
|
|
392
|
-
|
|
393
|
-
- **Screen Reader Support**: Proper ARIA labels and roles
|
|
394
|
-
- **Keyboard Navigation**: Full keyboard support
|
|
395
|
-
- **High Contrast**: Support for high contrast mode
|
|
396
|
-
- **Reduced Motion**: Respects user's motion preferences
|
|
397
|
-
- **Focus Management**: Proper focus handling
|
|
398
|
-
|
|
399
|
-
### Accessibility Features
|
|
400
|
-
|
|
401
|
-
```javascript
|
|
402
|
-
// Toast with proper ARIA attributes
|
|
403
|
-
GaToasts.show({
|
|
404
|
-
message: 'Important notification',
|
|
405
|
-
type: 'error',
|
|
406
|
-
role: 'alert', // For screen readers
|
|
407
|
-
duration: 0 // Don't auto-close important messages
|
|
408
|
-
});
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
## 🎪 Animation Effects
|
|
412
|
-
|
|
413
|
-
### Built-in Animations
|
|
414
|
-
|
|
415
|
-
1. **Fade** - Smooth opacity transition
|
|
416
|
-
2. **Slide** - Slides in from the side
|
|
417
|
-
3. **Bounce** - Bouncy entrance effect
|
|
418
|
-
4. **Scale** - Scales up from center
|
|
419
|
-
|
|
420
|
-
### Custom Animations
|
|
421
|
-
|
|
422
|
-
```css
|
|
423
|
-
/* Custom shake animation */
|
|
424
|
-
.ga-toast-shake {
|
|
425
|
-
animation: shake 0.5s ease-in-out;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
@keyframes shake {
|
|
429
|
-
0%, 100% { transform: translateX(0); }
|
|
430
|
-
10%, 30%, 50%, 70%, 90% { transform: translateX(-2px); }
|
|
431
|
-
20%, 40%, 60%, 80% { transform: translateX(2px); }
|
|
432
|
-
}
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
## 🔧 Advanced Usage
|
|
436
|
-
|
|
437
|
-
### Action Buttons
|
|
438
|
-
|
|
439
|
-
```javascript
|
|
440
|
-
GaToasts.show({
|
|
441
|
-
message: 'File uploaded successfully!',
|
|
442
|
-
type: 'success',
|
|
443
|
-
actions: [
|
|
444
|
-
{
|
|
445
|
-
text: 'View File',
|
|
446
|
-
class: 'ga-btn-primary',
|
|
447
|
-
click: function(e, toast) {
|
|
448
|
-
// Handle view action
|
|
449
|
-
window.open('/file.pdf');
|
|
450
|
-
GaToasts.close(toast);
|
|
451
|
-
}
|
|
452
|
-
},
|
|
453
|
-
{
|
|
454
|
-
text: 'Dismiss',
|
|
455
|
-
class: 'ga-btn-secondary',
|
|
456
|
-
click: function(e, toast) {
|
|
457
|
-
GaToasts.close(toast);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
]
|
|
461
|
-
});
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
### Custom Icons
|
|
465
|
-
|
|
466
|
-
```javascript
|
|
467
|
-
GaToasts.show({
|
|
468
|
-
message: 'Custom icon toast',
|
|
469
|
-
type: 'info',
|
|
470
|
-
icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/></svg>'
|
|
471
|
-
});
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
### Progress Indicators
|
|
475
|
-
|
|
476
|
-
```javascript
|
|
477
|
-
// Toast with progress bar
|
|
478
|
-
GaToasts.show({
|
|
479
|
-
message: 'Processing...',
|
|
480
|
-
type: 'info',
|
|
481
|
-
progress: true,
|
|
482
|
-
duration: 5000
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
// Toast with background fill
|
|
486
|
-
GaToasts.show({
|
|
487
|
-
message: 'Uploading file...',
|
|
488
|
-
type: 'primary',
|
|
489
|
-
progressBackground: true,
|
|
490
|
-
duration: 10000
|
|
491
|
-
});
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
### Toast Stacks
|
|
495
|
-
|
|
496
|
-
```javascript
|
|
497
|
-
// Show multiple toasts in a stack
|
|
498
|
-
for (let i = 1; i <= 5; i++) {
|
|
499
|
-
setTimeout(() => {
|
|
500
|
-
GaToasts.show({
|
|
501
|
-
message: `Stacked toast ${i}`,
|
|
502
|
-
type: 'info',
|
|
503
|
-
size: 'sm'
|
|
504
|
-
});
|
|
505
|
-
}, i * 200);
|
|
506
|
-
}
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
## 🌐 Browser Support
|
|
510
|
-
|
|
511
|
-
- **Chrome** 60+
|
|
512
|
-
- **Firefox** 55+
|
|
513
|
-
- **Safari** 12+
|
|
514
|
-
- **Edge** 79+
|
|
515
|
-
- **IE** 11+ (with polyfills for modern features)
|
|
516
|
-
|
|
517
|
-
**Note:** Since we removed jQuery dependency, the library is now lighter and faster while maintaining the same browser support.
|
|
518
|
-
|
|
519
|
-
## 📦 File Structure
|
|
520
|
-
|
|
521
|
-
```
|
|
522
|
-
ga-toasts/
|
|
523
|
-
├── src/
|
|
524
|
-
│ ├── toasts.js # JavaScript functionality
|
|
525
|
-
│ ├── toasts.css # Main toast styles
|
|
526
|
-
│ └── variables.css # CSS custom properties
|
|
527
|
-
├── index.html # Interactive demo page
|
|
528
|
-
└── README.md # This documentation
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
## 🤝 Contributing
|
|
532
|
-
|
|
533
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
534
|
-
|
|
535
|
-
1. Fork the repository
|
|
536
|
-
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
|
|
537
|
-
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
|
538
|
-
4. Push to the branch (`git push origin feature/AmazingFeature`)
|
|
539
|
-
5. Open a Pull Request
|
|
540
|
-
|
|
541
|
-
## 📄 License
|
|
542
|
-
|
|
543
|
-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
544
|
-
|
|
545
|
-
## 🙏 Acknowledgments
|
|
546
|
-
|
|
547
|
-
- Modern CSS features for beautiful styling
|
|
548
|
-
- Web accessibility guidelines for inclusive design
|
|
549
|
-
- Vanilla JavaScript community for inspiration
|
|
550
|
-
- Open source community for continuous improvement
|
|
551
|
-
|
|
552
|
-
---
|
|
553
|
-
|
|
554
|
-
Made with ❤️ by the GA Toasts team
|
|
1
|
+
# 🍞 GA Toasts
|
|
2
|
+
|
|
3
|
+
Modern, accessible, **dependency-free** toast notifications for the web.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/ga-toasts)
|
|
6
|
+
[](#typescript)
|
|
7
|
+
[](#)
|
|
8
|
+
[](./LICENSE)
|
|
9
|
+
|
|
10
|
+
- 🧩 **Zero dependencies** — one small file, works everywhere.
|
|
11
|
+
- 🎞️ **Stacked & animated** — cards stack with depth and fan out on hover, with spring enter/leave and self-drawing stroke icons.
|
|
12
|
+
- ♿ **Actually accessible** — real `aria-live` announcements, `role="alert"` for errors, Escape to dismiss.
|
|
13
|
+
- 🔒 **Safe by default** — messages are rendered as text; opt into HTML only when you want it.
|
|
14
|
+
- 🎨 **Themeable** — light/dark/auto, CSS-variable design tokens, 6 types + `filled`/`light` variants.
|
|
15
|
+
- 📱 **Responsive & touch-friendly** — swipe to dismiss, pause on hover/focus.
|
|
16
|
+
- 🧵 **Framework-agnostic** — use it in React, Vue, Svelte, plain HTML, or on the server (SSR-safe no-op).
|
|
17
|
+
- 🟦 **First-class TypeScript** — types ship in the box.
|
|
18
|
+
|
|
19
|
+
**Live demo:** https://harshad-pindoriya.github.io/gatoasts/
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install ga-toasts
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import { toast } from 'ga-toasts';
|
|
31
|
+
|
|
32
|
+
toast.success('Profile saved!');
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The stylesheet is **injected automatically** on first use — nothing else to import.
|
|
36
|
+
Prefer to manage the CSS yourself? Import it and it won't double-inject:
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
import 'ga-toasts/style.css';
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Via `<script>` / CDN (no build step)
|
|
43
|
+
|
|
44
|
+
```html
|
|
45
|
+
<script src="https://cdn.jsdelivr.net/npm/ga-toasts@2"></script>
|
|
46
|
+
<script>
|
|
47
|
+
GaToasts.success('It works!');
|
|
48
|
+
// or the callable shorthand: GaToasts.toast('Hi there');
|
|
49
|
+
</script>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
import { toast } from 'ga-toasts';
|
|
58
|
+
|
|
59
|
+
// Shorthand
|
|
60
|
+
toast('Just so you know…'); // info by default
|
|
61
|
+
|
|
62
|
+
// Typed helpers
|
|
63
|
+
toast.success('Saved!', { title: 'Done' });
|
|
64
|
+
toast.error('Upload failed', { title: 'Oops' });
|
|
65
|
+
toast.warning('Low disk space');
|
|
66
|
+
toast.info('New version available');
|
|
67
|
+
|
|
68
|
+
// Full control
|
|
69
|
+
toast.show({
|
|
70
|
+
title: 'File uploaded',
|
|
71
|
+
message: 'report.pdf is ready.',
|
|
72
|
+
type: 'success',
|
|
73
|
+
position: 'bottom-end',
|
|
74
|
+
duration: 6000,
|
|
75
|
+
});
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Action buttons
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
toast.show({
|
|
82
|
+
title: 'File uploaded',
|
|
83
|
+
message: 'What next?',
|
|
84
|
+
duration: 0, // sticky until dismissed
|
|
85
|
+
actions: [
|
|
86
|
+
{ text: 'View', className: 'ga-toast-btn-primary', onClick: (e, t) => { open('/file'); t.close(); } },
|
|
87
|
+
{ text: 'Dismiss' }, // closes by default
|
|
88
|
+
],
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Confirmations
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
toast.confirm('Delete this item?', {
|
|
96
|
+
confirmText: 'Delete',
|
|
97
|
+
onConfirm: () => reallyDelete(),
|
|
98
|
+
onCancel: () => {},
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Loading & promises
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
const t = toast.loading('Uploading…');
|
|
106
|
+
t.update({ type: 'success', message: 'Done!', duration: 4000 });
|
|
107
|
+
|
|
108
|
+
// Or let a promise drive it:
|
|
109
|
+
toast.promise(saveUser(), {
|
|
110
|
+
loading: 'Saving…',
|
|
111
|
+
success: (user) => `Saved ${user.name}`,
|
|
112
|
+
error: (err) => `Failed: ${err.message}`,
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Update or close later
|
|
117
|
+
|
|
118
|
+
Every call returns a **handle**:
|
|
119
|
+
|
|
120
|
+
```js
|
|
121
|
+
const t = toast.info('Connecting…', { duration: 0 });
|
|
122
|
+
t.update({ message: 'Connected', type: 'success', duration: 3000 });
|
|
123
|
+
t.close();
|
|
124
|
+
|
|
125
|
+
// Or address a toast by id:
|
|
126
|
+
toast.info('Hang on', { id: 'net' });
|
|
127
|
+
toast.update('net', { message: 'Ready' });
|
|
128
|
+
toast.close('net'); // ← id or '#id', both work
|
|
129
|
+
toast.close('#net');
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## API
|
|
135
|
+
|
|
136
|
+
### Creating toasts
|
|
137
|
+
|
|
138
|
+
| Method | Description |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| `toast(message, options?)` | Shorthand for an info toast. |
|
|
141
|
+
| `toast.show(options)` | Full-control toast. Returns a `ToastHandle`. |
|
|
142
|
+
| `toast.success/error/warning/info(message, options?)` | Typed helpers. |
|
|
143
|
+
| `toast.loading(message?, options?)` | Sticky spinner toast. |
|
|
144
|
+
| `toast.confirm(message, options?)` | **Modal** two-button confirmation (`onConfirm`/`onCancel`). Renders an `alertdialog` centered over a backdrop that blocks the page; focus is trapped and restored on close. Only one can be open at a time (further calls are ignored until it's answered). |
|
|
145
|
+
| `toast.promise(promise, { loading, success, error }, options?)` | Drives a toast from a promise; resolves/rejects like the input. |
|
|
146
|
+
| `toast.custom(content, options?)` | Render arbitrary content — an HTML string, a DOM element, or a factory returning one. |
|
|
147
|
+
|
|
148
|
+
### Managing toasts
|
|
149
|
+
|
|
150
|
+
| Method | Description |
|
|
151
|
+
| --- | --- |
|
|
152
|
+
| `toast.update(id, options)` | Patch an existing toast (title/message/type/icon/duration…). |
|
|
153
|
+
| `toast.close(id \| '#id' \| element)` | Close one toast. |
|
|
154
|
+
| `toast.closeAll()` | Close everything. |
|
|
155
|
+
| `toast.clear(type?)` | Close all, or all of one type. |
|
|
156
|
+
| `toast.getCount(type?)` | How many are on screen. |
|
|
157
|
+
| `toast.exists(id)` / `toast.get(id)` | Look one up. |
|
|
158
|
+
| `toast.setDefaults(options)` | Set global defaults merged into every toast. |
|
|
159
|
+
| `toast.setLogger(fn \| null)` | Receive lifecycle events (`toast:show`, `toast:close`, …). |
|
|
160
|
+
| `toast.injectStyles()` | Manually inject the stylesheet (usually automatic). |
|
|
161
|
+
|
|
162
|
+
The 1.x global name still works: `import { GaToasts } from 'ga-toasts'` — it's the same object as `toast`.
|
|
163
|
+
|
|
164
|
+
### Options
|
|
165
|
+
|
|
166
|
+
| Option | Type | Default | Notes |
|
|
167
|
+
| --- | --- | --- | --- |
|
|
168
|
+
| `title` | `string` | — | Bold heading. |
|
|
169
|
+
| `message` | `string` | — | Body text (escaped unless `html: true`). |
|
|
170
|
+
| `meta` | `string` | — | Small muted line above the message. |
|
|
171
|
+
| `type` | `success \| error \| warning \| info \| primary \| secondary \| loading` | `info` | |
|
|
172
|
+
| `duration` | `number` (ms) | `5000` | `0` = sticky. |
|
|
173
|
+
| `position` | 9 positions (`top-end`, `bottom-center`, …) | `top-end` | |
|
|
174
|
+
| `closable` | `boolean` | `true` | Show the × button. |
|
|
175
|
+
| `html` | `boolean` | `false` | Render `message` as HTML (⚠️ only for trusted content). |
|
|
176
|
+
| `icon` | `string \| false \| null` | auto | Custom icon markup, or `false` to hide. Built-in icons are animated stroke SVGs; pass your own `<img src="…gif">` or `<lottie-player>` markup here for animated icons without adding a dependency. |
|
|
177
|
+
| `actions` | `ToastAction[]` | — | `{ text, className?, onClick?, closeOnClick? }`. |
|
|
178
|
+
| `variant` | `'' \| filled \| light` | `''` | |
|
|
179
|
+
| `size` | `xs \| sm \| md \| lg \| xl` | `md` | Adjusts density. |
|
|
180
|
+
| `swipeToClose` | `boolean` | `true` | Drag horizontally to dismiss. |
|
|
181
|
+
| `pauseOnHover` | `boolean` | `true` | Pause the countdown on hover/focus. |
|
|
182
|
+
| `closeOnEscape` | `boolean` | `true` | Escape dismisses the newest toast. |
|
|
183
|
+
| `progress` | `boolean` | `true` | Countdown bar. |
|
|
184
|
+
| `avatar` / `avatarAlt` | `string` | — | Leading avatar image. |
|
|
185
|
+
| `unread` | `boolean` | `false` | Small unread dot. |
|
|
186
|
+
| `showStatus` / `statusText` | `boolean` / `string` | — | Status chip. |
|
|
187
|
+
| `steps` / `currentStep` | `number` | — | Segmented multi-step indicator. |
|
|
188
|
+
| `glassmorphism` | `boolean` | `true` | Frosted-glass background (auto-disabled under `prefers-reduced-transparency`). |
|
|
189
|
+
| `content` | `string \| HTMLElement \| () => …` | — | Arbitrary content instead of the default layout (used by `toast.custom`). |
|
|
190
|
+
| `moveFocus` | `boolean` | `false` | Move focus into the toast on show, restore on close (used by `confirm`). |
|
|
191
|
+
| `role` | `string` | auto | ARIA role; defaults to `alert` for error/warning, `status` otherwise. |
|
|
192
|
+
| `onShow` / `onClose` | `(handle) => void` | — | Lifecycle callbacks. |
|
|
193
|
+
| `id` | `string` | auto | Reusing an id updates in place instead of duplicating. |
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## TypeScript
|
|
198
|
+
|
|
199
|
+
Types are bundled — no `@types` package needed.
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
import { toast, type ToastOptions, type ToastHandle } from 'ga-toasts';
|
|
203
|
+
|
|
204
|
+
const opts: ToastOptions = { type: 'success', duration: 3000 };
|
|
205
|
+
const handle: ToastHandle = toast.show(opts);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Configuration & theming
|
|
211
|
+
|
|
212
|
+
Everything is configurable. Tune the default toaster with `toast.configure(...)` / `toast.theme(...)`, or mint fully **isolated** toasters with `createToaster(config)` — each with its own theme, defaults, icons, and mount root.
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
import { toast, createToaster } from 'ga-toasts';
|
|
216
|
+
|
|
217
|
+
// Configure the default (global) toaster:
|
|
218
|
+
toast.configure({
|
|
219
|
+
defaults: { position: 'bottom-center', duration: 6000 },
|
|
220
|
+
durations: { error: 10000, success: 2500 }, // per-type auto-close
|
|
221
|
+
theme: { accent: '#ff5c8a', radius: 8, density: 'compact' },
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// …or a shorthand for just the theme (tokens or a preset name):
|
|
225
|
+
toast.theme('minimal');
|
|
226
|
+
toast.theme({ preset: 'minimal', accent: '#ff5c8a', progress: 'ring' });
|
|
227
|
+
|
|
228
|
+
// An independent toaster (own theme + defaults + DOM root, e.g. shadow DOM):
|
|
229
|
+
const brandToast = createToaster({
|
|
230
|
+
theme: { accent: brand.primary, radius: 6, font: brand.font },
|
|
231
|
+
defaults: { position: 'top-center' },
|
|
232
|
+
root: document.querySelector('#app'),
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Presets
|
|
237
|
+
|
|
238
|
+
`soft` (default) · `solid` · `minimal` · `sharp` · `material`. Use as `theme: 'minimal'` or `theme: { preset: 'minimal', …overrides }`.
|
|
239
|
+
|
|
240
|
+
### Theme tokens
|
|
241
|
+
|
|
242
|
+
| Token | Type | Notes |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| `accent` | color | Primary accent (also the `primary` type). |
|
|
245
|
+
| `colors` | `{ [type]: color }` | Per-type accent colors. |
|
|
246
|
+
| `radius` · `width` · `gap` · `edge` | number \| string | Numbers → px. |
|
|
247
|
+
| `font` | string | Font stack. |
|
|
248
|
+
| `density` | `compact` · `comfortable` · `spacious` | Padding + type scale. |
|
|
249
|
+
| `elevation` | `flat` · `raised` · `floating` | Shadow depth. |
|
|
250
|
+
| `surface` | `glass` · `solid` · `outline` | Card background style. |
|
|
251
|
+
| `accentEdge` | number | Colored leading bar width (0 = none). |
|
|
252
|
+
| `progress` | `bar` · `ring` · `none` | Countdown style (`ring` = circular). |
|
|
253
|
+
| `text` · `textSoft` · `textMuted` · `border` · `shadow` · `chip` · `ease` | | Fine-grained overrides. |
|
|
254
|
+
| `dark` | `Partial<ThemeTokens>` | Overrides applied under the dark theme. |
|
|
255
|
+
|
|
256
|
+
Theme tokens are written as scoped CSS custom properties, so **dark mode still wins** where you don't override it.
|
|
257
|
+
|
|
258
|
+
### Escape hatches (total control)
|
|
259
|
+
|
|
260
|
+
```js
|
|
261
|
+
createToaster({
|
|
262
|
+
icons: { success: '<svg>…</svg>', close: '<svg>…</svg>' }, // swap icons (null hides one)
|
|
263
|
+
render: (opts, { id, close }) => myToastElement(opts), // replace the DOM entirely
|
|
264
|
+
injectStyles: false, // headless — ship your own CSS (or import 'ga-toasts/style.css')
|
|
265
|
+
styleNonce: nonce, // strict-CSP nonce on the injected <style>
|
|
266
|
+
stack: { maxVisible: 5, peek: 12, gap: 12, expand: 'always', newestOnTop: true },
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### CSS variables
|
|
271
|
+
|
|
272
|
+
You can also theme purely in CSS — every value is a namespaced `--gat-*` variable:
|
|
273
|
+
|
|
274
|
+
```css
|
|
275
|
+
.ga-toast-container {
|
|
276
|
+
--gat-radius: 12px;
|
|
277
|
+
--gat-width: 420px;
|
|
278
|
+
--gat-success: #10b981;
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Dark mode
|
|
283
|
+
|
|
284
|
+
Toggle with an attribute or class on any ancestor (or let it follow the OS):
|
|
285
|
+
|
|
286
|
+
```html
|
|
287
|
+
<html data-ga-theme="dark"> <!-- or class="ga-theme-dark" -->
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Accessibility
|
|
293
|
+
|
|
294
|
+
- Toasts announce through a dedicated `aria-live` region — **polite** for info/success, **assertive** (`role="alert"`) for warnings/errors.
|
|
295
|
+
- **Escape** dismisses the newest toast (`closeOnEscape`).
|
|
296
|
+
- The close button and actions are real, focusable `<button>`s with visible focus rings.
|
|
297
|
+
- The countdown pauses on hover **and** keyboard focus.
|
|
298
|
+
- `confirm()` is an `alertdialog`: focus moves to its buttons and returns to the trigger on close.
|
|
299
|
+
- Honors `prefers-reduced-motion` (animations collapse to a fade) and `prefers-reduced-transparency` (glass blur is dropped).
|
|
300
|
+
- Font sizes are in `rem`, so toasts scale with the user's browser font-size setting.
|
|
301
|
+
- **RTL** — set `dir="rtl"` on `<html>`; positions, layout, and enter/exit animations mirror automatically.
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## Migrating from 1.x
|
|
306
|
+
|
|
307
|
+
The 1.x API still works, but a few things changed for the better:
|
|
308
|
+
|
|
309
|
+
- **Messages are now escaped by default.** If you relied on passing HTML in `message`, add `html: true`.
|
|
310
|
+
- **Action buttons:** prefer `className`/`onClick` over `class`/`click` (the old names still work).
|
|
311
|
+
- **Sizes** (`xs`–`xl`) now change *density*, not width — all toasts share one width (set `--gat-width` to change it).
|
|
312
|
+
- Calls return a **`ToastHandle`** (`{ id, el, update(), close() }`) instead of a raw element (`handle.el` is the element).
|
|
313
|
+
- New: `toast.promise()`, the callable `toast()` shorthand, real `aria-live` announcements, and swipe-to-dismiss.
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Development
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
npm install
|
|
321
|
+
npm run build # → dist/ (ESM, CJS, IIFE, .d.ts, ga-toasts.css)
|
|
322
|
+
npm test # vitest + jsdom
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## License
|
|
326
|
+
|
|
327
|
+
MIT © Harshad Pindoriya
|