plain-toast 1.0.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.
Files changed (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +515 -0
  3. package/dist/plain-toast.cjs.js +359 -0
  4. package/dist/plain-toast.cjs.js.map +41 -0
  5. package/dist/plain-toast.esm.js +359 -0
  6. package/dist/plain-toast.esm.js.map +41 -0
  7. package/dist/plain-toast.iife.js +359 -0
  8. package/dist/plain-toast.iife.js.map +41 -0
  9. package/dist/types/config.d.ts +42 -0
  10. package/dist/types/config.d.ts.map +1 -0
  11. package/dist/types/container/create-container.d.ts +17 -0
  12. package/dist/types/container/create-container.d.ts.map +1 -0
  13. package/dist/types/container/index.d.ts +3 -0
  14. package/dist/types/container/index.d.ts.map +1 -0
  15. package/dist/types/icons/debug.d.ts +2 -0
  16. package/dist/types/icons/debug.d.ts.map +1 -0
  17. package/dist/types/icons/error.d.ts +2 -0
  18. package/dist/types/icons/error.d.ts.map +1 -0
  19. package/dist/types/icons/get-icon.d.ts +2 -0
  20. package/dist/types/icons/get-icon.d.ts.map +1 -0
  21. package/dist/types/icons/index.d.ts +14 -0
  22. package/dist/types/icons/index.d.ts.map +1 -0
  23. package/dist/types/icons/info.d.ts +2 -0
  24. package/dist/types/icons/info.d.ts.map +1 -0
  25. package/dist/types/icons/progress.d.ts +2 -0
  26. package/dist/types/icons/progress.d.ts.map +1 -0
  27. package/dist/types/icons/spinner.d.ts +2 -0
  28. package/dist/types/icons/spinner.d.ts.map +1 -0
  29. package/dist/types/icons/success.d.ts +2 -0
  30. package/dist/types/icons/success.d.ts.map +1 -0
  31. package/dist/types/icons/warning.d.ts +2 -0
  32. package/dist/types/icons/warning.d.ts.map +1 -0
  33. package/dist/types/main.d.ts +61 -0
  34. package/dist/types/main.d.ts.map +1 -0
  35. package/dist/types/main.iife.d.ts +17 -0
  36. package/dist/types/main.iife.d.ts.map +1 -0
  37. package/dist/types/styles/auto.d.ts +2 -0
  38. package/dist/types/styles/auto.d.ts.map +1 -0
  39. package/dist/types/styles/base.d.ts +2 -0
  40. package/dist/types/styles/base.d.ts.map +1 -0
  41. package/dist/types/styles/dark.d.ts +2 -0
  42. package/dist/types/styles/dark.d.ts.map +1 -0
  43. package/dist/types/styles/index.d.ts +7 -0
  44. package/dist/types/styles/index.d.ts.map +1 -0
  45. package/dist/types/styles/light.d.ts +2 -0
  46. package/dist/types/styles/light.d.ts.map +1 -0
  47. package/dist/types/toast.d.ts +33 -0
  48. package/dist/types/toast.d.ts.map +1 -0
  49. package/dist/types/toasts/close-toast.d.ts +10 -0
  50. package/dist/types/toasts/close-toast.d.ts.map +1 -0
  51. package/dist/types/toasts/create-toast.d.ts +11 -0
  52. package/dist/types/toasts/create-toast.d.ts.map +1 -0
  53. package/dist/types/toasts/default-options.d.ts +7 -0
  54. package/dist/types/toasts/default-options.d.ts.map +1 -0
  55. package/dist/types/toasts/enable-click-to-close.d.ts +9 -0
  56. package/dist/types/toasts/enable-click-to-close.d.ts.map +1 -0
  57. package/dist/types/toasts/get-options.d.ts +19 -0
  58. package/dist/types/toasts/get-options.d.ts.map +1 -0
  59. package/dist/types/toasts/index.d.ts +11 -0
  60. package/dist/types/toasts/index.d.ts.map +1 -0
  61. package/dist/types/toasts/populate-toast.d.ts +14 -0
  62. package/dist/types/toasts/populate-toast.d.ts.map +1 -0
  63. package/dist/types/toasts/types.d.ts +21 -0
  64. package/dist/types/toasts/types.d.ts.map +1 -0
  65. package/dist/types/toasts/update-toast.d.ts +13 -0
  66. package/dist/types/toasts/update-toast.d.ts.map +1 -0
  67. package/dist/types/types.d.ts +45 -0
  68. package/dist/types/types.d.ts.map +1 -0
  69. package/dist/types/utils/announce.d.ts +10 -0
  70. package/dist/types/utils/announce.d.ts.map +1 -0
  71. package/dist/types/utils/deep-merge.d.ts +11 -0
  72. package/dist/types/utils/deep-merge.d.ts.map +1 -0
  73. package/dist/types/utils/inject-css.d.ts +7 -0
  74. package/dist/types/utils/inject-css.d.ts.map +1 -0
  75. package/dist/types/utils/validate-and-merge-options.d.ts +19 -0
  76. package/dist/types/utils/validate-and-merge-options.d.ts.map +1 -0
  77. package/package.json +68 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Brian Tucker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,515 @@
1
+ # plain-toast 🍞
2
+
3
+ > Lightweight, accessible toast notifications with zero dependencies
4
+
5
+ [![npm version](https://img.shields.io/npm/v/plain-toast.svg)](https://www.npmjs.com/package/plain-toast)
6
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/plain-toast)](https://bundlephobia.com/package/plain-toast)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ [Live Demo](https://plain-toast.bybrian.io/) | [GitHub](https://github.com/briantuckerdesign/plain-toast)
10
+
11
+ ## Features
12
+
13
+ - **Lightweight** - ~5KB gzipped, zero dependencies
14
+ - **Accessible** - WCAG AA compliant with full ARIA support
15
+ - **Customizable** - Light, dark, and auto themes with CSS variables
16
+ - **Multiple Formats** - ESM, CJS, and IIFE builds
17
+ - **Progress Tracking** - Built-in progress toast with percentage display
18
+ - **Keyboard Friendly** - Full keyboard navigation support
19
+ - **TypeScript** - Full type definitions included
20
+ - **Motion Friendly** - Respects `prefers-reduced-motion`
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ # npm
26
+ npm install plain-toast
27
+
28
+ # yarn
29
+ yarn add plain-toast
30
+
31
+ # pnpm
32
+ pnpm add plain-toast
33
+
34
+ # bun
35
+ bun add plain-toast
36
+ ```
37
+
38
+ ### CDN
39
+
40
+ ```html
41
+ <!-- ES Module -->
42
+ <script type="module">
43
+ import { Toast } from 'https://cdn.jsdelivr.net/npm/plain-toast/dist/plain-toast.esm.js';
44
+ </script>
45
+
46
+ <!-- IIFE (adds plain-toast to window) -->
47
+ <script src="https://cdn.jsdelivr.net/npm/plain-toast/dist/plain-toast.iife.js"></script>
48
+ ```
49
+
50
+ ## Quick Start
51
+
52
+ ```javascript
53
+ import { Toast } from 'plain-toast';
54
+
55
+ // Create a success notification
56
+ new Toast({
57
+ type: 'success',
58
+ heading: 'Saved!',
59
+ body: 'Your changes have been saved successfully.'
60
+ });
61
+ ```
62
+
63
+ ## Configuration
64
+
65
+ Configure global settings that apply to all toasts:
66
+
67
+ ```javascript
68
+ import { configure } from 'plain-toast';
69
+
70
+ configure({
71
+ position: 'top-right', // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
72
+ theme: 'auto', // 'light' | 'dark' | 'auto' | 'none'
73
+ injectCss: true, // Automatically inject styles
74
+ announceToScreenReader: true, // Announce to screen readers
75
+ ariaLive: 'polite' // 'polite' | 'assertive'
76
+ });
77
+ ```
78
+
79
+ ### Configuration Options
80
+
81
+ | Option | Type | Default | Description |
82
+ | ------------------------ | ----------------------- | ---------------- | -------------------------------------------- |
83
+ | `position` | `Position` | `'bottom-right'` | Screen corner for toast container |
84
+ | `theme` | `Theme` | `'auto'` | Color theme (auto follows system preference) |
85
+ | `injectCss` | `boolean` | `true` | Automatically inject CSS styles |
86
+ | `target` | `HTMLElement \| string` | `undefined` | Custom container element or selector |
87
+ | `icons` | `Partial<JTIcons>` | `{}` | Custom icon SVGs for each type |
88
+ | `announceToScreenReader` | `boolean` | `true` | Announce toasts to screen readers |
89
+ | `ariaLive` | `AriaLive` | `'polite'` | ARIA live region priority |
90
+
91
+ ## Toast Types
92
+
93
+ ### Success
94
+
95
+ ```javascript
96
+ new Toast({
97
+ type: 'success',
98
+ heading: 'Success!',
99
+ body: 'Operation completed successfully.'
100
+ });
101
+ ```
102
+
103
+ ### Error
104
+
105
+ ```javascript
106
+ new Toast({
107
+ type: 'error',
108
+ heading: 'Error',
109
+ body: 'Something went wrong. Please try again.'
110
+ });
111
+ ```
112
+
113
+ ### Warning
114
+
115
+ ```javascript
116
+ new Toast({
117
+ type: 'warning',
118
+ heading: 'Warning',
119
+ body: 'This action cannot be undone.'
120
+ });
121
+ ```
122
+
123
+ ### Info
124
+
125
+ ```javascript
126
+ new Toast({
127
+ type: 'info',
128
+ heading: 'New Update Available',
129
+ body: 'Version 2.0 is now available for download.'
130
+ });
131
+ ```
132
+
133
+ ### Debug
134
+
135
+ ```javascript
136
+ new Toast({
137
+ type: 'debug',
138
+ heading: 'Debug Info',
139
+ body: 'API response: 200 OK'
140
+ });
141
+ ```
142
+
143
+ ### Spinner
144
+
145
+ ```javascript
146
+ const loadingToast = new Toast({
147
+ type: 'spinner',
148
+ heading: 'Loading...',
149
+ body: 'Please wait while we fetch your data.'
150
+ });
151
+
152
+ // Close when done
153
+ loadingToast.close();
154
+ ```
155
+
156
+ ## Progress
157
+
158
+ Track progress of long-running operations:
159
+
160
+ ```javascript
161
+ const uploadToast = new Toast({
162
+ type: 'progress',
163
+ heading: 'Uploading file...',
164
+ progress: {
165
+ total: 100,
166
+ current: 0,
167
+ showPercentage: true
168
+ }
169
+ });
170
+
171
+ // Update progress
172
+ uploadToast.setProgress(50); // 50%
173
+
174
+ // Increment progress
175
+ uploadToast.incrementProgress(10); // +10%
176
+
177
+ // Complete (sets to 100% and auto-closes after 2s)
178
+ uploadToast.complete();
179
+
180
+ // Or complete without auto-closing
181
+ uploadToast.complete(0);
182
+ ```
183
+
184
+ ### Progress Events
185
+
186
+ Listen for progress updates:
187
+
188
+ ```javascript
189
+ const toast = new Toast({
190
+ type: 'progress',
191
+ heading: 'Processing...',
192
+ progress: { total: 100 }
193
+ });
194
+
195
+ document.querySelector('[data-jt-toast]').addEventListener('jt:progress', (event) => {
196
+ console.log(`Progress: ${event.detail.percentage}%`);
197
+ });
198
+ ```
199
+
200
+ ## Toast Options
201
+
202
+ ```typescript
203
+ interface ToastOptions {
204
+ type: 'success' | 'error' | 'warning' | 'info' | 'debug' | 'spinner' | 'progress';
205
+ heading: string;
206
+ body?: string;
207
+ duration?: number | null; // Auto-close after ms (null = don't auto-close)
208
+ clickToClose?: boolean; // Click/keyboard to close
209
+ progress?: {
210
+ total: number;
211
+ current?: number;
212
+ showPercentage?: boolean;
213
+ };
214
+ }
215
+ ```
216
+
217
+ ## API Reference
218
+
219
+ ### Toast Class
220
+
221
+ #### Constructor
222
+
223
+ ```javascript
224
+ const toast = new Toast(options);
225
+ ```
226
+
227
+ #### Methods
228
+
229
+ ##### `update(options)`
230
+
231
+ Update toast content after creation:
232
+
233
+ ```javascript
234
+ toast.update({
235
+ heading: 'Updated!',
236
+ body: 'New content here'
237
+ });
238
+ ```
239
+
240
+ ##### `setProgress(current)`
241
+
242
+ Set progress to specific value (0-100):
243
+
244
+ ```javascript
245
+ toast.setProgress(75);
246
+ ```
247
+
248
+ ##### `incrementProgress(amount)`
249
+
250
+ Increment progress by amount:
251
+
252
+ ```javascript
253
+ toast.incrementProgress(5); // +5%
254
+ ```
255
+
256
+ ##### `complete(autoCloseDelay?)`
257
+
258
+ Complete progress and optionally auto-close:
259
+
260
+ ```javascript
261
+ toast.complete(); // Auto-close after 2s
262
+ toast.complete(0); // Don't auto-close
263
+ toast.complete(5000); // Auto-close after 5s
264
+ ```
265
+
266
+ ##### `close()`
267
+
268
+ Manually close the toast:
269
+
270
+ ```javascript
271
+ toast.close();
272
+ ```
273
+
274
+ ## Styling & Theming
275
+
276
+ ### Built-in Themes
277
+
278
+ plain-toast includes three themes:
279
+
280
+ - **light** - Light background with dark text
281
+ - **dark** - Dark background with light text
282
+ - **auto** - Automatically matches system preference
283
+ - **none** - No CSS injection (bring your own styles)
284
+
285
+ ```javascript
286
+ configure({ theme: 'dark' });
287
+ ```
288
+
289
+ ### CSS Variables
290
+
291
+ Customize colors using CSS variables:
292
+
293
+ ```css
294
+ :root {
295
+ /* Base colors */
296
+ --jt-background: #ffffff;
297
+ --jt-text: #475569;
298
+ --jt-heading: #1e293b;
299
+ --jt-border: #e2e8f0;
300
+
301
+ /* Toast type colors */
302
+ --jt-success-icon: #16a34a;
303
+ --jt-success-border: #16a34a;
304
+
305
+ --jt-error-icon: #ef4444;
306
+ --jt-error-border: #ef4444;
307
+
308
+ --jt-warning-icon: #d97706;
309
+ --jt-warning-border: #facc15;
310
+
311
+ /* ... more variables */
312
+ }
313
+ ```
314
+
315
+ ### Custom Styles
316
+
317
+ Opt out of CSS injection and provide your own:
318
+
319
+ ```javascript
320
+ configure({
321
+ theme: 'none',
322
+ injectCss: false
323
+ });
324
+ ```
325
+
326
+ Style elements with data attributes:
327
+
328
+ ```css
329
+ [data-jt-container] {
330
+ /* Container */
331
+ }
332
+ [data-jt-toast] {
333
+ /* Toast */
334
+ }
335
+ [data-jt-toast][data-jt-success] {
336
+ /* Success toast, replace success with error, info, etc. */
337
+ }
338
+ [data-jt-heading] {
339
+ /* Heading */
340
+ }
341
+ [data-jt-body] {
342
+ /* Body */
343
+ }
344
+ [data-jt-progress-bar] {
345
+ /* Progress bar */
346
+ }
347
+ ```
348
+
349
+ ## Accessibility
350
+
351
+ ### ARIA Support
352
+
353
+ - `role="status"` on each toast
354
+ - `aria-atomic="true"` for complete announcements
355
+ - `aria-live` region with configurable priority
356
+
357
+ ### Keyboard Navigation
358
+
359
+ Enable click-to-close for keyboard accessibility:
360
+
361
+ ```javascript
362
+ new Toast({
363
+ type: 'info',
364
+ heading: 'Press Enter to close',
365
+ clickToClose: true // Now focusable and keyboard-accessible
366
+ });
367
+ ```
368
+
369
+ - **Tab** - Focus the toast
370
+ - **Enter** or **Space** - Close the toast
371
+
372
+ ### Screen Reader Announcements
373
+
374
+ Toasts are automatically announced to screen readers. Use the utility for custom announcements:
375
+
376
+ ```javascript
377
+ import { announceToScreenReader } from 'plain-toast/utils/announce';
378
+
379
+ announceToScreenReader('File uploaded successfully', 'polite');
380
+ ```
381
+
382
+ ### Reduced Motion
383
+
384
+ Animations are automatically disabled for users who prefer reduced motion (`prefers-reduced-motion: reduce`).
385
+
386
+ ## Custom Container
387
+
388
+ Render toasts in a custom container:
389
+
390
+ ```javascript
391
+ // Using element
392
+ const container = document.getElementById('my-container');
393
+ configure({ target: container });
394
+
395
+ // Using selector
396
+ configure({ target: '#my-container' });
397
+ ```
398
+
399
+ ## TypeScript
400
+
401
+ Full TypeScript support with exported types:
402
+
403
+ ```typescript
404
+ import {
405
+ Toast,
406
+ configure,
407
+ type ToastOptions,
408
+ type JTConfig,
409
+ type Position,
410
+ type Theme
411
+ } from 'plain-toast';
412
+
413
+ const options: ToastOptions = {
414
+ type: 'success',
415
+ heading: 'Success!',
416
+ body: 'All done!'
417
+ };
418
+
419
+ new Toast(options);
420
+ ```
421
+
422
+ ## Examples
423
+
424
+ ### Form Submission
425
+
426
+ ```javascript
427
+ async function handleSubmit(data) {
428
+ const toast = new Toast({
429
+ type: 'spinner',
430
+ heading: 'Submitting...'
431
+ });
432
+
433
+ try {
434
+ await api.submit(data);
435
+
436
+ toast.update({
437
+ heading: 'Submitted!',
438
+ body: 'Form submitted successfully.'
439
+ });
440
+
441
+ setTimeout(() => toast.close(), 3000);
442
+ } catch (error) {
443
+ toast.close();
444
+
445
+ new Toast({
446
+ type: 'error',
447
+ heading: 'Error',
448
+ body: error.message
449
+ });
450
+ }
451
+ }
452
+ ```
453
+
454
+ ### File Upload with Progress
455
+
456
+ ```javascript
457
+ async function uploadFile(file) {
458
+ const toast = new Toast({
459
+ type: 'progress',
460
+ heading: `Uploading ${file.name}`,
461
+ progress: { total: 100, showPercentage: true }
462
+ });
463
+
464
+ const xhr = new XMLHttpRequest();
465
+
466
+ xhr.upload.addEventListener('progress', (e) => {
467
+ if (e.lengthComputable) {
468
+ const percentage = (e.loaded / e.total) * 100;
469
+ toast.setProgress(percentage);
470
+ }
471
+ });
472
+
473
+ xhr.upload.addEventListener('load', () => {
474
+ toast.complete();
475
+ });
476
+
477
+ // ... send file
478
+ }
479
+ ```
480
+
481
+ ### Multiple Toasts
482
+
483
+ ```javascript
484
+ function showToasts() {
485
+ new Toast({
486
+ type: 'info',
487
+ heading: 'Step 1',
488
+ body: 'Processing started'
489
+ });
490
+
491
+ setTimeout(() => {
492
+ new Toast({
493
+ type: 'info',
494
+ heading: 'Step 2',
495
+ body: 'Halfway there'
496
+ });
497
+ }, 1000);
498
+
499
+ setTimeout(() => {
500
+ new Toast({
501
+ type: 'success',
502
+ heading: 'Complete!',
503
+ body: 'All steps finished'
504
+ });
505
+ }, 2000);
506
+ }
507
+ ```
508
+
509
+ ## License
510
+
511
+ MIT © [Brian Tucker](https://github.com/briantuckerdesign)
512
+
513
+ ---
514
+
515
+ Made with ❤️ by [Brian Tucker](https://github.com/briantuckerdesign)