diff --git a/.travis.yml b/.travis.yml index 8c011941..dfccad75 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,3 +23,7 @@ deploy: github_token: $GH_TOKEN on: branch: master +notifications: + email: + on_success: never + on_failure: change diff --git a/README.md b/README.md index 7c6c5db9..1f65a987 100644 --- a/README.md +++ b/README.md @@ -21,31 +21,47 @@
## Features -- Toast Component Injection without being passed `ViewContainerRef` -- No use of `*ngFor`. Fewer dirty checks and higher performance. -- AoT compilation and lazy loading compatible -- Component inheritance for custom toasts -- SystemJS/UMD rollup bundle -- Animations using Angular's [Web Animations API](https://angular.io/docs/ts/latest/guide/animations.html) (polyfill needed for older devices) -- Output toasts to an optional target directive + +* Toast Component Injection without being passed `ViewContainerRef` +* No use of `*ngFor`. Fewer dirty checks and higher performance. +* AoT compilation and lazy loading compatible +* Component inheritance for custom toasts +* SystemJS/UMD rollup bundle +* Animations using Angular's + [Web Animations API](https://angular.io/docs/ts/latest/guide/animations.html) + (polyfill needed for older devices) +* Output toasts to an optional target directive ## Install + ```bash npm install ngx-toastr --save -``` +``` + `@angular/animations` package is a required dependency for the default toast + ```bash npm install @angular/animations --save ``` -## Setup -__step 1:__ add css -- copy [toast css](https://github.com/scttcper/ngx-toastr/blob/master/src/app/app.component.css) to your project. -- If you are using sass you can import the css. +Don't want to use `@angular/animations`? See +[Setup Without Animations](#setup-without-animations). + +## Setup + +**step 1:** add css + +* copy + [toast css](https://github.com/scttcper/ngx-toastr/blob/master/src/app/app.component.css) + to your project. +* If you are using sass you can import the css. + ```scss -@import "~ngx-toastr/toastr"; +@import '~ngx-toastr/toastr'; ``` -- If you are using angular-cli you can add it to your angular-cli.json + +* If you are using angular-cli you can add it to your angular-cli.json + ```json "styles": [ "styles.scss", @@ -53,28 +69,30 @@ __step 1:__ add css ] ``` -__step 2:__ add ToastrModule to app NgModule +**step 2:** add ToastrModule to app NgModule + ```typescript import { CommonModule } from '@angular/common'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ToastrModule } from 'ngx-toastr'; - @NgModule({ imports: [ CommonModule, BrowserAnimationsModule, // required animations module ToastrModule.forRoot(), // ToastrModule added - ], + ], bootstrap: [App], declarations: [App], }) class MainModule {} -``` +``` ## Use + Success: + ```typescript import { ToastrService } from 'ngx-toastr'; @Component({ @@ -82,7 +100,7 @@ import { ToastrService } from 'ngx-toastr'; }) export class YourComponent { constructor(private toastr: ToastrService) {} - + showSuccess() { this.toastr.success('Hello world!', 'Toastr fun!'); } @@ -90,38 +108,49 @@ export class YourComponent { ``` ## Options -There are __individual options__ and __global options__. -### Individual Options -Passed to `ToastrService.success/error/warn/info/show()` +There are **individual options** and **global options**. -| Option | Type | Default | Description | -| ----------------- | --------- | ----------------- | ---------------------------------------------------------------------------------- | -| toastComponent | Component | Toast | Angular component that will be used | -| closeButton | boolean | false | Show close button | -| timeOut | number | 5000 | Time to live in milliseconds | -| extendedTimeOut | number | 1000 | Time to close after a user hovers over toast | -| enableHtml | boolean | false | Allow html in message | -| progressBar | boolean | false | Show progress bar | -| progressAnimation | 'decreasing' | 'increasing' | 'decreasing' | Changes the animation of the progress bar. | -| toastClass | string | 'toast' | Class on toast | -| positionClass | string | 'toast-top-right' | Class on toast container | -| titleClass | string | 'toast-title' | Class inside toast on title | -| messageClass | string | 'toast-message' | Class inside toast on message | -| tapToDismiss | boolean | true | Close on click | -| onActivateTick | boolean | false | Fires `ApplicationRef.tick()` when activated. Helps show toast from asynchronous events outside of Angular's change detection | +### Individual Options + +Passed to `ToastrService.success/error/warn/info/show()` +| Option | Type | Default | Description | +| ----------------- | ------------------------------ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| toastComponent | Component | Toast | Angular component that will be used | +| closeButton | boolean | false | Show close button | +| timeOut | number | 5000 | Time to live in milliseconds | +| extendedTimeOut | number | 1000 | Time to close after a user hovers over toast | +| easing | string | 'ease-in' | Toast component easing | +| easeTime | string \| number | 300 | Time spent easing | +| enableHtml | boolean | false | Allow html in message | +| progressBar | boolean | false | Show progress bar | +| progressAnimation | `'decreasing' \| 'increasing'` | 'decreasing' | Changes the animation of the progress bar. | +| toastClass | string | 'toast' | Class on toast | +| positionClass | string | 'toast-top-right' | Class on toast container | +| titleClass | string | 'toast-title' | Class inside toast on title | +| messageClass | string | 'toast-message' | Class inside toast on message | +| tapToDismiss | boolean | true | Close on click | +| onActivateTick | boolean | false | Fires `changeDetectorRef.detectChanges()` when activated. Helps show toast from asynchronous events outside of Angular's change detection | #### Setting Individual Options -success, error, info, warning take ```(message, title, ToastConfig)``` pass an options object to replace any default option. + +success, error, info, warning take `(message, title, ToastConfig)` pass an +options object to replace any default option. + ```typescript -this.toastrService.error('everything is broken', 'title is optional', { timeOut: 3000 }); +this.toastrService.error('everything is broken', 'Major Error', { + timeOut: 3000, +}); ``` -### Global Options -All [individual options](#individual-options) can be overridden in the global options to affect all toasts. In addition, global options include the following options: +### Global Options -| Option | Type | Default | Description | +All [individual options](#individual-options) can be overridden in the global +options to affect all toasts. In addition, global options include the following +options: + +| Option | Type | Default | Description | | ----------------- | ------- | ---------------------------------- | -------------------------------------------------------- | | maxOpened | number | 0 | Max toasts opened. Toasts will be queued. 0 is unlimited | | autoDismiss | boolean | false | Dismiss current toast when max is reached | @@ -130,6 +159,7 @@ All [individual options](#individual-options) can be overridden in the global op | preventDuplicates | boolean | false | Block duplicate messages | ##### iconClasses defaults + ```typescript iconClasses = { error: 'toast-error', @@ -140,36 +170,49 @@ iconClasses = { ``` #### Setting Global Options -Pass values to `ToastrModule.forRoot()` + +Pass values to `ToastrModule.forRoot()` + ```typescript // root app NgModule imports: [ - ToastrModule.forRoot({ + ToastrModule.forRoot({ timeOut: 10000, positionClass: 'toast-bottom-right', preventDuplicates: true, }), -], +], ``` ### Toastr Service methods return: +Toastr Service will return undefined if prevent duplicates is enabled ```typescript export interface ActiveToast { - toastId: number; // Your Toast ID. Use this to close it individually - message: string; // the message of your toast. Stored for prevent duplicate reasons - portal?: any; // a reference to the component see portal.ts - toastRef?: ToastRef; // a reference to your toast - onShown?: Observable; // triggered when toast is active - onHidden?: Observable; // triggered when toast is destroyed - onTap?: Observable; // triggered on click - onAction?: Observable; // available for your use in custom toast + /** Your Toast ID. Use this to close it individually */ + toastId: number; + /** the message of your toast. Stored to prevent duplicates */ + message: string; + /** a reference to the component see portal.ts */ + portal: ComponentRef; + /** a reference to your toast */ + toastRef: ToastRef; + /** triggered when toast is active */ + onShown: Observable; + /** triggered when toast is destroyed */ + onHidden: Observable; + /** triggered on toast click */ + onTap: Observable; + /** available for your use in custom toast */ + onAction: Observable; } ``` -Toastr Service will return undefined if prevent duplicates is on. ### Put toasts in your own container -Put toasts in a specific div inside your application. This should probably be somewhere that doesn't get deleted. -Add `ToastContainerModule` to the ngModule where you need the directive available. + +Put toasts in a specific div inside your application. This should probably be +somewhere that doesn't get deleted. Add `ToastContainerModule` to the ngModule +where you need the directive available. + ```typescript import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; @@ -180,23 +223,22 @@ import { ToastrModule, ToastContainerModule } from 'ngx-toastr'; import { AppComponent } from './app.component'; @NgModule({ - declarations: [ - AppComponent - ], + declarations: [AppComponent], imports: [ BrowserModule, BrowserAnimationsModule, - ToastrModule.forRoot({positionClass: 'inline'}), + ToastrModule.forRoot({ positionClass: 'inline' }), ToastContainerModule, ], providers: [], - bootstrap: [AppComponent] + bootstrap: [AppComponent], }) -export class AppModule { } - +export class AppModule {} ``` + Add a div with `toastContainer` directive on it. + ```typescript import { Component, OnInit, ViewChild } from '@angular/core'; @@ -222,36 +264,98 @@ export class AppComponent implements OnInit { } ``` -### SystemJS -If you are using SystemJS, you should also adjust your configuration to point to the UMD bundle. +## SystemJS + +If you are using SystemJS, you should also adjust your configuration to point to +the UMD bundle. + +In your SystemJS config file, `map` needs to tell the System loader where to +look for `ngx-toastr`: -In your systemjs config file, `map` needs to tell the System loader where to look for `ngx-toastr`: ```js map: { 'ngx-toastr': 'node_modules/ngx-toastr/toastr.umd.js', } ``` - -### FAQ -1. ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked -When opening a toast inside an angular lifecycle wrap it in setTimeout + +## Setup Without Animations + +If you do not want to include `@angular/animations` in your project you can +override the default toast component in the global config to use +`ToastNoAnimation` instead of the default one. + +In your main module (ex: `app.module.ts`) + +```typescript +import { + ToastrModule, + ToastNoAnimation, + ToastNoAnimationModule, +} from 'ngx-toastr'; + +@NgModule({ + imports: [ + // ... + + // BrowserAnimationsModule no longer required + ToastNoAnimationModule, + ToastrModule.forRoot({ + toastComponent: ToastNoAnimation, + }), + ], + // ... +}) +class AppModule {} +``` + +That's it! Animations are no longer required. + +## Using A Custom Toast +Create your toast component extending Toast see the demo's pink toast for an example +https://github.com/scttcper/ngx-toastr/blob/master/src/app/pink.toast.ts + +```typescript +import { ToastrModule } from 'ngx-toastr'; + +@NgModule({ + imports: [ + ToastrModule.forRoot({ + toastComponent: YourToastComponent, // added custom toast! + }), + ], + entryComponents: [YourToastComponent], // add! + bootstrap: [App], + declarations: [App, YourToastComponent], // add! +}) +class AppModule {} +``` + + +## FAQ + +1. ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it + was checked\ + When opening a toast inside an angular lifecycle wrap it in setTimeout + ```typescript ngOnInit() { setTimeout(() => this.toastr.success('sup')) } ``` -2. Change default icons (check, warning sign, etc) -Overwrite the css background-image -https://github.com/scttcper/ngx-toastr/blob/master/src/lib/toastr.css -3. How do I use this in an ErrorHandler? -See: https://github.com/scttcper/ngx-toastr/issues/179 -4. How can I translate messages -See: https://github.com/scttcper/ngx-toastr/issues/201 + +2. Change default icons (check, warning sign, etc)\ + Overwrite the css background-image https://github.com/scttcper/ngx-toastr/blob/master/src/lib/toastr.css +3. How do I use this in an ErrorHandler? See: + https://github.com/scttcper/ngx-toastr/issues/179 +4. How can I translate messages See: + https://github.com/scttcper/ngx-toastr/issues/201 ## Previous Works -[toastr](https://github.com/CodeSeven/toastr) original toastr -[angular-toastr](https://github.com/Foxandxss/angular-toastr) AngularJS toastr + +[toastr](https://github.com/CodeSeven/toastr) original toastr\ +[angular-toastr](https://github.com/Foxandxss/angular-toastr) AngularJS toastr\ [notyf](https://github.com/caroso1222/notyf) notyf (css) ## License + MIT diff --git a/build.ts b/build.ts index 7ed81aa8..3a9d1b6b 100644 --- a/build.ts +++ b/build.ts @@ -16,7 +16,6 @@ const GLOBALS = { '@angular/common': 'ng.common', '@angular/animations': 'ng.animations', '@angular/platform-browser': 'ng.platformBrowser', - 'rxjs': 'Rx', 'rxjs/Observable': 'Rx', 'rxjs/Subject': 'Rx', 'rxjs/Observer': 'Rx', @@ -52,8 +51,16 @@ function generateBundle(input, file, globals, name, format) { external: Object.keys(globals), file, plugins, + onwarn(warning) { + if (warning.code === 'THIS_IS_UNDEFINED') { + return; + } + if (warning.code === 'UNUSED_EXTERNAL_IMPORT') { + return; + } + console.log(warning.message); + }, }).then(bundle => { - console.log(file); return bundle.write({ file, name, diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts index b5312990..a234f78b 100644 --- a/e2e/app.e2e-spec.ts +++ b/e2e/app.e2e-spec.ts @@ -8,7 +8,7 @@ describe('toastr App', () => { page = new ToastrPage(); }); - it('should display message saying app works', () => { + it('should display toast HELLO THERE', () => { page.navigateTo(); page.enterMessage(); page.clickShowToast(); diff --git a/e2e/app.po.ts b/e2e/app.po.ts index 585288ff..64d3119d 100644 --- a/e2e/app.po.ts +++ b/e2e/app.po.ts @@ -1,4 +1,4 @@ -import { browser, element, by, until } from 'protractor'; +import { browser, by, element, until } from 'protractor'; export class ToastrPage { navigateTo() { diff --git a/package-lock.json b/package-lock.json index 9c5fd3b3..c19aacf6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ngx-toastr", - "version": "6.5.0", + "version": "7.0.0-beta.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -12,55 +12,55 @@ "requires": { "loader-utils": "1.1.0", "source-map": "0.5.7", - "typescript": "2.6.1", - "webpack-sources": "1.0.2" + "typescript": "2.6.2", + "webpack-sources": "1.1.0" } }, "@angular-devkit/core": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.0.20.tgz", - "integrity": "sha512-lg5BvMxOfbVD//SOQvpq6TPIKTXYNMj0I9N/kfXbXkUGgiBGFLyFMf2fc+qNvDoa7lulKMPT8OJWS1YlGt93eg==", + "version": "0.0.21", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.0.21.tgz", + "integrity": "sha512-6cfjRE6W+ZOxE8Xk3PFRA8kJJK2sJhd5ZGQ/BsVYyz2cxN8Zb3Gmu1wxg7l5TiPbOjqfn797tBEpKGBXJV85xw==", "dev": true, "requires": { "source-map": "0.5.7" } }, "@angular-devkit/schematics": { - "version": "0.0.36", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.0.36.tgz", - "integrity": "sha512-6Aj2uuSaGVWhwVDJb7wrkVdunHY1FVak7/P24NuFTUT3ThShQs2LI5UrRKbIJKIHqxtb8PYHebFsjHCHISlRMw==", + "version": "0.0.37", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.0.37.tgz", + "integrity": "sha512-CF7+W4Flkvd6z4d/dvH0IP5PV8gSBHr4lE7eyScDpuet7s+I4b6SYh5bWDEvyDF+hZwDTFDyrHHj77kyeJu+8g==", "dev": true, "requires": { - "@angular-devkit/core": "0.0.20", + "@angular-devkit/core": "0.0.21", "@ngtools/json-schema": "1.1.0", "minimist": "1.2.0", "rxjs": "5.5.2" } }, "@angular/animations": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-4.4.6.tgz", - "integrity": "sha1-+mYYmaik44y3xYPHpcl85l1ZKjU=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-5.0.3.tgz", + "integrity": "sha1-8IsHAHsUn6EmecNG+lWCD1RLGeA=", "requires": { "tslib": "1.8.0" } }, "@angular/cli": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.5.3.tgz", - "integrity": "sha512-PuMcYmnoPP/RqCVIguiJrkc+vek9eVPi+iQ+UE3W/JTDQhZsAkm4qm8zLYR/Z2bp1a5xHuP+PFMtAQysPFag+Q==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.5.4.tgz", + "integrity": "sha512-Z5nltoJL09rr3dw9qFzcJ3YQEP63jqnhdmIxGcU5zQ7DyV9ptNm0slhL17d9AtqI/eIN4TshvOkfd72+oEVSIA==", "dev": true, "requires": { "@angular-devkit/build-optimizer": "0.0.33", - "@angular-devkit/schematics": "0.0.36", + "@angular-devkit/schematics": "0.0.37", "@ngtools/json-schema": "1.1.0", - "@ngtools/webpack": "1.8.3", - "@schematics/angular": "0.1.5", + "@ngtools/webpack": "1.8.4", + "@schematics/angular": "0.1.7", "autoprefixer": "6.7.7", "chalk": "2.2.2", "circular-dependency-plugin": "3.0.0", - "common-tags": "1.4.0", - "copy-webpack-plugin": "4.2.1", + "common-tags": "1.5.1", + "copy-webpack-plugin": "4.2.3", "core-object": "3.1.5", "css-loader": "0.28.7", "cssnano": "3.10.0", @@ -86,8 +86,8 @@ "opn": "5.1.0", "portfinder": "1.0.13", "postcss-custom-properties": "6.2.0", - "postcss-loader": "2.0.8", - "postcss-url": "7.2.1", + "postcss-loader": "2.0.9", + "postcss-url": "7.3.0", "raw-loader": "0.5.1", "resolve": "1.5.0", "rxjs": "5.5.2", @@ -103,96 +103,88 @@ "url-loader": "0.6.2", "webpack": "3.8.1", "webpack-concat-plugin": "1.4.0", - "webpack-dev-middleware": "1.12.0", - "webpack-dev-server": "2.9.4", + "webpack-dev-middleware": "1.12.2", + "webpack-dev-server": "2.9.5", "webpack-merge": "4.1.1", - "webpack-sources": "1.0.2", + "webpack-sources": "1.1.0", "webpack-subresource-integrity": "1.0.1", "zone.js": "0.8.18" } }, "@angular/common": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-4.4.6.tgz", - "integrity": "sha1-S4FCByTggooOg5uVpV6xp+g5GPI=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-5.0.3.tgz", + "integrity": "sha1-mwuHTgyMsIjXx94q9ywsPz69ALs=", "requires": { "tslib": "1.8.0" } }, "@angular/compiler": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-4.4.6.tgz", - "integrity": "sha1-LuH68lt1fh0SiXkHS+f65SmzvCA=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-5.0.3.tgz", + "integrity": "sha1-RYF8mjKxsQPAMHsPVWYPUw9KBqo=", "requires": { "tslib": "1.8.0" } }, "@angular/compiler-cli": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-4.4.6.tgz", - "integrity": "sha1-uv09HiYOmQh+uajPdTLb1gOrubE=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-5.0.3.tgz", + "integrity": "sha1-gg/pX1ZTwUGK2aycqegZqHnM5K4=", "dev": true, "requires": { - "@angular/tsc-wrapped": "4.4.6", + "chokidar": "1.7.0", "minimist": "1.2.0", - "reflect-metadata": "0.1.10" + "reflect-metadata": "0.1.10", + "tsickle": "0.24.1" } }, "@angular/core": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-4.4.6.tgz", - "integrity": "sha1-EwMf0Q3P5DiHVBmzjyESCVi8I1Q=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-5.0.3.tgz", + "integrity": "sha1-JWZAD2cTvxw59+ALwDpjKAqH5ms=", "requires": { "tslib": "1.8.0" } }, "@angular/forms": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-4.4.6.tgz", - "integrity": "sha1-/mSs5CQ1wbgPSQNLfEHOjK8UpEo=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.0.3.tgz", + "integrity": "sha1-IH+Swr2JZg3aWFjvWNHqwfLK8ac=", "requires": { "tslib": "1.8.0" } }, "@angular/language-service": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-4.4.6.tgz", - "integrity": "sha1-SY7OlcX2BmQDv5/TxYMa9CtFYYs=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-5.0.3.tgz", + "integrity": "sha1-6MIVgeBGTqUDY+jw1J17an5rPL8=", "dev": true }, "@angular/platform-browser": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-4.4.6.tgz", - "integrity": "sha1-qYOcVH4bZU+h0kqJeAyLpquNzOA=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.0.3.tgz", + "integrity": "sha1-SshyQEoqgWLdKKWxZCOLdr9eEmE=", "requires": { "tslib": "1.8.0" } }, "@angular/platform-browser-dynamic": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.4.6.tgz", - "integrity": "sha1-TT2aanvyzz3kBYphWuBZ7/ZB+jY=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.0.3.tgz", + "integrity": "sha1-vm3PA6BPpRxqBIS0Dl8afX5UzIc=", "requires": { "tslib": "1.8.0" } }, "@angular/router": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-4.4.6.tgz", - "integrity": "sha1-D2rSmuD/jSyeo3m9MgRHIXt+yGY=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-5.0.3.tgz", + "integrity": "sha1-YWzGp64zV1tU5hO3CvXH8pHIzR4=", "requires": { "tslib": "1.8.0" } }, - "@angular/tsc-wrapped": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@angular/tsc-wrapped/-/tsc-wrapped-4.4.6.tgz", - "integrity": "sha1-Fnh8u/UL3H5zgSOxnDJSfyROF40=", - "dev": true, - "requires": { - "tsickle": "0.21.6" - } - }, "@ngtools/json-schema": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.1.0.tgz", @@ -200,9 +192,9 @@ "dev": true }, "@ngtools/webpack": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-1.8.3.tgz", - "integrity": "sha512-Yf6leN/IuBhhZ93qq3NRJL1NlAtn1NsowRagZ2y5gpIw64wheuaHNg52EB+HiyQ23Mejc811gKYCbs1KpcaYVw==", + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-1.8.4.tgz", + "integrity": "sha512-/1d1aJ/W/VV2DnLDd2WMF5NV3lvYbG4euNd9GbMD4HhOfDJyEmBkl2DJ3+iPF5lOpR27DQnhKV64c8S7enxLBQ==", "dev": true, "requires": { "chalk": "2.2.2", @@ -215,12 +207,12 @@ } }, "@schematics/angular": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.1.5.tgz", - "integrity": "sha512-ls2mnpxVd5/la458whcPJYhEkDpvEsF8qcACMC4mNIsxqPUyn/SnjbuZExOW9+1QJGaSYTG17Kilh3N2nEl9XA==", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.1.7.tgz", + "integrity": "sha512-3dZbRkM7akVCazr9T7gX+BOKri1Mn/N36o36Nojf8LSRxMo7QSJ9s651RPc5snYqpbKrTXZXUO4xKknAf4x+Ng==", "dev": true, "requires": { - "@angular-devkit/core": "0.0.20" + "@angular-devkit/core": "0.0.21" } }, "@types/jasmine": { @@ -341,9 +333,9 @@ } }, "ajv": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.4.0.tgz", - "integrity": "sha1-MtHPCNvIDEMvQm8S4QslEfa0ZHQ=", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.0.tgz", + "integrity": "sha1-6yhAdG6dxIvV4GOjbj/UAMXqtak=", "dev": true, "requires": { "co": "4.6.0", @@ -555,7 +547,7 @@ "dev": true, "requires": { "define-properties": "1.1.2", - "es-abstract": "1.9.0" + "es-abstract": "1.10.0" } }, "array-slice": { @@ -683,7 +675,7 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000766", + "caniuse-db": "1.0.30000772", "normalize-range": "0.1.2", "num2fraction": "1.2.2", "postcss": "5.2.18", @@ -708,7 +700,7 @@ "integrity": "sha1-uk+S8XFn37q0CYN4VFS5rBScPG0=", "dev": true, "requires": { - "follow-redirects": "1.2.5", + "follow-redirects": "1.2.6", "is-buffer": "1.1.6" } }, @@ -1000,7 +992,7 @@ "deep-equal": "1.0.1", "dns-equal": "1.0.0", "dns-txt": "2.0.2", - "multicast-dns": "6.2.0", + "multicast-dns": "6.2.1", "multicast-dns-service-types": "1.1.0" } }, @@ -1181,7 +1173,7 @@ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", "dev": true, "requires": { - "caniuse-db": "1.0.30000766", + "caniuse-db": "1.0.30000772", "electron-to-chromium": "1.3.27" } }, @@ -1229,10 +1221,10 @@ "axios": "0.16.2", "bytes": "3.0.0", "ci-env": "1.5.2", - "commander": "2.11.0", + "commander": "2.12.1", "github-build": "1.2.0", "glob": "7.1.2", - "gzip-size": "4.0.0", + "gzip-size": "4.1.0", "opencollective": "1.0.3", "prettycli": "1.4.3", "read-pkg-up": "2.0.0" @@ -1363,15 +1355,15 @@ "dev": true, "requires": { "browserslist": "1.7.7", - "caniuse-db": "1.0.30000766", + "caniuse-db": "1.0.30000772", "lodash.memoize": "4.1.2", "lodash.uniq": "4.5.0" } }, "caniuse-db": { - "version": "1.0.30000766", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000766.tgz", - "integrity": "sha1-TJEao3R/ATiEUvpLknt4/PFDBoA=", + "version": "1.0.30000772", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000772.tgz", + "integrity": "sha1-UarokXaChureSj2DGep21qAbUSs=", "dev": true }, "caseless": { @@ -1410,9 +1402,9 @@ } }, "chardet": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.0.tgz", - "integrity": "sha1-C74TVaxE16PtSpJXB8TvcPgZD2w=", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "dev": true }, "charenc": { @@ -1606,9 +1598,9 @@ "dev": true }, "codelyzer": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-3.2.2.tgz", - "integrity": "sha512-VNvW9gRThsqRarEnLioiILd0Pdk0yCq/7cVgYvqHpC+3CHqfnrJfmXjoana7vzWfSis+9pODXofjCWX+nlU9Gw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.0.1.tgz", + "integrity": "sha512-MsOcaiLqcBK7hjHbfp9HZrflqWg5tD9A5qVSXkW208OJ8pkf63id8IiOjEiK/XU3o70W8tWbFKi1tAOwiJDMrQ==", "dev": true, "requires": { "app-root-path": "2.0.1", @@ -1690,15 +1682,15 @@ } }, "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.1.tgz", + "integrity": "sha512-PCNLExLlI5HiPdaJs4pMXwOTHkSCpNQ1QJH9ykZLKtKEyKu3p9HgmH5l97vM8c0IUz6d54l+xEu2GG9yuYrFzA==", "dev": true }, "common-tags": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", - "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.5.1.tgz", + "integrity": "sha512-NrUYGY5TApAk9KB+IZXkR3GR4tA3g26HDsoiGt4kCMHZ727gOGkC+UNfq0Z22jE15bLkc/6RV5Jw1RBW6Usg6A==", "dev": true, "requires": { "babel-runtime": "6.26.0" @@ -1838,9 +1830,9 @@ "dev": true }, "convert-source-map": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", - "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", "dev": true }, "cookie": { @@ -1903,19 +1895,17 @@ } }, "copy-webpack-plugin": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.2.1.tgz", - "integrity": "sha512-wZIe7EAcOrCQrZF2w6/bqloylIxeuPIope3Qt7ygJMFp4TqT0OZJoYwm/Uu36QMs9U+j6rOGrY8RupGiahE+Rg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.2.3.tgz", + "integrity": "sha512-cL/Wl3Y1QmmKThl/mWeGB+HH3YH+25tn8nhqEGsZda4Yn7GqGnDZ+TbeKJ7A6zvrxyNhhuviYAxn/tCyyAqh8Q==", "dev": true, "requires": { "bluebird": "3.5.1", - "fs-extra": "4.0.2", "glob": "7.1.2", "is-glob": "4.0.0", "loader-utils": "0.2.17", "lodash": "4.17.4", - "minimatch": "3.0.4", - "node-dir": "0.1.17" + "minimatch": "3.0.4" }, "dependencies": { "loader-utils": { @@ -2209,7 +2199,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.35" + "es5-ext": "0.10.37" } }, "dashdash": { @@ -2746,9 +2736,9 @@ } }, "es-abstract": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.9.0.tgz", - "integrity": "sha512-kk3IJoKo7A3pWJc0OV8yZ/VEX2oSUytfekrJiqoxBlKJMFAJVJVpGdHClCCTdv+Fn2zHfpDHHIelMFhZVfef3Q==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", + "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", "dev": true, "requires": { "es-to-primitive": "1.1.1", @@ -2770,9 +2760,9 @@ } }, "es5-ext": { - "version": "0.10.35", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.35.tgz", - "integrity": "sha1-GO6FjOajxFx9eekcFfzKnsVoSU8=", + "version": "0.10.37", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", + "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", "dev": true, "requires": { "es6-iterator": "2.0.3", @@ -2786,7 +2776,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-symbol": "3.1.1" } }, @@ -2797,7 +2787,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-iterator": "2.0.3", "es6-set": "0.1.5", "es6-symbol": "3.1.1", @@ -2817,7 +2807,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-iterator": "2.0.3", "es6-symbol": "3.1.1", "event-emitter": "0.3.5" @@ -2830,7 +2820,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35" + "es5-ext": "0.10.37" } }, "es6-weak-map": { @@ -2840,7 +2830,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35", + "es5-ext": "0.10.37", "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } @@ -2916,7 +2906,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.35" + "es5-ext": "0.10.37" } }, "eventemitter3": { @@ -3138,7 +3128,7 @@ "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", "dev": true, "requires": { - "chardet": "0.4.0", + "chardet": "0.4.2", "iconv-lite": "0.4.19", "tmp": "0.0.33" } @@ -3169,7 +3159,7 @@ "async": "2.6.0", "loader-utils": "1.1.0", "schema-utils": "0.3.0", - "webpack-sources": "1.0.2" + "webpack-sources": "1.1.0" } }, "extsprintf": { @@ -3386,12 +3376,23 @@ } }, "follow-redirects": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.2.5.tgz", - "integrity": "sha512-lMhwQTryFbG+wYsAIEKC1Kf5IGDlVNnONRogIBllh7LLoV7pNIxW0z9fhjRar9NBql+hd2Y49KboVVNxf6GEfg==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.2.6.tgz", + "integrity": "sha512-FrMqZ/FONtHnbqO651UPpfRUVukIEwJhXMfdr/JWAmrDbeYBu773b1J6gdWDyRIj4hvvzQEHoEOTrdR8o6KLYA==", "dev": true, "requires": { - "debug": "2.6.9" + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "for-in": { @@ -4611,7 +4612,7 @@ "dev": true, "requires": { "homedir-polyfill": "1.0.1", - "ini": "1.3.4", + "ini": "1.3.5", "is-windows": "0.2.0", "which": "1.3.0" } @@ -4654,9 +4655,9 @@ "dev": true }, "gzip-size": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-4.0.0.tgz", - "integrity": "sha512-6SWfFRd8r8VTKTpJCR7h/T6IbCaK+jM/n2gB1+pV3IrKcrLO1WTb8ZWdaRy1T/nwOz80cp4gAJf8sujpZxfA1w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-4.1.0.tgz", + "integrity": "sha1-iuCWJX6r59acRb4rZ8RIEk/7UXw=", "dev": true, "requires": { "duplexer": "0.1.1", @@ -4960,19 +4961,19 @@ "dev": true }, "html-minifier": { - "version": "3.5.6", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.6.tgz", - "integrity": "sha512-88FjtKrlak2XjczhxrBomgzV4jmGzM3UnHRBScRkJcmcRum0kb+IwhVAETJ8AVp7j0p3xugjSaw9L+RmI5/QOA==", + "version": "3.5.7", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.7.tgz", + "integrity": "sha512-GISXn6oKDo7+gVpKOgZJTbHMCUI2TSGfpg/8jgencWhWJsvEmsvp3M8emX7QocsXsYznWloLib3OeSfeyb/ewg==", "dev": true, "requires": { "camel-case": "3.0.0", "clean-css": "4.1.9", - "commander": "2.11.0", + "commander": "2.12.1", "he": "1.1.1", "ncname": "1.0.0", "param-case": "2.1.1", "relateurl": "0.2.7", - "uglify-js": "3.1.10" + "uglify-js": "3.2.0" } }, "html-webpack-plugin": { @@ -4982,7 +4983,7 @@ "dev": true, "requires": { "bluebird": "3.5.1", - "html-minifier": "3.5.6", + "html-minifier": "3.5.7", "loader-utils": "0.2.17", "lodash": "4.17.4", "pretty-error": "2.1.1", @@ -5280,9 +5281,9 @@ "dev": true }, "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, "inquirer": { @@ -5376,9 +5377,9 @@ } }, "interpret": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz", - "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, "invariant": { @@ -5788,7 +5789,7 @@ "integrity": "sha1-5UkpAKsLuoNe+oAkywC+mz7qJwA=", "dev": true, "requires": { - "convert-source-map": "1.5.0", + "convert-source-map": "1.5.1", "istanbul-lib-instrument": "1.9.1", "loader-utils": "0.2.17", "object-assign": "4.1.1" @@ -6117,7 +6118,7 @@ "isbinaryfile": "3.0.2", "lodash": "3.10.1", "log4js": "0.6.38", - "mime": "1.4.1", + "mime": "1.6.0", "minimatch": "3.0.4", "optimist": "0.6.1", "qjobs": "1.1.5", @@ -6239,7 +6240,7 @@ "errno": "0.1.4", "graceful-fs": "4.1.11", "image-size": "0.5.5", - "mime": "1.4.1", + "mime": "1.6.0", "mkdirp": "0.5.1", "promise": "7.3.1", "request": "2.81.0", @@ -6700,9 +6701,9 @@ } }, "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true }, "mime-db": { @@ -6827,9 +6828,9 @@ "dev": true }, "multicast-dns": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.0.tgz", - "integrity": "sha512-tnQqWkuWYHCOVRveiWQf+5KjHUnEmtxUycTy1esL4prQjXoT4qpndIS4fH63zObmHNxIHke3YHRnQrXYpXHf2A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.1.tgz", + "integrity": "sha512-uV3/ckdsffHx9IrGQrx613mturMdMqQ06WTq+C09NsStJ9iNG6RcUWgPKs1Rfjy+idZT6tfQoXEusGNnEZhT3w==", "dev": true, "requires": { "dns-packet": "1.2.2", @@ -6879,15 +6880,6 @@ "lower-case": "1.1.4" } }, - "node-dir": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", - "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=", - "dev": true, - "requires": { - "minimatch": "3.0.4" - } - }, "node-fetch": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz", @@ -7044,7 +7036,7 @@ "optional": true, "requires": { "chalk": "1.1.3", - "commander": "2.11.0", + "commander": "2.12.1", "is-my-json-valid": "2.16.1", "pinkie-promise": "2.0.1" } @@ -7918,9 +7910,9 @@ } }, "postcss-loader": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.8.tgz", - "integrity": "sha512-KtXBiQ/r/WYW8LxTSJK7h8wLqvCMSub/BqmRnud/Mu8RzwflW9cmXxwsMwbn15TNv287Hcufdb3ZSs7xHKnG8Q==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.0.9.tgz", + "integrity": "sha512-sgoXPtmgVT3aBAhU47Kig8oPF+mbXl8Unjvtz1Qj1q2D2EvSVJW2mKJNzxv5y/LvA9xWwuvdysvhc7Zn80UWWw==", "dev": true, "requires": { "loader-utils": "1.1.0", @@ -8298,12 +8290,12 @@ } }, "postcss-url": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.2.1.tgz", - "integrity": "sha512-jycW2XYgU39SpA+MJOOP7Fe7I2NxiCq8rOXiG61NBoJ4vG/WFn2IhS18vGiphla4VTN3WoHJOBMMJz1n4h1VYQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.0.tgz", + "integrity": "sha512-VBP6uf6iL3AZra23nkPkOEkS/5azj1xf/toRrjfkolfFEgg9Gyzg9UhJZeIsz12EGKZTNVeGbPa2XtaZm/iZvg==", "dev": true, "requires": { - "mime": "1.4.1", + "mime": "1.6.0", "minimatch": "3.0.4", "mkdirp": "0.5.1", "postcss": "6.0.14", @@ -8534,7 +8526,7 @@ "chalk": "1.1.3", "del": "2.2.2", "glob": "7.1.2", - "ini": "1.3.4", + "ini": "1.3.5", "minimist": "1.2.0", "q": "1.4.1", "request": "2.81.0", @@ -9077,9 +9069,9 @@ } }, "rollup": { - "version": "0.51.8", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.51.8.tgz", - "integrity": "sha512-e7FwWxqb4vhdonmwRH06nqC9wR6h1kZojK2D+lN1xjiB8FDtAKgy7o+r8fCXVzQZ1ZCdcVlls3mTq5g6u38Jew==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.52.0.tgz", + "integrity": "sha512-IQ+t5uoeMSHpDyeJj4uFVWj+ocS8sUbFPNKCssyCac3GVgLs62nFH6UdU0nGLRIxjasPaN7wGHEioVXbxXRaYQ==", "dev": true }, "rollup-plugin-filesize": { @@ -9219,7 +9211,7 @@ "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", "dev": true, "requires": { - "ajv": "5.4.0" + "ajv": "5.5.0" } }, "scss-tokenizer": { @@ -9317,6 +9309,14 @@ "on-finished": "2.3.0", "range-parser": "1.2.0", "statuses": "1.3.1" + }, + "dependencies": { + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + } } }, "serve-index": { @@ -10321,9 +10321,9 @@ } }, "tsickle": { - "version": "0.21.6", - "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.21.6.tgz", - "integrity": "sha1-U7Abl5xcE/2xOvs/uVgXflmRWI0=", + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.24.1.tgz", + "integrity": "sha512-XloFQZhVhgjpQsi3u2ORNRJvuID5sflOg6HfP093IqAbhE1+fIUXznULpdDwHgG4p+v8w78KdHruQtkWUKx5AQ==", "dev": true, "requires": { "minimist": "1.2.0", @@ -10346,7 +10346,7 @@ "babel-code-frame": "6.26.0", "builtin-modules": "1.1.1", "chalk": "2.2.2", - "commander": "2.11.0", + "commander": "2.12.1", "diff": "3.4.0", "glob": "7.1.2", "minimatch": "3.0.4", @@ -10404,18 +10404,18 @@ "dev": true }, "typescript": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.1.tgz", - "integrity": "sha1-7znN6ierrAtQAkLWcmq5DgyEZjE=", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", + "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", "dev": true }, "uglify-js": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.1.10.tgz", - "integrity": "sha512-0ul3BWx79We0mIPM1l72oqpMtWL0TVMnKZZY6FaHPy3tDzCZGXeFxw5N1ZvtkmQsLI+ECR/tUQyIYbyHUcuvEw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.2.0.tgz", + "integrity": "sha512-L98DlTshoPGnZGF8pr3MoE+CCo6n9joktHNHMPkckeBV8xTVc4CWtC0kGGhQsIvnX2Ug4nXFTAeE7SpTrPX2tg==", "dev": true, "requires": { - "commander": "2.11.0", + "commander": "2.12.1", "source-map": "0.6.1" }, "dependencies": { @@ -10444,18 +10444,18 @@ "find-cache-dir": "1.0.0", "schema-utils": "0.3.0", "source-map": "0.5.7", - "uglify-es": "3.1.10", - "webpack-sources": "1.0.2", + "uglify-es": "3.2.0", + "webpack-sources": "1.1.0", "worker-farm": "1.5.2" }, "dependencies": { "uglify-es": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.1.10.tgz", - "integrity": "sha512-RwBX0aOeHvO8MKKUeLCArQGb9OZ6xA+EqfVxsE9wqK0saFYFVLIFvHeeCOg61C6NO6KCuSiG9OjNjCA+OB4nzg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.2.0.tgz", + "integrity": "sha512-eD4rjK4o6rzrvE1SMZJLQFEVMnWRUyIu6phJ0BXk5TIthMmP5B4QP0HI8o3bkQB5wf1N4WHA0leZAQyQBAd+Jg==", "dev": true, "requires": { - "commander": "2.11.0", + "commander": "2.12.1", "source-map": "0.6.1" }, "dependencies": { @@ -10569,7 +10569,7 @@ "dev": true, "requires": { "loader-utils": "1.1.0", - "mime": "1.4.1", + "mime": "1.6.0", "schema-utils": "0.3.0" } }, @@ -10812,12 +10812,12 @@ "requires": { "acorn": "5.2.1", "acorn-dynamic-import": "2.0.2", - "ajv": "5.4.0", + "ajv": "5.5.0", "ajv-keywords": "2.1.1", "async": "2.6.0", "enhanced-resolve": "3.4.1", "escope": "3.6.0", - "interpret": "1.0.4", + "interpret": "1.1.0", "json-loader": "0.5.7", "json5": "0.5.1", "loader-runner": "2.3.0", @@ -10830,7 +10830,7 @@ "tapable": "0.2.8", "uglifyjs-webpack-plugin": "0.4.6", "watchpack": "1.4.0", - "webpack-sources": "1.0.2", + "webpack-sources": "1.1.0", "yargs": "8.0.2" }, "dependencies": { @@ -10985,7 +10985,7 @@ "requires": { "source-map": "0.5.7", "uglify-js": "2.8.29", - "webpack-sources": "1.0.2" + "webpack-sources": "1.1.0" } }, "which-module": { @@ -11146,22 +11146,22 @@ } }, "webpack-dev-middleware": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz", - "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", + "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", "dev": true, "requires": { "memory-fs": "0.4.1", - "mime": "1.4.1", + "mime": "1.6.0", "path-is-absolute": "1.0.1", "range-parser": "1.2.0", "time-stamp": "2.0.0" } }, "webpack-dev-server": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.4.tgz", - "integrity": "sha512-thrqC0EQEoSjXeYgP6pUXcUCZ+LNrKsDPn+mItLnn5VyyNZOJKd06hUP5vqkYwL8nWWXsii0loSF9NHNccT6ow==", + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.9.5.tgz", + "integrity": "sha512-o0lS6enIxyOPiRJTh8vcgK5TsGNTn7lH1q/pNniAgs46mCE8sQYeqv7Y/oAIh/+u4kiBsFizLJo5EWC+ezz6FQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -11189,7 +11189,7 @@ "spdy": "3.4.7", "strip-ansi": "3.0.1", "supports-color": "4.5.0", - "webpack-dev-middleware": "1.12.0", + "webpack-dev-middleware": "1.12.2", "yargs": "6.6.0" }, "dependencies": { @@ -11250,9 +11250,9 @@ } }, "webpack-sources": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.2.tgz", - "integrity": "sha512-Y7UddMCv6dGjy81nBv6nuQeFFIt5aalHm7uyDsAsW86nZwfOVPGRr3XMjEQLaT+WKo8rlzhC9qtbJvYKLtAwaw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", + "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", "dev": true, "requires": { "source-list-map": "2.0.0", diff --git a/package.json b/package.json index 1304195a..0f90ff55 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,10 @@ "homepage": "https://github.com/scttcper/ngx-toastr", "bugs": "https://github.com/scttcper/ngx-toastr/issues", "repository": "https://github.com/scttcper/ngx-toastr.git", - "version": "6.5.0", + "version": "7.0.0-beta.1", + "publishConfig": { + "tag": "next" + }, "license": "MIT", "scripts": { "ng": "ng", @@ -20,15 +23,15 @@ }, "private": true, "dependencies": { - "@angular/animations": "^4.4.6", - "@angular/common": "^4.4.6", - "@angular/compiler": "^4.4.6", - "@angular/core": "^4.4.6", - "@angular/forms": "^4.4.6", - "@angular/platform-browser": "^4.4.6", - "@angular/platform-browser-dynamic": "^4.4.6", - "@angular/router": "^4.4.6", - "bootstrap": "^4.0.0-beta", + "@angular/animations": "^5.0.3", + "@angular/common": "^5.0.3", + "@angular/compiler": "^5.0.3", + "@angular/core": "^5.0.3", + "@angular/forms": "^5.0.3", + "@angular/platform-browser": "^5.0.3", + "@angular/platform-browser-dynamic": "^5.0.3", + "@angular/router": "^5.0.3", + "bootstrap": "4.0.0-beta.2", "core-js": "^2.5.1", "lodash-es": "^4.17.4", "rxjs": "^5.5.2", @@ -36,15 +39,15 @@ "zone.js": "^0.8.18" }, "devDependencies": { - "@angular/cli": "1.5.3", - "@angular/compiler-cli": "^4.4.6", - "@angular/language-service": "^4.4.6", - "@types/jasmine": "^2.6.3", + "@angular/cli": "1.5.4", + "@angular/compiler-cli": "^5.0.3", + "@angular/language-service": "^5.0.3", + "@types/jasmine": "^2.8.2", "@types/jasminewd2": "^2.0.3", "@types/lodash-es": "^4.17.0", - "@types/node": "^8.0.51", + "@types/node": "^8.0.53", "bundlesize": "^0.15.3", - "codelyzer": "^3.2.2", + "codelyzer": "^4.0.1", "copy": "^0.3.1", "fs-extra": "^4.0.2", "jasmine-core": "^2.8.0", @@ -57,17 +60,17 @@ "karma-jasmine-html-reporter": "^0.2.2", "protractor": "^5.2.0", "rimraf": "^2.6.2", - "rollup": "^0.51.8", + "rollup": "^0.52.0", "rollup-plugin-filesize": "^1.5.0", "rollup-plugin-sourcemaps": "^0.4.2", "ts-node": "^3.3.0", "tslint": "^5.8.0", - "typescript": "^2.5.3" + "typescript": "^2.6.2" }, "bundlesize": [ { "path": "./dist/packages-dist/toastr.umd.js", - "maxSize": "8 kB" + "maxSize": "9 kB" }, { "path": "./dist/packages-dist/toastr.css", diff --git a/src/app/app.component.html b/src/app/app.component.html index d7eb5af8..08c7c52f 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -76,15 +76,19 @@ 0 is no limit +
+ +
-
- +
+ +
@@ -200,6 +204,9 @@

Example Custom Toasts:

+ diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 11ded8d3..6db3f07b 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,18 +1,18 @@ /* tslint:disable:no-use-before-declare */ -import { TestBed, async } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; +import { async, TestBed } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { CommonModule } from '@angular/common'; -import { ToastrModule, ActiveToast } from '../lib/public_api'; +import { ActiveToast, ToastrModule } from '../lib/public_api'; import { AppComponent } from './app.component'; -import { PinkToast } from './pink.toast'; -import { NotyfToast } from './notyf.toast'; import { FooterComponent } from './footer/footer.component'; -import { HeaderComponent } from './header/header.component'; import { GithubLinkComponent } from './github-link/github-link.component'; +import { HeaderComponent } from './header/header.component'; +import { NotyfToast } from './notyf.toast'; +import { PinkToast } from './pink.toast'; describe('AppComponent', () => { beforeEach(() => { @@ -47,7 +47,7 @@ describe('AppComponent', () => { const app = fixture.debugElement.componentInstance; const opened: ActiveToast = app.openToast(); expect(opened).toBeDefined(); - opened.onShown!.toPromise().then(() => { + opened.onShown.toPromise().then(() => { done(); }); }); @@ -56,7 +56,7 @@ describe('AppComponent', () => { const app = fixture.debugElement.componentInstance; const opened: ActiveToast = app.openToast(); expect(opened.portal).toBeDefined(); - opened.onHidden!.toPromise().then(() => { + opened.onHidden.toPromise().then(() => { done(); }); }); @@ -65,19 +65,19 @@ describe('AppComponent', () => { const app = fixture.debugElement.componentInstance; const opened: ActiveToast = app.openToast(); expect(opened.portal).toBeDefined(); - opened.onTap!.toPromise() + opened.onTap.toPromise() .then(() => { done(); }); - opened.portal!.instance.tapToast(); + opened.portal.instance.tapToast(); }); it('should extend life on mouseover and exit', (done) => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; const opened: ActiveToast = app.openToast(); - opened.portal!.instance.stickAround(); - opened.portal!.instance.delayedHideToast(); - expect(opened.portal!.instance.options.timeOut).toBe(1000); + opened.portal.instance.stickAround(); + opened.portal.instance.delayedHideToast(); + expect(opened.portal.instance.options.timeOut).toBe(1000); done(); }); it('should keep on mouse exit with extended timeout 0', (done) => { @@ -85,16 +85,16 @@ describe('AppComponent', () => { const app = fixture.debugElement.componentInstance; app.options.extendedTimeOut = 0; const opened: ActiveToast = app.openToast(); - opened.portal!.instance.stickAround(); - opened.portal!.instance.delayedHideToast(); - expect(opened.portal!.instance.options.timeOut).toBe(0); + opened.portal.instance.stickAround(); + opened.portal.instance.delayedHideToast(); + expect(opened.portal.instance.options.timeOut).toBe(0); done(); }); it('should trigger onShown for openPinkToast', (done) => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; const opened: ActiveToast = app.openPinkToast(); - opened.onShown!.toPromise().then(() => { + opened.onShown.toPromise().then(() => { done(); }); }); @@ -102,7 +102,7 @@ describe('AppComponent', () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; const opened: ActiveToast = app.openPinkToast(); - opened.onHidden!.toPromise().then(() => { + opened.onHidden.toPromise().then(() => { done(); }); }); @@ -110,7 +110,7 @@ describe('AppComponent', () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; const opened: ActiveToast = app.openNotyf(); - opened.onShown!.toPromise().then(() => { + opened.onShown.toPromise().then(() => { done(); }); }); @@ -118,7 +118,7 @@ describe('AppComponent', () => { const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; const opened: ActiveToast = app.openNotyf(); - opened.onHidden!.toPromise().then(() => { + opened.onHidden.toPromise().then(() => { done(); }); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 5d1a96fd..4d2cd812 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -2,11 +2,15 @@ import { Component, VERSION } from '@angular/core'; import { Title } from '@angular/platform-browser'; import { cloneDeep, random } from 'lodash-es'; -import { GlobalConfig, ToastrService } from '../lib/public_api'; import json from '../lib/package.json'; +import { + GlobalConfig, + ToastrService, + ToastNoAnimation, +} from '../lib/public_api'; -import { PinkToast } from './pink.toast'; import { NotyfToast } from './notyf.toast'; +import { PinkToast } from './pink.toast'; interface Quote { title?: string; @@ -16,17 +20,17 @@ interface Quote { const quotes: Quote[] = [ { title: 'Title', - message: 'Message' + message: 'Message', }, { title: '😃', - message: 'Supports Emoji' + message: 'Supports Emoji', }, { message: 'My name is Inigo Montoya. You killed my father. Prepare to die!', }, { - message: 'Titles are not always needed' + message: 'Titles are not always needed', }, { title: 'Title only 👊', @@ -50,21 +54,17 @@ export class AppComponent { version = VERSION; private lastInserted: number[] = []; - constructor( - public toastr: ToastrService, - private t: Title - ) { + constructor(public toastr: ToastrService, title: Title) { // sync options to toastrservice // this sets the options in the demo this.options = this.toastr.toastrConfig; - const current = t.getTitle(); + const current = title.getTitle(); // fix for tests if (json) { - t.setTitle(`${current} ${json.version}`); + title.setTitle(`${current}: v${json.version}`); } } - openToast() { - // Clone current config so it doesn't change when ngModel updates + getMessage() { let m: string | undefined = this.message; let t: string | undefined = this.title; if (!this.title.length && !this.message.length) { @@ -72,8 +72,36 @@ export class AppComponent { m = randomMessage.message; t = randomMessage.title; } + return { + message: m, + title: t, + }; + } + openToast() { + const { message, title } = this.getMessage(); + // Clone current config so it doesn't change when ngModel updates + const opt = cloneDeep(this.options); + const inserted = this.toastr.show( + message, + title, + opt, + this.options.iconClasses[this.type], + ); + if (inserted) { + this.lastInserted.push(inserted.toastId); + } + return inserted; + } + openToastNoAnimation() { + const { message, title } = this.getMessage(); const opt = cloneDeep(this.options); - const inserted = this.toastr[this.type](m, t, opt); + opt.toastComponent = ToastNoAnimation; + const inserted = this.toastr.show( + message, + title, + opt, + this.options.iconClasses[this.type], + ); if (inserted) { this.lastInserted.push(inserted.toastId); } @@ -83,14 +111,8 @@ export class AppComponent { const opt = cloneDeep(this.options); opt.toastComponent = PinkToast; opt.toastClass = 'pinktoast'; - let m: string | undefined = this.message; - let t: string | undefined = this.title; - if (!this.title.length && !this.message.length) { - const randomMessage = quotes[random(0, quotes.length - 1)]; - m = randomMessage.message || ''; - t = randomMessage.title; - } - const inserted = this.toastr.show(m, t, opt); + const { message, title } = this.getMessage(); + const inserted = this.toastr.show(message, title, opt); if (inserted && inserted.toastId) { this.lastInserted.push(inserted.toastId); } @@ -102,15 +124,8 @@ export class AppComponent { opt.toastClass = 'notyf confirm'; opt.positionClass = 'notyf-container'; this.options.newestOnTop = false; - let m: string | undefined = this.message; - let t: string | undefined = this.title; - if (!this.title.length && !this.message.length) { - const randomMessage = quotes[random(0, quotes.length - 1)]; - m = randomMessage.message; - t = randomMessage.title; - } - m = m || 'Success'; - const inserted = this.toastr.show(m, t, opt); + const { message, title } = this.getMessage(); + const inserted = this.toastr.show(message || 'Success', title, opt); if (inserted && inserted.toastId) { this.lastInserted.push(inserted.toastId); } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 453f598d..c832cb3b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,17 +1,17 @@ -import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { ToastrModule } from '../lib/public_api'; +import { ToastrModule, ToastNoAnimationModule } from '../lib/public_api'; import { AppComponent } from './app.component'; -import { PinkToast } from './pink.toast'; -import { NotyfToast } from './notyf.toast'; import { FooterComponent } from './footer/footer.component'; -import { HeaderComponent } from './header/header.component'; import { GithubLinkComponent } from './github-link/github-link.component'; -// import { ToastContainerModule } from '../lib/toast-directive'; +import { HeaderComponent } from './header/header.component'; +import { NotyfToast } from './notyf.toast'; +import { PinkToast } from './pink.toast'; +// import { ToastContainerModule } from '../lib/toast.directive'; @NgModule({ declarations: [ @@ -26,6 +26,7 @@ import { GithubLinkComponent } from './github-link/github-link.component'; BrowserModule, FormsModule, BrowserAnimationsModule, + ToastNoAnimationModule, ToastrModule.forRoot(), // ToastContainerModule.forRoot(), ], diff --git a/src/app/footer/footer.component.ts b/src/app/footer/footer.component.ts index 1c46e8db..84aa6921 100644 --- a/src/app/footer/footer.component.ts +++ b/src/app/footer/footer.component.ts @@ -4,7 +4,7 @@ import { Component, OnInit, VERSION } from '@angular/core'; selector: 'app-footer', template: `
- Demo using Angular {{version}} + Demo using Angular {{ version }}
Released under the MIT license. diff --git a/src/app/github-link/github-link.component.ts b/src/app/github-link/github-link.component.ts index 80f409cb..923b01a9 100644 --- a/src/app/github-link/github-link.component.ts +++ b/src/app/github-link/github-link.component.ts @@ -1,5 +1,5 @@ /* tslint:disable:max-line-length */ -import { Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; @Component({ selector: 'github-link', @@ -21,6 +21,7 @@ import { Component, Input } from '@angular/core';
`, + changeDetection: ChangeDetectionStrategy.OnPush, }) export class GithubLinkComponent { @Input() username = 'scttcper'; diff --git a/src/app/header/header.component.ts b/src/app/header/header.component.ts index 806e89ee..88397d77 100644 --- a/src/app/header/header.component.ts +++ b/src/app/header/header.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'app-header', @@ -21,12 +21,7 @@ import { Component, OnInit } from '@angular/core';

Easy Toasts for Angular

`, + changeDetection: ChangeDetectionStrategy.OnPush, }) -export class HeaderComponent implements OnInit { - - constructor() { } - - ngOnInit() { - } - +export class HeaderComponent { } diff --git a/src/app/notyf.toast.ts b/src/app/notyf.toast.ts index ac658f97..822ee688 100644 --- a/src/app/notyf.toast.ts +++ b/src/app/notyf.toast.ts @@ -1,14 +1,13 @@ -/* tslint:disable:no-access-missing-member */ -import { Component, ApplicationRef } from '@angular/core'; import { - trigger, - state, - transition, animate, + keyframes, + state, style, - keyframes + transition, + trigger } from '@angular/animations'; -import { Toast, ToastPackage, ToastrService, ToastRef } from '../lib/public_api'; +import { Component } from '@angular/core'; +import { Toast, ToastrService, ToastPackage } from '../lib/public_api'; @Component({ selector: '[notyf-toast-component]', @@ -18,7 +17,7 @@ import { Toast, ToastPackage, ToastrService, ToastRef } from '../lib/public_api'
-
{{message}}
+
{{ message }}
`, animations: [ @@ -75,9 +74,8 @@ export class NotyfToast extends Toast { // constructor is only necessary when not using AoT constructor( protected toastrService: ToastrService, - public toastPackage: ToastPackage, - protected appRef: ApplicationRef, + public toastPackage: ToastPackage ) { - super(toastrService, toastPackage, appRef); + super(toastrService, toastPackage); } } diff --git a/src/app/pink.toast.ts b/src/app/pink.toast.ts index ffd8c86c..c28fa3a5 100644 --- a/src/app/pink.toast.ts +++ b/src/app/pink.toast.ts @@ -1,15 +1,14 @@ -/* tslint:disable:no-access-missing-member */ -import { Component, ApplicationRef } from '@angular/core'; import { - trigger, - state, - transition, animate, + keyframes, + state, style, - keyframes + transition, + trigger } from '@angular/animations'; -import { DomSanitizer } from '@angular/platform-browser'; -import { Toast, ToastPackage, ToastrService, ToastRef } from '../lib/public_api'; +import { Component } from '@angular/core'; + +import { Toast, ToastrService, ToastPackage } from '../lib/public_api'; @Component({ selector: '[pink-toast-component]', @@ -34,17 +33,20 @@ import { Toast, ToastPackage, ToastrService, ToastRef } from '../lib/public_api' template: `
-
-
+
`, animations: [ @@ -90,6 +92,7 @@ import { Toast, ToastPackage, ToastrService, ToastRef } from '../lib/public_api' ]))), ]), ], + preserveWhitespaces: false, }) export class PinkToast extends Toast { // used for demo purposes @@ -99,9 +102,8 @@ export class PinkToast extends Toast { constructor( protected toastrService: ToastrService, public toastPackage: ToastPackage, - protected appRef: ApplicationRef, ) { - super(toastrService, toastPackage, appRef); + super(toastrService, toastPackage); } action(event: Event) { diff --git a/src/lib/overlay/overlay.ts b/src/lib/overlay/overlay.ts index cc23f513..6bae8130 100644 --- a/src/lib/overlay/overlay.ts +++ b/src/lib/overlay/overlay.ts @@ -1,9 +1,9 @@ -import { ComponentFactoryResolver, Injectable, ApplicationRef } from '@angular/core'; +import { ApplicationRef, ComponentFactoryResolver, Injectable } from '@angular/core'; import { DomPortalHost } from '../portal/dom-portal-host'; import { OverlayRef } from './overlay-ref'; +import { ToastContainerDirective } from '../toastr/toast.directive'; import { OverlayContainer } from './overlay-container'; -import { ToastContainerDirective } from '../toastr/toast-directive'; /** diff --git a/src/lib/package.json b/src/lib/package.json index 68602065..34cf3619 100644 --- a/src/lib/package.json +++ b/src/lib/package.json @@ -1,15 +1,18 @@ { "name": "ngx-toastr", - "version": "6.5.0", + "version": "7.0.0-beta.1", + "publishConfig": { + "tag": "next" + }, "description": "Toastr for Angular", "main": "./toastr.umd.js", "module": "./toastr.es5.js", "es2015": "./toastr.es2015.js", "typings": "./index.d.ts", "peerDependencies": { - "@angular/core": ">=4.3.0 <=6.0.0", - "@angular/common": ">=4.3.0 <=6.0.0", - "rxjs": "^5.4.0" + "@angular/core": ">=5.0.0 <=6.0.0", + "@angular/common": ">=5.0.0 <=6.0.0", + "rxjs": "^5.5.0" }, "repository": "https://github.com/scttcper/ngx-toastr.git", "homepage": "https://github.com/scttcper/ngx-toastr", diff --git a/src/lib/portal/dom-portal-host.ts b/src/lib/portal/dom-portal-host.ts index f61064d9..6240a8c4 100644 --- a/src/lib/portal/dom-portal-host.ts +++ b/src/lib/portal/dom-portal-host.ts @@ -1,8 +1,8 @@ import { + ApplicationRef, ComponentFactoryResolver, ComponentRef, EmbeddedViewRef, - ApplicationRef, } from '@angular/core'; import { BasePortalHost, ComponentPortal } from './portal'; diff --git a/src/lib/portal/portal.ts b/src/lib/portal/portal.ts index 42ffa758..607b2fb0 100644 --- a/src/lib/portal/portal.ts +++ b/src/lib/portal/portal.ts @@ -1,7 +1,7 @@ import { - ViewContainerRef, ComponentRef, - Injector + Injector, + ViewContainerRef } from '@angular/core'; export interface ComponentType { diff --git a/src/lib/public_api.ts b/src/lib/public_api.ts index 4ac44c4e..35b63da0 100644 --- a/src/lib/public_api.ts +++ b/src/lib/public_api.ts @@ -2,10 +2,11 @@ export * from './portal/portal'; export * from './overlay/overlay'; export * from './overlay/overlay-container'; export * from './overlay/overlay-ref'; -export * from './toastr/toast-directive'; -export * from './toastr/toast-component'; -export * from './toastr/toastr-service'; +export * from './toastr/toast.directive'; +export * from './toastr/toast.component'; +export * from './toastr/toastr.service'; export * from './toastr/toastr-config'; -export * from './toastr/toastr-module'; +export * from './toastr/toastr.module'; export * from './toastr/toast-injector'; export * from './toastr/toast-token'; +export * from './toastr/toast-noanimation.component'; diff --git a/src/lib/toastr.css b/src/lib/toastr.css index 6c65fc38..bf2eb788 100644 --- a/src/lib/toastr.css +++ b/src/lib/toastr.css @@ -21,9 +21,8 @@ font-size: 20px; font-weight: bold; color: #FFFFFF; - -webkit-text-shadow: 0 1px 0 #ffffff; text-shadow: 0 1px 0 #ffffff; - opacity: 0.8; + /* opacity: 0.8; */ } .toast-close-button:hover, .toast-close-button:focus { @@ -40,13 +39,10 @@ button.toast-close-button { cursor: pointer; background: transparent; border: 0; - -webkit-appearance: none; - -moz-appearance: none; } .toast-center-center { top: 50%; left: 50%; - -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); } .toast-top-center { @@ -89,11 +85,8 @@ button.toast-close-button { pointer-events: none; position: fixed; z-index: 999999; - /*overrides*/ } #toast-container * { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; box-sizing: border-box; } #toast-container .toast { @@ -102,20 +95,13 @@ button.toast-close-button { margin: 0 0 6px; padding: 15px 15px 15px 50px; width: 300px; - -moz-border-radius: 3px 3px 3px 3px; - -webkit-border-radius: 3px 3px 3px 3px; border-radius: 3px 3px 3px 3px; background-position: 15px center; background-repeat: no-repeat; - -moz-box-shadow: 0 0 12px #999999; - -webkit-box-shadow: 0 0 12px #999999; box-shadow: 0 0 12px #999999; color: #FFFFFF; - opacity: 0.8; } #toast-container .toast:hover { - -moz-box-shadow: 0 0 12px #000000; - -webkit-box-shadow: 0 0 12px #000000; box-shadow: 0 0 12px #000000; opacity: 1; cursor: pointer; diff --git a/src/lib/toastr/default-config.ts b/src/lib/toastr/default-config.ts index 829e9ebf..40cb80eb 100644 --- a/src/lib/toastr/default-config.ts +++ b/src/lib/toastr/default-config.ts @@ -1,5 +1,5 @@ +import { Toast } from './toast.component'; import { GlobalConfig } from './toastr-config'; -import { Toast } from './toast-component'; export class DefaultGlobalConfig implements GlobalConfig { // Global @@ -25,6 +25,8 @@ export class DefaultGlobalConfig implements GlobalConfig { positionClass = 'toast-top-right'; titleClass = 'toast-title'; messageClass = 'toast-message'; + easing = 'ease-in'; + easeTime = 300; tapToDismiss = true; onActivateTick = false; progressAnimation: 'decreasing' | 'increasing' = 'decreasing'; diff --git a/src/lib/toastr/toast-injector.ts b/src/lib/toastr/toast-injector.ts index 6bc3ad92..bd06db23 100644 --- a/src/lib/toastr/toast-injector.ts +++ b/src/lib/toastr/toast-injector.ts @@ -13,9 +13,11 @@ export class ToastRef { componentInstance: T; /** Subject for notifying the user that the toast has finished closing. */ - private _afterClosed: Subject = new Subject(); - private _activate: Subject = new Subject(); - private _manualClose: Subject = new Subject(); + private _afterClosed = new Subject(); + /** triggered when toast is activated */ + private _activate = new Subject(); + /** notifies the toast that it should close before the timeout */ + private _manualClose = new Subject(); constructor(private _overlayRef: OverlayRef) { } @@ -35,6 +37,8 @@ export class ToastRef { this._overlayRef.detach(); this._afterClosed.next(); this._afterClosed.complete(); + this._manualClose.complete(); + this._activate.complete(); } /** Gets an observable that is notified when the toast is finished closing. */ diff --git a/src/lib/toastr/toast-noanimation.component.ts b/src/lib/toastr/toast-noanimation.component.ts new file mode 100644 index 00000000..61aa4678 --- /dev/null +++ b/src/lib/toastr/toast-noanimation.component.ts @@ -0,0 +1,177 @@ +import { CommonModule } from '@angular/common'; +import { + ApplicationRef, + Component, + HostBinding, + HostListener, + NgModule, + OnDestroy, +} from '@angular/core'; +import { SafeHtml } from '@angular/platform-browser'; + +import { Subscription } from 'rxjs/Subscription'; + +import { IndividualConfig, ToastPackage } from './toastr-config'; +import { ToastrService } from './toastr.service'; + +@Component({ + selector: '[toast-component]', + template: ` + +
+ {{ title }} +
+
+
+
+ {{ message }} +
+
+
+
+ `, +}) +export class ToastNoAnimation implements OnDestroy { + message?: string | SafeHtml | null; + title?: string; + options: IndividualConfig; + /** width of progress bar */ + width = -1; + /** a combination of toast type and options.toastClass */ + @HostBinding('class') toastClasses = ''; + /** controls animation */ + state = 'inactive'; + private timeout: any; + private intervalId: any; + private hideTime: number; + private sub: Subscription; + private sub1: Subscription; + + constructor( + protected toastrService: ToastrService, + public toastPackage: ToastPackage, + protected appRef: ApplicationRef, + ) { + this.message = toastPackage.message; + this.title = toastPackage.title; + this.options = toastPackage.config; + this.toastClasses = `${toastPackage.toastType} ${ + toastPackage.config.toastClass + }`; + this.sub = toastPackage.toastRef.afterActivate().subscribe(() => { + this.activateToast(); + }); + this.sub1 = toastPackage.toastRef.manualClosed().subscribe(() => { + this.remove(); + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + this.sub1.unsubscribe(); + clearInterval(this.intervalId); + clearTimeout(this.timeout); + } + /** + * activates toast and sets timeout + */ + activateToast() { + this.state = 'active'; + if (this.options.timeOut) { + this.timeout = setTimeout(() => { + this.remove(); + }, this.options.timeOut); + this.hideTime = new Date().getTime() + this.options.timeOut; + if (this.options.progressBar) { + this.intervalId = setInterval(() => this.updateProgress(), 10); + } + } + if (this.options.onActivateTick) { + this.appRef.tick(); + } + } + /** + * updates progress bar width + */ + updateProgress() { + if (this.width === 0 || this.width === 100 || !this.options.timeOut) { + return; + } + const now = new Date().getTime(); + const remaining = this.hideTime - now; + this.width = remaining / this.options.timeOut * 100; + if (this.options.progressAnimation === 'increasing') { + this.width = 100 - this.width; + } + if (this.width <= 0) { + this.width = 0; + } + if (this.width >= 100) { + this.width = 100; + } + } + + /** + * tells toastrService to remove this toast after animation time + */ + remove() { + if (this.state === 'removed') { + return; + } + clearTimeout(this.timeout); + this.state = 'removed'; + this.timeout = setTimeout( + () => this.toastrService.remove(this.toastPackage.toastId), + ); + } + @HostListener('click') + tapToast() { + if (this.state === 'removed') { + return; + } + this.toastPackage.triggerTap(); + if (this.options.tapToDismiss) { + this.remove(); + } + } + @HostListener('mouseenter') + stickAround() { + if (this.state === 'removed') { + return; + } + clearTimeout(this.timeout); + this.options.timeOut = 0; + this.hideTime = 0; + + // disable progressBar + clearInterval(this.intervalId); + this.width = 0; + } + @HostListener('mouseleave') + delayedHideToast() { + if (this.options.extendedTimeOut === 0 || this.state === 'removed') { + return; + } + this.timeout = setTimeout( + () => this.remove(), + this.options.extendedTimeOut, + ); + this.options.timeOut = this.options.extendedTimeOut; + this.hideTime = new Date().getTime() + (this.options.timeOut || 0); + this.width = 100; + if (this.options.progressBar) { + this.intervalId = setInterval(() => this.updateProgress(), 10); + } + } +} + +@NgModule({ + imports: [CommonModule], + declarations: [ToastNoAnimation], + exports: [ToastNoAnimation], + entryComponents: [ToastNoAnimation], +}) +export class ToastNoAnimationModule {} diff --git a/src/lib/toastr/toast-token.ts b/src/lib/toastr/toast-token.ts index b90e9e82..6fc5a4d3 100644 --- a/src/lib/toastr/toast-token.ts +++ b/src/lib/toastr/toast-token.ts @@ -2,4 +2,9 @@ import { InjectionToken } from '@angular/core'; import { GlobalConfig } from './toastr-config'; -export const TOAST_CONFIG = new InjectionToken('ToastConfig'); +export interface ToastToken { + config: GlobalConfig; + defaults: any; +} + +export const TOAST_CONFIG = new InjectionToken('ToastConfig'); diff --git a/src/lib/toastr/toast-component.ts b/src/lib/toastr/toast.component.ts similarity index 74% rename from src/lib/toastr/toast-component.ts rename to src/lib/toastr/toast.component.ts index 955eeb34..c806fc3a 100644 --- a/src/lib/toastr/toast-component.ts +++ b/src/lib/toastr/toast.component.ts @@ -1,25 +1,22 @@ +import { + animate, + state, + style, + transition, + trigger, +} from '@angular/animations'; import { Component, - OnDestroy, HostBinding, HostListener, - ApplicationRef, + OnDestroy, } from '@angular/core'; -import { - trigger, - state, - transition, - animate, - style, -} from '@angular/animations'; import { SafeHtml } from '@angular/platform-browser'; import { Subscription } from 'rxjs/Subscription'; -import { Subject } from 'rxjs/Subject'; -import { ToastPackage, IndividualConfig } from './toastr-config'; -import { ToastrService } from './toastr-service'; -import { ToastRef } from './toast-injector'; +import { IndividualConfig, ToastPackage } from './toastr-config'; +import { ToastrService } from './toastr.service'; @Component({ selector: '[toast-component]', @@ -27,30 +24,37 @@ import { ToastRef } from './toast-injector'; -
- {{title}} +
+ {{ title }}
-
+
-
- {{message}} +
+ {{ message }}
-
+
`, animations: [ trigger('flyInOut', [ state('inactive', style({ display: 'none', - opacity: 0 + opacity: 0, })), state('active', style({ opacity: 1 })), state('removed', style({ opacity: 0 })), - transition('inactive => active', animate('300ms ease-in')), - transition('active => removed', animate('300ms ease-in')), + transition('inactive => active', + animate('{{ easeTime }}ms {{ easing }}') + ), + transition('active => removed', + animate('{{ easeTime }}ms {{ easing }}'), + ), ]), ], + preserveWhitespaces: false, }) export class Toast implements OnDestroy { message?: string | SafeHtml | null; @@ -61,7 +65,13 @@ export class Toast implements OnDestroy { /** a combination of toast type and options.toastClass */ @HostBinding('class') toastClasses = ''; /** controls animation */ - @HostBinding('@flyInOut') state = 'inactive'; + @HostBinding('@flyInOut') state = { + value: 'inactive', + params: { + easeTime: this.toastPackage.config.easeTime, + easing: 'ease-in', + }, + }; private timeout: any; private intervalId: any; private hideTime: number; @@ -71,7 +81,6 @@ export class Toast implements OnDestroy { constructor( protected toastrService: ToastrService, public toastPackage: ToastPackage, - protected appRef: ApplicationRef, ) { this.message = toastPackage.message; this.title = toastPackage.title; @@ -94,7 +103,7 @@ export class Toast implements OnDestroy { * activates toast and sets timeout */ activateToast() { - this.state = 'active'; + this.state = { ...this.state, value: 'active' }; if (this.options.timeOut) { this.timeout = setTimeout(() => { this.remove(); @@ -104,9 +113,6 @@ export class Toast implements OnDestroy { this.intervalId = setInterval(() => this.updateProgress(), 10); } } - if (this.options.onActivateTick) { - this.appRef.tick(); - } } /** * updates progress bar width @@ -133,19 +139,19 @@ export class Toast implements OnDestroy { * tells toastrService to remove this toast after animation time */ remove() { - if (this.state === 'removed') { + if (this.state.value === 'removed') { return; } clearTimeout(this.timeout); - this.state = 'removed'; + this.state = {...this.state, value: 'removed'}; this.timeout = setTimeout(() => this.toastrService.remove(this.toastPackage.toastId), - 300, + this.toastPackage.config.easeTime, ); } @HostListener('click') tapToast() { - if (this.state === 'removed') { + if (this.state.value === 'removed') { return; } this.toastPackage.triggerTap(); @@ -155,7 +161,7 @@ export class Toast implements OnDestroy { } @HostListener('mouseenter') stickAround() { - if (this.state === 'removed') { + if (this.state.value === 'removed') { return; } clearTimeout(this.timeout); @@ -168,7 +174,7 @@ export class Toast implements OnDestroy { } @HostListener('mouseleave') delayedHideToast() { - if (this.options.extendedTimeOut === 0 || this.state === 'removed') { + if (this.options.extendedTimeOut === 0 || this.state.value === 'removed') { return; } this.timeout = setTimeout(() => this.remove(), this.options.extendedTimeOut); diff --git a/src/lib/toastr/toast-directive.ts b/src/lib/toastr/toast.directive.ts similarity index 95% rename from src/lib/toastr/toast-directive.ts rename to src/lib/toastr/toast.directive.ts index c30517f0..d135caf9 100644 --- a/src/lib/toastr/toast-directive.ts +++ b/src/lib/toastr/toast.directive.ts @@ -1,8 +1,7 @@ import { - NgModule, - ModuleWithProviders, Directive, ElementRef, + NgModule, } from '@angular/core'; @Directive({ diff --git a/src/lib/toastr/toastr-config.ts b/src/lib/toastr/toastr-config.ts index 01e8fd92..5544154b 100644 --- a/src/lib/toastr/toastr-config.ts +++ b/src/lib/toastr/toastr-config.ts @@ -1,10 +1,9 @@ import { SafeHtml } from '@angular/platform-browser'; -import { Subject } from 'rxjs/Subject'; import { Observable } from 'rxjs/Observable'; +import { Subject } from 'rxjs/Subject'; import { ComponentType } from '../portal/portal'; -import { Toast } from './toast-component'; import { ToastRef } from './toast-injector'; /** @@ -63,6 +62,16 @@ import { ToastRef } from './toast-injector'; * default: toast-title */ messageClass: string; + /** + * animation easing on toast + * default: ease-in + */ + easing: string; + /** + * animation ease time on toast + * default: 300 + */ + easeTime: string | number; /** * clicking on toast dismisses it * default: true @@ -120,8 +129,8 @@ export interface GlobalConfig extends IndividualConfig { * Everything a toast needs to launch */ export class ToastPackage { - private _onTap: Subject = new Subject(); - private _onAction: Subject = new Subject(); + private _onTap = new Subject(); + private _onAction = new Subject(); constructor( public toastId: number, @@ -130,7 +139,12 @@ export class ToastPackage { public title: string | undefined, public toastType: string, public toastRef: ToastRef, - ) { } + ) { + this.toastRef.afterClosed().subscribe(() => { + this._onAction.complete(); + this._onTap.complete(); + }); + } /** Fired on click */ triggerTap() { @@ -145,13 +159,11 @@ export class ToastPackage { /** available for use in custom toast */ triggerAction(action?: any) { this._onAction.next(action); - this._onAction.complete(); } onAction(): Observable { return this._onAction.asObservable(); } - } /* tslint:disable:no-empty-interface */ diff --git a/src/lib/toastr/toastr-module.ts b/src/lib/toastr/toastr.module.ts similarity index 79% rename from src/lib/toastr/toastr-module.ts rename to src/lib/toastr/toastr.module.ts index 8d1f2708..66e97e73 100644 --- a/src/lib/toastr/toastr-module.ts +++ b/src/lib/toastr/toastr.module.ts @@ -1,17 +1,18 @@ +import { CommonModule } from '@angular/common'; import { - NgModule, ModuleWithProviders, - SkipSelf, + NgModule, Optional, + SkipSelf, } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { Toast } from './toast-component'; +import { Overlay } from '../overlay/overlay'; +import { OverlayContainer } from '../overlay/overlay-container'; +import { DefaultGlobalConfig } from './default-config'; import { TOAST_CONFIG } from './toast-token'; -import { ToastrService } from './toastr-service'; +import { Toast } from './toast.component'; import { GlobalConfig } from './toastr-config'; -import { OverlayContainer } from '../overlay/overlay-container'; -import { Overlay } from '../overlay/overlay'; +import { ToastrService } from './toastr.service'; @NgModule({ @@ -30,11 +31,11 @@ export class ToastrModule { return { ngModule: ToastrModule, providers: [ - { provide: TOAST_CONFIG, useValue: config }, + { provide: TOAST_CONFIG, useValue: { config, defaults: DefaultGlobalConfig } }, OverlayContainer, Overlay, ToastrService, - ] + ], }; } } diff --git a/src/lib/toastr/toastr-service.ts b/src/lib/toastr/toastr.service.ts similarity index 77% rename from src/lib/toastr/toastr-service.ts rename to src/lib/toastr/toastr.service.ts index f1544861..54e16c56 100644 --- a/src/lib/toastr/toastr-service.ts +++ b/src/lib/toastr/toastr.service.ts @@ -6,52 +6,61 @@ import { SecurityContext, } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; -import { Observable } from 'rxjs/Observable'; +import { Observable } from 'rxjs/Observable'; import { Overlay } from '../overlay/overlay'; import { ComponentPortal } from '../portal/portal'; -import { DefaultGlobalConfig } from './default-config'; -import { ToastContainerDirective } from './toast-directive'; -import { ToastRef, ToastInjector } from './toast-injector'; -import { TOAST_CONFIG } from './toast-token'; +import { ToastInjector, ToastRef } from './toast-injector'; +import { ToastToken, TOAST_CONFIG } from './toast-token'; +import { ToastContainerDirective } from './toast.directive'; import { GlobalConfig, IndividualConfig, - ToastrIconClasses, ToastPackage, } from './toastr-config'; export interface ActiveToast { - toastId?: number; - message?: string; - portal?: ComponentRef; + /** Your Toast ID. Use this to close it individually */ + toastId: number; + /** the message of your toast. Stored to prevent duplicates */ + message: string; + /** a reference to the component see portal.ts */ + portal: ComponentRef; + /** a reference to your toast */ toastRef: ToastRef; - onShown?: Observable; - onHidden?: Observable; - onTap?: Observable; - onAction?: Observable; + /** triggered when toast is active */ + onShown: Observable; + /** triggered when toast is destroyed */ + onHidden: Observable; + /** triggered on toast click */ + onTap: Observable; + /** available for your use in custom toast */ + onAction: Observable; } @Injectable() export class ToastrService { toastrConfig: GlobalConfig; - private index = 0; - private previousToastMessage?: string; currentlyActive = 0; toasts: ActiveToast[] = []; overlayContainer: ToastContainerDirective; + previousToastMessage: string | undefined; + private index = 0; constructor( - @Inject(TOAST_CONFIG) toastrConfig: GlobalConfig, + @Inject(TOAST_CONFIG) token: ToastToken, private overlay: Overlay, private _injector: Injector, private sanitizer: DomSanitizer, ) { - const defaultConfig = new DefaultGlobalConfig; - this.toastrConfig = { ...defaultConfig, ...toastrConfig }; - this.toastrConfig.iconClasses = { ...defaultConfig.iconClasses, ...toastrConfig.iconClasses }; + const defaultConfig = new token.defaults; + this.toastrConfig = { ...defaultConfig, ...token.config }; + this.toastrConfig.iconClasses = { + ...defaultConfig.iconClasses, + ...token.config.iconClasses, + }; } /** show toast */ show(message?: string, title?: string, override: Partial = {}, type = '') { @@ -59,22 +68,22 @@ export class ToastrService { } /** show successful toast */ success(message?: string, title?: string, override: Partial = {}) { - const type = this.toastrConfig.iconClasses!.success || ''; + const type = this.toastrConfig.iconClasses.success || ''; return this._buildNotification(type, message, title, this.applyConfig(override)); } /** show error toast */ error(message?: string, title?: string, override: Partial = {}) { - const type = this.toastrConfig.iconClasses!.error || ''; + const type = this.toastrConfig.iconClasses.error || ''; return this._buildNotification(type, message, title, this.applyConfig(override)); } /** show info toast */ info(message?: string, title?: string, override: Partial = {}) { - const type = this.toastrConfig.iconClasses!.info || ''; + const type = this.toastrConfig.iconClasses.info || ''; return this._buildNotification(type, message, title, this.applyConfig(override)); } /** show warning toast */ warning(message?: string, title?: string, override: Partial = {}) { - const type = this.toastrConfig.iconClasses!.warning || ''; + const type = this.toastrConfig.iconClasses.warning || ''; return this._buildNotification(type, message, title, this.applyConfig(override)); } /** @@ -186,24 +195,32 @@ export class ToastrService { toastType, toastRef, ); + const toastInjector = new ToastInjector(toastPackage, this._injector); + const component = new ComponentPortal(config.toastComponent, toastInjector); const ins: ActiveToast = { toastId: this.index, - message, + message: message || '', toastRef, onShown: toastRef.afterActivate(), onHidden: toastRef.afterClosed(), onTap: toastPackage.onTap(), onAction: toastPackage.onAction(), + portal: overlayRef.attach(component, this.toastrConfig.newestOnTop), }; - const toastInjector = new ToastInjector(toastPackage, this._injector); - const component = new ComponentPortal(config.toastComponent, toastInjector); - ins.portal = overlayRef.attach(component, this.toastrConfig.newestOnTop); + if (!keepInactive) { + // Trigger change detection if onActivateTick is set to true + if (config.onActivateTick && ins.onShown) { + ins.onShown.subscribe(() => { + ins.portal.changeDetectorRef.detectChanges(); + }); + } setTimeout(() => { ins.toastRef.activate(); this.currentlyActive = this.currentlyActive + 1; }); } + this.toasts.push(ins); return ins; } diff --git a/src/lib/tsconfig-build.json b/src/lib/tsconfig-build.json index 4046c31d..a76b97c3 100644 --- a/src/lib/tsconfig-build.json +++ b/src/lib/tsconfig-build.json @@ -12,7 +12,7 @@ "declaration": false, "removeComments": false, "strictNullChecks": true, - "lib": ["es2015", "dom"], + "lib": ["es2015", "dom", "es2015.promise", "es2015.collection", "es2015.iterable"], "skipLibCheck": true, "moduleResolution": "node" }, @@ -20,11 +20,11 @@ "public_api.ts" ], "angularCompilerOptions": { - "annotateForClosureCompiler": true, "skipTemplateCodegen": true, "strictMetadataEmit": true, "enableSummariesForJit": true, "flatModuleOutFile": "index.js", - "flatModuleId": "ngx-toastr" + "flatModuleId": "ngx-toastr", + "annotationsAs": "decorators" } } diff --git a/src/lib/tsconfig-esm.json b/src/lib/tsconfig-esm.json index b41bcf22..4bfe138a 100644 --- a/src/lib/tsconfig-esm.json +++ b/src/lib/tsconfig-esm.json @@ -3,18 +3,17 @@ "compilerOptions": { "target": "es5", "outDir": "../../dist/es5", - "declaration": true, - "removeComments": false + "declaration": true }, "files": [ "public_api.ts" ], "angularCompilerOptions": { - "annotateForClosureCompiler": true, "skipTemplateCodegen": true, "strictMetadataEmit": true, "enableSummariesForJit": true, "flatModuleOutFile": "index.js", - "flatModuleId": "ngx-toastr" + "flatModuleId": "ngx-toastr", + "annotationsAs": "decorators" } } diff --git a/src/polyfills.ts b/src/polyfills.ts index 2fbb9c9c..89b4daa7 100644 --- a/src/polyfills.ts +++ b/src/polyfills.ts @@ -33,30 +33,29 @@ // import 'core-js/es6/map'; // import 'core-js/es6/weak-map'; // import 'core-js/es6/set'; - /** IE10 and IE11 requires the following for NgClass support on SVG elements */ // import 'classlist.js'; // Run `npm install --save classlist.js`. +/** IE10 and IE11 requires the following for the Reflect API. */ +// import 'core-js/es6/reflect'; /** Evergreen browsers require these. **/ -import 'core-js/es6/reflect'; +// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. import 'core-js/es7/reflect'; /** - * Required to support Web Animations `@angular/animation`. + * Required to support Web Animations `@angular/platform-browser/animations`. * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation **/ import 'web-animations-js'; // Run `npm install --save web-animations-js`. - /*************************************************************************************************** * Zone JS is required by Angular itself. */ import 'zone.js/dist/zone'; // Included with Angular CLI. - /*************************************************************************************************** * APPLICATION IMPORTS */ diff --git a/src/styles.scss b/src/styles.scss index ce14b1a4..29f9b2ec 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,37 +1,39 @@ -@import "node_modules/bootstrap/scss/functions"; -@import "node_modules/bootstrap/scss/variables"; -@import "node_modules/bootstrap/scss/mixins"; -@import "node_modules/bootstrap/scss/print"; -@import "node_modules/bootstrap/scss/reboot"; -@import "node_modules/bootstrap/scss/type"; -// @import "node_modules/bootstrap/scss/images"; -// @import "node_modules/bootstrap/scss/code"; -@import "node_modules/bootstrap/scss/grid"; -// @import "node_modules/bootstrap/scss/tables"; -@import "node_modules/bootstrap/scss/forms"; -@import "node_modules/bootstrap/scss/buttons"; -@import "node_modules/bootstrap/scss/transitions"; -// @import "node_modules/bootstrap/scss/dropdown"; -// @import "node_modules/bootstrap/scss/button-group"; -// @import "node_modules/bootstrap/scss/input-group"; -// @import "node_modules/bootstrap/scss/custom-forms"; -// @import "node_modules/bootstrap/scss/nav"; -// @import "node_modules/bootstrap/scss/navbar"; -@import "node_modules/bootstrap/scss/card"; -// @import "node_modules/bootstrap/scss/breadcrumb"; -// @import "node_modules/bootstrap/scss/pagination"; -// @import "node_modules/bootstrap/scss/badge"; -// @import "node_modules/bootstrap/scss/jumbotron"; -// @import "node_modules/bootstrap/scss/alert"; -// @import "node_modules/bootstrap/scss/progress"; -// @import "node_modules/bootstrap/scss/media"; -// @import "node_modules/bootstrap/scss/list-group"; -// @import "node_modules/bootstrap/scss/close"; -// @import "node_modules/bootstrap/scss/modal"; -// @import "node_modules/bootstrap/scss/tooltip"; -// @import "node_modules/bootstrap/scss/popover"; -// @import "node_modules/bootstrap/scss/carousel"; -@import "node_modules/bootstrap/scss/utilities"; +@import "~bootstrap/scss/functions"; +@import "~bootstrap/scss/variables"; +$enable-shadows: true; +$enable-gradients: true; +@import "~bootstrap/scss/mixins"; +@import "~bootstrap/scss/print"; +@import "~bootstrap/scss/reboot"; +@import "~bootstrap/scss/type"; +// @import "~bootstrap/scss/images"; +// @import "~bootstrap/scss/code"; +@import "~bootstrap/scss/grid"; +// @import "~bootstrap/scss/tables"; +@import "~bootstrap/scss/forms"; +@import "~bootstrap/scss/buttons"; +@import "~bootstrap/scss/transitions"; +// @import "~bootstrap/scss/dropdown"; +// @import "~bootstrap/scss/button-group"; +// @import "~bootstrap/scss/input-group"; +// @import "~bootstrap/scss/custom-forms"; +// @import "~bootstrap/scss/nav"; +// @import "~bootstrap/scss/navbar"; +@import "~bootstrap/scss/card"; +// @import "~bootstrap/scss/breadcrumb"; +// @import "~bootstrap/scss/pagination"; +// @import "~bootstrap/scss/badge"; +// @import "~bootstrap/scss/jumbotron"; +// @import "~bootstrap/scss/alert"; +// @import "~bootstrap/scss/progress"; +// @import "~bootstrap/scss/media"; +// @import "~bootstrap/scss/list-group"; +// @import "~bootstrap/scss/close"; +// @import "~bootstrap/scss/modal"; +// @import "~bootstrap/scss/tooltip"; +// @import "~bootstrap/scss/popover"; +// @import "~bootstrap/scss/carousel"; +@import "~bootstrap/scss/utilities"; @import "notyf.css"; @@ -48,7 +50,13 @@ strong { .btn-pink { color: #FFFFFF; - background-color: #FF69B4; - border-color: #F013B1; - background-image: linear-gradient(#ea7be2, #f50079 6%, #ff1493); + background-color: $pink; + border-color: $pink; + background: $pink linear-gradient(180deg, $pink, darken($pink, 10%)) repeat-x; + border-color: $pink; +} +.btn-pink:hover { + background-color: darken($pink, 10%); + background: darken($pink, 10%) linear-gradient(180deg, darken($pink, 5%), darken($pink, 15%)) repeat-x; + border-color: darken($pink, 10%); } diff --git a/src/test.ts b/src/test.ts index 237bf3c6..046d04ee 100644 --- a/src/test.ts +++ b/src/test.ts @@ -1,12 +1,12 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files -import 'rxjs/add/operator/toPromise'; - +/* tslint:disable:ordered-imports */ import 'zone.js/dist/long-stack-trace-zone'; import 'zone.js/dist/proxy.js'; import 'zone.js/dist/sync-test'; import 'zone.js/dist/jasmine-patch'; import 'zone.js/dist/async-test'; import 'zone.js/dist/fake-async-test'; + import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, diff --git a/tsconfig.json b/tsconfig.json index 19b5d6e9..a6c016bf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,20 +2,17 @@ "compileOnSave": false, "compilerOptions": { "outDir": "./dist/out-tsc", - "baseUrl": "src", "sourceMap": true, "declaration": false, "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es5", - "skipLibCheck": true, - "strictNullChecks": true, "typeRoots": [ "node_modules/@types" ], "lib": [ - "es2016", + "es2017", "dom" ] } diff --git a/tslint.json b/tslint.json index 2ab4cda8..f6e73de5 100644 --- a/tslint.json +++ b/tslint.json @@ -1,33 +1,19 @@ { - "rulesDirectory": [ - "node_modules/codelyzer" - ], + "rulesDirectory": ["node_modules/codelyzer"], "rules": { "arrow-return-shorthand": true, "callable-types": true, "class-name": true, - "comment-format": [ - true, - "check-space" - ], + "comment-format": [true, "check-space"], "curly": true, "eofline": true, "forin": true, - "import-blacklist": [ - true, - "rxjs" - ], + "import-blacklist": [true, "rxjs", "rxjs/Rx"], "import-spacing": true, - "indent": [ - true, - "spaces" - ], + "indent": [true, "spaces"], "interface-over-type-literal": true, "label-position": true, - "max-line-length": [ - true, - 140 - ], + "max-line-length": [true, 140], "member-access": false, "member-ordering": [ true, @@ -42,26 +28,16 @@ ], "no-arg": true, "no-bitwise": true, - "no-console": [ - true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], + "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], "no-construct": true, "no-debugger": true, "no-duplicate-super": true, "no-empty": false, "no-empty-interface": true, "no-eval": true, - "no-inferrable-types": [ - true, - "ignore-params" - ], + "no-inferrable-types": [true, "ignore-params"], "no-misused-new": true, - "no-non-null-assertion": false, + "no-non-null-assertion": true, "no-shadowed-variable": true, "no-string-literal": false, "no-string-throw": true, @@ -80,19 +56,10 @@ "check-whitespace" ], "prefer-const": true, - "quotemark": [ - true, - "single" - ], + "quotemark": [true, "single"], "radix": true, - "semicolon": [ - true, - "always" - ], - "triple-equals": [ - true, - "allow-null-check" - ], + "semicolon": [true, "always"], + "triple-equals": [true, "allow-null-check"], "typedef-whitespace": [ true, { @@ -114,18 +81,10 @@ "check-separator", "check-type" ], - // "directive-selector": [ - // true, - // "attribute", - // "app", - // "camelCase" - // ], - // "component-selector": [ - // true, - // "element", - // "app", - // "kebab-case" - // ], + "directive-selector": [false, "attribute", "app", "camelCase"], + "component-selector": [false, "element", "app", "kebab-case"], + "angular-whitespace": [true, "check-interpolation"], + "no-output-on-prefix": true, "use-input-property-decorator": true, "use-output-property-decorator": true, "use-host-property-decorator": true, @@ -133,10 +92,15 @@ "no-output-rename": true, "use-life-cycle-interface": true, "use-pipe-transform-interface": true, - // "component-class-suffix": true, + "component-class-suffix": false, "directive-class-suffix": true, - "no-access-missing-member": true, - "templates-use-public": true, - "invoke-injectable": true + "no-unused-variable": true, + "ordered-imports": [ + true, + { + "import-sources-order": "lowercase-last", + "named-imports-order": "lowercase-first" + } + ] } }