├── .circleci
└── config.yml
├── .editorconfig
├── .eslintrc.json
├── .firebaserc
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .vscode
└── extensions.json
├── README.md
├── angular.json
├── apps
├── .gitkeep
├── reactive-code-animations-e2e
│ ├── .eslintrc.json
│ ├── cypress.json
│ ├── src
│ │ ├── fixtures
│ │ │ └── example.json
│ │ ├── integration
│ │ │ └── app.spec.ts
│ │ ├── plugins
│ │ │ └── index.js
│ │ └── support
│ │ │ ├── app.po.ts
│ │ │ ├── commands.ts
│ │ │ └── index.ts
│ ├── tsconfig.e2e.json
│ └── tsconfig.json
└── reactive-code-animations
│ ├── .browserslistrc
│ ├── .eslintrc.json
│ ├── jest.config.js
│ ├── src
│ ├── app
│ │ ├── app.component.html
│ │ ├── app.component.scss
│ │ ├── app.component.spec.ts
│ │ ├── app.component.ts
│ │ └── app.module.ts
│ ├── assets
│ │ ├── .gitkeep
│ │ ├── illustration1-code.svg
│ │ ├── illustration1-keyboard.svg
│ │ ├── illustration1-nx-cloud-layer.svg
│ │ ├── illustration1-nx-layer.svg
│ │ └── spongebob
│ │ │ ├── gary-01.png
│ │ │ ├── gary-02.png
│ │ │ ├── gary-03.png
│ │ │ ├── patrick-01.png
│ │ │ ├── patrick-02.png
│ │ │ ├── patrick-03.png
│ │ │ ├── spongebob-01.png
│ │ │ ├── spongebob-02.png
│ │ │ └── spongebob-03.png
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.svg
│ ├── index.html
│ ├── main.ts
│ ├── polyfills.ts
│ ├── styles.scss
│ └── test-setup.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.editor.json
│ ├── tsconfig.json
│ └── tsconfig.spec.json
├── decorate-angular-cli.js
├── firebase.json
├── jest.config.js
├── jest.preset.js
├── libs
├── examples
│ ├── carousel
│ │ ├── .eslintrc.json
│ │ ├── README.md
│ │ ├── jest.config.js
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ ├── lib
│ │ │ │ ├── carousel
│ │ │ │ │ ├── carousel.component.html
│ │ │ │ │ ├── carousel.component.scss
│ │ │ │ │ └── carousel.component.ts
│ │ │ │ └── examples-carousel.module.ts
│ │ │ └── test-setup.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.lib.json
│ │ └── tsconfig.spec.json
│ ├── click-counter
│ │ ├── .eslintrc.json
│ │ ├── README.md
│ │ ├── jest.config.js
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ ├── lib
│ │ │ │ ├── chart-data.function.ts
│ │ │ │ ├── click-counter
│ │ │ │ │ ├── click-counter.component.html
│ │ │ │ │ ├── click-counter.component.scss
│ │ │ │ │ ├── click-counter.component.spec.ts
│ │ │ │ │ └── click-counter.component.ts
│ │ │ │ ├── examples-click-counter.module.ts
│ │ │ │ ├── imperative-click-counter
│ │ │ │ │ ├── imperative-click-counter.component.css
│ │ │ │ │ ├── imperative-click-counter.component.html
│ │ │ │ │ ├── imperative-click-counter.component.spec.ts
│ │ │ │ │ └── imperative-click-counter.component.ts
│ │ │ │ ├── line-chart
│ │ │ │ │ ├── line-chart.component.html
│ │ │ │ │ ├── line-chart.component.scss
│ │ │ │ │ ├── line-chart.component.spec.ts
│ │ │ │ │ └── line-chart.component.ts
│ │ │ │ └── windowed-count.function.ts
│ │ │ └── test-setup.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.lib.json
│ │ └── tsconfig.spec.json
│ └── series
│ │ ├── .eslintrc.json
│ │ ├── README.md
│ │ ├── jest.config.js
│ │ ├── src
│ │ ├── index.ts
│ │ ├── lib
│ │ │ ├── examples-series.module.ts
│ │ │ └── series-example
│ │ │ │ ├── series-example.component.html
│ │ │ │ ├── series-example.component.scss
│ │ │ │ └── series-example.component.ts
│ │ └── test-setup.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.lib.json
│ │ └── tsconfig.spec.json
├── shared
│ ├── animations
│ │ ├── .eslintrc.json
│ │ ├── README.md
│ │ ├── jest.config.js
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ ├── lib
│ │ │ │ ├── drop.animation.ts
│ │ │ │ ├── fade.animation.ts
│ │ │ │ ├── lift.animation.ts
│ │ │ │ ├── rotate.animation.ts
│ │ │ │ └── slide.animation.ts
│ │ │ └── test-setup.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.lib.json
│ │ └── tsconfig.spec.json
│ └── carousel
│ │ ├── .eslintrc.json
│ │ ├── jest.config.js
│ │ ├── src
│ │ ├── index.ts
│ │ ├── lib
│ │ │ ├── carousel-item
│ │ │ │ ├── carousel-item.component.html
│ │ │ │ ├── carousel-item.component.scss
│ │ │ │ └── carousel-item.component.ts
│ │ │ ├── carousel
│ │ │ │ ├── auto-advance.operator.ts
│ │ │ │ ├── carousel.component.html
│ │ │ │ ├── carousel.component.scss
│ │ │ │ ├── carousel.component.ts
│ │ │ │ └── carousel.utils.ts
│ │ │ └── shared-carousel.module.ts
│ │ └── test-setup.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.lib.json
│ │ └── tsconfig.spec.json
└── styles
│ ├── _variables.scss
│ └── base.scss
├── nx.json
├── package.json
├── tools
├── generators
│ └── .gitkeep
└── tsconfig.tools.json
├── tsconfig.base.json
└── yarn.lock
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 |
3 | orbs:
4 | node: circleci/node@3.0.0
5 |
6 | commands:
7 | npm_install:
8 | description: "Install & Cache Dependencies"
9 | steps:
10 | - run: npm install
11 | - save_cache:
12 | key: rca-{{ checksum "package-lock.json" }}
13 | paths:
14 | - ~/.cache
15 | - node_modules
16 |
17 | restore_npm_cache:
18 | description: "Restore Cached Dependencies"
19 | steps:
20 | - restore_cache:
21 | keys:
22 | - rca-{{ checksum "package-lock.json" }}
23 | - rca- # used if checksum fails
24 |
25 | setup:
26 | description: "Setup Executor"
27 | steps:
28 | - checkout
29 | - attach_workspace:
30 | at: ~/project
31 |
32 | jobs:
33 | initialize:
34 | executor:
35 | name: node/default
36 | steps:
37 | - checkout
38 | - restore_npm_cache
39 | - npm_install
40 | - persist_to_workspace:
41 | root: ~/project
42 | paths:
43 | - node_modules
44 | - dist
45 |
46 | lint:
47 | executor:
48 | name: node/default
49 | steps:
50 | - setup
51 | - run:
52 | name: Lint all affected projects
53 | command: npx nx affected:lint --base=main --head=HEAD
54 |
55 | build:
56 | executor:
57 | name: node/default
58 | steps:
59 | - setup
60 | - run:
61 | name: Build all affected projects
62 | command: npx nx affected:build --base=main --head=HEAD
63 |
64 | test:
65 | executor:
66 | name: node/default
67 | steps:
68 | - setup
69 | - run:
70 | name: Test all affected projects
71 | command: npx nx affected:test --base=main --head=HEAD
72 |
73 | workflows:
74 | verify:
75 | jobs:
76 | - initialize
77 | - lint:
78 | requires:
79 | - initialize
80 | - test:
81 | requires:
82 | - initialize
83 | - build:
84 | requires:
85 | - initialize
86 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "ignorePatterns": ["**/*"],
4 | "plugins": ["@nrwl/nx"],
5 | "overrides": [
6 | {
7 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
8 | "rules": {
9 | "@nrwl/nx/enforce-module-boundaries": [
10 | "error",
11 | {
12 | "enforceBuildableLibDependency": true,
13 | "allow": [],
14 | "depConstraints": [
15 | { "sourceTag": "*", "onlyDependOnLibsWithTags": ["*"] }
16 | ]
17 | }
18 | ]
19 | }
20 | },
21 | {
22 | "files": ["*.ts", "*.tsx"],
23 | "extends": ["plugin:@nrwl/nx/typescript"],
24 | "rules": {}
25 | },
26 | {
27 | "files": ["*.js", "*.jsx"],
28 | "extends": ["plugin:@nrwl/nx/javascript"],
29 | "rules": {}
30 | }
31 | ]
32 | }
33 |
--------------------------------------------------------------------------------
/.firebaserc:
--------------------------------------------------------------------------------
1 | {
2 | "targets": {
3 | "reactive-code-and-animations": {
4 | "hosting": {
5 | "reactive-code-animations": [
6 | "reactive-code-and-animations"
7 | ]
8 | }
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/.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 | yarn-error.log
34 | testem.log
35 | /typings
36 | .firebase
37 |
38 | # System Files
39 | .DS_Store
40 | Thumbs.db
41 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Add files here to ignore them from prettier formatting
2 |
3 | /dist
4 | /coverage
5 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true
3 | }
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "nrwl.angular-console",
4 | "angular.ng-template",
5 | "ms-vscode.vscode-typescript-tslint-plugin",
6 | "esbenp.prettier-vscode",
7 | "firsttris.vscode-jest-runner"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Reactive Code + Animations Examples
2 | Examples from "Best Friends Forever: Reactive Code + Animations" at [ng-conf 2021](https://www.2021.ng-conf.org/).
3 |
4 | This project was generated using [Nx](https://nx.dev).
5 |
6 |
7 |
8 | 🔎 **Nx is a set of Angular CLI power-ups for modern development.**
9 |
10 | ## ☁ Nx Cloud
11 |
12 | ### Computation Memoization in the Cloud
13 |
14 |
15 |
16 | Visit [Nx Cloud](https://nx.app/) to learn more.
17 |
18 |
19 | ## Quick Start
20 | To start the application, run `npm start` and visit http://localhost:4792/ in your browser.
21 |
22 | ## Tooling
23 |
24 | - [Nx](https://nx.dev/)
25 | - [Nx Cloud](https://nx.app/)
26 | - [Angular](https://angular.io/)
27 | - [Jest](https://jestjs.io/en/)
28 | - [Cypress](https://www.cypress.io/)
29 | - [ESLint](https://eslint.org/)
30 | - [CircleCI](https://circleci.com/)
31 |
32 | Thanks for stopping by!
33 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "cli": {
4 | "defaultCollection": "@nrwl/angular",
5 | "analytics": "fe575fcd-3803-43fc-8564-3c5a17d48e1b"
6 | },
7 | "defaultProject": "reactive-code-animations",
8 | "schematics": {
9 | "@nrwl/angular": {
10 | "application": {
11 | "linter": "eslint"
12 | },
13 | "library": {
14 | "linter": "eslint"
15 | },
16 | "storybook-configuration": {
17 | "linter": "eslint"
18 | }
19 | },
20 | "@nrwl/angular:application": {
21 | "style": "scss",
22 | "linter": "eslint",
23 | "unitTestRunner": "jest",
24 | "e2eTestRunner": "cypress"
25 | },
26 | "@nrwl/angular:library": {
27 | "style": "scss",
28 | "linter": "eslint",
29 | "unitTestRunner": "jest"
30 | },
31 | "@nrwl/angular:component": {
32 | "style": "scss"
33 | }
34 | },
35 | "projects": {
36 | "reactive-code-animations": {
37 | "projectType": "application",
38 | "root": "apps/reactive-code-animations",
39 | "sourceRoot": "apps/reactive-code-animations/src",
40 | "prefix": "rca",
41 | "architect": {
42 | "build": {
43 | "builder": "@angular-devkit/build-angular:browser",
44 | "options": {
45 | "outputPath": "dist/apps/reactive-code-animations",
46 | "index": "apps/reactive-code-animations/src/index.html",
47 | "main": "apps/reactive-code-animations/src/main.ts",
48 | "polyfills": "apps/reactive-code-animations/src/polyfills.ts",
49 | "tsConfig": "apps/reactive-code-animations/tsconfig.app.json",
50 | "aot": true,
51 | "assets": [
52 | "apps/reactive-code-animations/src/favicon.ico",
53 | "apps/reactive-code-animations/src/assets"
54 | ],
55 | "styles": ["apps/reactive-code-animations/src/styles.scss"],
56 | "stylePreprocessorOptions": {
57 | "includePaths": ["libs/styles"]
58 | },
59 | "scripts": []
60 | },
61 | "configurations": {
62 | "production": {
63 | "fileReplacements": [
64 | {
65 | "replace": "apps/reactive-code-animations/src/environments/environment.ts",
66 | "with": "apps/reactive-code-animations/src/environments/environment.prod.ts"
67 | }
68 | ],
69 | "optimization": true,
70 | "outputHashing": "all",
71 | "sourceMap": false,
72 | "namedChunks": false,
73 | "extractLicenses": true,
74 | "vendorChunk": false,
75 | "buildOptimizer": true,
76 | "budgets": [
77 | {
78 | "type": "initial",
79 | "maximumWarning": "2mb",
80 | "maximumError": "5mb"
81 | },
82 | {
83 | "type": "anyComponentStyle",
84 | "maximumWarning": "6kb",
85 | "maximumError": "10kb"
86 | }
87 | ]
88 | }
89 | }
90 | },
91 | "serve": {
92 | "builder": "@angular-devkit/build-angular:dev-server",
93 | "options": {
94 | "browserTarget": "reactive-code-animations:build"
95 | },
96 | "configurations": {
97 | "production": {
98 | "browserTarget": "reactive-code-animations:build:production"
99 | }
100 | }
101 | },
102 | "extract-i18n": {
103 | "builder": "@angular-devkit/build-angular:extract-i18n",
104 | "options": {
105 | "browserTarget": "reactive-code-animations:build"
106 | }
107 | },
108 | "lint": {
109 | "builder": "@nrwl/linter:eslint",
110 | "options": {
111 | "lintFilePatterns": [
112 | "apps/reactive-code-animations/src/**/*.ts",
113 | "apps/reactive-code-animations/src/**/*.html"
114 | ]
115 | }
116 | },
117 | "test": {
118 | "builder": "@nrwl/jest:jest",
119 | "outputs": ["coverage/apps/reactive-code-animations"],
120 | "options": {
121 | "jestConfig": "apps/reactive-code-animations/jest.config.js",
122 | "passWithNoTests": true
123 | }
124 | },
125 | "deploy": {
126 | "builder": "@angular/fire:deploy",
127 | "options": {}
128 | }
129 | }
130 | },
131 | "reactive-code-animations-e2e": {
132 | "root": "apps/reactive-code-animations-e2e",
133 | "sourceRoot": "apps/reactive-code-animations-e2e/src",
134 | "projectType": "application",
135 | "architect": {
136 | "e2e": {
137 | "builder": "@nrwl/cypress:cypress",
138 | "options": {
139 | "cypressConfig": "apps/reactive-code-animations-e2e/cypress.json",
140 | "tsConfig": "apps/reactive-code-animations-e2e/tsconfig.e2e.json",
141 | "devServerTarget": "reactive-code-animations:serve"
142 | },
143 | "configurations": {
144 | "production": {
145 | "devServerTarget": "reactive-code-animations:serve:production"
146 | }
147 | }
148 | },
149 | "lint": {
150 | "builder": "@nrwl/linter:eslint",
151 | "options": {
152 | "lintFilePatterns": [
153 | "apps/reactive-code-animations-e2e/**/*.{js,ts}"
154 | ]
155 | }
156 | }
157 | }
158 | },
159 | "styles": {
160 | "projectType": "library",
161 | "root": "libs/styles",
162 | "sourceRoot": "libs/styles/src",
163 | "architect": {}
164 | },
165 | "shared-animations": {
166 | "projectType": "library",
167 | "root": "libs/shared/animations",
168 | "sourceRoot": "libs/shared/animations/src",
169 | "prefix": "reactive-code-animations",
170 | "architect": {
171 | "lint": {
172 | "builder": "@nrwl/linter:eslint",
173 | "options": {
174 | "lintFilePatterns": [
175 | "libs/shared/animations/src/**/*.ts",
176 | "libs/shared/animations/src/**/*.html"
177 | ]
178 | }
179 | },
180 | "test": {
181 | "builder": "@nrwl/jest:jest",
182 | "outputs": ["coverage/libs/shared/animations"],
183 | "options": {
184 | "jestConfig": "libs/shared/animations/jest.config.js",
185 | "passWithNoTests": true
186 | }
187 | }
188 | }
189 | },
190 | "examples-carousel": {
191 | "projectType": "library",
192 | "root": "libs/examples/carousel",
193 | "sourceRoot": "libs/examples/carousel/src",
194 | "prefix": "rca",
195 | "architect": {
196 | "lint": {
197 | "builder": "@nrwl/linter:eslint",
198 | "options": {
199 | "lintFilePatterns": [
200 | "libs/examples/carousel/src/**/*.ts",
201 | "libs/examples/carousel/src/**/*.html"
202 | ]
203 | }
204 | },
205 | "test": {
206 | "builder": "@nrwl/jest:jest",
207 | "outputs": ["coverage/libs/examples/carousel"],
208 | "options": {
209 | "jestConfig": "libs/examples/carousel/jest.config.js",
210 | "passWithNoTests": true
211 | }
212 | }
213 | }
214 | },
215 | "shared-carousel": {
216 | "projectType": "library",
217 | "root": "libs/shared/carousel",
218 | "sourceRoot": "libs/shared/carousel/src",
219 | "prefix": "rca",
220 | "architect": {
221 | "lint": {
222 | "builder": "@nrwl/linter:eslint",
223 | "options": {
224 | "lintFilePatterns": [
225 | "libs/shared/carousel/src/**/*.ts",
226 | "libs/shared/carousel/src/**/*.html"
227 | ]
228 | }
229 | },
230 | "test": {
231 | "builder": "@nrwl/jest:jest",
232 | "outputs": ["coverage/libs/shared/carousel"],
233 | "options": {
234 | "jestConfig": "libs/shared/carousel/jest.config.js",
235 | "passWithNoTests": true
236 | }
237 | }
238 | }
239 | },
240 | "examples-click-counter": {
241 | "projectType": "library",
242 | "root": "libs/examples/click-counter",
243 | "sourceRoot": "libs/examples/click-counter/src",
244 | "prefix": "reactive-code-animations",
245 | "architect": {
246 | "lint": {
247 | "builder": "@nrwl/linter:eslint",
248 | "options": {
249 | "lintFilePatterns": [
250 | "libs/examples/click-counter/src/**/*.ts",
251 | "libs/examples/click-counter/src/**/*.html"
252 | ]
253 | }
254 | },
255 | "test": {
256 | "builder": "@nrwl/jest:jest",
257 | "outputs": ["coverage/libs/examples/click-counter"],
258 | "options": {
259 | "jestConfig": "libs/examples/click-counter/jest.config.js",
260 | "passWithNoTests": true
261 | }
262 | }
263 | }
264 | },
265 | "examples-series": {
266 | "projectType": "library",
267 | "root": "libs/examples/series",
268 | "sourceRoot": "libs/examples/series/src",
269 | "prefix": "reactive-code-animations",
270 | "architect": {
271 | "lint": {
272 | "builder": "@nrwl/linter:eslint",
273 | "options": {
274 | "lintFilePatterns": [
275 | "libs/examples/series/src/**/*.ts",
276 | "libs/examples/series/src/**/*.html"
277 | ]
278 | }
279 | },
280 | "test": {
281 | "builder": "@nrwl/jest:jest",
282 | "outputs": ["coverage/libs/examples/series"],
283 | "options": {
284 | "jestConfig": "libs/examples/series/jest.config.js",
285 | "passWithNoTests": true
286 | }
287 | }
288 | }
289 | }
290 | }
291 | }
292 |
--------------------------------------------------------------------------------
/apps/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/.gitkeep
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7 | "parserOptions": {
8 | "project": "apps/reactive-code-animations-e2e/tsconfig.*?.json"
9 | },
10 | "rules": {}
11 | },
12 | {
13 | "files": ["src/plugins/index.js"],
14 | "rules": {
15 | "@typescript-eslint/no-var-requires": "off",
16 | "no-undef": "off"
17 | }
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/cypress.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileServerFolder": ".",
3 | "fixturesFolder": "./src/fixtures",
4 | "integrationFolder": "./src/integration",
5 | "modifyObstructiveCode": false,
6 | "pluginsFile": "./src/plugins/index",
7 | "supportFile": "./src/support/index.ts",
8 | "video": true,
9 | "videosFolder": "../../dist/cypress/apps/reactive-code-animations-e2e/videos",
10 | "screenshotsFolder": "../../dist/cypress/apps/reactive-code-animations-e2e/screenshots",
11 | "chromeWebSecurity": false
12 | }
13 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/src/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io"
4 | }
5 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/src/integration/app.spec.ts:
--------------------------------------------------------------------------------
1 | // import { getGreeting } from '../support/app.po';
2 |
3 | describe('reactive-code-animations', () => {
4 | beforeEach(() => cy.visit('/'));
5 |
6 | it('should display welcome message', () => {
7 | // Custom command example, see `../support/commands.ts` file
8 | cy.login('my-email@something.com', 'myPassword');
9 |
10 | // Function helper example, see `../support/app.po.ts` file
11 | // getGreeting().contains('Welcome to reactive-code-animations!');
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/src/plugins/index.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example plugins/index.js can be used to load plugins
3 | //
4 | // You can change the location of this file or turn off loading
5 | // the plugins file with the 'pluginsFile' configuration option.
6 | //
7 | // You can read more here:
8 | // https://on.cypress.io/plugins-guide
9 | // ***********************************************************
10 |
11 | // This function is called when a project is opened or re-opened (e.g. due to
12 | // the project's config changing)
13 |
14 | const { preprocessTypescript } = require('@nrwl/cypress/plugins/preprocessor');
15 |
16 | module.exports = (on, config) => {
17 | // `on` is used to hook into various events Cypress emits
18 | // `config` is the resolved Cypress config
19 |
20 | // Preprocess Typescript file using Nx helper
21 | on('file:preprocessor', preprocessTypescript(config));
22 | };
23 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/src/support/app.po.ts:
--------------------------------------------------------------------------------
1 | export const getGreeting = () => cy.get('h1');
2 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/src/support/commands.ts:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 |
11 | // eslint-disable-next-line @typescript-eslint/no-namespace
12 | declare namespace Cypress {
13 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
14 | interface Chainable {
15 | login(email: string, password: string): void;
16 | }
17 | }
18 | //
19 | // -- This is a parent command --
20 | Cypress.Commands.add('login', (email, password) => {
21 | console.log('Custom command example: Login', email, password);
22 | });
23 | //
24 | // -- This is a child command --
25 | // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
26 | //
27 | //
28 | // -- This is a dual command --
29 | // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
30 | //
31 | //
32 | // -- This will overwrite an existing command --
33 | // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
34 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/src/support/index.ts:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/index.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import './commands';
18 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "sourceMap": false,
5 | "outDir": "../../dist/out-tsc",
6 | "allowJs": true,
7 | "types": ["cypress", "node"]
8 | },
9 | "include": ["src/**/*.ts", "src/**/*.js"]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations-e2e/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.e2e.json"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/.browserslistrc:
--------------------------------------------------------------------------------
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 | # For the full list of supported browsers by the Angular framework, please see:
6 | # https://angular.io/guide/browser-support
7 |
8 | # You can see what browsers were selected by your queries by running:
9 | # npx browserslist
10 |
11 | last 1 Chrome version
12 | last 1 Firefox version
13 | last 2 Edge major versions
14 | last 2 Safari major versions
15 | last 2 iOS major versions
16 | Firefox ESR
17 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
18 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts"],
7 | "extends": [
8 | "plugin:@nrwl/nx/angular",
9 | "plugin:@angular-eslint/template/process-inline-templates"
10 | ],
11 | "parserOptions": {
12 | "project": ["apps/reactive-code-animations/tsconfig.*?.json"]
13 | },
14 | "rules": {
15 | "@angular-eslint/directive-selector": [
16 | "error",
17 | {
18 | "type": "attribute",
19 | "prefix": "rca",
20 | "style": "camelCase"
21 | }
22 | ],
23 | "@angular-eslint/component-selector": [
24 | "error",
25 | {
26 | "type": "element",
27 | "prefix": "rca",
28 | "style": "kebab-case"
29 | }
30 | ]
31 | }
32 | },
33 | {
34 | "files": ["*.html"],
35 | "extends": ["plugin:@nrwl/nx/angular-template"],
36 | "rules": {}
37 | }
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'reactive-code-animations',
3 | preset: '../../jest.preset.js',
4 | setupFilesAfterEnv: ['/src/test-setup.ts'],
5 | globals: {
6 | 'ts-jest': {
7 | tsConfig: '/tsconfig.spec.json',
8 | stringifyContentPathRegex: '\\.(html|svg)$',
9 | astTransformers: {
10 | before: [
11 | 'jest-preset-angular/build/InlineFilesTransformer',
12 | 'jest-preset-angular/build/StripStylesTransformer',
13 | ],
14 | },
15 | },
16 | },
17 | coverageDirectory: '../../coverage/apps/reactive-code-animations',
18 | snapshotSerializers: [
19 | 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
20 | 'jest-preset-angular/build/AngularSnapshotSerializer.js',
21 | 'jest-preset-angular/build/HTMLCommentSerializer.js',
22 | ],
23 | };
24 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/app/app.component.scss:
--------------------------------------------------------------------------------
1 | @import 'variables';
2 |
3 | header {
4 | display: flex;
5 | flex-direction: column;
6 | align-items: flex-end;
7 | margin-bottom: 2rem;
8 | }
9 |
10 | .menu-button {
11 | background-color: $main-text;
12 | }
13 |
14 | nav {
15 | margin: 2rem;
16 | margin-top: 0;
17 |
18 | a {
19 | display: inline-block;
20 | text-underline-offset: 3px;
21 | margin: 0 1rem 1rem 0;
22 |
23 | &.active {
24 | font-weight: bold;
25 | }
26 | }
27 | }
28 |
29 | main {
30 | padding: 2rem;
31 | max-width: 1100px;
32 | margin: 0 auto;
33 | min-height: 30rem;
34 | }
35 |
36 | h1 {
37 | padding: 0 3rem 1rem 0;
38 | margin-left: 2rem;
39 | border-bottom: dotted 4px $secondary;
40 | }
41 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { RouterTestingModule } from '@angular/router/testing';
3 | import { AppComponent } from './app.component';
4 |
5 | describe('AppComponent', () => {
6 | beforeEach(async () => {
7 | await TestBed.configureTestingModule({
8 | declarations: [AppComponent],
9 | imports: [RouterTestingModule],
10 | }).compileComponents();
11 | });
12 |
13 | it('should create the app', () => {
14 | const fixture = TestBed.createComponent(AppComponent);
15 | const app = fixture.componentInstance;
16 | expect(app).toBeTruthy();
17 | });
18 |
19 | it('should render title', () => {
20 | const fixture = TestBed.createComponent(AppComponent);
21 | fixture.detectChanges();
22 | const compiled = fixture.nativeElement;
23 | expect(compiled.querySelector('h1').textContent).toContain(
24 | 'Reactive Code + Animations'
25 | );
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | interface MenuItem {
4 | name: string;
5 | path: string;
6 | }
7 | @Component({
8 | selector: 'rca-root',
9 | templateUrl: './app.component.html',
10 | styleUrls: ['./app.component.scss'],
11 | })
12 | export class AppComponent {
13 | menuItems: MenuItem[] = [
14 | { name: 'Click Counter', path: '/examples/click-counter' },
15 | { name: 'Series', path: '/examples/series' },
16 | { name: 'Carousel', path: '/examples/carousel' },
17 | ];
18 | }
19 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
4 |
5 | import { RouterModule } from '@angular/router';
6 |
7 | import { AppComponent } from './app.component';
8 |
9 | const APP_ROUTES = [
10 | {
11 | path: 'examples/carousel',
12 | loadChildren: () =>
13 | import('libs/examples/carousel/src/lib/examples-carousel.module').then(
14 | (m) => m.ExamplesCarouselModule
15 | ),
16 | },
17 | {
18 | path: 'examples/click-counter',
19 | loadChildren: () =>
20 | import(
21 | 'libs/examples/click-counter/src/lib/examples-click-counter.module'
22 | ).then((m) => m.ExamplesClickCounterModule),
23 | },
24 | {
25 | path: 'examples/series',
26 | loadChildren: () =>
27 | import('libs/examples/series/src/lib/examples-series.module').then(
28 | (m) => m.ExamplesSeriesModule
29 | ),
30 | },
31 | {
32 | path: '**',
33 | redirectTo: '/examples/carousel',
34 | pathMatch: 'full',
35 | },
36 | ];
37 |
38 | @NgModule({
39 | declarations: [AppComponent],
40 | imports: [
41 | BrowserModule,
42 | BrowserAnimationsModule,
43 | RouterModule.forRoot(APP_ROUTES),
44 | ],
45 | providers: [],
46 | bootstrap: [AppComponent],
47 | })
48 | export class AppModule {}
49 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/.gitkeep
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/illustration1-code.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/illustration1-keyboard.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/illustration1-nx-cloud-layer.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/illustration1-nx-layer.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/spongebob/gary-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/spongebob/gary-01.png
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/spongebob/gary-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/spongebob/gary-02.png
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/spongebob/gary-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/spongebob/gary-03.png
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/spongebob/patrick-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/spongebob/patrick-01.png
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/spongebob/patrick-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/spongebob/patrick-02.png
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/spongebob/patrick-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/spongebob/patrick-03.png
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/spongebob/spongebob-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/spongebob/spongebob-01.png
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/spongebob/spongebob-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/spongebob/spongebob-02.png
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/assets/spongebob/spongebob-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/apps/reactive-code-animations/src/assets/spongebob/spongebob-03.png
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true,
3 | };
4 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false,
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Reactive Code + Animations
6 |
7 |
8 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/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()
12 | .bootstrapModule(AppModule)
13 | .catch((err) => console.error(err));
14 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /**
22 | * IE11 requires the following for NgClass support on SVG elements
23 | */
24 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
25 |
26 | /**
27 | * Web Animations `@angular/platform-browser/animations`
28 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
29 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
30 | */
31 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
32 |
33 | /**
34 | * By default, zone.js will patch all possible macroTask and DomEvents
35 | * user can disable parts of macroTask/DomEvents patch by setting following flags
36 | * because those flags need to be set before `zone.js` being loaded, and webpack
37 | * will put import in the top of bundle, so user need to create a separate file
38 | * in this directory (for example: zone-flags.ts), and put the following flags
39 | * into that file, and then add the following code before importing zone.js.
40 | * import './zone-flags';
41 | *
42 | * The flags allowed in zone-flags.ts are listed here.
43 | *
44 | * The following flags will work for all browsers.
45 | *
46 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
47 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
48 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
49 | *
50 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
51 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
52 | *
53 | * (window as any).__Zone_enable_cross_context_check = true;
54 | *
55 | */
56 |
57 | /***************************************************************************************************
58 | * Zone JS is required by default for Angular itself.
59 | */
60 | import 'zone.js/dist/zone'; // Included with Angular CLI.
61 |
62 | /***************************************************************************************************
63 | * APPLICATION IMPORTS
64 | */
65 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/styles.scss:
--------------------------------------------------------------------------------
1 | @import 'base';
2 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/src/test-setup.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": []
6 | },
7 | "files": ["src/main.ts", "src/polyfills.ts"]
8 | }
9 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/tsconfig.editor.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "include": ["**/*.ts"],
4 | "compilerOptions": {
5 | "types": ["jest", "node"]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.app.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | },
12 | {
13 | "path": "./tsconfig.editor.json"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/apps/reactive-code-animations/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "files": ["src/test-setup.ts"],
9 | "include": ["**/*.spec.ts", "**/*.d.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/decorate-angular-cli.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This file decorates the Angular CLI with the Nx CLI to enable features such as computation caching
3 | * and faster execution of tasks.
4 | *
5 | * It does this by:
6 | *
7 | * - Patching the Angular CLI to warn you in case you accidentally use the undecorated ng command.
8 | * - Symlinking the ng to nx command, so all commands run through the Nx CLI
9 | * - Updating the package.json postinstall script to give you control over this script
10 | *
11 | * The Nx CLI decorates the Angular CLI, so the Nx CLI is fully compatible with it.
12 | * Every command you run should work the same when using the Nx CLI, except faster.
13 | *
14 | * Because of symlinking you can still type `ng build/test/lint` in the terminal. The ng command, in this case,
15 | * will point to nx, which will perform optimizations before invoking ng. So the Angular CLI is always invoked.
16 | * The Nx CLI simply does some optimizations before invoking the Angular CLI.
17 | *
18 | * To opt out of this patch:
19 | * - Replace occurrences of nx with ng in your package.json
20 | * - Remove the script from your postinstall script in your package.json
21 | * - Delete and reinstall your node_modules
22 | */
23 |
24 | const fs = require('fs');
25 | const os = require('os');
26 | const cp = require('child_process');
27 | const isWindows = os.platform() === 'win32';
28 | let output;
29 | try {
30 | output = require('@nrwl/workspace').output;
31 | } catch (e) {
32 | console.warn('Angular CLI could not be decorated to enable computation caching. Please ensure @nrwl/workspace is installed.');
33 | process.exit(0);
34 | }
35 |
36 | /**
37 | * Symlink of ng to nx, so you can keep using `ng build/test/lint` and still
38 | * invoke the Nx CLI and get the benefits of computation caching.
39 | */
40 | function symlinkNgCLItoNxCLI() {
41 | try {
42 | const ngPath = './node_modules/.bin/ng';
43 | const nxPath = './node_modules/.bin/nx';
44 | if (isWindows) {
45 | /**
46 | * This is the most reliable way to create symlink-like behavior on Windows.
47 | * Such that it works in all shells and works with npx.
48 | */
49 | ['', '.cmd', '.ps1'].forEach(ext => {
50 | if (fs.existsSync(nxPath + ext)) fs.writeFileSync(ngPath + ext, fs.readFileSync(nxPath + ext));
51 | });
52 | } else {
53 | // If unix-based, symlink
54 | cp.execSync(`ln -sf ./nx ${ngPath}`);
55 | }
56 | }
57 | catch(e) {
58 | output.error({ title: 'Unable to create a symlink from the Angular CLI to the Nx CLI:' + e.message });
59 | throw e;
60 | }
61 | }
62 |
63 | try {
64 | symlinkNgCLItoNxCLI();
65 | require('@nrwl/cli/lib/decorate-cli').decorateCli();
66 | output.log({ title: 'Angular CLI has been decorated to enable computation caching.' });
67 | } catch(e) {
68 | output.error({ title: 'Decoration of the Angular CLI did not complete successfully' });
69 | }
70 |
--------------------------------------------------------------------------------
/firebase.json:
--------------------------------------------------------------------------------
1 | {
2 | "hosting": [
3 | {
4 | "target": "reactive-code-animations",
5 | "public": "dist/apps/reactive-code-animations",
6 | "ignore": [
7 | "**/.*"
8 | ],
9 | "headers": [
10 | {
11 | "source": "*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)",
12 | "headers": [
13 | {
14 | "key": "Cache-Control",
15 | "value": "public,max-age=31536000,immutable"
16 | }
17 | ]
18 | }
19 | ],
20 | "rewrites": [
21 | {
22 | "source": "**",
23 | "destination": "/index.html"
24 | }
25 | ]
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | projects: [
3 | '/apps/reactive-code-animations',
4 | '/libs/styles',
5 | '/libs/shared/animations',
6 | '/libs/examples/carousel',
7 | '/libs/shared/carousel',
8 | '/libs/examples/click-counter',
9 | '/libs/examples/series',
10 | ],
11 | };
12 |
--------------------------------------------------------------------------------
/jest.preset.js:
--------------------------------------------------------------------------------
1 | const nxPreset = require('@nrwl/jest/preset');
2 |
3 | module.exports = { ...nxPreset };
4 |
--------------------------------------------------------------------------------
/libs/examples/carousel/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts"],
7 | "extends": [
8 | "plugin:@nrwl/nx/angular",
9 | "plugin:@angular-eslint/template/process-inline-templates"
10 | ],
11 | "parserOptions": {
12 | "project": ["libs/examples/carousel/tsconfig.*?.json"]
13 | },
14 | "rules": {
15 | "@angular-eslint/directive-selector": [
16 | "error",
17 | {
18 | "type": "attribute",
19 | "prefix": "rca",
20 | "style": "camelCase"
21 | }
22 | ],
23 | "@angular-eslint/component-selector": [
24 | "error",
25 | {
26 | "type": "element",
27 | "prefix": "rca",
28 | "style": "kebab-case"
29 | }
30 | ]
31 | }
32 | },
33 | {
34 | "files": ["*.html"],
35 | "extends": ["plugin:@nrwl/nx/angular-template"],
36 | "rules": {}
37 | }
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/libs/examples/carousel/README.md:
--------------------------------------------------------------------------------
1 | # examples-carousel
2 |
3 | This library was generated with [Nx](https://nx.dev).
4 |
5 | ## Running unit tests
6 |
7 | Run `nx test examples-carousel` to execute the unit tests.
8 |
--------------------------------------------------------------------------------
/libs/examples/carousel/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'examples-carousel',
3 | preset: '../../../jest.preset.js',
4 | setupFilesAfterEnv: ['/src/test-setup.ts'],
5 | globals: {
6 | 'ts-jest': {
7 | tsConfig: '/tsconfig.spec.json',
8 | stringifyContentPathRegex: '\\.(html|svg)$',
9 | astTransformers: {
10 | before: [
11 | 'jest-preset-angular/build/InlineFilesTransformer',
12 | 'jest-preset-angular/build/StripStylesTransformer',
13 | ],
14 | },
15 | },
16 | },
17 | coverageDirectory: '../../../coverage/libs/examples/carousel',
18 | snapshotSerializers: [
19 | 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
20 | 'jest-preset-angular/build/AngularSnapshotSerializer.js',
21 | 'jest-preset-angular/build/HTMLCommentSerializer.js',
22 | ],
23 | };
24 |
--------------------------------------------------------------------------------
/libs/examples/carousel/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/examples-carousel.module';
2 |
--------------------------------------------------------------------------------
/libs/examples/carousel/src/lib/carousel/carousel.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
14 |
19 |
20 |
21 |
26 |
31 |
36 |
37 |
38 |
43 |
44 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/libs/examples/carousel/src/lib/carousel/carousel.component.scss:
--------------------------------------------------------------------------------
1 | @import 'variables';
2 |
3 | :host {
4 | display: flex;
5 | justify-content: center;
6 | width: 100%;
7 | }
8 |
9 | .carousel-item-images {
10 | align-items: flex-end;
11 | display: flex;
12 | flex-direction: column;
13 | }
14 |
15 | img {
16 | border-radius: 50%;
17 | }
18 |
19 | .size-sm {
20 | height: 10rem;
21 | width: 10rem;
22 | }
23 |
24 | .size-md {
25 | height: 15rem;
26 | width: 15rem;
27 | }
28 |
29 | .size-lg {
30 | height: 20rem;
31 | width: 20rem;
32 | }
33 |
34 | .size-xl {
35 | height: 25rem;
36 | width: 25rem;
37 | }
38 |
39 | .m-sm {
40 | margin-top: 4rem;
41 | }
42 |
43 | .m-md {
44 | margin-top: 8rem;
45 | }
46 |
47 | .m-lg {
48 | margin-top: 12rem;
49 | }
50 |
--------------------------------------------------------------------------------
/libs/examples/carousel/src/lib/carousel/carousel.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'rca-example-carousel',
5 | templateUrl: './carousel.component.html',
6 | styleUrls: ['./carousel.component.scss'],
7 | })
8 | export class CarouselComponent {}
9 |
--------------------------------------------------------------------------------
/libs/examples/carousel/src/lib/examples-carousel.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { RouterModule, Route } from '@angular/router';
4 | import { CarouselComponent } from './carousel/carousel.component';
5 | import { SharedCarouselModule } from '@rca/shared/carousel';
6 |
7 | export const examplesCarouselRoutes: Route[] = [
8 | { path: '', component: CarouselComponent },
9 | ];
10 |
11 | @NgModule({
12 | imports: [
13 | CommonModule,
14 | RouterModule.forChild(examplesCarouselRoutes),
15 | SharedCarouselModule,
16 | ],
17 | declarations: [CarouselComponent],
18 | })
19 | export class ExamplesCarouselModule {}
20 |
--------------------------------------------------------------------------------
/libs/examples/carousel/src/test-setup.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 |
--------------------------------------------------------------------------------
/libs/examples/carousel/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/libs/examples/carousel/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "target": "es2015",
6 | "declaration": true,
7 | "declarationMap": true,
8 | "inlineSources": true,
9 | "types": [],
10 | "lib": ["dom", "es2018"]
11 | },
12 | "angularCompilerOptions": {
13 | "skipTemplateCodegen": true,
14 | "strictMetadataEmit": true,
15 | "enableResourceInlining": true
16 | },
17 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"],
18 | "include": ["**/*.ts"]
19 | }
20 |
--------------------------------------------------------------------------------
/libs/examples/carousel/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "files": ["src/test-setup.ts"],
9 | "include": ["**/*.spec.ts", "**/*.d.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts"],
7 | "extends": [
8 | "plugin:@nrwl/nx/angular",
9 | "plugin:@angular-eslint/template/process-inline-templates"
10 | ],
11 | "parserOptions": {
12 | "project": ["libs/examples/click-counter/tsconfig.*?.json"]
13 | },
14 | "rules": {
15 | "@angular-eslint/directive-selector": [
16 | "error",
17 | {
18 | "type": "attribute",
19 | "prefix": "reactive-code-animations",
20 | "style": "camelCase"
21 | }
22 | ],
23 | "@angular-eslint/component-selector": [
24 | "error",
25 | {
26 | "type": "element",
27 | "prefix": "reactive-code-animations",
28 | "style": "kebab-case"
29 | }
30 | ]
31 | }
32 | },
33 | {
34 | "files": ["*.html"],
35 | "extends": ["plugin:@nrwl/nx/angular-template"],
36 | "rules": {}
37 | }
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/README.md:
--------------------------------------------------------------------------------
1 | # examples-click-counter
2 |
3 | This library was generated with [Nx](https://nx.dev).
4 |
5 | ## Running unit tests
6 |
7 | Run `nx test examples-click-counter` to execute the unit tests.
8 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'examples-click-counter',
3 | preset: '../../../jest.preset.js',
4 | setupFilesAfterEnv: ['/src/test-setup.ts'],
5 | globals: {
6 | 'ts-jest': {
7 | tsConfig: '/tsconfig.spec.json',
8 | stringifyContentPathRegex: '\\.(html|svg)$',
9 | astTransformers: {
10 | before: [
11 | 'jest-preset-angular/build/InlineFilesTransformer',
12 | 'jest-preset-angular/build/StripStylesTransformer',
13 | ],
14 | },
15 | },
16 | },
17 | coverageDirectory: '../../../coverage/libs/examples/click-counter',
18 | snapshotSerializers: [
19 | 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
20 | 'jest-preset-angular/build/AngularSnapshotSerializer.js',
21 | 'jest-preset-angular/build/HTMLCommentSerializer.js',
22 | ],
23 | };
24 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/examples-click-counter.module';
2 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/chart-data.function.ts:
--------------------------------------------------------------------------------
1 | import { combineLatest, Observable } from 'rxjs';
2 | import { map, scan, startWith, tap } from 'rxjs/operators';
3 |
4 | export interface CreateChartDataParams {
5 | oneSecondWindow: Observable;
6 | fiveSecondWindow: Observable;
7 | fifteenSecondWindow: Observable;
8 | }
9 |
10 | export interface SeriesDataPoint {
11 | clicksPerWindow: number;
12 | timeElapsed: number;
13 | }
14 |
15 | export interface ChartData {
16 | oneSecond: SeriesDataPoint[];
17 | fiveSeconds: SeriesDataPoint[];
18 | fifteenSeconds: SeriesDataPoint[];
19 | }
20 |
21 | export function createChartData({
22 | oneSecondWindow,
23 | fiveSecondWindow,
24 | fifteenSecondWindow,
25 | }: CreateChartDataParams): Observable {
26 | let startTime: Date;
27 | const initialData: ChartData = {
28 | oneSecond: [{ clicksPerWindow: 0, timeElapsed: 0 }],
29 | fiveSeconds: [{ clicksPerWindow: 0, timeElapsed: 0 }],
30 | fifteenSeconds: [{ clicksPerWindow: 0, timeElapsed: 0 }],
31 | };
32 | return combineLatest([
33 | oneSecondWindow,
34 | fiveSecondWindow,
35 | fifteenSecondWindow,
36 | ]).pipe(
37 | tap(() => {
38 | if (!startTime) {
39 | startTime = new Date();
40 | }
41 | }),
42 | map(([one, five, fifteen]) => {
43 | const date = new Date();
44 | const timeElapsed = (date as any) - (startTime as any);
45 | return {
46 | one: { clicksPerWindow: one, timeElapsed },
47 | five: { clicksPerWindow: five, timeElapsed },
48 | fifteen: { clicksPerWindow: fifteen, timeElapsed },
49 | };
50 | }),
51 | scan(
52 | (acc, curr) => ({
53 | oneSecond: acc.oneSecond.concat([curr.one]),
54 | fiveSeconds: acc.fiveSeconds.concat([curr.five]),
55 | fifteenSeconds: acc.fifteenSeconds.concat([curr.fifteen]),
56 | }),
57 | initialData
58 | ),
59 | startWith(initialData)
60 | );
61 | }
62 |
63 | export function convertToFormattedData(
64 | chartData: SeriesDataPoint
65 | ): { x: number; y: number } {
66 | return {
67 | x: chartData.timeElapsed / 1000,
68 | y: chartData.clicksPerWindow,
69 | };
70 | }
71 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/click-counter/click-counter.component.html:
--------------------------------------------------------------------------------
1 | Click Me!
2 | Clicks in Last Second: {{ lastSecondCounter$ | async }}
3 | Clicks in Last 5 Seconds: {{ lastFiveSecondsCounter$ | async }}
4 | Clicks in Last 15 Seconds: {{ lastFifteenSecondsCounter$ | async }}
5 | Total Count: {{ clickCounter$ | async }}
6 |
9 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/click-counter/click-counter.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/libs/examples/click-counter/src/lib/click-counter/click-counter.component.scss
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/click-counter/click-counter.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ClickCounterComponent } from './click-counter.component';
4 |
5 | describe('ClickCounterComponent', () => {
6 | let component: ClickCounterComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [ClickCounterComponent],
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(ClickCounterComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | xit('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/click-counter/click-counter.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
2 | import { fromEvent, Observable } from 'rxjs';
3 | import { scan, startWith } from 'rxjs/operators';
4 | import { ChartData, createChartData } from '../chart-data.function';
5 | import { windowedCount } from '../windowed-count.function';
6 |
7 | function createClickObservable(target: ElementRef): Observable {
8 | return fromEvent(target.nativeElement, 'click');
9 | }
10 |
11 | function count(incoming: Observable): Observable {
12 | return incoming.pipe(
13 | scan((acc) => acc + 1, 0),
14 | startWith(0)
15 | );
16 | }
17 |
18 | @Component({
19 | selector: 'reactive-code-animations-click-counter',
20 | templateUrl: './click-counter.component.html',
21 | styleUrls: ['./click-counter.component.scss'],
22 | })
23 | export class ClickCounterComponent implements OnInit {
24 | @ViewChild('button', { static: true }) button: ElementRef;
25 | private _buttonClicks$: Observable;
26 | clickCounter$: Observable;
27 | lastSecondCounter$: Observable;
28 | lastFiveSecondsCounter$: Observable;
29 | lastFifteenSecondsCounter$: Observable;
30 | chartData$: Observable;
31 |
32 | ngOnInit(): void {
33 | this._buttonClicks$ = createClickObservable(this.button);
34 | this.clickCounter$ = this._buttonClicks$.pipe(count);
35 | this.lastSecondCounter$ = this._buttonClicks$.pipe(windowedCount(1000));
36 | this.lastFiveSecondsCounter$ = this._buttonClicks$.pipe(
37 | windowedCount(5000)
38 | );
39 | this.lastFifteenSecondsCounter$ = this._buttonClicks$.pipe(
40 | windowedCount(15000)
41 | );
42 | this.chartData$ = createChartData({
43 | oneSecondWindow: this.lastSecondCounter$,
44 | fiveSecondWindow: this.lastFiveSecondsCounter$,
45 | fifteenSecondWindow: this.lastFifteenSecondsCounter$,
46 | });
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/examples-click-counter.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { RouterModule } from '@angular/router';
4 | import { ClickCounterComponent } from './click-counter/click-counter.component';
5 | import { LineChartComponent } from './line-chart/line-chart.component';
6 | import { ImperativeClickCounterComponent } from './imperative-click-counter/imperative-click-counter.component';
7 |
8 | @NgModule({
9 | imports: [
10 | CommonModule,
11 | RouterModule.forChild([
12 | { path: '', component: ClickCounterComponent },
13 | { path: 'imperative', component: ImperativeClickCounterComponent },
14 | ]),
15 | ],
16 | declarations: [
17 | ClickCounterComponent,
18 | LineChartComponent,
19 | ImperativeClickCounterComponent,
20 | ],
21 | })
22 | export class ExamplesClickCounterModule {}
23 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/imperative-click-counter/imperative-click-counter.component.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/libs/examples/click-counter/src/lib/imperative-click-counter/imperative-click-counter.component.css
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/imperative-click-counter/imperative-click-counter.component.html:
--------------------------------------------------------------------------------
1 | Click Me!
2 | Total Count: {{ count }}
3 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/imperative-click-counter/imperative-click-counter.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ImperativeClickCounterComponent } from './imperative-click-counter.component';
4 |
5 | describe('ImperativeClickCounterComponent', () => {
6 | let component: ImperativeClickCounterComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [ ImperativeClickCounterComponent ]
12 | })
13 | .compileComponents();
14 | });
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(ImperativeClickCounterComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/imperative-click-counter/imperative-click-counter.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'reactive-code-animations-imperative-click-counter',
5 | templateUrl: './imperative-click-counter.component.html',
6 | styleUrls: ['./imperative-click-counter.component.css'],
7 | })
8 | export class ImperativeClickCounterComponent {
9 | count = 0;
10 |
11 | addOne() {
12 | this.count++;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/line-chart/line-chart.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/line-chart/line-chart.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/libs/examples/click-counter/src/lib/line-chart/line-chart.component.scss
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/line-chart/line-chart.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { LineChartComponent } from './line-chart.component';
4 |
5 | describe('LineChartComponent', () => {
6 | let component: LineChartComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [LineChartComponent],
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(LineChartComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | xit('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/line-chart/line-chart.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component,
3 | ElementRef,
4 | Input,
5 | OnChanges,
6 | OnInit,
7 | SimpleChanges,
8 | ViewChild,
9 | } from '@angular/core';
10 | import { Chart } from 'chart.js';
11 | import { ChartData, convertToFormattedData } from '../chart-data.function';
12 |
13 | @Component({
14 | selector: 'reactive-code-animations-line-chart',
15 | templateUrl: './line-chart.component.html',
16 | styleUrls: ['./line-chart.component.scss'],
17 | })
18 | export class LineChartComponent implements OnInit, OnChanges {
19 | @ViewChild('canvas', { static: true }) canvas: ElementRef;
20 | @Input() data: ChartData;
21 | chart;
22 | config;
23 | initialized = false;
24 |
25 | ngOnInit(): void {
26 | this.config = {
27 | data: {
28 | datasets: [
29 | {
30 | label: 'One Second',
31 | data: this.data.oneSecond.map(convertToFormattedData),
32 | borderColor: 'rgb(255, 99, 132)',
33 | backgroundColor: Chart.helpers
34 | .color('rgb(255, 99, 132)')
35 | .alpha(0.2)
36 | .rgbString(),
37 | showLine: true,
38 | lineWidth: 5,
39 | pointRadius: 0,
40 | pointHoverRadius: 0,
41 | },
42 | {
43 | label: 'Five Seconds',
44 | data: this.data.fiveSeconds.map(convertToFormattedData),
45 | borderColor: 'rgb(54, 162, 235)',
46 | backgroundColor: Chart.helpers
47 | .color('rgb(54, 162, 235)')
48 | .alpha(0.2)
49 | .rgbString(),
50 | showLine: true,
51 | lineWidth: 5,
52 | pointRadius: 0,
53 | pointHoverRadius: 0,
54 | },
55 | {
56 | label: 'Fifteen Seconds',
57 | data: this.data.fifteenSeconds.map(convertToFormattedData),
58 | borderColor: 'rgb(255, 159, 64)',
59 | backgroundColor: Chart.helpers
60 | .color('rgb(255, 159, 64)')
61 | .alpha(0.2)
62 | .rgbString(),
63 | showLine: true,
64 | lineWidth: 5,
65 | pointRadius: 0,
66 | pointHoverRadius: 0,
67 | animations: {
68 | tension: {
69 | duration: 1000,
70 | easing: 'linear',
71 | from: 1,
72 | to: 0,
73 | loop: true,
74 | },
75 | },
76 | },
77 | ],
78 | },
79 | type: 'scatter',
80 | options: {
81 | animations: {
82 | tension: {
83 | duration: 1000,
84 | easing: 'linear',
85 | from: 1,
86 | to: 0,
87 | loop: true,
88 | },
89 | },
90 | responsive: false,
91 | title: {
92 | display: true,
93 | text: 'Clicks Per Sliding Window',
94 | },
95 | // tooltips: {
96 | // mode: 'nearest',
97 | // intersect: false,
98 | // },
99 | // hover: {
100 | // mode: 'nearest',
101 | // intersect: true,
102 | // },
103 | scales: {
104 | xAxes: [
105 | {
106 | display: true,
107 | scaleLabel: {
108 | display: true,
109 | labelString: 'Time Elapsed',
110 | },
111 | ticks: {
112 | min: 0,
113 | max: 1,
114 | },
115 | },
116 | ],
117 | yAxes: [
118 | {
119 | display: true,
120 | scaleLabel: {
121 | display: true,
122 | labelString: 'Clicks Per Window',
123 | },
124 | ticks: {
125 | min: 0,
126 | max: 1,
127 | },
128 | },
129 | ],
130 | },
131 | },
132 | };
133 | const ctx = (document.getElementById(
134 | 'chart'
135 | ) as HTMLCanvasElement).getContext('2d');
136 | this.chart = new Chart(ctx, this.config);
137 | this.initialized = true;
138 | }
139 |
140 | ngOnChanges(changes: SimpleChanges) {
141 | if (!this.initialized) {
142 | return;
143 | }
144 | if (changes.data) {
145 | for (const property of [
146 | 'oneSecond',
147 | 'fiveSeconds',
148 | 'fifteenSeconds',
149 | ] as const) {
150 | const lastValueOfCurrent =
151 | changes.data.currentValue[property][
152 | changes.data.currentValue[property].length - 1
153 | ];
154 | const lastValueOfPrevious =
155 | changes.data.previousValue[property][
156 | changes.data.previousValue[property].length - 1
157 | ];
158 | if (
159 | lastValueOfCurrent.clicksPerWindow !==
160 | lastValueOfPrevious.clicksPerWindow
161 | ) {
162 | const index =
163 | property === 'oneSecond' ? 0 : property === 'fiveSeconds' ? 1 : 2;
164 | this.config.data.datasets[index].data.push(
165 | convertToFormattedData(lastValueOfCurrent)
166 | );
167 | this.config.options.scales.xAxes[0].ticks.max =
168 | lastValueOfCurrent.timeElapsed / 1000;
169 | if (
170 | property === 'fifteenSeconds' &&
171 | lastValueOfCurrent.clicksPerWindow >
172 | this.config.options.scales.yAxes[0].ticks.max
173 | ) {
174 | this.config.options.scales.yAxes[0].ticks.max =
175 | lastValueOfCurrent.clicksPerWindow;
176 | }
177 | this.chart.update();
178 | }
179 | }
180 | }
181 | }
182 | }
183 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/lib/windowed-count.function.ts:
--------------------------------------------------------------------------------
1 | import { Observable, timer } from 'rxjs';
2 | import { mergeMap, take, map, scan, startWith } from 'rxjs/operators';
3 |
4 | export function windowedCount(windowLength: number) {
5 | return function (incoming: Observable): Observable {
6 | return incoming.pipe(
7 | mergeMap(() =>
8 | timer(0, windowLength).pipe(
9 | take(2),
10 | map((_, i) => (i === 0 ? ('start' as const) : ('stop' as const)))
11 | )
12 | ),
13 | scan((acc, signal) => (signal === 'start' ? acc + 1 : acc - 1), 0),
14 | startWith(0)
15 | );
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/src/test-setup.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "target": "es2015",
6 | "declaration": true,
7 | "declarationMap": true,
8 | "inlineSources": true,
9 | "types": [],
10 | "lib": ["dom", "es2018"]
11 | },
12 | "angularCompilerOptions": {
13 | "skipTemplateCodegen": true,
14 | "strictMetadataEmit": true,
15 | "enableResourceInlining": true
16 | },
17 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"],
18 | "include": ["**/*.ts"]
19 | }
20 |
--------------------------------------------------------------------------------
/libs/examples/click-counter/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "files": ["src/test-setup.ts"],
9 | "include": ["**/*.spec.ts", "**/*.d.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/libs/examples/series/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts"],
7 | "extends": [
8 | "plugin:@nrwl/nx/angular",
9 | "plugin:@angular-eslint/template/process-inline-templates"
10 | ],
11 | "parserOptions": { "project": ["libs/examples/series/tsconfig.*?.json"] },
12 | "rules": {
13 | "@angular-eslint/directive-selector": [
14 | "error",
15 | {
16 | "type": "attribute",
17 | "prefix": "rca",
18 | "style": "camelCase"
19 | }
20 | ],
21 | "@angular-eslint/component-selector": [
22 | "error",
23 | {
24 | "type": "element",
25 | "prefix": "rca",
26 | "style": "kebab-case"
27 | }
28 | ]
29 | }
30 | },
31 | {
32 | "files": ["*.html"],
33 | "extends": ["plugin:@nrwl/nx/angular-template"],
34 | "rules": {}
35 | }
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------
/libs/examples/series/README.md:
--------------------------------------------------------------------------------
1 | # examples-series
2 |
3 | This library was generated with [Nx](https://nx.dev).
4 |
5 | ## Running unit tests
6 |
7 | Run `nx test examples-series` to execute the unit tests.
8 |
--------------------------------------------------------------------------------
/libs/examples/series/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'examples-series',
3 | preset: '../../../jest.preset.js',
4 | setupFilesAfterEnv: ['/src/test-setup.ts'],
5 | globals: {
6 | 'ts-jest': {
7 | tsConfig: '/tsconfig.spec.json',
8 | stringifyContentPathRegex: '\\.(html|svg)$',
9 | astTransformers: {
10 | before: [
11 | 'jest-preset-angular/build/InlineFilesTransformer',
12 | 'jest-preset-angular/build/StripStylesTransformer',
13 | ],
14 | },
15 | },
16 | },
17 | coverageDirectory: '../../../coverage/libs/examples/series',
18 | snapshotSerializers: [
19 | 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
20 | 'jest-preset-angular/build/AngularSnapshotSerializer.js',
21 | 'jest-preset-angular/build/HTMLCommentSerializer.js',
22 | ],
23 | };
24 |
--------------------------------------------------------------------------------
/libs/examples/series/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/examples-series.module';
2 |
--------------------------------------------------------------------------------
/libs/examples/series/src/lib/examples-series.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { RouterModule, Route } from '@angular/router';
4 | import { SeriesExampleComponent } from './series-example/series-example.component';
5 |
6 | export const examplesSeriesRoutes: Route[] = [
7 | {
8 | path: '',
9 | component: SeriesExampleComponent,
10 | },
11 | ];
12 |
13 | @NgModule({
14 | imports: [CommonModule, RouterModule.forChild(examplesSeriesRoutes)],
15 | declarations: [SeriesExampleComponent],
16 | })
17 | export class ExamplesSeriesModule {}
18 |
--------------------------------------------------------------------------------
/libs/examples/series/src/lib/series-example/series-example.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ item }}
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 | Load more
17 |
18 |
19 |
--------------------------------------------------------------------------------
/libs/examples/series/src/lib/series-example/series-example.component.scss:
--------------------------------------------------------------------------------
1 | @import 'variables';
2 |
3 | .blocks {
4 | display: flex;
5 | flex-wrap: wrap;
6 | }
7 |
8 | .block {
9 | background-color: $primary;
10 | color: white;
11 | font-size: 2.5rem;
12 | display: flex;
13 | align-items: center;
14 | justify-content: center;
15 | height: 10rem;
16 | width: 15rem;
17 | margin: 0 1rem 1rem 0;
18 | }
19 |
20 | .load-more-control {
21 | display: flex;
22 | flex-direction: column;
23 | align-items: center;
24 | justify-content: center;
25 | margin: 2rem;
26 | }
27 |
28 | .loading-animation {
29 | display: flex;
30 | justify-content: center;
31 | margin: 2rem;
32 | min-height: 2rem;
33 | }
34 |
35 | .loading-dot {
36 | animation: pulse 1s infinite alternate ease-out;
37 | background-color: $secondary-dark;
38 | border-radius: 50%;
39 | display: block;
40 | height: 1rem;
41 | width: 1rem;
42 |
43 | &:not(:last-child) {
44 | margin-right: 2rem;
45 | }
46 | }
47 |
48 | @keyframes pulse {
49 | from {
50 | transform: scale(0.5);
51 | }
52 |
53 | to {
54 | transform: scale(1);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/libs/examples/series/src/lib/series-example/series-example.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | query,
3 | stagger,
4 | style,
5 | transition,
6 | trigger,
7 | useAnimation,
8 | } from '@angular/animations';
9 | import { Component } from '@angular/core';
10 | import { fadeInAnimation, fadeOutAnimation } from '@rca/shared/animations';
11 | import { BehaviorSubject, timer } from 'rxjs';
12 |
13 | @Component({
14 | selector: 'rca-series-example',
15 | templateUrl: './series-example.component.html',
16 | styleUrls: ['./series-example.component.scss'],
17 | animations: [
18 | trigger('rotateInStaggeredAnimation', [
19 | transition('* => *', [
20 | query(
21 | ':enter',
22 | [
23 | style({ opacity: 0 }),
24 | stagger(100, [useAnimation(fadeInAnimation)]),
25 | ],
26 | {
27 | optional: true,
28 | }
29 | ),
30 | query(':leave', [stagger(0, [useAnimation(fadeOutAnimation)])], {
31 | optional: true,
32 | }),
33 | ]),
34 | ]),
35 | ],
36 | })
37 | export class SeriesExampleComponent {
38 | items = ['a', 'b', 'c', 'd'];
39 | items$ = new BehaviorSubject>(this.items);
40 | complete = false;
41 | isLoading = false;
42 |
43 | trackByFn(index, item) {
44 | return index;
45 | }
46 |
47 | loadMore() {
48 | this.isLoading = true;
49 | timer(3000).subscribe((_) => {
50 | this.items$.next([...this.items, 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm']);
51 | this.isLoading = false;
52 | this.complete = true;
53 | });
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/libs/examples/series/src/test-setup.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 |
--------------------------------------------------------------------------------
/libs/examples/series/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/libs/examples/series/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "target": "es2015",
6 | "declaration": true,
7 | "declarationMap": true,
8 | "inlineSources": true,
9 | "types": [],
10 | "lib": ["dom", "es2018"]
11 | },
12 | "angularCompilerOptions": {
13 | "skipTemplateCodegen": true,
14 | "strictMetadataEmit": true,
15 | "enableResourceInlining": true
16 | },
17 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"],
18 | "include": ["**/*.ts"]
19 | }
20 |
--------------------------------------------------------------------------------
/libs/examples/series/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "files": ["src/test-setup.ts"],
9 | "include": ["**/*.spec.ts", "**/*.d.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/libs/shared/animations/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts"],
7 | "extends": [
8 | "plugin:@nrwl/nx/angular",
9 | "plugin:@angular-eslint/template/process-inline-templates"
10 | ],
11 | "parserOptions": {
12 | "project": ["libs/shared/animations/tsconfig.*?.json"]
13 | },
14 | "rules": {
15 | "@angular-eslint/directive-selector": [
16 | "error",
17 | {
18 | "type": "attribute",
19 | "prefix": "rca",
20 | "style": "camelCase"
21 | }
22 | ],
23 | "@angular-eslint/component-selector": [
24 | "error",
25 | {
26 | "type": "element",
27 | "prefix": "rca",
28 | "style": "kebab-case"
29 | }
30 | ]
31 | }
32 | },
33 | {
34 | "files": ["*.html"],
35 | "extends": ["plugin:@nrwl/nx/angular-template"],
36 | "rules": {}
37 | }
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/libs/shared/animations/README.md:
--------------------------------------------------------------------------------
1 | # shared-animations
2 |
3 | This library was generated with [Nx](https://nx.dev).
4 |
5 | ## Running unit tests
6 |
7 | Run `nx test shared-animations` to execute the unit tests.
8 |
--------------------------------------------------------------------------------
/libs/shared/animations/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'shared-animations',
3 | preset: '../../../jest.preset.js',
4 | setupFilesAfterEnv: ['/src/test-setup.ts'],
5 | globals: {
6 | 'ts-jest': {
7 | tsConfig: '/tsconfig.spec.json',
8 | stringifyContentPathRegex: '\\.(html|svg)$',
9 | astTransformers: {
10 | before: [
11 | 'jest-preset-angular/build/InlineFilesTransformer',
12 | 'jest-preset-angular/build/StripStylesTransformer',
13 | ],
14 | },
15 | },
16 | },
17 | coverageDirectory: '../../../coverage/libs/shared/animations',
18 | snapshotSerializers: [
19 | 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
20 | 'jest-preset-angular/build/AngularSnapshotSerializer.js',
21 | 'jest-preset-angular/build/HTMLCommentSerializer.js',
22 | ],
23 | };
24 |
--------------------------------------------------------------------------------
/libs/shared/animations/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/slide.animation';
2 | export * from './lib/fade.animation';
3 | export * from './lib/lift.animation';
4 | export * from './lib/drop.animation';
5 | export * from './lib/rotate.animation';
6 |
--------------------------------------------------------------------------------
/libs/shared/animations/src/lib/drop.animation.ts:
--------------------------------------------------------------------------------
1 | import { animation, style, animate } from '@angular/animations';
2 |
3 | export const dropInAnimation = animation(
4 | [
5 | style({ opacity: '{{ start }}', transform: 'translate({{ startPos }})' }),
6 | animate(
7 | '{{ time }}',
8 | style({ opacity: '{{ end }}', transform: 'translate({{ endPos }})' })
9 | ),
10 | ],
11 | {
12 | params: {
13 | time: '500ms ease-out',
14 | start: 0,
15 | end: 1,
16 | startPos: '0, -100px',
17 | endPos: '0, 0',
18 | },
19 | }
20 | );
21 |
22 | export const dropOutAnimation = animation(
23 | [
24 | style({ opacity: '{{ start }}', transform: 'translate({{ startPos }})' }),
25 | animate(
26 | '{{ time }}',
27 | style({ opacity: '{{ end }}', transform: 'translate({{ endPos }})' })
28 | ),
29 | ],
30 | {
31 | params: {
32 | time: '500ms ease-in',
33 | start: 1,
34 | end: 0,
35 | startPos: '0, 0',
36 | endPos: '0, 100px',
37 | },
38 | }
39 | );
40 |
--------------------------------------------------------------------------------
/libs/shared/animations/src/lib/fade.animation.ts:
--------------------------------------------------------------------------------
1 | import { animation, style, animate } from '@angular/animations';
2 |
3 | export const fadeInAnimation = animation(
4 | [
5 | style({ opacity: '{{ start }}', transform: 'scale({{ startScale }})' }),
6 | animate(
7 | '{{ time }}',
8 | style({ opacity: '{{ end }}', transform: 'scale({{ endScale }})' })
9 | ),
10 | ],
11 | {
12 | params: {
13 | time: '500ms ease-out',
14 | start: 0,
15 | end: 1,
16 | startScale: 0.9,
17 | endScale: 1,
18 | },
19 | }
20 | );
21 |
22 | export const fadeOutAnimation = animation(
23 | [
24 | style({ opacity: '{{ start }}', transform: 'scale({{ startScale }})' }),
25 | animate(
26 | '{{ time }}',
27 | style({ opacity: '{{ end }}', transform: 'scale({{ endScale }})' })
28 | ),
29 | ],
30 | {
31 | params: {
32 | time: '500ms ease-in',
33 | start: 1,
34 | end: 0,
35 | startScale: 1,
36 | endScale: 0.9,
37 | },
38 | }
39 | );
40 |
--------------------------------------------------------------------------------
/libs/shared/animations/src/lib/lift.animation.ts:
--------------------------------------------------------------------------------
1 | import { animation, style, animate } from '@angular/animations';
2 |
3 | export const liftInAnimation = animation(
4 | [
5 | style({ opacity: '{{ start }}', transform: 'translate({{ startPos }})' }),
6 | animate(
7 | '{{ time }}',
8 | style({ opacity: '{{ end }}', transform: 'translate({{ endPos }})' })
9 | ),
10 | ],
11 | {
12 | params: {
13 | time: '500ms ease-out',
14 | start: 0,
15 | end: 1,
16 | startPos: '0, 100px',
17 | endPos: '0, 0',
18 | },
19 | }
20 | );
21 |
22 | export const liftOutAnimation = animation(
23 | [
24 | style({ opacity: '{{ start }}', transform: 'translate({{ startPos }})' }),
25 | animate(
26 | '{{ time }}',
27 | style({ opacity: '{{ end }}', transform: 'translate({{ endPos }})' })
28 | ),
29 | ],
30 | {
31 | params: {
32 | time: '500ms ease-in',
33 | start: 1,
34 | end: 0,
35 | startPos: '0, 0',
36 | endPos: '0, -100px',
37 | },
38 | }
39 | );
40 |
--------------------------------------------------------------------------------
/libs/shared/animations/src/lib/rotate.animation.ts:
--------------------------------------------------------------------------------
1 | import { animation, style, animate } from '@angular/animations';
2 |
3 | export const rotateInAnimation = animation(
4 | [
5 | style({
6 | opacity: '{{ start }}',
7 | transform: 'translate({{ startPos }}) rotate({{startRotation}})',
8 | }),
9 | animate(
10 | '{{ time }}',
11 | style({
12 | opacity: '{{ end }}',
13 | transform: 'translate({{ endPos }}) rotate({{endRotation}})',
14 | })
15 | ),
16 | ],
17 | {
18 | params: {
19 | time: '500ms ease-out',
20 | start: 0,
21 | end: 1,
22 | startPos: '0, -100px',
23 | endPos: '0, 0',
24 | startRotation: '-15deg',
25 | endRotation: '0',
26 | },
27 | }
28 | );
29 |
30 | export const rotateOutAnimation = animation(
31 | [
32 | style({
33 | opacity: '{{ start }}',
34 | transform: 'translate({{ startPos }}) rotate({{startRotation}})',
35 | }),
36 | animate(
37 | '{{ time }}',
38 | style({
39 | opacity: '{{ end }}',
40 | transform: 'translate({{ endPos }}) rotate({{endRotation}})',
41 | })
42 | ),
43 | ],
44 | {
45 | params: {
46 | time: '500ms ease-in',
47 | start: 1,
48 | end: 0,
49 | startPos: '0, 0',
50 | endPos: '0, 100px',
51 | startRotation: '0',
52 | endRotation: '15deg',
53 | },
54 | }
55 | );
56 |
--------------------------------------------------------------------------------
/libs/shared/animations/src/lib/slide.animation.ts:
--------------------------------------------------------------------------------
1 | import { animation, style, animate } from '@angular/animations';
2 |
3 | export const slideInAnimation = animation(
4 | [
5 | style({ opacity: '{{ start }}', height: '{{ startHeight }}' }),
6 | animate(
7 | '{{ time }}',
8 | style({ opacity: '{{ end }}', height: '{{ endHeight }}' })
9 | ),
10 | ],
11 | {
12 | params: {
13 | time: '500ms ease-out',
14 | start: 0,
15 | end: 1,
16 | startHeight: 0,
17 | endHeight: '*',
18 | },
19 | }
20 | );
21 |
22 | export const slideOutAnimation = animation(
23 | [
24 | style({ opacity: '{{ start }}', height: '{{ startHeight }}' }),
25 | animate(
26 | '{{ time }}',
27 | style({ opacity: '{{ end }}', height: '{{ endHeight }}' })
28 | ),
29 | ],
30 | {
31 | params: {
32 | time: '500ms ease-in',
33 | start: 1,
34 | end: 0,
35 | startHeight: '*',
36 | endHeight: 0,
37 | },
38 | }
39 | );
40 |
--------------------------------------------------------------------------------
/libs/shared/animations/src/test-setup.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 |
--------------------------------------------------------------------------------
/libs/shared/animations/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/libs/shared/animations/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "target": "es2015",
6 | "declaration": true,
7 | "declarationMap": true,
8 | "inlineSources": true,
9 | "types": [],
10 | "lib": ["dom", "es2018"]
11 | },
12 | "angularCompilerOptions": {
13 | "skipTemplateCodegen": true,
14 | "strictMetadataEmit": true,
15 | "enableResourceInlining": true
16 | },
17 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"],
18 | "include": ["**/*.ts"]
19 | }
20 |
--------------------------------------------------------------------------------
/libs/shared/animations/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "files": ["src/test-setup.ts"],
9 | "include": ["**/*.spec.ts", "**/*.d.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/libs/shared/carousel/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["../../../.eslintrc.json"],
3 | "ignorePatterns": ["!**/*"],
4 | "overrides": [
5 | {
6 | "files": ["*.ts"],
7 | "extends": [
8 | "plugin:@nrwl/nx/angular",
9 | "plugin:@angular-eslint/template/process-inline-templates"
10 | ],
11 | "parserOptions": { "project": ["libs/shared/carousel/tsconfig.*?.json"] },
12 | "rules": {
13 | "@angular-eslint/directive-selector": [
14 | "error",
15 | { "type": "attribute", "prefix": "rca", "style": "camelCase" }
16 | ],
17 | "@angular-eslint/component-selector": [
18 | "error",
19 | { "type": "element", "prefix": "rca", "style": "kebab-case" }
20 | ]
21 | }
22 | },
23 | {
24 | "files": ["*.html"],
25 | "extends": ["plugin:@nrwl/nx/angular-template"],
26 | "rules": {}
27 | }
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/libs/shared/carousel/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | displayName: 'shared-carousel',
3 | preset: '../../../jest.preset.js',
4 | setupFilesAfterEnv: ['/src/test-setup.ts'],
5 | globals: {
6 | 'ts-jest': {
7 | tsConfig: '/tsconfig.spec.json',
8 | stringifyContentPathRegex: '\\.(html|svg)$',
9 | astTransformers: {
10 | before: [
11 | 'jest-preset-angular/build/InlineFilesTransformer',
12 | 'jest-preset-angular/build/StripStylesTransformer',
13 | ],
14 | },
15 | },
16 | },
17 | coverageDirectory: '../../../coverage/libs/shared/carousel',
18 | snapshotSerializers: [
19 | 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js',
20 | 'jest-preset-angular/build/AngularSnapshotSerializer.js',
21 | 'jest-preset-angular/build/HTMLCommentSerializer.js',
22 | ],
23 | };
24 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/shared-carousel.module';
2 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/lib/carousel-item/carousel-item.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/lib/carousel-item/carousel-item.component.scss:
--------------------------------------------------------------------------------
1 | :host {
2 | display: flex;
3 | justify-content: center;
4 | max-width: 100%;
5 | position: absolute;
6 | width: 100%;
7 |
8 | @media (max-width: 960px) {
9 | flex-direction: column;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/lib/carousel-item/carousel-item.component.ts:
--------------------------------------------------------------------------------
1 | import { transition, trigger, useAnimation } from '@angular/animations';
2 | import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
3 | import { dropInAnimation, fadeOutAnimation } from '@rca/shared/animations';
4 | import { CarouselState } from '../carousel/carousel.utils';
5 |
6 | @Component({
7 | selector: 'rca-carousel-item',
8 | templateUrl: './carousel-item.component.html',
9 | styleUrls: ['./carousel-item.component.scss'],
10 | animations: [
11 | trigger('fadeToCenter1', [
12 | transition(':enter', [
13 | useAnimation(dropInAnimation, {
14 | params: {
15 | startPos: '-50px, -50px',
16 | time: '500ms 600ms ease-out',
17 | },
18 | }),
19 | ]),
20 | transition(':leave', [useAnimation(fadeOutAnimation)]),
21 | ]),
22 | trigger('fadeToCenter2', [
23 | transition(':enter', [
24 | useAnimation(dropInAnimation, {
25 | params: {
26 | startPos: '50px, 50px',
27 | time: '500ms 800ms ease-out',
28 | },
29 | }),
30 | ]),
31 | transition(':leave', [useAnimation(fadeOutAnimation)]),
32 | ]),
33 | trigger('fadeToCenter3', [
34 | transition(':enter', [
35 | useAnimation(dropInAnimation, {
36 | params: {
37 | startPos: '50px, -50px',
38 | time: '500ms 1000ms ease-out',
39 | },
40 | }),
41 | ]),
42 | transition(':leave', [useAnimation(fadeOutAnimation)]),
43 | ]),
44 | ],
45 | changeDetection: ChangeDetectionStrategy.OnPush,
46 | })
47 | export class CarouselItemComponent {
48 | @Input() state: CarouselState;
49 | @Input() activeState: CarouselState;
50 | }
51 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/lib/carousel/auto-advance.operator.ts:
--------------------------------------------------------------------------------
1 | import { interval, merge, Observable, of } from 'rxjs';
2 | import { scan, switchMap } from 'rxjs/operators';
3 |
4 | export function autoAdvance(
5 | period: number,
6 | nextState: (currentState: T) => T
7 | ) {
8 | return function (incoming: Observable): Observable {
9 | return incoming.pipe(
10 | switchMap((currentState) =>
11 | merge(
12 | of(currentState),
13 | interval(period).pipe(scan((acc) => nextState(acc), currentState))
14 | )
15 | )
16 | );
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/lib/carousel/carousel.component.html:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/lib/carousel/carousel.component.scss:
--------------------------------------------------------------------------------
1 | @import 'variables';
2 |
3 | :host {
4 | display: block;
5 | min-height: 650px;
6 | width: 100%;
7 | }
8 | .carousel-control-container {
9 | justify-content: center;
10 | display: flex;
11 | margin: 1rem;
12 | }
13 | .carousel-control {
14 | display: flex;
15 | justify-content: space-between;
16 | max-width: 40rem;
17 | margin-bottom: 2rem;
18 | width: 10rem;
19 |
20 | @media (max-width: 500px) {
21 | width: 100%;
22 | }
23 |
24 | button {
25 | background-color: #ccc;
26 | border: 0;
27 | border-radius: 50%;
28 | height: 0.75rem;
29 | position: relative;
30 | transition: all 0.3s;
31 | width: 0.75rem;
32 |
33 | &:hover {
34 | transform: scale(2);
35 | }
36 |
37 | &:disabled {
38 | background-color: $primary;
39 | }
40 |
41 | &:last-child {
42 | margin-right: 0;
43 | }
44 | }
45 | }
46 |
47 | .item-container {
48 | width: 100%;
49 | position: relative;
50 | }
51 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/lib/carousel/carousel.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import {
3 | CarouselState,
4 | CAROUSEL_STATES,
5 | createReactiveCarouselMachine,
6 | } from './carousel.utils';
7 |
8 | let _id = 0;
9 | @Component({
10 | selector: 'rca-carousel',
11 | templateUrl: './carousel.component.html',
12 | styleUrls: ['./carousel.component.scss'],
13 | })
14 | export class CarouselComponent {
15 | carouselId = `rca-carousel-${_id++}`;
16 | states = CAROUSEL_STATES;
17 | private _reactiveMachine = createReactiveCarouselMachine();
18 | activeState$ = this._reactiveMachine.activeState$;
19 |
20 | userClick(state: CarouselState) {
21 | this._reactiveMachine.userInitiatedStateChange(state);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/lib/carousel/carousel.utils.ts:
--------------------------------------------------------------------------------
1 | import { merge, Observable, Observer } from 'rxjs';
2 | import { map, shareReplay, startWith } from 'rxjs/operators';
3 | import { autoAdvance } from './auto-advance.operator';
4 |
5 | export const CAROUSEL_STATES = ['spongebob', 'patrick', 'gary'] as const;
6 |
7 | export type CarouselState = typeof CAROUSEL_STATES[number];
8 |
9 | export interface ReactiveCarouselMachine {
10 | activeState$: Observable;
11 | userInitiatedStateChange: (carouselState: CarouselState) => void;
12 | }
13 |
14 | export function createReactiveCarouselMachine(
15 | timeToAutoAdvance: number = 5000,
16 | initialState: CarouselState = 'spongebob'
17 | ): ReactiveCarouselMachine {
18 | const observers: Record> = {
19 | spongebob: null,
20 | patrick: null,
21 | gary: null,
22 | };
23 | const userInitiatedActions = CAROUSEL_STATES.reduce((acc, carouselState) => {
24 | acc[carouselState] = new Observable((observer) => {
25 | observers[carouselState] = observer;
26 | });
27 | return acc;
28 | }, {} as Record>);
29 | const activeState$ = activeCarouselState({
30 | userInitiatedActions,
31 | initialState,
32 | timeToAutoAdvance,
33 | });
34 | const userInitiatedStateChange = (carouselState: CarouselState) => {
35 | observers[carouselState].next();
36 | };
37 | return {
38 | userInitiatedStateChange,
39 | activeState$,
40 | };
41 | }
42 |
43 | interface ActiveCarouselItemParams {
44 | userInitiatedActions: Record>;
45 | initialState: CarouselState;
46 | timeToAutoAdvance: number;
47 | }
48 |
49 | function activeCarouselState({
50 | userInitiatedActions,
51 | initialState,
52 | timeToAutoAdvance,
53 | }: ActiveCarouselItemParams): Observable {
54 | return merge(
55 | ...Object.entries(
56 | userInitiatedActions
57 | ).map(
58 | ([carouselState, userInitiatedObservable]: [
59 | CarouselState,
60 | Observable
61 | ]) => userInitiatedObservable.pipe(map(() => carouselState))
62 | )
63 | ).pipe(
64 | startWith(initialState),
65 | autoAdvance(timeToAutoAdvance, nextState),
66 | shareReplay(1)
67 | );
68 | }
69 |
70 | function nextState(state: CarouselState): CarouselState {
71 | if (state === 'spongebob') {
72 | return 'patrick';
73 | }
74 | if (state === 'patrick') {
75 | return 'gary';
76 | }
77 | return 'spongebob';
78 | }
79 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/lib/shared-carousel.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { CarouselComponent } from './carousel/carousel.component';
4 | import { CarouselItemComponent } from './carousel-item/carousel-item.component';
5 |
6 | @NgModule({
7 | imports: [CommonModule],
8 | declarations: [CarouselComponent, CarouselItemComponent],
9 | exports: [CarouselComponent, CarouselItemComponent],
10 | })
11 | export class SharedCarouselModule {}
12 |
--------------------------------------------------------------------------------
/libs/shared/carousel/src/test-setup.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 |
--------------------------------------------------------------------------------
/libs/shared/carousel/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig.base.json",
3 | "files": [],
4 | "include": [],
5 | "references": [
6 | {
7 | "path": "./tsconfig.lib.json"
8 | },
9 | {
10 | "path": "./tsconfig.spec.json"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/libs/shared/carousel/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "target": "es2015",
6 | "declaration": true,
7 | "declarationMap": true,
8 | "inlineSources": true,
9 | "types": [],
10 | "lib": ["dom", "es2018"]
11 | },
12 | "angularCompilerOptions": {
13 | "skipTemplateCodegen": true,
14 | "strictMetadataEmit": true,
15 | "enableResourceInlining": true
16 | },
17 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"],
18 | "include": ["**/*.ts"]
19 | }
20 |
--------------------------------------------------------------------------------
/libs/shared/carousel/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "files": ["src/test-setup.ts"],
9 | "include": ["**/*.spec.ts", "**/*.d.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/libs/styles/_variables.scss:
--------------------------------------------------------------------------------
1 | $light-gray: #efefef;
2 | $dark-gray: #333;
3 |
4 | $primary: #4285f4;
5 |
6 | $secondary: #ff5722;
7 | $secondary-dark: #ce4d25;
8 |
9 | $main-background: $light-gray;
10 | $main-text: $dark-gray;
11 |
--------------------------------------------------------------------------------
/libs/styles/base.scss:
--------------------------------------------------------------------------------
1 | @import 'variables';
2 |
3 | html,
4 | body {
5 | margin: 0;
6 | }
7 |
8 | html {
9 | background-color: $main-background;
10 | box-sizing: border-box;
11 | font-size: 16px;
12 | font-family: 'Recursive', sans-serif;
13 | font-weight: 300;
14 | color: $main-text;
15 | }
16 |
17 | *,
18 | *:before,
19 | *:after {
20 | box-sizing: inherit;
21 | }
22 |
23 | h1 {
24 | font-size: 300%;
25 | margin-top: 2rem;
26 | margin-bottom: 1rem;
27 | }
28 |
29 | h2 {
30 | font-size: 250%;
31 | margin-top: 2rem;
32 | margin-bottom: 1rem;
33 | }
34 |
35 | h3 {
36 | font-size: 200%;
37 | margin-top: 2rem;
38 | margin-bottom: 1rem;
39 | }
40 |
41 | h4 {
42 | font-size: 150%;
43 | margin-top: 2rem;
44 | margin-bottom: 1rem;
45 | }
46 |
47 | h5 {
48 | font-size: 125%;
49 | margin-top: 2rem;
50 | margin-bottom: 1rem;
51 | }
52 |
53 | h6 {
54 | font-size: 90%;
55 | text-transform: uppercase;
56 | letter-spacing: 0.3rem;
57 | margin-top: 1rem;
58 | margin-bottom: 0.5rem;
59 | }
60 |
61 | p {
62 | line-height: 1.5rem;
63 | margin-bottom: 1.5rem;
64 | }
65 |
66 | a {
67 | color: $main-text;
68 | text-decoration: $main-text underline 1px;
69 | text-underline-offset: 2px;
70 | }
71 |
72 | small {
73 | font-size: 85%;
74 | }
75 |
76 | .button {
77 | border: 0;
78 | border-radius: 4px;
79 | background-color: $secondary;
80 | color: white;
81 | cursor: pointer;
82 | font-family: inherit;
83 | font-size: inherit;
84 | font-weight: 600;
85 | padding: 0.75rem 1.5rem;
86 | transition: background-color 0.2s;
87 |
88 | &:not([disabled]) {
89 | &:hover,
90 | &:active {
91 | background-color: $secondary-dark;
92 | }
93 | }
94 |
95 | &[disabled] {
96 | border-color: #aaa;
97 | background-color: #aaa;
98 | color: #777;
99 | cursor: not-allowed;
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/nx.json:
--------------------------------------------------------------------------------
1 | {
2 | "implicitDependencies": {
3 | "angular.json": "*",
4 | "package.json": { "dependencies": "*", "devDependencies": "*" },
5 | "tsconfig.base.json": "*",
6 | "tslint.json": "*",
7 | ".eslintrc.json": "*",
8 | "nx.json": "*"
9 | },
10 | "affected": { "defaultBase": "main" },
11 | "npmScope": "reactive-code-animations",
12 | "tasksRunnerOptions": {
13 | "default": {
14 | "runner": "@nrwl/nx-cloud",
15 | "options": {
16 | "cacheableOperations": ["build", "lint", "test", "e2e"],
17 | "accessToken": "MDQ1NjRmOGYtZjdiYi00NTBlLWE0NTgtMTUxZGU0NzAwZTM2fHJlYWQ=",
18 | "canTrackAnalytics": false,
19 | "showUsageWarnings": true
20 | }
21 | }
22 | },
23 | "projects": {
24 | "reactive-code-animations": { "tags": [] },
25 | "reactive-code-animations-e2e": {
26 | "tags": [],
27 | "implicitDependencies": ["reactive-code-animations"]
28 | },
29 | "styles": { "tags": ["type:ui"] },
30 | "shared-animations": { "tags": ["type:util"] },
31 | "examples-carousel": { "tags": ["type:feature"] },
32 | "shared-carousel": { "tags": ["type:ui"] },
33 | "examples-click-counter": { "tags": ["type:feature"] },
34 | "examples-series": { "tags": ["type:feature"] }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "reactive-code-animations",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "nx",
7 | "postinstall": "node ./decorate-angular-cli.js && ngcc --properties es2015 browser module main",
8 | "nx": "nx",
9 | "start": "ng serve --port 4792",
10 | "build": "ng build",
11 | "test": "ng test",
12 | "lint": "nx workspace-lint && ng lint",
13 | "e2e": "ng e2e",
14 | "affected:apps": "nx affected:apps",
15 | "affected:libs": "nx affected:libs",
16 | "affected:build": "nx affected:build",
17 | "affected:e2e": "nx affected:e2e",
18 | "affected:test": "nx affected:test",
19 | "affected:lint": "nx affected:lint",
20 | "affected:dep-graph": "nx affected:dep-graph",
21 | "affected": "nx affected",
22 | "format": "nx format:write",
23 | "format:write": "nx format:write",
24 | "format:check": "nx format:check",
25 | "update": "nx migrate latest",
26 | "workspace-generator": "nx workspace-generator",
27 | "dep-graph": "nx dep-graph",
28 | "help": "nx help"
29 | },
30 | "private": true,
31 | "dependencies": {
32 | "@angular/animations": "^11.2.0",
33 | "@angular/common": "^11.2.0",
34 | "@angular/compiler": "^11.2.0",
35 | "@angular/core": "^11.2.0",
36 | "@angular/fire": "^6.1.4",
37 | "@angular/forms": "^11.2.0",
38 | "@angular/platform-browser": "^11.2.0",
39 | "@angular/platform-browser-dynamic": "^11.2.0",
40 | "@angular/router": "^11.2.0",
41 | "@nrwl/angular": "11.5.1",
42 | "chart.js": "^2.9.4",
43 | "firebase": "^7.0 || ^8.0",
44 | "rxjs": "~6.6.3",
45 | "tslib": "^2.0.0",
46 | "zone.js": "^0.10.2"
47 | },
48 | "devDependencies": {
49 | "@angular-devkit/architect": ">= 0.900 < 0.1200",
50 | "@angular-devkit/build-angular": "~0.1102.0",
51 | "@angular-eslint/eslint-plugin": "~1.0.0",
52 | "@angular-eslint/eslint-plugin-template": "~1.0.0",
53 | "@angular-eslint/template-parser": "~1.0.0",
54 | "@angular/cli": "~11.0.0",
55 | "@angular/compiler-cli": "^11.2.0",
56 | "@angular/language-service": "^11.2.0",
57 | "@nrwl/cli": "11.5.1",
58 | "@nrwl/cypress": "11.5.1",
59 | "@nrwl/eslint-plugin-nx": "11.5.1",
60 | "@nrwl/jest": "11.5.1",
61 | "@nrwl/linter": "11.5.1",
62 | "@nrwl/nx-cloud": "^13.0.2",
63 | "@nrwl/tao": "11.5.1",
64 | "@nrwl/workspace": "11.5.1",
65 | "@types/jest": "26.0.8",
66 | "@types/node": "12.12.38",
67 | "@typescript-eslint/eslint-plugin": "4.3.0",
68 | "@typescript-eslint/parser": "4.3.0",
69 | "cypress": "^6.0.1",
70 | "dotenv": "6.2.0",
71 | "eslint": "7.10.0",
72 | "eslint-config-prettier": "8.1.0",
73 | "eslint-plugin-cypress": "^2.10.3",
74 | "firebase-tools": "^8.0.0",
75 | "fuzzy": "^0.1.3",
76 | "inquirer": "^6.2.2",
77 | "inquirer-autocomplete-prompt": "^1.0.1",
78 | "jest": "26.2.2",
79 | "jest-preset-angular": "8.3.2",
80 | "open": "^7.0.3",
81 | "prettier": "2.2.1",
82 | "ts-jest": "26.4.0",
83 | "ts-node": "~9.1.1",
84 | "typescript": "~4.0.3"
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/tools/generators/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nixallover/reactive-code-animations/272b5349910436044bba27da0dca3394a043340b/tools/generators/.gitkeep
--------------------------------------------------------------------------------
/tools/tsconfig.tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.base.json",
3 | "compilerOptions": {
4 | "outDir": "../dist/out-tsc/tools",
5 | "rootDir": ".",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": ["node"],
9 | "importHelpers": false
10 | },
11 | "include": ["**/*.ts"]
12 | }
13 |
--------------------------------------------------------------------------------
/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "rootDir": ".",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "importHelpers": true,
11 | "target": "es2015",
12 | "module": "esnext",
13 | "lib": ["es2017", "dom"],
14 | "skipLibCheck": true,
15 | "skipDefaultLibCheck": true,
16 | "baseUrl": ".",
17 | "paths": {
18 | "@rca/styles": ["libs/styles/src/index.ts"],
19 | "@rca/shared/animations": ["libs/shared/animations/src/index.ts"],
20 | "@rca/examples/carousel": ["libs/examples/carousel/src/index.ts"],
21 | "@rca/shared/carousel": ["libs/shared/carousel/src/index.ts"],
22 | "@reactive-code-animations/examples/click-counter": [
23 | "libs/examples/click-counter/src/index.ts"],
24 | "@rca/examples/series": [
25 | "libs/examples/series/src/index.ts"
26 | ]
27 | }
28 | },
29 | "exclude": ["node_modules", "tmp"]
30 | }
31 |
--------------------------------------------------------------------------------