├── .editorconfig ├── .firebaserc ├── .gitignore ├── .prettierrc ├── .stylelintrc.json ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── angular.json ├── apps └── animations-demo │ ├── browserslist │ └── src │ ├── app │ ├── app.component.css │ ├── app.component.html │ ├── app.component.ts │ └── app.module.ts │ ├── assets │ └── .gitkeep │ ├── environments │ ├── environment.prod.ts │ └── environment.ts │ ├── favicon.ico │ ├── index.html │ ├── main.ts │ ├── polyfills.ts │ ├── styles.css │ ├── tsconfig.app.json │ └── typings.d.ts ├── firebase.json ├── karma.conf.js ├── libs └── ngx-animations │ ├── browserslist │ ├── index.ts │ ├── package.json │ ├── public_api.ts │ └── src │ ├── animations.ts │ ├── directives │ ├── README.md │ ├── bounce-in-and-out.directive.ts │ ├── fade-in-and-out.directive.ts │ ├── grow-in-shrink-out.directive.ts │ ├── index.ts │ └── swing-in-and-out.directive.ts │ ├── models.ts │ └── ngx-animations.module.ts ├── package-lock.json ├── package.json ├── test.js ├── tsconfig.json ├── tsconfig.spec.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.firebaserc: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | testem.log 34 | /typings 35 | 36 | # e2e 37 | /e2e/*.js 38 | /e2e/*.map 39 | 40 | # System Files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "stylelint-config-standard", 3 | "rules": { 4 | "at-rule-no-unknown": null, 5 | "no-empty-source": null, 6 | "selector-pseudo-element-no-unknown": null, 7 | "selector-type-no-unknown": null 8 | } 9 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "customizability", 4 | "params" 5 | ] 6 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Hyland Software, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ngx-animations 2 | ngx-animations is the quickest way to get started with Angular animations - without writing your own animations! 3 | 4 | Specifically, this package specializes in animations that can be used when adding or removing items from a list. 5 | 6 | You can view a demo of the site [here](https://ngx-animations-demo.firebaseapp.com/). 7 | 8 | ## Using ngx-animations 9 | 10 | ### Just give me animations! 11 | First, import the animations into the appropriate module. 12 | ```typescript 13 | import { NgxAnimationsModule } from 'ngx-animations'; 14 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 15 | 16 | @NgModule({ 17 | ... 18 | imports: [ 19 | BrowserAnimationsModule, // This module is required for all Angular animations. 20 | NgxAnimationsModule, // This module is only needed when using the animation directives. 21 | ], 22 | }) 23 | export class AppModule { } 24 | ``` 25 | Then just add the appropriate animation directive to the element you wish to animate. 26 | ```html 27 | Something I want to animate 28 | ``` 29 | The element will now animate when it is added or removed from the DOM. 30 | 31 | You can also change some of the animation's options 32 | ```html 33 | 34 | Something I want to animate 35 | 36 | ``` 37 | The `fadeInAndOut` animation has the options shown above. All other animations only include the `animationDuration` option. 38 | 39 | ### Give me more control! 40 | For more granular customizability, import useSlideFadeIn and useSlideFadeOut animations. These animations can then be added to whatever trigger you choose: 41 | ```typescript 42 | import { useSlideFadeInAnimation, useSlideFadeOutAnimation } from 'ngx-animations'; 43 | @Component({ 44 | selector: 'my-component', 45 | animations: [ 46 | trigger('myTriggerName', [ 47 | transition(':enter', useSlideFadeInAnimation()), 48 | transition(':leave', useSlideFadeOutAnimation()) 49 | ]) 50 | }) 51 | ``` 52 | and in the template: 53 | ```html 54 | 55 | ``` 56 | 57 | When importing the animations, you can add parameters to adjust the duration and other properties of the animation: 58 | ```typescript 59 | import { useSlideFadeInAnimation, useSlideFadeOutAnimation } from 'ngx-animations'; 60 | 61 | @Component({ 62 | selector: 'my-component', 63 | animations: [ 64 | trigger('myTriggerName', [ 65 | transition(':enter', useSlideFadeInAnimation('500ms', '300px') ), 66 | transition(':leave', useSlideFadeOutAnimation('1000ms', '-100px')), 67 | ]) 68 | ] 69 | }) 70 | ``` 71 | 72 | rather than using the `useAnimationNameAnimation` functions included in this package, you could instead use Angular's `useAnimation` function, passing the appropriate parameters like so: 73 | 74 | ```typescript 75 | import { slideFadeIn, slideFadeOut } from 'ngx-animations'; 76 | 77 | @Component({ 78 | selector: 'my-component', 79 | animations: [ 80 | trigger('myTriggerName', [ 81 | transition(':enter', useAnimation(slideFadeIn, { params: { time: '500ms', startPos: '300px' }})), 82 | transition(':leave', useAnimation(slideFadeOut)), 83 | ]) 84 | ] 85 | }) 86 | ``` 87 | 88 | The result will be the same whether you use `useAnimation` or `useAnimationNameAnimation`. 89 | 90 | ## Included Animations 91 | (default parameters shown in examples) 92 | ### Animations with special parameters 93 | | Animation Name | Parameters | Example | 94 | |----------------|-------------|---------| 95 | |SlideFadeIn |time, startPos|```useSlideFadeInAnimation('200ms','100%')```| 96 | |SlideFadeOut|time, endPos|```useSlideFadeOutAnimation('200ms','100%')```| 97 | all parameters are optional. 98 | 99 | ### Animations with no extra parameters 100 | The following animations only have a time parameter 101 | 102 | | Animation Name | 103 | |----------------| 104 | | growIn | 105 | | shrinkOut | 106 | | swingIn | 107 | | swingOut | 108 | | bounceInUp | 109 | | bounceOutDown | 110 | 111 | #### Example 112 | ```typescript 113 | useGrowInAnimation('200ms') 114 | ``` 115 | or 116 | ```typescript 117 | useAnimation(growIn, {params:{time: '200ms'}}) 118 | ``` 119 | 120 | ## Demo App 121 | Follow these instructions to run the demo app. 122 | 123 | 1. Clone the repository to your local machine 124 | 2. From the project folder, run `npm install` to install all required dependencies 125 | 3. Run `ng serve` to serve the project from a live-updating server. 126 | 4. Go to `localhost:4200` to see the demo site 127 | 128 | 129 | ## Tips 130 | * If you want to fade between two elements without shrinking and growing, 131 | add `position:absolute` and `max-height: [some-height]px` to the proper elements. 132 | See the cat picture in the demo site for an example. 133 | 134 | ## Contributing 135 | Contributions are welcome! Continue reading for instructions on how to contribute. 136 | 137 | ### Commit Message 138 | When you are happy with the changes you have made, commit the updated code to the repository. Commit messages should follow the [material commit message guidelines](https://github.com/angular/material2/blob/master/CONTRIBUTING.md#-commit-message-guidelines). It is recommended that you install the [commitizen](https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-commitizen) VS Code extension to help. Alternatively, run `npm run commit` to commit from the command line. 139 | 140 | ### Contribution Ideas 141 | Want to contribute, but not sure where to start? Here are some suggestions 142 | * Take a look at [animate.css](https://github.com/daneden/animate.css) for inspiration. You can also use the transitions on that site as a starting point for your animations 143 | * Make some emphasis transitions. Currently all animations run when the element is added to a view. There could be plenty of uses for animations that transition from an active to inactive state, or for emphasizing elements. 144 | * Currently, all animations grow and shrink in height, but not in width. See if shrinking width in the current animations works well, or add separate animations that shrink on the X axis. 145 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "animations-demo": { 7 | "root": "apps/animations-demo", 8 | "sourceRoot": "apps\\animations-demo\\src", 9 | "projectType": "application", 10 | "architect": { 11 | "build": { 12 | "builder": "@angular-devkit/build-angular:browser", 13 | "options": { 14 | "aot": true, 15 | "outputPath": "dist\\apps\\animations-demo", 16 | "index": "apps\\animations-demo\\src/index.html", 17 | "main": "apps\\animations-demo\\src/main.ts", 18 | "tsConfig": "apps\\animations-demo\\src/tsconfig.app.json", 19 | "polyfills": "apps\\animations-demo\\src/polyfills.ts", 20 | "assets": [ 21 | "apps/animations-demo/src/assets", 22 | "apps/animations-demo/src/favicon.ico" 23 | ], 24 | "styles": [ 25 | "apps/animations-demo/src/styles.css" 26 | ], 27 | "scripts": [] 28 | }, 29 | "configurations": { 30 | "production": { 31 | "budgets": [ 32 | { 33 | "type": "anyComponentStyle", 34 | "maximumWarning": "6kb" 35 | } 36 | ], 37 | "optimization": true, 38 | "outputHashing": "all", 39 | "sourceMap": false, 40 | "extractCss": true, 41 | "namedChunks": false, 42 | "aot": true, 43 | "extractLicenses": true, 44 | "vendorChunk": false, 45 | "buildOptimizer": true, 46 | "fileReplacements": [ 47 | { 48 | "replace": "apps\\animations-demo\\src/environments/environment.ts", 49 | "with": "apps\\animations-demo\\src/environments/environment.prod.ts" 50 | } 51 | ] 52 | } 53 | } 54 | }, 55 | "serve": { 56 | "builder": "@angular-devkit/build-angular:dev-server", 57 | "options": { 58 | "browserTarget": "animations-demo:build" 59 | }, 60 | "configurations": { 61 | "production": { 62 | "browserTarget": "animations-demo:build:production" 63 | } 64 | } 65 | }, 66 | "extract-i18n": { 67 | "builder": "@angular-devkit/build-angular:extract-i18n", 68 | "options": { 69 | "browserTarget": "animations-demo:build" 70 | } 71 | }, 72 | "test": { 73 | "builder": "@angular-devkit/build-angular:karma", 74 | "options": { 75 | "main": "apps\\animations-demo\\src/../../../test.js", 76 | "karmaConfig": "./karma.conf.js", 77 | "polyfills": "apps\\animations-demo\\src/polyfills.ts", 78 | "tsConfig": "apps\\animations-demo\\src/../../../tsconfig.spec.json", 79 | "scripts": [], 80 | "styles": [ 81 | "apps/animations-demo/src/styles.css" 82 | ], 83 | "assets": [ 84 | "apps/animations-demo/src/assets", 85 | "apps/animations-demo/src/favicon.ico" 86 | ] 87 | } 88 | }, 89 | "lint": { 90 | "builder": "@angular-devkit/build-angular:tslint", 91 | "options": { 92 | "tsConfig": [ 93 | "apps\\ngx-animations\\src/tsconfig.app.json", 94 | "./tsconfig.spec.json" 95 | ], 96 | "exclude": [ 97 | "**/node_modules/**" 98 | ] 99 | } 100 | } 101 | } 102 | }, 103 | "ngx-animations": { 104 | "root": "libs/ngx-animations", 105 | "sourceRoot": "libs/ngx-animations/src", 106 | "projectType": "application", 107 | "architect": { 108 | "build": { 109 | "builder": "@angular-devkit/build-angular:browser", 110 | "options": { 111 | "aot": true, 112 | "outputPath": "dist/", 113 | "index": "libs/ngx-animations/src/index.html", 114 | "main": "libs/ngx-animations/src/main.ts", 115 | "tsConfig": "libs/ngx-animations/src/tsconfig.app.json", 116 | "assets": [], 117 | "styles": [], 118 | "scripts": [] 119 | }, 120 | "configurations": { 121 | "production": { 122 | "budgets": [ 123 | { 124 | "type": "anyComponentStyle", 125 | "maximumWarning": "6kb" 126 | } 127 | ], 128 | "optimization": true, 129 | "outputHashing": "all", 130 | "sourceMap": false, 131 | "extractCss": true, 132 | "namedChunks": false, 133 | "aot": true, 134 | "extractLicenses": true, 135 | "vendorChunk": false, 136 | "buildOptimizer": true 137 | } 138 | } 139 | }, 140 | "serve": { 141 | "builder": "@angular-devkit/build-angular:dev-server", 142 | "options": { 143 | "browserTarget": "ngx-animations:build" 144 | }, 145 | "configurations": {} 146 | }, 147 | "extract-i18n": { 148 | "builder": "@angular-devkit/build-angular:extract-i18n", 149 | "options": { 150 | "browserTarget": "ngx-animations:build" 151 | } 152 | }, 153 | "test": { 154 | "builder": "@angular-devkit/build-angular:karma", 155 | "options": { 156 | "main": "libs/ngx-animations/src/../../../test.js", 157 | "karmaConfig": "./karma.conf.js", 158 | "scripts": [], 159 | "styles": [], 160 | "assets": [] 161 | } 162 | }, 163 | "lint": { 164 | "builder": "@angular-devkit/build-angular:tslint", 165 | "options": { 166 | "tsConfig": [ 167 | "apps\\ngx-animations\\src/tsconfig.app.json", 168 | "./tsconfig.spec.json" 169 | ], 170 | "exclude": [ 171 | "**/node_modules/**" 172 | ] 173 | } 174 | } 175 | } 176 | } 177 | }, 178 | "defaultProject": "animations-demo", 179 | "schematics": { 180 | "@nrwl/schematics:component": { 181 | "prefix": "app", 182 | "styleext": "css" 183 | }, 184 | "@nrwl/schematics:directive": { 185 | "prefix": "app" 186 | } 187 | }, 188 | "cli": { 189 | "analytics": false 190 | } 191 | } -------------------------------------------------------------------------------- /apps/animations-demo/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /apps/animations-demo/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | .list-item { 2 | border-radius: 5px; 3 | width: 200px; 4 | padding: 15px; 5 | margin: 15px; 6 | height: 50px; 7 | background-color: lightblue; 8 | display: flex; 9 | align-items: center; 10 | justify-content: space-between; 11 | } 12 | -------------------------------------------------------------------------------- /apps/animations-demo/src/app/app.component.html: -------------------------------------------------------------------------------- 1 |

ngx-animations

2 | 3 | 4 | 5 | fade-in/out 6 | 7 | 8 | grow-in/shrink-out 9 | 10 | 11 | bounce-in/out 12 | 13 | 14 | swing-in/out 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | % or px value 23 | 24 | 25 | 26 | % or px value 27 | 28 | 29 | 30 | 'ms' or 's' value 31 | 32 |
33 | 34 | paramater only available on fade animation 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 |
45 |
46 | 47 |
48 |
51 | 52 |
53 |
54 | 55 |
56 | 57 |
58 | {{ listItem.title }} 59 |
60 | 61 |
62 |
63 | 64 | 65 | 66 |
67 | 70 | 73 |
74 | -------------------------------------------------------------------------------- /apps/animations-demo/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { transition, trigger, useAnimation } from '@angular/animations'; 2 | import { Component } from '@angular/core'; 3 | import { slideFadeOut, useSlideFadeInAnimation } from 'ngx-animations'; 4 | 5 | @Component({ 6 | selector: 'app-root', 7 | templateUrl: 'app.component.html', 8 | styleUrls: ['app.component.css'], 9 | animations: [ 10 | 11 | // The following is a custom trigger using animations from the package. 12 | // Use this approach if you need to customize the animation or use your own states. 13 | // Note that this trigger is not used in the template. 14 | trigger('enterFromLeftLeaveToRight', [ 15 | // this transition uses a function that returns an animation with custom parameters. 16 | transition(':enter', useSlideFadeInAnimation('300ms', '20px')), 17 | // This transition uses useAnimation and passes the parameters directly - accomplishing the same thing as the above function. 18 | transition(':leave', useAnimation(slideFadeOut, {params: {time: '2000ms', endPos: '100px'}})), 19 | ]), 20 | ], 21 | }) 22 | export class AppComponent { 23 | selectedAnimation = 'fade'; 24 | listItems: Array<{id: number; title: string}> = [ 25 | {id: 1, title: 'first item'}, 26 | {id: 2, title: 'second Item'}, 27 | {id: 3, title: 'third item'}, 28 | ]; 29 | nextId = 4; 30 | cat = false; 31 | 32 | constructor() {} 33 | 34 | replaceItem(itemName: string) { 35 | this.listItems = [{id: this.nextId++, title: itemName}, ...this.listItems.splice(1, this.listItems.length)]; 36 | } 37 | 38 | removeItem(itemName: number) { 39 | this.listItems = this.listItems.filter(item => item.id !== itemName); 40 | } 41 | 42 | changeAnimation(newAnimation: string) { 43 | console.log('animation', newAnimation ); 44 | this.selectedAnimation = newAnimation; 45 | } 46 | 47 | addItem(itemName: string) { 48 | this.listItems = [{id: this.nextId++, title: itemName}, ...this.listItems]; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /apps/animations-demo/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { MatButtonModule } from '@angular/material/button'; 3 | import { MatInputModule } from '@angular/material/input'; 4 | import { MatSelectModule } from '@angular/material/select'; 5 | import { BrowserModule } from '@angular/platform-browser'; 6 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 7 | 8 | import { NgxAnimationsModule } from 'ngx-animations'; 9 | import { AppComponent } from './app.component'; 10 | 11 | @NgModule({ 12 | declarations: [ 13 | AppComponent, 14 | ], 15 | imports: [ 16 | BrowserModule, 17 | BrowserAnimationsModule, 18 | NgxAnimationsModule, 19 | MatButtonModule, 20 | MatInputModule, 21 | MatSelectModule, 22 | ], 23 | providers: [], 24 | bootstrap: [AppComponent], 25 | }) 26 | export class AppModule { } 27 | -------------------------------------------------------------------------------- /apps/animations-demo/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HylandSoftware/ngx-animations/0da7f355f5faaf65583fe8de21f11b20f664ddae/apps/animations-demo/src/assets/.gitkeep -------------------------------------------------------------------------------- /apps/animations-demo/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | }; 4 | -------------------------------------------------------------------------------- /apps/animations-demo/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false, 8 | }; 9 | -------------------------------------------------------------------------------- /apps/animations-demo/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HylandSoftware/ngx-animations/0da7f355f5faaf65583fe8de21f11b20f664ddae/apps/animations-demo/src/favicon.ico -------------------------------------------------------------------------------- /apps/animations-demo/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ngx-animations 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /apps/animations-demo/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /apps/animations-demo/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Required to support Web Animations `@angular/platform-browser/animations`. 4 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation 5 | */ 6 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 7 | 8 | /* 9 | * Zone JS is required by Angular itself. 10 | */ 11 | import 'zone.js/dist/zone'; // Included with Angular CLI. 12 | 13 | /* 14 | * APPLICATION IMPORTS 15 | */ 16 | 17 | /** 18 | * Date, currency, decimal and percent pipes. 19 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 20 | */ 21 | // import 'intl'; // Run `npm install --save intl`. 22 | /** 23 | * Need to import at least one locale-data with intl. 24 | */ 25 | // import 'intl/locale-data/jsonp/en'; 26 | -------------------------------------------------------------------------------- /apps/animations-demo/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | @import "~@angular/material/prebuilt-themes/indigo-pink.css"; -------------------------------------------------------------------------------- /apps/animations-demo/src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../dist/out-tsc/apps/ngx-animations", 5 | "types": [] 6 | }, 7 | "files": [ 8 | "main.ts", 9 | "polyfills.ts" 10 | ], 11 | "include": [ 12 | "**/*.d.ts" 13 | ], 14 | "angularCompilerOptions": { 15 | "enableIvy": false 16 | } 17 | } -------------------------------------------------------------------------------- /apps/animations-demo/src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "dist/apps/animations-demo", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ], 9 | "rewrites": [ 10 | { 11 | "source": "**", 12 | "destination": "/index.html" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ], 20 | fixWebpackSourcePaths: true 21 | }, 22 | 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /libs/ngx-animations/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /libs/ngx-animations/index.ts: -------------------------------------------------------------------------------- 1 | export { NgxAnimationsModule } from './src/ngx-animations.module'; 2 | export * from './src/animations'; 3 | export * from './src/directives'; 4 | -------------------------------------------------------------------------------- /libs/ngx-animations/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ngx-animations", 3 | "version": "0.0.0-beta.0", 4 | "license": "MIT", 5 | "keywords": [ 6 | "ng", 7 | "angular", 8 | "angular2", 9 | "angular4", 10 | "angular5", 11 | "animation", 12 | "ngweb", 13 | "animate" 14 | ], 15 | "private": false, 16 | "peerDependencies": { 17 | "@angular/animations": ">=4.3.0", 18 | "@angular/common": ">=4.3.0" 19 | }, 20 | "ngPackage": { 21 | "lib": { 22 | "entryFile": "public_api.ts" 23 | }, 24 | "dest": "../../dist/libs/ngx-animations" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /libs/ngx-animations/public_api.ts: -------------------------------------------------------------------------------- 1 | export * from './index'; 2 | -------------------------------------------------------------------------------- /libs/ngx-animations/src/animations.ts: -------------------------------------------------------------------------------- 1 | import { animate, animation, AnimationAnimateRefMetadata, AnimationReferenceMetadata, AnimationTriggerMetadata, 2 | group, keyframes, query, state, style, transition, trigger, useAnimation } from '@angular/animations'; 3 | /** Many of the following animations were inspired by: (inspired by: https://daneden.github.io/animate.css/) */ 4 | 5 | /** 6 | * shrink and grow are used within most enter/leave animations so surrounding elements will appropriately slide 7 | */ 8 | const shrink = animation( 9 | animate('{{time}}', style({ height: '0px', paddingTop: '0px', paddingBottom: '0px', marginTop: '0px', marginBottom: '0px' })), 10 | {params: {time: '200ms'}}, 11 | ); 12 | const grow = animation( 13 | [ 14 | style({height: '0px', paddingTop: '0px', paddingBottom: '0px', marginTop: '0px', marginBottom: '0px'}), 15 | animate('{{time}}', style({ height: '*', paddingTop: '*', paddingBottom: '*', marginTop: '*', marginBottom: '*' })), 16 | ], 17 | {params: {time: '200ms'}}, 18 | ); 19 | 20 | export const slideFadeIn = animation( 21 | [ 22 | style({ opacity: '0', transform: 'translateX({{startPos}})' }), 23 | group([ 24 | useAnimation(grow), 25 | animate('{{time}}', style({ opacity: '1', transform: '*' })), 26 | ]), 27 | ], 28 | { params: { time: '200ms', startPos: '100%' } }, 29 | ); 30 | 31 | /** 32 | * fade in while sliding horizontally. 33 | * 34 | * @param time the duration of the animation 35 | * @param startPos the location that the element should start from before moving to its final position. 36 | * use a negative value to start to the left 37 | */ 38 | export function useSlideFadeInAnimation(time: string = '200ms', startPos: string = '100%'): AnimationReferenceMetadata { 39 | return useAnimation(slideFadeIn, {params: {time, startPos}}); 40 | } 41 | 42 | export const slideFadeOut = animation([ 43 | group([ 44 | useAnimation(shrink, {params: {time: '{{time}}'}}), 45 | animate('{{time}}', style({ opacity: '0', transform: 'translateX({{endPos}})' })), 46 | ]), 47 | ], 48 | { params: { time: '200ms', endPos: '100%' } }, 49 | ); 50 | 51 | /** 52 | * fade out while sliding horizontally. 53 | * 54 | * @param time the duration of the animation 55 | * @param endPos the amount that the element should move (horizontally) by the end of the animation. 56 | * Use a negative value to move left 57 | */ 58 | export function useSlideFadeOutAnimation(time: string = '200ms', endPos: string = '100%'): AnimationReferenceMetadata { 59 | return useAnimation(slideFadeOut, {params: {time, endPos}}); 60 | } 61 | 62 | export const growIn = animation( 63 | [ 64 | style({ height: '0px', transform: 'scaleY(0)' }), 65 | group([ 66 | useAnimation(grow, {params: {time: '{{time}}'}}), 67 | animate('{{time}}', style({ transform: '*' })), 68 | ]), 69 | ], 70 | { params: { time: '200ms' } }, 71 | ); 72 | 73 | /** 74 | * start at 0px height and grow to full height without any opacity changes 75 | * @param time the duration of the animation 76 | */ 77 | export function useGrowInAnimation(time: string = '200ms'): AnimationReferenceMetadata { 78 | return useAnimation(growIn, {params: {time}}); 79 | } 80 | export const shrinkOut = animation( 81 | group([ 82 | useAnimation(shrink, {params: {time: '{{time}}'}}), 83 | animate('{{time}}', style({ transform: 'scaleY(0)' })), 84 | ]), 85 | { params: { time: '200ms' } }, 86 | ); 87 | /** 88 | * shrink to 0px height without any opacity changes 89 | * @param time the duration of the animation 90 | */ 91 | export function useShrinkOutAnimation(time: string = '200ms'): AnimationReferenceMetadata { 92 | return useAnimation(shrinkOut, {params: {time}}); 93 | } 94 | 95 | export const swingIn = animation( 96 | [ 97 | style({transformOrigin: '50% 0px', transform: 'perspective(500px) rotate3d(1, 0, 0, 90deg)' }), 98 | group([ 99 | useAnimation(grow, {params: {time: '200ms'}}), 100 | animate('{{time}}', 101 | keyframes([ 102 | style({transform: 'perspective(500px) rotate3d(1, 0, 0, -70deg)' }), 103 | style({transform: 'perspective(500px) rotate3d(1, 0, 0, 40deg)' }), 104 | style({transform: 'perspective(500px) rotate3d(1, 0, 0, -15deg)' }), 105 | style({transform: 'perspective(500px) rotate3d(1, 0, 0, 0deg)' }), 106 | ]), 107 | ), 108 | ]), 109 | ], 110 | {params: {time: '600ms'}}, 111 | ); 112 | /** 113 | * rotate element in on the X axis as if it is hanging on a hinge. 114 | * @param time the duration of the animation 115 | */ 116 | export function useSwingInAnimation(time: string = '600ms'): AnimationReferenceMetadata { 117 | return useAnimation(swingIn, {params: {time}}); 118 | } 119 | 120 | export const swingOut = animation( 121 | [ 122 | animate( '{{time}}', 123 | keyframes([ 124 | style([{transformOrigin: '50% 0px', transform: 'perspective(500px) rotate3d(1, 0, 0, 0deg)' }, {offset: 0}]), 125 | style([{transform: 'perspective(500px) rotate3d(1, 0, 0, -30deg)'}, {offset: 0.3}]), 126 | style([{transform: 'perspective(500px) rotate3d(1, 0, 0, 90deg)'}, {offset: 1}]), 127 | ]), 128 | ), 129 | useAnimation(shrink, {params: {time: '200ms'}}), 130 | ], 131 | {params: {time: '300ms'}}, 132 | ); 133 | /** 134 | * rotate element out on the X axis until it is facing up and invisible to the user 135 | * @param time the duration of the animation 136 | */ 137 | export function useSwingOutAnimation(time: string = '300ms'): AnimationReferenceMetadata { 138 | return useAnimation(swingOut, {params: {time}}); 139 | } 140 | 141 | export const bounceInUp = animation( 142 | [ 143 | style([{ opacity: 0}]), 144 | useAnimation(grow, {params: {time: '200ms'}}), 145 | animate('{{time}} cubic-bezier(0.215, 0.610, 0.355, 1.000)', 146 | keyframes([ 147 | style([{ opacity: 0, transform: 'translate3d(0, 20px, 0)', offset: 0 }]), 148 | style([{ opacity: 1, transform: 'translate3d(0, -20px, 0)'}, {offset: 0.5 }]), 149 | style([{ transform: 'translate3d(0, 10px, 0)'}, {offset: 0.75 }]), 150 | style([{ transform: 'translate3d(0, -5px, 0)'}, {offset: 0.95 }]), 151 | style(['*', {offset: 1 }]), 152 | ]), 153 | ), 154 | ], 155 | {params: {time: '400ms'}}, 156 | ); 157 | /** 158 | * bounce from below 159 | * @param time the duration of the animation 160 | */ 161 | export function useBounceInUpAnimation(time: string = '200ms'): AnimationReferenceMetadata { 162 | return useAnimation(bounceInUp, {params: {time}}); 163 | } 164 | 165 | export const bounceOutDown = animation( 166 | [ 167 | animate('{{time}}', keyframes([ 168 | style([{ transform: 'translate3d(0, -5px, 0)'}, {offset: 0.05 }]), 169 | style([{ transform: 'translate3d(0, 10px, 0)'}, {offset: 0.25 }]), 170 | style([{ opacity: 1, transform: 'translate3d(0, -20px, 0)'}, {offset: .5 }]), 171 | style([{ opacity: 0, transform: 'translate3d(0, 20px, 0)'}, {offset: 1 }]), 172 | ])), 173 | useAnimation(shrink, {params: {time: '200ms'}}), 174 | ], 175 | {params: {time: '300ms'}}, 176 | ); 177 | 178 | /** 179 | * bounce down to the area below 180 | * @param time The duration of the animation 181 | */ 182 | export function useBounceOutDownAnimation(time: string = '200ms'): AnimationReferenceMetadata { 183 | return useAnimation(bounceOutDown, {params: {time}}); 184 | } 185 | -------------------------------------------------------------------------------- /libs/ngx-animations/src/directives/README.md: -------------------------------------------------------------------------------- 1 | ## Directives Workaround Notice 2 | 3 | The directives in this folder use a workaround which is required until [this issue](https://github.com/angular/angular/issues/9947) is completed 4 | 5 | ### The Issue 6 | You cannot add animations to a directive's decorator. 7 | 8 | ### The Workaround 9 | Make a faux-directive by creating a component that only has an attribute selector (eg. `[myDirective]`) and that has a template of `` -------------------------------------------------------------------------------- /libs/ngx-animations/src/directives/bounce-in-and-out.directive.ts: -------------------------------------------------------------------------------- 1 | import { transition, trigger } from '@angular/animations'; 2 | import { Component, Directive, HostBinding, Input } from '@angular/core'; 3 | import { useBounceInUpAnimation, useBounceOutDownAnimation } from '../animations'; 4 | import { AnimationTrigger } from '../models'; 5 | 6 | @Component({ 7 | // tslint:disable-next-line:component-selector 8 | selector: '[animateBounceInAndOut]', 9 | animations: [ 10 | trigger('bounceInAndOut', [ 11 | transition(':enter', 12 | useBounceInUpAnimation('{{duration}}'), 13 | {params: {duration: '200ms'}}, 14 | ), 15 | transition(':leave', 16 | useBounceOutDownAnimation('{{duration}}'), 17 | {params: {duration: '200ms'}}, 18 | ), 19 | ]), 20 | ], 21 | template: ``, 22 | }) 23 | // tslint:disable-next-line:component-class-suffix 24 | export class BoundeInAndOutDirective { 25 | @HostBinding('@bounceInAndOut') trigger: AnimationTrigger = { 26 | value: '', 27 | params: {}, 28 | }; 29 | 30 | @Input('animationDuration') 31 | set animationDuration(duration: string | number) { 32 | this.trigger.params.duration = duration; 33 | } 34 | constructor() { } 35 | } 36 | -------------------------------------------------------------------------------- /libs/ngx-animations/src/directives/fade-in-and-out.directive.ts: -------------------------------------------------------------------------------- 1 | import { AnimationTriggerMetadata, transition, trigger, useAnimation } from '@angular/animations'; 2 | import { Component, Directive, HostBinding, Input, OnInit } from '@angular/core'; 3 | import { slideFadeIn, slideFadeOut, useSlideFadeInAnimation, useSlideFadeOutAnimation } from '../animations'; 4 | import { AnimationParams, AnimationTrigger } from '../models'; 5 | 6 | @Component({ 7 | // tslint:disable-next-line:component-selector 8 | selector: '[animateFadeInAndOut]', 9 | animations: [ 10 | trigger('fadeInAndOut', [ 11 | transition(':enter', 12 | useSlideFadeInAnimation('{{duration}}', '{{enterPosition}}'), 13 | {params: {duration: '200ms', enterPosition: '0px'}}, 14 | ), 15 | transition(':leave', 16 | useSlideFadeOutAnimation('{{duration}}', '{{leavePosition}}'), 17 | {params: {duration: '200ms', leavePosition: '0px'}}, 18 | ), 19 | ]), 20 | ], 21 | template: ``, 22 | }) 23 | 24 | // tslint:disable-next-line:component-class-suffix 25 | export class FadeInAndOutDirective { 26 | @HostBinding('@fadeInAndOut') trigger: AnimationTrigger = { 27 | value: '', 28 | params: {}, 29 | }; 30 | 31 | @Input('animationDuration') 32 | set animationDuration(duration: string | number) { 33 | this.trigger.params.duration = duration; 34 | } 35 | 36 | @Input('animationEnterPosition') 37 | set animationEnterPosition(enterPosition: string ) { 38 | this.trigger.params.enterPosition = enterPosition; 39 | } 40 | 41 | @Input('animationLeavePosition') 42 | set animationLeavePosition(leavePosition: string ) { 43 | this.trigger.params.leavePosition = leavePosition; 44 | } 45 | 46 | constructor() { } 47 | } 48 | -------------------------------------------------------------------------------- /libs/ngx-animations/src/directives/grow-in-shrink-out.directive.ts: -------------------------------------------------------------------------------- 1 | import { AnimationTriggerMetadata, transition, trigger, useAnimation } from '@angular/animations'; 2 | import { Component, Directive, HostBinding, Input } from '@angular/core'; 3 | import { useGrowInAnimation, useShrinkOutAnimation } from '../animations'; 4 | import { AnimationTrigger } from '../models'; 5 | 6 | @Component({ 7 | // tslint:disable-next-line:component-selector 8 | selector: '[animateGrowInShrinkOut]', 9 | animations: [ 10 | trigger('growInShrinkOut', [ 11 | transition(':enter', 12 | useGrowInAnimation('{{duration}}'), 13 | {params: {duration: '200ms'}}, 14 | ), 15 | transition(':leave', 16 | useShrinkOutAnimation('{{duration}}'), 17 | {params: {duration: '200ms'}}, 18 | ), 19 | ]), 20 | 21 | ], 22 | template: ``, 23 | }) 24 | // tslint:disable-next-line:component-class-suffix 25 | export class GrowInShrinkOutDirective { 26 | @HostBinding('@growInShrinkOut') trigger: AnimationTrigger = { 27 | value: '', 28 | params: {}, 29 | }; 30 | 31 | @Input('animationDuration') 32 | set animationDuration(duration: string | number) { 33 | this.trigger.params.duration = duration; 34 | } 35 | constructor() { } 36 | } 37 | -------------------------------------------------------------------------------- /libs/ngx-animations/src/directives/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bounce-in-and-out.directive'; 2 | export * from './fade-in-and-out.directive'; 3 | export * from './grow-in-shrink-out.directive'; 4 | export * from './swing-in-and-out.directive'; 5 | -------------------------------------------------------------------------------- /libs/ngx-animations/src/directives/swing-in-and-out.directive.ts: -------------------------------------------------------------------------------- 1 | import { transition, trigger } from '@angular/animations'; 2 | import { Component, Directive, HostBinding, Input } from '@angular/core'; 3 | import { useSwingInAnimation, useSwingOutAnimation } from '../animations'; 4 | import { AnimationTrigger } from '../models'; 5 | 6 | @Component({ 7 | // tslint:disable-next-line:component-selector 8 | selector: '[animateSwingInAndOut]', 9 | animations: [ 10 | trigger('swingInAndOut', [ 11 | transition(':enter', useSwingInAnimation('{{duration}}'), {params: {duration: '200ms'}}), 12 | transition(':leave', useSwingOutAnimation('{{duration}}'), {params: {duration: '200ms'}}), 13 | ]), 14 | ], 15 | template: ``, 16 | }) 17 | // tslint:disable-next-line:component-class-suffix 18 | export class SwingInAndOutDirective { 19 | @HostBinding('@swingInAndOut') trigger: AnimationTrigger = { 20 | value: '', 21 | params: {}, 22 | }; 23 | 24 | @Input('animationDuration') 25 | set animationDuration(duration: string | number) { 26 | this.trigger.params.duration = duration; 27 | } 28 | constructor() { } 29 | } 30 | -------------------------------------------------------------------------------- /libs/ngx-animations/src/models.ts: -------------------------------------------------------------------------------- 1 | export interface AnimationTrigger { 2 | value: any; 3 | params: AnimationParams; 4 | } 5 | 6 | export interface AnimationParams { 7 | [name: string]: string | number; 8 | } 9 | -------------------------------------------------------------------------------- /libs/ngx-animations/src/ngx-animations.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BoundeInAndOutDirective, FadeInAndOutDirective, 3 | GrowInShrinkOutDirective, SwingInAndOutDirective } from './directives'; 4 | 5 | const ALL_DIRECTIVES = [ 6 | FadeInAndOutDirective, 7 | BoundeInAndOutDirective, 8 | GrowInShrinkOutDirective, 9 | SwingInAndOutDirective, 10 | ]; 11 | 12 | @NgModule({ 13 | declarations: ALL_DIRECTIVES, 14 | exports: ALL_DIRECTIVES, 15 | }) 16 | export class NgxAnimationsModule { 17 | } 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ngx-animations", 3 | "version": "0.0.0-beta.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e", 11 | "commit": "git-cz" 12 | }, 13 | "keywords": [ 14 | "ng", 15 | "ngx", 16 | "Hyland", 17 | "angular", 18 | "angular2", 19 | "angular4", 20 | "angular5", 21 | "animation", 22 | "ngweb", 23 | "animate" 24 | ], 25 | "private": false, 26 | "devDependencies": { 27 | "@angular-devkit/build-angular": "~0.900.6", 28 | "@angular/animations": "9.0.6", 29 | "@angular/cdk": "^9.1.2", 30 | "@angular/cli": "^9.0.6", 31 | "@angular/common": "9.0.6", 32 | "@angular/compiler": "9.0.6", 33 | "@angular/compiler-cli": "9.0.6", 34 | "@angular/core": "9.0.6", 35 | "@angular/forms": "9.0.6", 36 | "@angular/language-service": "9.0.6", 37 | "@angular/material": "^9.1.2", 38 | "@angular/platform-browser": "9.0.6", 39 | "@angular/platform-browser-dynamic": "9.0.6", 40 | "@angular/router": "9.0.6", 41 | "@types/jasmine": "^2.5.54", 42 | "@types/node": "^12.11.1", 43 | "codelyzer": "^5.1.2", 44 | "commitizen": "^2.10.1", 45 | "core-js": "^2.6.9", 46 | "ng-packagr": "^9.0.3", 47 | "protractor": "~5.1.2", 48 | "rxjs": "^6.5.4", 49 | "rxjs-tslint-rules": "^4.29.1", 50 | "stylelint-config-standard": "^20.0.0", 51 | "tslint": "~5.7.0", 52 | "typescript": "3.7.5", 53 | "zone.js": "~0.10.2" 54 | }, 55 | "dependencies": { 56 | "tslib": "^1.10.0" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | require('zone.js/dist/zone-testing'); 3 | const getTestBed = require('@angular/core/testing').getTestBed; 4 | const BrowserDynamicTestingModule = require('@angular/platform-browser-dynamic/testing').BrowserDynamicTestingModule; 5 | const platformBrowserDynamicTesting = require('@angular/platform-browser-dynamic/testing').platformBrowserDynamicTesting; 6 | 7 | // Prevent Karma from running prematurely. 8 | __karma__.loaded = function () {}; 9 | 10 | // First, initialize the Angular testing environment. 11 | getTestBed().initTestEnvironment( 12 | BrowserDynamicTestingModule, 13 | platformBrowserDynamicTesting() 14 | ); 15 | // Then we find all the tests. 16 | const contextApps = require.context('./apps', true, /\.spec\.ts$/); 17 | // And load the modules. 18 | contextApps.keys().map(contextApps); 19 | 20 | const contextLibs = require.context('./libs', true, /\.spec\.ts$/); 21 | // And load the modules. 22 | contextLibs.keys().map(contextLibs); 23 | 24 | // Finally, start Karma to run the tests. 25 | __karma__.start(); 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "downlevelIteration": true, 5 | "importHelpers": true, 6 | "outDir": "./dist/out-tsc", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "moduleResolution": "node", 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "target": "es2015", 13 | "typeRoots": [ 14 | "node_modules/@types" 15 | ], 16 | "lib": [ 17 | "es2017", 18 | "dom" 19 | ], 20 | "paths": { 21 | "ngx-animations": [ 22 | "libs/ngx-animations" 23 | ] 24 | }, 25 | "baseUrl": ".", 26 | "module": "esnext" 27 | } 28 | } -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc/spec", 5 | "baseUrl": "./", 6 | "types": [ 7 | "jasmine", 8 | "node" 9 | ] 10 | }, 11 | "files": [ 12 | "test.js", 13 | "polyfills.ts" 14 | ], 15 | "include": [ 16 | "**/*.ts" 17 | ], 18 | "exclude": [ 19 | "**/e2e/*.ts", 20 | "**/*.e2e-spec.ts", 21 | "**/*.po.ts", 22 | "node_modules", 23 | "tmp" 24 | ] 25 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "tslint:recommended", 4 | "rxjs-tslint-rules" 5 | ], 6 | "rulesDirectory": [ 7 | "codelyzer" 8 | ], 9 | "rules": { 10 | "rxjs-no-subject-unsubscribe": true, 11 | "rxjs-no-unused-add": true, 12 | "arrow-parens": false, 13 | "import-blacklist": [ 14 | true, 15 | "rxjs/Rx" 16 | ], 17 | "indent": [ 18 | true, 19 | "spaces", 20 | 2 21 | ], 22 | "interface-name": false, 23 | "max-line-length": [ 24 | true, 25 | 140 26 | ], 27 | "member-access": [ 28 | true, 29 | "no-public" 30 | ], 31 | "member-ordering": [ 32 | true, 33 | { 34 | "order": [ 35 | "static-field", 36 | "instance-field", 37 | "static-method", 38 | "instance-method" 39 | ] 40 | } 41 | ], 42 | "no-console": [ 43 | true, 44 | "debug", 45 | "info", 46 | "time", 47 | "timeEnd", 48 | "trace" 49 | ], 50 | "no-duplicate-imports": true, 51 | "no-empty": false, 52 | "no-inferrable-types": [ 53 | true, 54 | "ignore-params" 55 | ], 56 | "no-null-keyword": true, 57 | "no-switch-case-fall-through": true, 58 | "object-literal-sort-keys": false, 59 | "quotemark": [ 60 | true, 61 | "single" 62 | ], 63 | "variable-name": [ 64 | true, 65 | "check-format", 66 | "allow-leading-underscore", 67 | "ban-keywords" 68 | ], 69 | "whitespace": [ 70 | true, 71 | "check-branch", 72 | "check-decl", 73 | "check-module", 74 | "check-operator", 75 | "check-rest-spread", 76 | "check-separator", 77 | "check-type", 78 | "check-typecast", 79 | "check-type-operator", 80 | "check-preblock" 81 | ], 82 | "template-banana-in-box": true, 83 | "directive-class-suffix": true, 84 | "no-attribute-decorator": true, 85 | "no-forward-ref": true, 86 | "no-input-rename": true, 87 | "no-output-rename": true, 88 | "no-host-metadata-property": true, 89 | "no-inputs-metadata-property": true, 90 | "use-lifecycle-interface": true, 91 | "no-outputs-metadata-property": true, 92 | "use-pipe-decorator": true, 93 | "use-pipe-transform-interface": true, 94 | "component-selector": [ 95 | true, 96 | "element", 97 | ["app"], 98 | "kebab-case" 99 | ], 100 | "directive-selector": [ 101 | true, 102 | "attribute", 103 | ["app"], 104 | "camelCase" 105 | ], 106 | "component-class-suffix": [ 107 | true, 108 | "Component", 109 | "View" 110 | ] 111 | }, 112 | "nx-enforce-module-boundaries": [ 113 | true, 114 | { 115 | "allow": [], 116 | "depConstraints": [ 117 | { 118 | "sourceTag": "*", 119 | "onlyDependOnLibsWithTags": [ 120 | "*" 121 | ] 122 | } 123 | ] 124 | } 125 | ] 126 | } --------------------------------------------------------------------------------