1 | <div align="center">
|
2 | <img src="https://raw.githubusercontent.com/scttcper/ngx-toastr/master/misc/documentation-assets/ngx-toastr-example.png" width="300" alt="Angular Toastr">
|
3 | <br>
|
4 | <h1>ngx-toastr</h1>
|
5 | <br>
|
6 | <a href="https://www.npmjs.org/package/ngx-toastr">
|
7 | <img src="https://badge.fury.io/js/ngx-toastr.svg" alt="npm">
|
8 | </a>
|
9 | <a href="https://codecov.io/github/scttcper/ngx-toastr">
|
10 | <img src="https://img.shields.io/codecov/c/github/scttcper/ngx-toastr.svg" alt="codecov">
|
11 | </a>
|
12 | <br>
|
13 | <br>
|
14 | </div>
|
15 |
|
16 | DEMO: https://ngx-toastr.vercel.app
|
17 |
|
18 | ## Features
|
19 |
|
20 | - Toast Component Injection without being passed `ViewContainerRef`
|
21 | - No use of `*ngFor`. Fewer dirty checks and higher performance.
|
22 | - AoT compilation and lazy loading compatible
|
23 | - Component inheritance for custom toasts
|
24 | - SystemJS/UMD rollup bundle
|
25 | - Animations using Angular's
|
26 | [Web Animations API](https://angular.io/docs/ts/latest/guide/animations.html)
|
27 | - Output toasts to an optional target directive
|
28 |
|
29 | ## Dependencies
|
30 |
|
31 | Latest version available for each version of Angular
|
32 |
|
33 | | ngx-toastr | Angular |
|
34 | | ---------- | ----------- |
|
35 | | 13.2.1 | 10.x 11.x |
|
36 | | 14.3.0 | 12.x 13.x |
|
37 | | 15.2.2 | 14.x. |
|
38 | | 16.2.0 | 15.x |
|
39 | | 17.0.2 | 16.x |
|
40 | | current | >= 17.x |
|
41 |
|
42 | ## Install
|
43 |
|
44 | ```bash
|
45 | npm install ngx-toastr --save
|
46 | ```
|
47 |
|
48 | `@angular/animations` package is a required dependency for the default toast
|
49 |
|
50 | ```bash
|
51 | npm install @angular/animations --save
|
52 | ```
|
53 |
|
54 | Don't want to use `@angular/animations`? See
|
55 | [Setup Without Animations](#setup-without-animations).
|
56 |
|
57 | ## Setup
|
58 |
|
59 | **step 1:** add css
|
60 |
|
61 | - copy
|
62 | [toast css](/src/lib/toastr.css)
|
63 | to your project.
|
64 | - If you are using sass you can import the css.
|
65 |
|
66 | ```scss
|
67 | // regular style toast
|
68 | @import 'ngx-toastr/toastr';
|
69 |
|
70 | // bootstrap style toast
|
71 | // or import a bootstrap 4 alert styled design (SASS ONLY)
|
72 | // should be after your bootstrap imports, it uses bs4 variables, mixins, functions
|
73 | @import 'ngx-toastr/toastr-bs4-alert';
|
74 |
|
75 | // if you'd like to use it without importing all of bootstrap it requires
|
76 | @import 'bootstrap/scss/functions';
|
77 | @import 'bootstrap/scss/variables';
|
78 | @import 'bootstrap/scss/mixins';
|
79 | // bootstrap 4
|
80 | @import 'ngx-toastr/toastr-bs4-alert';
|
81 | // boostrap 5
|
82 | @import 'ngx-toastr/toastr-bs5-alert';
|
83 | ```
|
84 |
|
85 | - If you are using angular-cli you can add it to your angular.json
|
86 |
|
87 | ```ts
|
88 | "styles": [
|
89 | "styles.scss",
|
90 | "node_modules/ngx-toastr/toastr.css" // try adding '../' if you're using angular cli before 6
|
91 | ]
|
92 | ```
|
93 |
|
94 | **step 2:** add `ToastrModule` to app `NgModule`, or `provideToastr` to providers, make sure you have `BrowserAnimationsModule` (or `provideAnimations`) as well.
|
95 |
|
96 | - Module based
|
97 |
|
98 | ```typescript
|
99 | import { CommonModule } from '@angular/common';
|
100 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
101 |
|
102 | import { ToastrModule } from 'ngx-toastr';
|
103 |
|
104 | @NgModule({
|
105 | imports: [
|
106 | CommonModule,
|
107 | BrowserAnimationsModule, // required animations module
|
108 | ToastrModule.forRoot(), // ToastrModule added
|
109 | ],
|
110 | bootstrap: [App],
|
111 | declarations: [App],
|
112 | })
|
113 | class MainModule {}
|
114 | ```
|
115 |
|
116 | - Standalone
|
117 |
|
118 | ```typescript
|
119 | import { AppComponent } from './src/app.component';
|
120 | import { provideAnimations } from '@angular/platform-browser/animations';
|
121 |
|
122 | import { provideToastr } from 'ngx-toastr';
|
123 |
|
124 | bootstrapApplication(AppComponent, {
|
125 | providers: [
|
126 | provideAnimations(), // required animations providers
|
127 | provideToastr(), // Toastr providers
|
128 | ]
|
129 | });
|
130 | ```
|
131 |
|
132 | ## Use
|
133 |
|
134 | ```typescript
|
135 | import { ToastrService } from 'ngx-toastr';
|
136 |
|
137 | @Component({...})
|
138 | export class YourComponent {
|
139 | constructor(private toastr: ToastrService) {}
|
140 |
|
141 | showSuccess() {
|
142 | this.toastr.success('Hello world!', 'Toastr fun!');
|
143 | }
|
144 | }
|
145 | ```
|
146 |
|
147 | ## Options
|
148 |
|
149 | There are **individual options** and **global options**.
|
150 |
|
151 | ### Individual Options
|
152 |
|
153 | Passed to `ToastrService.success/error/warning/info/show()`
|
154 |
|
155 | | Option | Type | Default | Description
|
156 | | ----------------- | ------------------------------ | ------------------------------ | ------------------------------------------------- |
|
157 | | toastComponent | Component | Toast | Angular component that will be used |
|
158 | | closeButton | boolean | false | Show close button |
|
159 | | timeOut | number | 5000 | Time to live in milliseconds |
|
160 | | extendedTimeOut | number | 1000 | Time to close after a user hovers over toast |
|
161 | | disableTimeOut | `boolean \| 'timeOut' \| 'extendedTimeOut'` | false | Disable both timeOut and extendedTimeOut when set to `true`. Allows specifying which timeOut to disable, either: `timeOut` or `extendedTimeOut` |
|
162 | | easing | string | 'ease-in' | Toast component easing |
|
163 | | easeTime | string \| number | 300 | Time spent easing |
|
164 | | enableHtml | boolean | false | Allow html in message |
|
165 | | newestOnTop | boolean | true | New toast placement |
|
166 | | progressBar | boolean | false | Show progress bar |
|
167 | | progressAnimation | `'decreasing' \| 'increasing'` | 'decreasing' | Changes the animation of the progress bar. |
|
168 | | toastClass | string | 'ngx-toastr' | CSS class(es) for toast |
|
169 | | positionClass | string | 'toast-top-right' | CSS class(es) for toast container |
|
170 | | titleClass | string | 'toast-title' | CSS class(es) for inside toast on title |
|
171 | | messageClass | string | 'toast-message' | CSS class(es) for inside toast on message |
|
172 | | tapToDismiss | boolean | true | Close on click |
|
173 | | onActivateTick | boolean | false | Fires `changeDetectorRef.detectChanges()` when activated. Helps show toast from asynchronous events outside of Angular's change detection |
|
174 |
|
175 | #### Setting Individual Options
|
176 |
|
177 | success, error, info, warning take `(message, title, ToastConfig)` pass an
|
178 | options object to replace any default option.
|
179 |
|
180 | ```typescript
|
181 | this.toastrService.error('everything is broken', 'Major Error', {
|
182 | timeOut: 3000,
|
183 | });
|
184 | ```
|
185 |
|
186 | ### Global Options
|
187 |
|
188 | All [individual options](#individual-options) can be overridden in the global
|
189 | options to affect all toasts. In addition, global options include the following
|
190 | options:
|
191 |
|
192 | | Option | Type | Default | Description |
|
193 | | ----------------------- | ------- | ---------------------------------- | ------------------------------------------------------------------ |
|
194 | | maxOpened | number | 0 | Max toasts opened. Toasts will be queued. 0 is unlimited |
|
195 | | autoDismiss | boolean | false | Dismiss current toast when max is reached |
|
196 | | iconClasses | object | [see below](#iconclasses-defaults) | Classes used on toastr service methods |
|
197 | | preventDuplicates | boolean | false | Block duplicate messages |
|
198 | | countDuplicates | boolean | false | Displays a duplicates counter (preventDuplicates must be true). Toast must have a title and duplicate message |
|
199 | | resetTimeoutOnDuplicate | boolean | false | Reset toast timeout on duplicate (preventDuplicates must be true) |
|
200 | | includeTitleDuplicates | boolean | false | Include the title of a toast when checking for duplicates (by default only message is compared) |
|
201 |
|
202 | ##### iconClasses defaults
|
203 |
|
204 | ```typescript
|
205 | iconClasses = {
|
206 | error: 'toast-error',
|
207 | info: 'toast-info',
|
208 | success: 'toast-success',
|
209 | warning: 'toast-warning',
|
210 | };
|
211 | ```
|
212 |
|
213 | #### Setting Global Options
|
214 |
|
215 | Pass values to `ToastrModule.forRoot()` or `provideToastr()` to set global options.
|
216 |
|
217 | - Module based
|
218 |
|
219 | ```typescript
|
220 | // root app NgModule
|
221 | imports: [
|
222 | ToastrModule.forRoot({
|
223 | timeOut: 10000,
|
224 | positionClass: 'toast-bottom-right',
|
225 | preventDuplicates: true,
|
226 | }),
|
227 | ],
|
228 | ```
|
229 |
|
230 | - Standalone
|
231 |
|
232 | ```typescript
|
233 | import { AppComponent } from './src/app.component';
|
234 | import { provideAnimations } from '@angular/platform-browser/animations';
|
235 |
|
236 | import { provideToastr } from 'ngx-toastr';
|
237 |
|
238 | bootstrapApplication(AppComponent, {
|
239 | providers: [
|
240 | provideToastr({
|
241 | timeOut: 10000,
|
242 | positionClass: 'toast-bottom-right',
|
243 | preventDuplicates: true,
|
244 | }),
|
245 | ]
|
246 | });
|
247 | ```
|
248 |
|
249 |
|
250 | ### Toastr Service methods return:
|
251 |
|
252 | ```typescript
|
253 | export interface ActiveToast {
|
254 | /** Your Toast ID. Use this to close it individually */
|
255 | toastId: number;
|
256 | /** the title of your toast. Stored to prevent duplicates if includeTitleDuplicates set */
|
257 | title: string;
|
258 | /** the message of your toast. Stored to prevent duplicates */
|
259 | message: string;
|
260 | /** a reference to the component see portal.ts */
|
261 | portal: ComponentRef<any>;
|
262 | /** a reference to your toast */
|
263 | toastRef: ToastRef<any>;
|
264 | /** triggered when toast is active */
|
265 | onShown: Observable<any>;
|
266 | /** triggered when toast is destroyed */
|
267 | onHidden: Observable<any>;
|
268 | /** triggered on toast click */
|
269 | onTap: Observable<any>;
|
270 | /** available for your use in custom toast */
|
271 | onAction: Observable<any>;
|
272 | }
|
273 | ```
|
274 |
|
275 | ### Put toasts in your own container
|
276 |
|
277 | Put toasts in a specific div inside your application. This should probably be
|
278 | somewhere that doesn't get deleted. Add `ToastContainerModule` to the ngModule
|
279 | where you need the directive available. Make sure that your container has
|
280 | an `aria-live="polite"` attribute, so that any time a toast is injected into
|
281 | the container it is announced by screen readers.
|
282 |
|
283 | ```typescript
|
284 | import { BrowserModule } from '@angular/platform-browser';
|
285 | import { NgModule } from '@angular/core';
|
286 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
287 |
|
288 | import { ToastrModule, ToastContainerModule } from 'ngx-toastr';
|
289 |
|
290 | import { AppComponent } from './app.component';
|
291 |
|
292 | @NgModule({
|
293 | declarations: [AppComponent],
|
294 | imports: [
|
295 | BrowserModule,
|
296 | BrowserAnimationsModule,
|
297 |
|
298 | ToastrModule.forRoot({ positionClass: 'inline' }),
|
299 | ToastContainerModule,
|
300 | ],
|
301 | providers: [],
|
302 | bootstrap: [AppComponent],
|
303 | })
|
304 | export class AppModule {}
|
305 | ```
|
306 |
|
307 | Add a div with `toastContainer` directive on it.
|
308 |
|
309 | ```typescript
|
310 | import { Component, OnInit, ViewChild } from '@angular/core';
|
311 |
|
312 | import { ToastContainerDirective, ToastrService } from 'ngx-toastr';
|
313 |
|
314 | @Component({
|
315 | selector: 'app-root',
|
316 | template: `
|
317 | <h1><a (click)="onClick()">Click</a></h1>
|
318 | <div aria-live="polite" toastContainer></div>
|
319 | `,
|
320 | })
|
321 | export class AppComponent implements OnInit {
|
322 | @ViewChild(ToastContainerDirective, { static: true })
|
323 | toastContainer: ToastContainerDirective;
|
324 |
|
325 | constructor(private toastrService: ToastrService) {}
|
326 | ngOnInit() {
|
327 | this.toastrService.overlayContainer = this.toastContainer;
|
328 | }
|
329 | onClick() {
|
330 | this.toastrService.success('in div');
|
331 | }
|
332 | }
|
333 | ```
|
334 |
|
335 | ## Functions
|
336 |
|
337 | ##### Clear
|
338 |
|
339 | Remove all or a single toast by optional id
|
340 |
|
341 | ```ts
|
342 | toastrService.clear(toastId?: number);
|
343 | ```
|
344 |
|
345 | ##### Remove
|
346 |
|
347 | Remove and destroy a single toast by id
|
348 |
|
349 | ```
|
350 | toastrService.remove(toastId: number);
|
351 | ```
|
352 |
|
353 | ## SystemJS
|
354 |
|
355 | If you are using SystemJS, you should also adjust your configuration to point to
|
356 | the UMD bundle.
|
357 |
|
358 | In your SystemJS config file, `map` needs to tell the System loader where to
|
359 | look for `ngx-toastr`:
|
360 |
|
361 | ```js
|
362 | map: {
|
363 | 'ngx-toastr': 'node_modules/ngx-toastr/bundles/ngx-toastr.umd.min.js',
|
364 | }
|
365 | ```
|
366 |
|
367 | ## Setup Without Animations
|
368 |
|
369 | If you do not want to include `@angular/animations` in your project you can
|
370 | override the default toast component in the global config to use
|
371 | `ToastNoAnimation` instead of the default one.
|
372 |
|
373 | In your main module (ex: `app.module.ts`)
|
374 |
|
375 | ```typescript
|
376 | import { ToastrModule, ToastNoAnimation, ToastNoAnimationModule } from 'ngx-toastr';
|
377 |
|
378 | @NgModule({
|
379 | imports: [
|
380 | // ...
|
381 |
|
382 | // BrowserAnimationsModule no longer required
|
383 | ToastNoAnimationModule.forRoot(),
|
384 | ],
|
385 | // ...
|
386 | })
|
387 | class AppModule {}
|
388 | ```
|
389 |
|
390 | That's it! Animations are no longer required.
|
391 |
|
392 | ## Using A Custom Toast
|
393 |
|
394 | Create your toast component extending Toast see the demo's pink toast for an example
|
395 | https://github.com/scttcper/ngx-toastr/blob/master/src/app/pink.toast.ts
|
396 |
|
397 | ```typescript
|
398 | import { ToastrModule } from 'ngx-toastr';
|
399 |
|
400 | @NgModule({
|
401 | imports: [
|
402 | ToastrModule.forRoot({
|
403 | toastComponent: YourToastComponent, // added custom toast!
|
404 | }),
|
405 | ],
|
406 | bootstrap: [App],
|
407 | declarations: [App, YourToastComponent], // add!
|
408 | })
|
409 | class AppModule {}
|
410 | ```
|
411 |
|
412 | ## FAQ
|
413 |
|
414 | 1. ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it
|
415 | was checked\
|
416 | When opening a toast inside an angular lifecycle wrap it in setTimeout
|
417 |
|
418 | ```typescript
|
419 | ngOnInit() {
|
420 | setTimeout(() => this.toastr.success('sup'))
|
421 | }
|
422 | ```
|
423 |
|
424 | 2. Change default icons (check, warning sign, etc)\
|
425 | Overwrite the css background-image: https://github.com/scttcper/ngx-toastr/blob/master/src/lib/toastr.css.
|
426 | 3. How do I use this in an ErrorHandler?\
|
427 | See: https://github.com/scttcper/ngx-toastr/issues/179.
|
428 | 4. How can I translate messages?\
|
429 | See: https://github.com/scttcper/ngx-toastr/issues/201.
|
430 | 5. How to handle toastr click/tap action?
|
431 | ```ts
|
432 | showToaster() {
|
433 | this.toastr.success('Hello world!', 'Toastr fun!')
|
434 | .onTap
|
435 | .pipe(take(1))
|
436 | .subscribe(() => this.toasterClickedHandler());
|
437 | }
|
438 |
|
439 | toasterClickedHandler() {
|
440 | console.log('Toastr clicked');
|
441 | }
|
442 | ```
|
443 | 6. How to customize styling without overridding defaults?\
|
444 | Add multiple CSS classes separated by a space:
|
445 | ```ts
|
446 | toastClass: 'yourclass ngx-toastr'
|
447 | ```
|
448 | See: https://github.com/scttcper/ngx-toastr/issues/594.
|
449 |
|
450 | ## Previous Works
|
451 |
|
452 | [toastr](https://github.com/CodeSeven/toastr) original toastr\
|
453 | [angular-toastr](https://github.com/Foxandxss/angular-toastr) AngularJS toastr\
|
454 | [notyf](https://github.com/caroso1222/notyf) notyf (css)
|
455 |
|
456 | ## License
|
457 |
|
458 | MIT
|
459 |
|
460 | ---
|
461 |
|
462 | > GitHub [@scttcper](https://github.com/scttcper) ·
|
463 | > Twitter [@scttcper](https://twitter.com/scttcper)
|