toast-message-display 18.0.17 → 20.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.
package/README.md CHANGED
@@ -1,80 +1,61 @@
1
- # Toast Message Display Service
1
+ # Toast Message Display
2
2
 
3
3
  ## Overview
4
4
 
5
5
  The `toast-message-display` library provides a comprehensive notification service for displaying toast messages with customizable styling and behavior. Built on Angular Material's SnackBar, it offers a robust queuing system, predefined color themes, flexible positioning, and action button support for creating professional user feedback experiences.
6
6
 
7
- ### Core Capabilities
7
+ **Version 20.0.0+** — Standalone components, signal `input()`/`output()` APIs, `provideToast()` configuration function. Requires Angular 20+.
8
8
 
9
- #### 🔔 Advanced Toast Notification System
9
+ ### Core Capabilities
10
10
 
11
11
  - **Message Queuing**: Automatically queues multiple toasts and displays them sequentially
12
- - **Six Color Themes**: Predefined color schemes for different message types (SUCCESS, ERROR, INFO, WARN, NOTIFY, GENERAL)
12
+ - **Six Color Themes**: Predefined color schemes (SUCCESS, ERROR, INFO, WARN, NOTIFY, GENERAL)
13
13
  - **Flexible Positioning**: Top or bottom positioning with configurable alignment
14
14
  - **Action Support**: Optional action buttons with custom dismissal timing
15
15
  - **Icon Integration**: Material icons displayed alongside messages
16
16
  - **Duration Control**: Automatic or manual dismissal with configurable timing
17
- - **Service-based Architecture**: Easy injection and usage throughout applications
18
-
19
- #### 🔧 Features
20
-
21
- ✅ **Message Queuing** - Sequential display of multiple toast messages
22
- ✅ **Six Color Themes** - SUCCESS (green), ERROR (red), INFO (blue), WARN (yellow), NOTIFY (dark grey), GENERAL (light grey)
23
- ✅ **Flexible Positioning** - Top or bottom alignment
24
- ✅ **Action Buttons** - Optional action buttons with custom text
25
- ✅ **Icon Support** - Material icons alongside messages
26
- ✅ **Duration Control** - Configurable auto-dismiss timing
27
- ✅ **Service Integration** - Easy injection throughout applications
28
- ✅ **Queue Management** - Handles multiple simultaneous requests
29
-
30
- ### Key Benefits
31
-
32
- | Feature | Description |
33
- |---------|-------------|
34
- | **Professional UI** | Material Design based toast notifications |
35
- | **Message Queuing** | Handles multiple messages gracefully |
36
- | **Theme Support** | Six predefined color themes for different message types |
37
- | **Flexible Positioning** | Top or bottom positioning options |
38
- | **Action Support** | Interactive action buttons with custom handlers |
39
- | **Icon Integration** | Visual icons for better message recognition |
17
+ - **Standalone Components**: No NgModule required import components directly
18
+ - **Signal Inputs/Outputs**: Uses Angular `input()` / `output()` functions
40
19
 
41
20
  ---
42
21
 
43
- ## Summary
22
+ ## Quick Start Guide
44
23
 
45
- The `toast-message-display` library provides a professional notification system for Angular applications, offering comprehensive message queuing, theming, and interaction capabilities built on Angular Material's foundation.
24
+ ### Installation
46
25
 
47
- ---
26
+ ```bash
27
+ npm install toast-message-display @angular/material @angular/cdk @angular/forms
28
+ ```
48
29
 
49
- ## Quick Start Guide
30
+ ### Setup with provideToast()
31
+
32
+ ```typescript
33
+ // app.config.ts (standalone bootstrap)
34
+ import { ApplicationConfig } from '@angular/core';
35
+ import { provideToast } from 'toast-message-display';
50
36
 
51
- ### Installation & Setup (2 minutes)
37
+ export const appConfig: ApplicationConfig = {
38
+ providers: [
39
+ provideToast()
40
+ ]
41
+ };
42
+ ```
52
43
 
53
- #### 1. Import Module
44
+ Or in an NgModule:
54
45
 
55
46
  ```typescript
56
47
  // app.module.ts
57
- import { ToastMessageDisplayModule } from 'toast-message-display';
48
+ import { provideToast } from 'toast-message-display';
58
49
 
59
50
  @NgModule({
60
- imports: [
61
- ToastMessageDisplayModule
62
- ]
51
+ providers: [provideToast()]
63
52
  })
64
53
  export class AppModule { }
65
54
  ```
66
55
 
67
- #### 2. Dependencies
68
-
69
- The package integrates with Angular Material:
70
-
71
- ```bash
72
- npm install @angular/material @angular/cdk
73
- ```
74
-
75
56
  ### Quick Examples
76
57
 
77
- #### Example 1: Basic Success Message
58
+ #### Basic Success Message
78
59
 
79
60
  ```typescript
80
61
  import { Component, inject } from '@angular/core';
@@ -83,9 +64,7 @@ import { ToastDisplay, ToastColors } from 'toast-message-display';
83
64
 
84
65
  @Component({
85
66
  selector: 'app-success-example',
86
- template: `
87
- <button (click)="showSuccess()">Show Success Message</button>
88
- `
67
+ template: `<button (click)="showSuccess()">Show Success</button>`
89
68
  })
90
69
  export class SuccessExampleComponent {
91
70
  private toastService = inject(ToastMessageDisplayService);
@@ -97,259 +76,89 @@ export class SuccessExampleComponent {
97
76
  color: ToastColors.SUCCESS,
98
77
  icon: 'check_circle'
99
78
  });
100
-
101
- this.toastService.toastMessageDisplay(display, 3000);
79
+ this.toastService.toastMessage(display, 3000);
102
80
  }
103
81
  }
104
82
  ```
105
83
 
106
- #### Example 2: Error Message with Custom Duration
84
+ #### Error Message with Custom Duration
107
85
 
108
86
  ```typescript
109
- import { Component, inject } from '@angular/core';
110
- import { ToastMessageDisplayService } from 'toast-message-display';
111
- import { ToastDisplay, ToastColors, VerticalAlignment } from 'toast-message-display';
112
-
113
- @Component({
114
- selector: 'app-error-example',
115
- template: `
116
- <button (click)="showError()">Show Error Message</button>
117
- `
118
- })
119
- export class ErrorExampleComponent {
120
- private toastService = inject(ToastMessageDisplayService);
121
-
122
- showError() {
123
- const display = ToastDisplay.adapt({
124
- message: 'Failed to save data. Please try again.',
125
- action: 'Retry',
126
- color: ToastColors.ERROR,
127
- icon: 'error'
128
- });
129
-
130
- // Show for 5 seconds at the bottom
131
- this.toastService.toastMessageDisplay(display, 5000, VerticalAlignment.BOTTOM);
132
- }
87
+ showError() {
88
+ const display = ToastDisplay.adapt({
89
+ message: 'Failed to save data.',
90
+ action: 'Retry',
91
+ color: ToastColors.ERROR,
92
+ icon: 'error'
93
+ });
94
+ this.toastService.toastMessage(display, 5000, VerticalAlignment.BOTTOM);
133
95
  }
134
96
  ```
135
97
 
136
- #### Example 3: Information Message
137
-
138
- ```typescript
139
- import { Component, inject } from '@angular/core';
140
- import { ToastMessageDisplayService } from 'toast-message-display';
141
- import { ToastDisplay, ToastColors } from 'toast-message-display';
98
+ ---
142
99
 
143
- @Component({
144
- selector: 'app-info-example',
145
- template: `
146
- <button (click)="showInfo()">Show Info Message</button>
147
- `
148
- })
149
- export class InfoExampleComponent {
150
- private toastService = inject(ToastMessageDisplayService);
100
+ ## Service API
151
101
 
152
- showInfo() {
153
- const display = ToastDisplay.adapt({
154
- message: 'Your profile has been updated successfully.',
155
- color: ToastColors.INFO,
156
- icon: 'info'
157
- });
102
+ ### ToastMessageDisplayService
158
103
 
159
- this.toastService.toastMessageDisplay(display);
160
- }
161
- }
162
- ```
104
+ #### `toastMessage(options?: ToastDisplay, duration?: number, vertical?: VerticalAlignment): void`
163
105
 
164
- #### Example 4: Warning Message with Action
106
+ Displays a toast message with the specified configuration.
165
107
 
166
- ```typescript
167
- import { Component, inject } from '@angular/core';
168
- import { ToastMessageDisplayService } from 'toast-message-display';
169
- import { ToastDisplay, ToastColors } from 'toast-message-display';
108
+ **Parameters:**
109
+ - `options?: ToastDisplay` Configuration object for the toast message
110
+ - `duration?: number` Duration in seconds (default: 3, -1 = manual dismiss only)
111
+ - `vertical?: VerticalAlignment` Position alignment (TOP or BOTTOM)
170
112
 
171
- @Component({
172
- selector: 'app-warning-example',
173
- template: `
174
- <button (click)="showWarning()">Show Warning</button>
175
- `
176
- })
177
- export class WarningExampleComponent {
178
- private toastService = inject(ToastMessageDisplayService);
113
+ ---
179
114
 
180
- showWarning() {
181
- const display = ToastDisplay.adapt({
182
- message: 'You have unsaved changes. Do you want to save?',
183
- action: 'Save',
184
- color: ToastColors.WARN,
185
- icon: 'warning'
186
- });
115
+ ## Standalone Components
187
116
 
188
- this.toastService.toastMessageDisplay(display, 0); // 0 = manual dismiss only
189
- }
190
- }
191
- ```
117
+ ### ToastUIComponent
192
118
 
193
- #### Example 5: Multiple Sequential Messages
119
+ Standalone component used internally by the service. Can also be used directly in templates with signal inputs:
194
120
 
195
121
  ```typescript
196
- import { Component, inject } from '@angular/core';
197
- import { ToastMessageDisplayService } from 'toast-message-display';
198
- import { ToastDisplay, ToastColors } from 'toast-message-display';
122
+ import { ToastUIComponent } from 'toast-message-display';
199
123
 
200
124
  @Component({
201
- selector: 'app-sequence-example',
202
- template: `
203
- <button (click)="showSequence()">Show Message Sequence</button>
204
- `
125
+ selector: 'app-custom-toast',
126
+ template: `<app-toast-ui [options]="display" (close)="onClose($event)"></app-toast-ui>`,
127
+ imports: [ToastUIComponent]
205
128
  })
206
- export class SequenceExampleComponent {
207
- private toastService = inject(ToastMessageDisplayService);
208
-
209
- showSequence() {
210
- // These will be queued and displayed sequentially
211
- const messages = [
212
- {
213
- message: 'Starting process...',
214
- color: ToastColors.INFO,
215
- icon: 'hourglass_empty'
216
- },
217
- {
218
- message: 'Processing data...',
219
- color: ToastColors.INFO,
220
- icon: 'process'
221
- },
222
- {
223
- message: 'Process completed successfully!',
224
- color: ToastColors.SUCCESS,
225
- icon: 'check_circle'
226
- }
227
- ];
228
-
229
- messages.forEach((msg, index) => {
230
- setTimeout(() => {
231
- const display = ToastDisplay.adapt(msg);
232
- this.toastService.toastMessageDisplay(display, 2000);
233
- }, index * 2500); // Stagger the messages
234
- });
235
- }
129
+ export class CustomToastComponent {
130
+ display = ToastDisplay.adapt({
131
+ message: 'Inline toast',
132
+ color: ToastColors.INFO,
133
+ icon: 'info'
134
+ });
135
+ onClose(toast: ToastDisplay) { /* handle close */ }
236
136
  }
237
137
  ```
238
138
 
239
- #### Example 6: Notification Center Pattern
139
+ **Signal inputs:** `options = input<ToastDisplay>()`
140
+ **Signal outputs:** `close = output<ToastDisplay>()`
141
+
142
+ ### ToastMessageInlineComponent
143
+
144
+ Standalone inline toast list component with signal inputs:
240
145
 
241
146
  ```typescript
242
- import { Component, inject } from '@angular/core';
243
- import { ToastMessageDisplayService } from 'toast-message-display';
244
- import { ToastDisplay, ToastColors } from 'toast-message-display';
147
+ import { ToastMessageInlineComponent } from 'toast-message-display';
245
148
 
246
149
  @Component({
247
- selector: 'app-notification-center',
248
- template: `
249
- <div class="notification-controls">
250
- <button (click)="notifySuccess()">Success</button>
251
- <button (click)="notifyError()">Error</button>
252
- <button (click)="notifyWarning()">Warning</button>
253
- <button (click)="notifyInfo()">Info</button>
254
- <button (click)="notifyCustom()">Custom</button>
255
- </div>
256
- `,
257
- styles: [`
258
- .notification-controls {
259
- display: flex;
260
- gap: 1rem;
261
- flex-wrap: wrap;
262
- }
263
- button {
264
- padding: 0.5rem 1rem;
265
- border: none;
266
- border-radius: 4px;
267
- cursor: pointer;
268
- }
269
- `]
150
+ selector: 'app-inline-demo',
151
+ template: `<app-toast-message-display-inline [toast]="toastData" [duration]="5" (close)="onClose($event)"></app-toast-message-display-inline>`,
152
+ imports: [ToastMessageInlineComponent]
270
153
  })
271
- export class NotificationCenterComponent {
272
- private toastService = inject(ToastMessageDisplayService);
273
-
274
- notifySuccess() {
275
- const display = ToastDisplay.adapt({
276
- message: 'Operation completed successfully!',
277
- action: 'View',
278
- color: ToastColors.SUCCESS,
279
- icon: 'check_circle'
280
- });
281
- this.toastService.toastMessageDisplay(display);
282
- }
283
-
284
- notifyError() {
285
- const display = ToastDisplay.adapt({
286
- message: 'An error occurred while processing your request.',
287
- action: 'Retry',
288
- color: ToastColors.ERROR,
289
- icon: 'error'
290
- });
291
- this.toastService.toastMessageDisplay(display, 0); // Manual dismiss
292
- }
293
-
294
- notifyWarning() {
295
- const display = ToastDisplay.adapt({
296
- message: 'Your session will expire in 5 minutes.',
297
- action: 'Extend',
298
- color: ToastColors.WARN,
299
- icon: 'schedule'
300
- });
301
- this.toastService.toastMessageDisplay(display, 10000);
302
- }
303
-
304
- notifyInfo() {
305
- const display = ToastDisplay.adapt({
306
- message: 'New features are available. Check them out!',
307
- color: ToastColors.INFO,
308
- icon: 'new_releases'
309
- });
310
- this.toastService.toastMessageDisplay(display, 4000);
311
- }
312
-
313
- notifyCustom() {
314
- const display = ToastDisplay.adapt({
315
- message: 'Custom notification with your own styling',
316
- action: 'Details',
317
- color: ToastColors.NOTIFY,
318
- icon: 'notifications'
319
- });
320
- this.toastService.toastMessageDisplay(display);
321
- }
154
+ export class InlineDemoComponent {
155
+ toastData = ToastDisplay.adapt({ message: 'Inline!', color: ToastColors.WARN });
156
+ onClose(toast: ToastDisplay) { /* handle close */ }
322
157
  }
323
158
  ```
324
159
 
325
- ---
326
-
327
- ## Service API
328
-
329
- ### ToastMessageDisplayService
330
-
331
- #### Methods
332
-
333
- ##### `toastMessageDisplay(display: ToastDisplay, duration?: number, alignment?: VerticalAlignment): void`
334
-
335
- Displays a toast message with the specified configuration.
336
-
337
- **Parameters:**
338
- - `display: ToastDisplay` - Configuration object for the toast message
339
- - `duration?: number` - Duration in milliseconds (0 = manual dismiss only)
340
- - `alignment?: VerticalAlignment` - Position alignment (TOP or BOTTOM)
341
-
342
- **Example:**
343
- ```typescript
344
- const display = ToastDisplay.adapt({
345
- message: 'Hello World!',
346
- action: 'OK',
347
- color: ToastColors.SUCCESS,
348
- icon: 'info'
349
- });
350
-
351
- this.toastService.toastMessageDisplay(display, 3000, VerticalAlignment.TOP);
352
- ```
160
+ **Signal inputs:** `toast`, `duration`, `position`
161
+ **Signal outputs:** `close`
353
162
 
354
163
  ---
355
164
 
@@ -359,28 +168,23 @@ this.toastService.toastMessageDisplay(display, 3000, VerticalAlignment.TOP);
359
168
 
360
169
  ```typescript
361
170
  export interface ToastDisplayInterface {
362
- message: string; // Required: The message text to display
363
- action?: string; // Optional: Action button text
364
- color?: ToastColors; // Optional: Color theme
365
- icon?: string; // Optional: Material icon name
171
+ id?: string;
172
+ message: string;
173
+ action?: string;
174
+ color: ToastColors;
175
+ icon?: string;
366
176
  }
367
177
 
368
178
  export class ToastDisplay implements ToastDisplayInterface {
369
179
  constructor(
370
- public message: string,
180
+ public id?: string,
181
+ public message = 'Sample message',
371
182
  public action?: string,
372
- public color?: ToastColors,
183
+ public color = ToastColors.INFO,
373
184
  public icon?: string,
374
185
  ) {}
375
186
 
376
- static adapt(item?: any): ToastDisplay {
377
- return new ToastDisplay(
378
- item?.message,
379
- item?.action,
380
- item?.color,
381
- item?.icon,
382
- );
383
- }
187
+ static adapt(item?: any): ToastDisplay { /* ... */ }
384
188
  }
385
189
  ```
386
190
 
@@ -388,12 +192,12 @@ export class ToastDisplay implements ToastDisplayInterface {
388
192
 
389
193
  ```typescript
390
194
  export enum ToastColors {
391
- SUCCESS = "#006B31", // Green
392
- ERROR = "#CC0000", // Red
393
- INFO = "#02559F", // Blue
394
- WARN = "#FFC20E", // Yellow
395
- NOTIFY = "#080808", // Dark Grey
396
- GENERAL = "#f5f5f5" // Light Grey
195
+ SUCCESS = '#006B31', // Green
196
+ ERROR = '#CC0000', // Red
197
+ INFO = '#02559F', // Blue
198
+ WARN = '#FFC20E', // Yellow
199
+ NOTIFY = '#080808', // Dark Grey
200
+ GENERAL = '#f5f5f5', // Light Grey
397
201
  }
398
202
  ```
399
203
 
@@ -401,540 +205,40 @@ export enum ToastColors {
401
205
 
402
206
  ```typescript
403
207
  export enum VerticalAlignment {
404
- TOP = "top", // Display at the top of the screen
405
- BOTTOM = "bottom" // Display at the bottom of the screen
208
+ TOP = 'top',
209
+ BOTTOM = 'bottom'
406
210
  }
407
211
  ```
408
212
 
409
- ### Usage Examples
410
-
411
- ```typescript
412
- // Basic message configuration
413
- const basicMessage = ToastDisplay.adapt({
414
- message: 'This is a basic message'
415
- });
416
-
417
- // Full configuration
418
- const fullMessage = ToastDisplay.adapt({
419
- message: 'Complete configuration with all options',
420
- action: 'Click Me',
421
- color: ToastColors.SUCCESS,
422
- icon: 'check_circle'
423
- });
424
-
425
- // String-based configuration (backward compatibility)
426
- const stringMessage = ToastDisplay.adapt('Simple string message');
427
- ```
428
-
429
213
  ---
430
214
 
431
- ## Configuration Options
432
-
433
- ### ToastDisplay Configuration
434
-
435
- | Property | Type | Description | Required |
436
- |----------|------|-------------|----------|
437
- | `message` | `string` | The text message to display in the toast | Yes |
438
- | `action` | `string` | Optional action button text | No |
439
- | `color` | `ToastColors` | Color theme for the toast | No |
440
- | `icon` | `string` | Material icon name to display | No |
441
-
442
- ### Display Method Options
443
-
444
- | Parameter | Type | Description | Default |
445
- |-----------|------|-------------|---------|
446
- | `display` | `ToastDisplay` | Toast configuration object | Required |
447
- | `duration` | `number` | Duration in milliseconds (0 = manual) | 3000 |
448
- | `alignment` | `VerticalAlignment` | Top or bottom positioning | TOP |
215
+ ## Peer Dependencies
449
216
 
450
- ### Color Themes
451
-
452
- | Color | Hex Value | Use Case | Example |
453
- |-------|-----------|----------|---------|
454
- | `SUCCESS` | `#006B31` | Success messages, confirmations | "Data saved successfully" |
455
- | `ERROR` | `#CC0000` | Error messages, failures | "Failed to save data" |
456
- | `INFO` | `#02559F` | Informational messages | "New features available" |
457
- | `WARN` | `#FFC20E` | Warning messages | "Session expires soon" |
458
- | `NOTIFY` | `#080808` | General notifications | "Settings updated" |
459
- | `GENERAL` | `#f5f5f5` | Default/neutral messages | "Processing..." |
217
+ | Package | Version |
218
+ |---------|---------|
219
+ | `@angular/common` | `^20.0.0` |
220
+ | `@angular/core` | `^20.0.0` |
221
+ | `@angular/forms` | `^20.0.0` |
222
+ | `@angular/material` | `^20.0.0` |
223
+ | `@angular/cdk` | `^20.0.0` |
460
224
 
461
225
  ---
462
226
 
463
- ## Module Configuration
464
-
465
- ### ToastMessageDisplayModule
466
-
467
- **No Global Configuration Required**
227
+ ## Migration from v18 (NgModule to Standalone)
468
228
 
469
- The `ToastMessageDisplayModule` does not provide a `forRoot()` method or global configuration options. All configuration is done at the service level through method parameters.
229
+ If upgrading from v18.x:
470
230
 
471
- #### Module Structure
231
+ 1. Replace `ToastMessageDisplayModule` import with `provideToast()` in providers
232
+ 2. Remove `ToastMessageDisplayModule` from `imports` array
233
+ 3. Import standalone components directly in your component's `imports` array
234
+ 4. Use `toastMessage()` method name (was `toastMessageDisplay` in some docs)
472
235
 
473
236
  ```typescript
474
- @NgModule({
475
- declarations: [
476
- ToastUIComponent,
477
- ToastMessageInlineComponent,
478
- ],
479
- imports: [
480
- // Dependencies are handled by Angular Material
481
- ],
482
- exports: [
483
- ToastUIComponent,
484
- ToastMessageInlineComponent,
485
- ]
486
- })
487
- export class ToastMessageDisplayModule { }
488
- ```
489
-
490
- #### Dependencies
491
-
492
- - **@angular/material**: Material Design components (SnackBar)
493
- - **@angular/cdk**: Component Development Kit
494
- - **@angular/common**: Core Angular functionality
495
-
496
- ---
497
-
498
- ## Advanced Usage Patterns
499
-
500
- ### Integration with HTTP Request Manager
501
-
502
- ```typescript
503
- import { Component, inject } from '@angular/core';
504
- import { ToastMessageDisplayService } from 'toast-message-display';
505
- import { HTTPManagerService } from 'http-request-manager';
506
- import { ToastDisplay, ToastColors } from 'toast-message-display';
507
-
508
- @Component({
509
- selector: 'app-http-integration',
510
- template: `
511
- <button (click)="saveData()">Save Data</button>
512
- `
513
- })
514
- export class HttpIntegrationComponent {
515
- private toastService = inject(ToastMessageDisplayService);
516
- private httpManager = inject(HTTPManagerService);
517
-
518
- saveData() {
519
- // Show loading toast
520
- const loadingToast = ToastDisplay.adapt({
521
- message: 'Saving data...',
522
- color: ToastColors.INFO,
523
- icon: 'hourglass_empty'
524
- });
525
- this.toastService.toastMessageDisplay(loadingToast);
526
-
527
- // Make HTTP request
528
- this.httpManager.postRequest({
529
- path: ['api', 'data'],
530
- body: { data: 'sample' }
531
- }).subscribe({
532
- next: (response) => {
533
- // Show success toast
534
- const successToast = ToastDisplay.adapt({
535
- message: 'Data saved successfully!',
536
- action: 'View',
537
- color: ToastColors.SUCCESS,
538
- icon: 'check_circle'
539
- });
540
- this.toastService.toastMessageDisplay(successToast);
541
- },
542
- error: (error) => {
543
- // Show error toast
544
- const errorToast = ToastDisplay.adapt({
545
- message: 'Failed to save data. Please try again.',
546
- action: 'Retry',
547
- color: ToastColors.ERROR,
548
- icon: 'error'
549
- });
550
- this.toastService.toastMessageDisplay(errorToast, 0);
551
- }
552
- });
553
- }
554
- }
555
- ```
556
-
557
- ### Toast Queue Management
558
-
559
- ```typescript
560
- import { Component, inject } from '@angular/core';
561
- import { ToastMessageDisplayService } from 'toast-message-display';
562
- import { ToastDisplay, ToastColors } from 'toast-message-display';
563
-
564
- @Component({
565
- selector: 'app-queue-management',
566
- template: `
567
- <div class="queue-controls">
568
- <button (click)="addToQueue()">Add to Queue</button>
569
- )="clearQueue()">Clear All</button>
570
- </div>
571
- `
572
- })
573
- export class QueueManagementComponent {
574
- private toastService = <button (click inject(ToastMessageDisplayService);
575
- private messageCount = 0;
576
-
577
- addToQueue() {
578
- this.messageCount++;
579
- const message = ToastDisplay.adapt({
580
- message: `Queued message #${this.messageCount}`,
581
- action: 'Dismiss',
582
- color: ToastColors.INFO,
583
- icon: 'queue'
584
- });
585
-
586
- // All messages go to the same queue
587
- this.toastService.toastMessageDisplay(message, 2000);
588
- }
589
-
590
- clearQueue() {
591
- // Messages are automatically cleared when dismissed
592
- // For immediate clearing, you might need to implement custom logic
593
- console.log('Queue will clear as messages are dismissed');
594
- }
595
- }
596
- ```
597
-
598
- ### Custom Toast Factory
599
-
600
- ```typescript
601
- import { Component, inject } from '@angular/core';
602
- import { ToastMessageDisplayService } from 'toast-message-display';
603
- import { ToastDisplay, ToastColors } from 'toast-message-display';
604
-
605
- @Component({
606
- selector: 'app-toast-factory',
607
- template: `
608
- <button (click)="showUserMessage('success')">Success</button>
609
- <button (click)="showUserMessage('error')">Error</button>
610
- <button (click)="showUserMessage('warning')">Warning</button>
611
- `
612
- })
613
- export class ToastFactoryComponent {
614
- private toastService = inject(ToastMessageDisplayService);
615
-
616
- showUserMessage(type: 'success' | 'error' | 'warning') {
617
- const configs = {
618
- success: {
619
- message: 'Operation completed successfully!',
620
- color: ToastColors.SUCCESS,
621
- icon: 'check_circle',
622
- action: 'Great!'
623
- },
624
- error: {
625
- message: 'An error occurred. Please try again.',
626
- color: ToastColors.ERROR,
627
- icon: 'error',
628
- action: 'Retry'
629
- },
630
- warning: {
631
- message: 'Please review your input before proceeding.',
632
- color: ToastColors.WARN,
633
- icon: 'warning',
634
- action: 'Review'
635
- }
636
- };
637
-
638
- const config = configs[type];
639
- const display = ToastDisplay.adapt(config);
640
- this.toastService.toastMessageDisplay(display);
641
- }
642
- }
643
- ```
644
-
645
- ---
646
-
647
- ## Styling and Customization
648
-
649
- ### CSS Customization
650
-
651
- While the component uses Material Design styling, you can customize the appearance:
652
-
653
- ```scss
654
- // Custom toast styling
655
- .mat-snack-bar-container {
656
- &.custom-toast {
657
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
658
- color: white;
659
-
660
- .mat-button {
661
- color: white;
662
-
663
- &:hover {
664
- background: rgba(255, 255, 255, 0.1);
665
- }
666
- }
667
- }
668
- }
669
- ```
670
-
671
- ### Theme Integration
672
-
673
- ```scss
674
- // Integrate with Angular Material theme
675
- @use '@angular/material' as mat;
676
-
677
- $custom-palette: (
678
- toast-success: #006B31,
679
- toast-error: #CC0000,
680
- toast-info: #02559F,
681
- toast-warning: #FFC20E
682
- );
683
-
684
- @include mat.core();
685
- ```
686
-
687
- ---
688
-
689
- ## Best Practices
690
-
691
- ### Message Guidelines
692
-
693
- 1. **Keep messages concise**: Use short, clear messages
694
- 2. **Use appropriate colors**: Match message type to color theme
695
- 3. **Provide meaningful actions**: Action buttons should be actionable
696
- 4. **Set appropriate durations**: Longer for important messages, shorter for notifications
697
- 5. **Queue management**: Let the system handle multiple messages gracefully
698
-
699
- ### Performance Considerations
700
-
701
- 1. **Avoid excessive queuing**: Don't create too many simultaneous toasts
702
- 2. **Use appropriate durations**: Manual dismiss for critical errors
703
- 3. **Clean up subscriptions**: Ensure proper cleanup in component lifecycle
704
-
705
- ### Accessibility
706
-
707
- 1. **Screen reader support**: Messages are announced by screen readers
708
- 2. **Keyboard navigation**: Action buttons are keyboard accessible
709
- 3. **Color contrast**: Ensure sufficient contrast for readability
710
-
711
- ---
712
-
713
- ## Integration Examples
714
-
715
- ### With Form Validation
716
-
717
- ```typescript
718
- import { Component, inject } from '@angular/core';
719
- import { FormBuilder, Validators } from '@angular/forms';
720
- import { ToastMessageDisplayService } from 'toast-message-display';
721
- import { ToastDisplay, ToastColors } from 'toast-message-display';
722
-
723
- @Component({
724
- selector: 'app-form-with-toasts',
725
- template: `
726
- <form [formGroup]="userForm" (ngSubmit)="onSubmit()">
727
- <input formControlName="email" placeholder="Email">
728
- <input formControlName="name" placeholder="Name">
729
- <button type="submit" [disabled]="userForm.invalid">Submit</button>
730
- </form>
731
- `
732
- })
733
- export class FormWithToastsComponent {
734
- private fb = inject(FormBuilder);
735
- private toastService = inject(ToastMessageDisplayService);
736
-
737
- userForm = this.fb.group({
738
- email: ['', [Validators.required, Validators.email]],
739
- name: ['', Validators.required]
740
- });
741
-
742
- onSubmit() {
743
- if (this.userForm.valid) {
744
- // Show success message
745
- const successToast = ToastDisplay.adapt({
746
- message: 'Form submitted successfully!',
747
- color: ToastColors.SUCCESS,
748
- icon: 'check_circle'
749
- });
750
- this.toastService.toastMessageDisplay(successToast);
751
-
752
- this.userForm.reset();
753
- } else {
754
- // Show validation errors
755
- const errors = [];
756
- if (this.userForm.get('email')?.errors?.['required']) {
757
- errors.push('Email is required');
758
- }
759
- if (this.userForm.get('email')?.errors?.['email']) {
760
- errors.push('Please enter a valid email');
761
- }
762
- if (this.userForm.get('name')?.errors?.['required']) {
763
- errors.push('Name is required');
764
- }
765
-
766
- const errorToast = ToastDisplay.adapt({
767
- message: errors.join('. '),
768
- color: ToastColors.ERROR,
769
- icon: 'error'
770
- });
771
- this.toastService.toastMessageDisplay(errorToast, 0);
772
- }
773
- }
774
- }
775
- ```
776
-
777
- ### With State Management
778
-
779
- ```typescript
780
- import { Component, inject } from '@angular/core';
781
- import { Store } from '@ngrx/store';
782
- import { ToastMessageDisplayService } from 'toast-message-display';
783
- import { ToastDisplay, ToastColors } from 'toast-message-display';
784
-
785
- @Component({
786
- selector: 'app-state-integration',
787
- template: `
788
- <div *ngFor="let item of items$ | async">
789
- {{ item.name }}
790
- <button (click)="deleteItem(item.id)">Delete</button>
791
- </div>
792
- `
793
- })
794
- export class StateIntegrationComponent {
795
- private store = inject(Store);
796
- private toastService = inject(ToastMessageDisplayService);
797
-
798
- items$ = this.store.select(state => state.items);
799
-
800
- deleteItem(id: string) {
801
- this.store.dispatch(deleteItem({ id }));
802
-
803
- // Show toast notification
804
- const toast = ToastDisplay.adapt({
805
- message: 'Item deleted successfully',
806
- action: 'Undo',
807
- color: ToastColors.INFO,
808
- icon: 'delete'
809
- });
810
- this.toastService.toastMessageDisplay(toast);
811
- }
812
- }
813
- ```
814
-
815
- ---
816
-
817
- ## Testing
818
-
819
- ### Unit Testing Example
820
-
821
- ```typescript
822
- import { TestBed, inject } from '@angular/core/testing';
823
- import { ToastMessageDisplayService } from './toast-message-display.service';
824
- import { ToastDisplay, ToastColors } from './models/toast-display.model';
825
-
826
- describe('ToastMessageDisplayService', () => {
827
- let service: ToastMessageDisplayService;
828
-
829
- beforeEach(() => {
830
- TestBed.configureTestingModule({
831
- providers: [ToastMessageDisplayService]
832
- });
833
- });
834
-
835
- it('should be created', inject([ToastMessageDisplayService], (service: ToastMessageDisplayService) => {
836
- expect(service).toBeTruthy();
837
- }));
838
-
839
- it('should display a basic message', inject([ToastMessageDisplayService], (service: ToastMessageDisplayService) => {
840
- spyOn(service, 'toastMessageDisplay');
841
-
842
- const display = ToastDisplay.adapt({
843
- message: 'Test message',
844
- color: ToastColors.SUCCESS,
845
- icon: 'check'
846
- });
847
-
848
- service.toastMessageDisplay(display);
849
-
850
- expect(service.toastMessageDisplay).toHaveBeenCalledWith(display, 3000, undefined);
851
- }));
852
-
853
- it('should handle custom duration', inject([ToastMessageDisplayService], (service: ToastMessageDisplayService) => {
854
- spyOn(service, 'toastMessageDisplay');
855
-
856
- const display = ToastDisplay.adapt({ message: 'Test message' });
857
-
858
- service.toastMessageDisplay(display, 5000);
859
-
860
- expect(service.toastMessageDisplay).toHaveBeenCalledWith(display, 5000, undefined);
861
- }));
862
- });
863
- ```
864
-
865
- ---
866
-
867
- ## Troubleshooting
868
-
869
- ### Common Issues
870
-
871
- 1. **Toast not displaying**: Ensure ToastMessageDisplayModule is imported
872
- 2. **Styling issues**: Verify Angular Material theme is properly configured
873
- 3. **Action button not working**: Check that action text is provided
874
- 4. **Queue not working**: Multiple toasts should automatically queue
875
-
876
- ### Debug Mode
877
-
878
- ```typescript
879
- @Component({
880
- template: `
881
- <div class="debug-info">
882
- <button (click)="testBasicToast()">Test Basic Toast</button>
883
- <button (click)="testCustomToast()">Test Custom Toast</button>
884
- </div>
885
- `
886
- })
887
- export class ToastDebugComponent {
888
- private toastService = inject(ToastMessageDisplayService);
889
-
890
- testBasicToast() {
891
- const display = ToastDisplay.adapt({
892
- message: 'Debug: Basic toast message',
893
- color: ToastColors.INFO,
894
- icon: 'bug_report'
895
- });
896
- this.toastService.toastMessageDisplay(display);
897
- }
237
+ // Before (v18)
238
+ import { ToastMessageDisplayModule } from 'toast-message-display';
239
+ @NgModule({ imports: [ToastMessageDisplayModule] })
898
240
 
899
- testCustomToast() {
900
- const display = ToastDisplay.adapt({
901
- message: 'Debug: Custom configuration',
902
- action: 'Debug Action',
903
- color: ToastColors.WARN,
904
- icon: 'settings'
905
- });
906
- this.toastService.toastMessageDisplay(display, 0); // Manual dismiss
907
- }
908
- }
241
+ // After (v20+)
242
+ import { provideToast } from 'toast-message-display';
243
+ @NgModule({ providers: [provideToast()] })
909
244
  ```
910
-
911
- ### Performance Issues
912
-
913
- ```typescript
914
- // Monitor toast queue performance
915
- @Component({
916
- template: `
917
- <div class="performance-monitor">
918
- <p>Active Toasts: {{ activeToastCount }}</p>
919
- <button (click)="stressTest()">Stress Test</button>
920
- </div>
921
- `
922
- })
923
- export class PerformanceMonitorComponent {
924
- activeToastCount = 0;
925
-
926
- stressTest() {
927
- // Create multiple toasts to test queue performance
928
- for (let i = 0; i < 10; i++) {
929
- setTimeout(() => {
930
- const display = ToastDisplay.adapt({
931
- message: `Stress test message ${i + 1}`,
932
- color: ToastColors.INFO,
933
- icon: 'speed'
934
- });
935
- this.toastService.toastMessageDisplay(display, 1000);
936
- }, i * 200);
937
- }
938
- }
939
- }
940
- ```