├── .editorconfig
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── .prettierignore
├── .prettierrc
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── angular.json
├── apps
├── .gitkeep
├── angular-app
│ ├── browserslist
│ ├── jest.config.js
│ ├── src
│ │ ├── app
│ │ │ ├── app.component.html
│ │ │ ├── app.component.scss
│ │ │ ├── app.component.spec.ts
│ │ │ ├── app.component.ts
│ │ │ └── app.module.ts
│ │ ├── assets
│ │ │ └── .gitkeep
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── main.ts
│ │ ├── polyfills.ts
│ │ ├── styles.scss
│ │ └── test-setup.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.spec.json
│ └── tslint.json
├── angular-ivy-app
│ ├── browserslist
│ ├── jest.config.js
│ ├── src
│ │ ├── app
│ │ │ ├── app.component.html
│ │ │ ├── app.component.scss
│ │ │ ├── app.component.spec.ts
│ │ │ ├── app.component.ts
│ │ │ └── app.module.ts
│ │ ├── assets
│ │ │ └── .gitkeep
│ │ ├── environments
│ │ │ ├── environment.prod.ts
│ │ │ └── environment.ts
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ ├── main.ts
│ │ ├── polyfills.ts
│ │ ├── styles.scss
│ │ └── test-setup.ts
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.spec.json
│ └── tslint.json
└── react-app
│ ├── browserslist
│ ├── jest.config.js
│ ├── src
│ ├── app
│ │ └── app.tsx
│ ├── assets
│ │ └── .gitkeep
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── index.html
│ ├── main.tsx
│ ├── polyfills.ts
│ └── styles.scss
│ ├── tsconfig.app.json
│ ├── tsconfig.json
│ ├── tsconfig.spec.json
│ └── tslint.json
├── jest.config.js
├── libs
├── .gitkeep
├── angular-component-library
│ ├── README.md
│ ├── ng-package.json
│ ├── package.json
│ ├── src
│ │ ├── index.ts
│ │ └── lib
│ │ │ ├── angular-component-library.module.ts
│ │ │ ├── hello-world
│ │ │ └── hello-world.component.ts
│ │ │ └── timer
│ │ │ └── timer.component.ts
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ └── tslint.json
├── angular-wrappers
│ ├── README.md
│ ├── jest.config.js
│ ├── ng-package.json
│ ├── package.json
│ ├── src
│ │ ├── lib
│ │ │ ├── .gitkeep
│ │ │ ├── angular-wrapper.module.ts
│ │ │ └── hello-jsx.component.tsx
│ │ └── public_api.ts
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ ├── tsconfig.spec.json
│ └── tslint.json
├── react-component-library
│ ├── README.md
│ ├── jest.config.js
│ ├── ng-package.json
│ ├── package.json
│ ├── src
│ │ ├── lib
│ │ │ ├── .gitkeep
│ │ │ └── react.component.tsx
│ │ └── public_api.ts
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ ├── tsconfig.spec.json
│ └── tslint.json
├── react-ng-wrapper
│ ├── README.md
│ ├── ng-package.json
│ ├── package.json
│ ├── src
│ │ ├── index.ts
│ │ └── lib
│ │ │ └── react-ng-wrapper.tsx
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ └── tslint.json
└── react-wrappers
│ ├── README.md
│ ├── jest.config.js
│ ├── ng-package.json
│ ├── package.json
│ ├── src
│ ├── index.ts
│ └── lib
│ │ ├── hello.tsx
│ │ └── timer.tsx
│ ├── tsconfig.json
│ ├── tsconfig.lib.json
│ ├── tsconfig.spec.json
│ └── tslint.json
├── nx.json
├── package.json
├── renovate.json
├── tools
├── schematics
│ └── .gitkeep
└── tsconfig.tools.json
├── tsconfig.json
├── tslint.json
└── yarn.lock
/.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 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.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 |
37 | # System Files
38 | .DS_Store
39 | Thumbs.db
40 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Add files here to ignore them from prettier formatting
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true
3 | }
4 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at rjgunning+github@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Richard Sahrakorpi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular React hybrid aplications
2 |
3 | Proof of Concept Angular-React Hybrid project based on ng-packagr example application https://github.com/ng-packagr/ng-packagr/tree/master/integration
4 |
5 | This project has 2 component libraries, 1 written in react and one in Angular. Using the `react-wrappers` library, we then convert the angular components into react compatible components. Likewise using the `angular-wrappers` library we convert the react components for use in angular applications.
6 |
7 | Three demo applications are included in this repository
8 |
9 | - `react-app` - is a react application which imports both the `react-component-library` and the `angular-component-library` (via the `react-wrappers` and `react-ng-wrapper` libraries).
10 | - `angular-app` - imports the `react-component-library` (via the `angular-wrappers` library)
11 | - `angular-ivy-app` - imports the `angular-component-library` to show they can still be used within angular.
12 |
13 | This project was generated using [Nx](https://nx.dev).
14 |
15 | ## Build
16 |
17 | Run `yarn build:all` to build all the libraries.
18 |
19 | ## Development server
20 |
21 | Run `yarn start [app]` (where app is one of `react-app`, `angular-app` or `angular-ivy-app`).
22 |
23 | Navigate to `http://localhost:4200/`.
24 |
--------------------------------------------------------------------------------
/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "",
5 | "projects": {
6 | "react-app": {
7 | "root": "apps/react-app/",
8 | "sourceRoot": "apps/react-app/src",
9 | "projectType": "application",
10 | "prefix": "hybrid",
11 | "schematics": {
12 | "@nrwl/schematics:component": {
13 | "style": "scss"
14 | }
15 | },
16 | "architect": {
17 | "build": {
18 | "builder": "@nrwl/web:build",
19 | "options": {
20 | "outputPath": "dist/apps/react-app",
21 | "index": "apps/react-app/src/index.html",
22 | "main": "apps/react-app/src/main.tsx",
23 | "polyfills": "apps/react-app/src/polyfills.ts",
24 | "tsConfig": "apps/react-app/tsconfig.app.json",
25 | "assets": [
26 | "apps/react-app/src/favicon.ico",
27 | "apps/react-app/src/assets"
28 | ],
29 | "styles": [
30 | "apps/react-app/src/styles.scss"
31 | ],
32 | "scripts": [],
33 | "webpackConfig": "@nrwl/react/plugins/babel"
34 | },
35 | "configurations": {
36 | "production": {
37 | "fileReplacements": [
38 | {
39 | "replace": "apps/react-app/src/environments/environment.ts",
40 | "with": "apps/react-app/src/environments/environment.prod.ts"
41 | }
42 | ],
43 | "optimization": true,
44 | "outputHashing": "all",
45 | "sourceMap": false,
46 | "extractCss": true,
47 | "namedChunks": false,
48 | "extractLicenses": true,
49 | "vendorChunk": false,
50 | "budgets": [
51 | {
52 | "type": "initial",
53 | "maximumWarning": "2mb",
54 | "maximumError": "5mb"
55 | }
56 | ]
57 | }
58 | }
59 | },
60 | "serve": {
61 | "builder": "@nrwl/web:dev-server",
62 | "options": {
63 | "buildTarget": "react-app:build"
64 | },
65 | "configurations": {
66 | "production": {
67 | "buildTarget": "react-app:build:production"
68 | }
69 | }
70 | }
71 | }
72 | },
73 | "angular-app": {
74 | "root": "apps/angular-app/",
75 | "sourceRoot": "apps/angular-app/src",
76 | "projectType": "application",
77 | "prefix": "hybrid",
78 | "schematics": {
79 | "@nrwl/schematics:component": {
80 | "style": "scss"
81 | }
82 | },
83 | "architect": {
84 | "build": {
85 | "builder": "@angular-devkit/build-angular:browser",
86 | "options": {
87 | "outputPath": "dist/apps/angular-app",
88 | "index": "apps/angular-app/src/index.html",
89 | "main": "apps/angular-app/src/main.ts",
90 | "polyfills": "apps/angular-app/src/polyfills.ts",
91 | "tsConfig": "apps/angular-app/tsconfig.app.json",
92 | "assets": [
93 | "apps/angular-app/src/favicon.ico",
94 | "apps/angular-app/src/assets"
95 | ],
96 | "styles": [
97 | "apps/angular-app/src/styles.scss"
98 | ],
99 | "scripts": [],
100 | "es5BrowserSupport": true
101 | },
102 | "configurations": {
103 | "production": {
104 | "fileReplacements": [
105 | {
106 | "replace": "apps/angular-app/src/environments/environment.ts",
107 | "with": "apps/angular-app/src/environments/environment.prod.ts"
108 | }
109 | ],
110 | "optimization": true,
111 | "outputHashing": "all",
112 | "sourceMap": false,
113 | "extractCss": true,
114 | "namedChunks": false,
115 | "aot": true,
116 | "extractLicenses": true,
117 | "vendorChunk": false,
118 | "buildOptimizer": true,
119 | "budgets": [
120 | {
121 | "type": "initial",
122 | "maximumWarning": "2mb",
123 | "maximumError": "5mb"
124 | }
125 | ]
126 | }
127 | }
128 | },
129 | "serve": {
130 | "builder": "@angular-devkit/build-angular:dev-server",
131 | "options": {
132 | "browserTarget": "angular-app:build"
133 | },
134 | "configurations": {
135 | "production": {
136 | "browserTarget": "angular-app:build:production"
137 | }
138 | }
139 | }
140 | }
141 | },
142 | "angular-ivy-app": {
143 | "root": "apps/angular-ivy-app/",
144 | "sourceRoot": "apps/angular-ivy-app/src",
145 | "projectType": "application",
146 | "prefix": "hybrid",
147 | "schematics": {
148 | "@nrwl/schematics:component": {
149 | "style": "scss"
150 | }
151 | },
152 | "architect": {
153 | "build": {
154 | "builder": "@angular-devkit/build-angular:browser",
155 | "options": {
156 | "outputPath": "dist/apps/angular-ivy-app",
157 | "index": "apps/angular-ivy-app/src/index.html",
158 | "main": "apps/angular-ivy-app/src/main.ts",
159 | "polyfills": "apps/angular-ivy-app/src/polyfills.ts",
160 | "tsConfig": "apps/angular-ivy-app/tsconfig.app.json",
161 | "assets": [
162 | "apps/angular-ivy-app/src/favicon.ico",
163 | "apps/angular-ivy-app/src/assets"
164 | ],
165 | "styles": [
166 | "apps/angular-ivy-app/src/styles.scss"
167 | ],
168 | "scripts": [],
169 | "es5BrowserSupport": true
170 | },
171 | "configurations": {
172 | "production": {
173 | "fileReplacements": [
174 | {
175 | "replace": "apps/angular-ivy-app/src/environments/environment.ts",
176 | "with": "apps/angular-ivy-app/src/environments/environment.prod.ts"
177 | }
178 | ],
179 | "optimization": true,
180 | "outputHashing": "all",
181 | "sourceMap": false,
182 | "extractCss": true,
183 | "namedChunks": false,
184 | "aot": true,
185 | "extractLicenses": true,
186 | "vendorChunk": false,
187 | "buildOptimizer": true,
188 | "budgets": [
189 | {
190 | "type": "initial",
191 | "maximumWarning": "2mb",
192 | "maximumError": "5mb"
193 | }
194 | ]
195 | }
196 | }
197 | },
198 | "serve": {
199 | "builder": "@angular-devkit/build-angular:dev-server",
200 | "options": {
201 | "browserTarget": "angular-ivy-app:build"
202 | },
203 | "configurations": {
204 | "production": {
205 | "browserTarget": "angular-ivy-app:build:production"
206 | }
207 | }
208 | }
209 | }
210 | },
211 | "angular-wrappers": {
212 | "root": "libs/angular-wrappers",
213 | "sourceRoot": "libs/angular-wrappers/src",
214 | "projectType": "library",
215 | "prefix": "hybrid",
216 | "architect": {
217 | "build": {
218 | "builder": "@angular-devkit/build-ng-packagr:build",
219 | "options": {
220 | "tsConfig": "libs/angular-wrappers/tsconfig.lib.json",
221 | "project": "libs/angular-wrappers/ng-package.json"
222 | }
223 | }
224 | },
225 | "schematics": {
226 | "@nrwl/schematics:component": {
227 | "styleext": "scss"
228 | }
229 | }
230 | },
231 | "react-component-library": {
232 | "root": "libs/react-component-library",
233 | "sourceRoot": "libs/react-component-library/src",
234 | "projectType": "library",
235 | "prefix": "hybrid",
236 | "architect": {
237 | "build": {
238 | "builder": "@angular-devkit/build-ng-packagr:build",
239 | "options": {
240 | "tsConfig": "libs/react-component-library/tsconfig.lib.json",
241 | "project": "libs/react-component-library/ng-package.json"
242 | }
243 | }
244 | }
245 | },
246 | "react-ng-wrapper": {
247 | "root": "libs/react-ng-wrapper",
248 | "sourceRoot": "libs/react-ng-wrapper/src",
249 | "projectType": "library",
250 | "schematics": {},
251 | "architect": {
252 | "build": {
253 | "builder": "@angular-devkit/build-ng-packagr:build",
254 | "options": {
255 | "tsConfig": "libs/react-ng-wrapper/tsconfig.lib.json",
256 | "project": "libs/react-ng-wrapper/ng-package.json"
257 | }
258 | }
259 | }
260 | },
261 | "react-wrappers": {
262 | "root": "libs/react-wrappers",
263 | "sourceRoot": "libs/react-wrappers/src",
264 | "projectType": "library",
265 | "schematics": {},
266 | "architect": {
267 | "build": {
268 | "builder": "@angular-devkit/build-ng-packagr:build",
269 | "options": {
270 | "tsConfig": "libs/react-wrappers/tsconfig.lib.json",
271 | "project": "libs/react-wrappers/ng-package.json"
272 | }
273 | }
274 | }
275 | },
276 | "angular-component-library": {
277 | "projectType": "library",
278 | "root": "libs/angular-component-library",
279 | "sourceRoot": "libs/angular-component-library/src",
280 | "prefix": "hybrid",
281 | "architect": {
282 | "build": {
283 | "builder": "@angular-devkit/build-ng-packagr:build",
284 | "options": {
285 | "tsConfig": "libs/angular-component-library/tsconfig.lib.json",
286 | "project": "libs/angular-component-library/ng-package.json"
287 | }
288 | }
289 | },
290 | "schematics": {}
291 | }
292 | },
293 | "cli": {
294 | "warnings": {
295 | "typescriptMismatch": false,
296 | "versionMismatch": false
297 | },
298 | "defaultCollection": "@nrwl/angular",
299 | "packageManager": "yarn"
300 | },
301 | "schematics": {
302 | "@nrwl/schematics:application": {
303 | "style": "scss",
304 | "framework": "react"
305 | },
306 | "@nrwl/react": {
307 | "application": {
308 | "style": "css",
309 | "linter": "eslint",
310 | "babel": true
311 | },
312 | "component": {
313 | "style": "css"
314 | },
315 | "library": {
316 | "style": "css",
317 | "linter": "eslint"
318 | }
319 | },
320 | "@nrwl/next": {
321 | "application": {
322 | "linter": "eslint"
323 | }
324 | },
325 | "@nrwl/web": {
326 | "application": {
327 | "linter": "eslint"
328 | }
329 | },
330 | "@nrwl/schematics:library": {
331 | "style": "scss"
332 | }
333 | },
334 | "defaultProject": "react-app"
335 | }
336 |
--------------------------------------------------------------------------------
/apps/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/apps/angular-app/browserslist:
--------------------------------------------------------------------------------
1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 | #
5 | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed
6 |
7 | > 0.5%
8 | last 2 versions
9 | Firefox ESR
10 | not dead
11 | not IE 9-11
--------------------------------------------------------------------------------
/apps/angular-app/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'angular-app',
3 | preset: '../../jest.config.js',
4 | coverageDirectory: '../../coverage/apps/angular-app/',
5 | snapshotSerializers: [
6 | 'jest-preset-angular/AngularSnapshotSerializer.js',
7 | 'jest-preset-angular/HTMLCommentSerializer.js'
8 | ]
9 | };
10 |
--------------------------------------------------------------------------------
/apps/angular-app/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
Angular Root!
2 |
3 |
4 |
--------------------------------------------------------------------------------
/apps/angular-app/src/app/app.component.scss:
--------------------------------------------------------------------------------
1 | :host{
2 | text-align: center;
3 | font-size: xx-large;
4 | }
5 |
6 | hybrid-hello-jsx {
7 | margin-bottom: 2rem;
8 | }
9 |
10 | hybrid-hello-jsx, hybrid-hello-world, hybrid-timer {
11 | display:block;
12 | }
13 |
--------------------------------------------------------------------------------
/apps/angular-app/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, async } from '@angular/core/testing';
2 | import { AppComponent } from './app.component';
3 |
4 | describe('AppComponent', () => {
5 | beforeEach(async(() => {
6 | TestBed.configureTestingModule({
7 | declarations: [AppComponent]
8 | }).compileComponents();
9 | }));
10 |
11 | it('should create the app', () => {
12 | const fixture = TestBed.createComponent(AppComponent);
13 | const app = fixture.debugElement.componentInstance;
14 | expect(app).toBeTruthy();
15 | });
16 |
17 | it(`should have as title 'angular-app'`, () => {
18 | const fixture = TestBed.createComponent(AppComponent);
19 | const app = fixture.debugElement.componentInstance;
20 | expect(app.title).toEqual('angular-app');
21 | });
22 |
23 | it('should render title in a h1 tag', () => {
24 | const fixture = TestBed.createComponent(AppComponent);
25 | fixture.detectChanges();
26 | const compiled = fixture.debugElement.nativeElement;
27 | expect(compiled.querySelector('h1').textContent).toContain(
28 | 'Welcome to angular-app!'
29 | );
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/apps/angular-app/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'hybrid-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.scss']
7 | })
8 | export class AppComponent {
9 | title = 'angular-app';
10 | }
11 |
--------------------------------------------------------------------------------
/apps/angular-app/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 |
4 | import { AppComponent } from './app.component';
5 | import { AngularWrapperModule } from '@hybrid/angular-wrappers';
6 |
7 | @NgModule({
8 | declarations: [AppComponent],
9 | imports: [
10 | BrowserModule,
11 | AngularWrapperModule
12 | ],
13 | providers: [],
14 | bootstrap: [AppComponent]
15 | })
16 | export class AppModule { }
17 |
--------------------------------------------------------------------------------
/apps/angular-app/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/apps/angular-app/src/assets/.gitkeep
--------------------------------------------------------------------------------
/apps/angular-app/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/apps/angular-app/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/angular-app/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/apps/angular-app/src/favicon.ico
--------------------------------------------------------------------------------
/apps/angular-app/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AngularApp
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/apps/angular-app/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/angular-app/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 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
22 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
23 |
24 | /**
25 | * Web Animations `@angular/platform-browser/animations`
26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
28 | */
29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
30 |
31 | /**
32 | * By default, zone.js will patch all possible macroTask and DomEvents
33 | * user can disable parts of macroTask/DomEvents patch by setting following flags
34 | * because those flags need to be set before `zone.js` being loaded, and webpack
35 | * will put import in the top of bundle, so user need to create a separate file
36 | * in this directory (for example: zone-flags.ts), and put the following flags
37 | * into that file, and then add the following code before importing zone.js.
38 | * import './zone-flags.ts';
39 | *
40 | * The flags allowed in zone-flags.ts are listed here.
41 | *
42 | * The following flags will work for all browsers.
43 | *
44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
46 | * (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
47 | *
48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
50 | *
51 | * (window as any).__Zone_enable_cross_context_check = true;
52 | *
53 | */
54 |
55 | /***************************************************************************************************
56 | * Zone JS is required by default for Angular itself.
57 | */
58 | import 'zone.js/dist/zone'; // Included with Angular CLI.
59 |
60 | /***************************************************************************************************
61 | * APPLICATION IMPORTS
62 | */
63 |
--------------------------------------------------------------------------------
/apps/angular-app/src/styles.scss:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/apps/angular-app/src/test-setup.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 |
--------------------------------------------------------------------------------
/apps/angular-app/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": []
6 | },
7 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"],
8 | "include": ["**/*.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/angular-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "types": ["node", "jest"]
5 | },
6 | "angularCompilerOptions": {
7 | "enableIvy": false
8 | },
9 | "include": ["**/*.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/angular-app/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 |
--------------------------------------------------------------------------------
/apps/angular-app/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.json",
3 | "rules": {
4 | "directive-selector": [true, "attribute", "hybrid", "camelCase"],
5 | "component-selector": [true, "element", "hybrid", "kebab-case"]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/browserslist:
--------------------------------------------------------------------------------
1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 | #
5 | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed
6 |
7 | > 0.5%
8 | last 2 versions
9 | Firefox ESR
10 | not dead
11 | not IE 9-11
--------------------------------------------------------------------------------
/apps/angular-ivy-app/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'angular-app',
3 | preset: '../../jest.config.js',
4 | coverageDirectory: '../../coverage/apps/angular-app/',
5 | snapshotSerializers: [
6 | 'jest-preset-angular/AngularSnapshotSerializer.js',
7 | 'jest-preset-angular/HTMLCommentSerializer.js'
8 | ]
9 | };
10 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/app/app.component.html:
--------------------------------------------------------------------------------
1 | Angular Root!
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/app/app.component.scss:
--------------------------------------------------------------------------------
1 | :host{
2 | text-align: center;
3 | font-size: xx-large;
4 | }
5 |
6 | hybrid-hello-jsx {
7 | margin-bottom: 2rem;
8 | }
9 |
10 | hybrid-hello-jsx, hybrid-hello-world, hybrid-timer {
11 | display:block;
12 | }
13 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, async } from '@angular/core/testing';
2 | import { AppComponent } from './app.component';
3 |
4 | describe('AppComponent', () => {
5 | beforeEach(async(() => {
6 | TestBed.configureTestingModule({
7 | declarations: [AppComponent]
8 | }).compileComponents();
9 | }));
10 |
11 | it('should create the app', () => {
12 | const fixture = TestBed.createComponent(AppComponent);
13 | const app = fixture.debugElement.componentInstance;
14 | expect(app).toBeTruthy();
15 | });
16 |
17 | it(`should have as title 'angular-app'`, () => {
18 | const fixture = TestBed.createComponent(AppComponent);
19 | const app = fixture.debugElement.componentInstance;
20 | expect(app.title).toEqual('angular-app');
21 | });
22 |
23 | it('should render title in a h1 tag', () => {
24 | const fixture = TestBed.createComponent(AppComponent);
25 | fixture.detectChanges();
26 | const compiled = fixture.debugElement.nativeElement;
27 | expect(compiled.querySelector('h1').textContent).toContain(
28 | 'Welcome to angular-app!'
29 | );
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'hybrid-root',
5 | templateUrl: './app.component.html',
6 | styleUrls: ['./app.component.scss']
7 | })
8 | export class AppComponent {
9 | title = 'angular-app';
10 | }
11 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 |
4 | import { AppComponent } from './app.component';
5 | import { AngularComponentLibraryModule } from '@hybrid/angular-component-library'
6 | //import { AngularWrapperModule } from '@hybrid/angular-wrappers'
7 | @NgModule({
8 | declarations: [AppComponent],
9 | imports: [
10 | BrowserModule,
11 | AngularComponentLibraryModule,
12 | //AngularWrapperModule
13 | ],
14 | providers: [],
15 | bootstrap: [AppComponent]
16 | })
17 | export class AppModule { }
18 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/apps/angular-ivy-app/src/assets/.gitkeep
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/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/angular-ivy-app/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/apps/angular-ivy-app/src/favicon.ico
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AngularApp
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/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/angular-ivy-app/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 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
22 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
23 |
24 | /**
25 | * Web Animations `@angular/platform-browser/animations`
26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
28 | */
29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
30 |
31 | /**
32 | * By default, zone.js will patch all possible macroTask and DomEvents
33 | * user can disable parts of macroTask/DomEvents patch by setting following flags
34 | * because those flags need to be set before `zone.js` being loaded, and webpack
35 | * will put import in the top of bundle, so user need to create a separate file
36 | * in this directory (for example: zone-flags.ts), and put the following flags
37 | * into that file, and then add the following code before importing zone.js.
38 | * import './zone-flags.ts';
39 | *
40 | * The flags allowed in zone-flags.ts are listed here.
41 | *
42 | * The following flags will work for all browsers.
43 | *
44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
46 | * (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
47 | *
48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
50 | *
51 | * (window as any).__Zone_enable_cross_context_check = true;
52 | *
53 | */
54 |
55 | /***************************************************************************************************
56 | * Zone JS is required by default for Angular itself.
57 | */
58 | import 'zone.js/dist/zone'; // Included with Angular CLI.
59 |
60 | /***************************************************************************************************
61 | * APPLICATION IMPORTS
62 | */
63 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/styles.scss:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/src/test-setup.ts:
--------------------------------------------------------------------------------
1 | import 'jest-preset-angular';
2 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": []
6 | },
7 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"],
8 | "include": ["**/*.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "types": ["node", "jest"]
5 | },
6 | "include": ["**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/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 |
--------------------------------------------------------------------------------
/apps/angular-ivy-app/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.json",
3 | "rules": {
4 | "directive-selector": [true, "attribute", "hybrid", "camelCase"],
5 | "component-selector": [true, "element", "hybrid", "kebab-case"]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/apps/react-app/browserslist:
--------------------------------------------------------------------------------
1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 | #
5 | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed
6 |
7 | > 0.5%
8 | last 2 versions
9 | Firefox ESR
10 | not dead
11 | not IE 9-11
--------------------------------------------------------------------------------
/apps/react-app/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: "react-app",
3 | preset: "../../jest.config.js",
4 | transform: {
5 | "^.+\\.[tj]sx?$": "ts-jest"
6 | },
7 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "html"],
8 | coverageDirectory: "../../coverage/apps/react-app/"
9 | };
10 |
--------------------------------------------------------------------------------
/apps/react-app/src/app/app.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { ReactTimerComponent, ReactHelloComponent } from '@hybrid/react-wrappers';
3 | import { HelloJSX } from '@hybrid/react-component-library'
4 | export class App extends React.Component {
5 | constructor(props) {
6 | super(props);
7 |
8 | this.state = {
9 | name: "project-react",
10 | };
11 | }
12 |
13 | componentDidMount() {
14 | setTimeout(() => {
15 | this.setState({ name: "project-angular-react" })
16 | }, 2000);
17 | }
18 |
19 | onStuff(e) {
20 | console.log(`stuff happened ${e}`)
21 | }
22 |
23 | render() {
24 | return (
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/apps/react-app/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/apps/react-app/src/assets/.gitkeep
--------------------------------------------------------------------------------
/apps/react-app/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/apps/react-app/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/react-app/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/apps/react-app/src/favicon.ico
--------------------------------------------------------------------------------
/apps/react-app/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | TestWorkspace
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/apps/react-app/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import { App } from "./app/app";
5 |
6 | ReactDOM.render(, document.getElementById('root'));
7 |
8 |
--------------------------------------------------------------------------------
/apps/react-app/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file contains polyfills loaded on all browsers
3 | **/
4 | //import 'core-js/stable';
5 |
6 | import 'regenerator-runtime/runtime';
7 |
--------------------------------------------------------------------------------
/apps/react-app/src/styles.scss:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/apps/react-app/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": []
6 | },
7 | "exclude": ["src/test-setup.ts", "**/*.spec.ts"],
8 | "include": ["**/*.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/apps/react-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "jsx": "react",
5 | "allowJs": true,
6 | "esModuleInterop": true,
7 | "allowSyntheticDefaultImports": true,
8 | "types": ["node", "jest"]
9 | },
10 | "include": ["**/*.ts", "**/*.tsx"]
11 | }
12 |
--------------------------------------------------------------------------------
/apps/react-app/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.spec.ts",
10 | "**/*.spec.tsx",
11 | "**/*.spec.js",
12 | "**/*.spec.jsx",
13 | "**/*.d.ts"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/apps/react-app/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.json",
3 | "rules": []
4 | }
5 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
3 | transform: {
4 | '^.+\\.(ts|js|html)$': 'ts-jest'
5 | },
6 | resolver: '@nrwl/jest/plugins/resolver',
7 | moduleFileExtensions: ['ts', 'js', 'html'],
8 | coverageReporters: ['html']
9 | };
10 |
--------------------------------------------------------------------------------
/libs/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/libs/.gitkeep
--------------------------------------------------------------------------------
/libs/angular-component-library/README.md:
--------------------------------------------------------------------------------
1 | # angular-component-library
2 |
3 | This library was generated with [Nx](https://nx.dev).
4 |
--------------------------------------------------------------------------------
/libs/angular-component-library/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/angular-component-library",
4 | "lib": {
5 | "entryFile": "src/index.ts",
6 | "umdModuleIds": {
7 | "react": "React",
8 | "react-dom": "ReactDOM"
9 | },
10 | "jsx": "react"
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/libs/angular-component-library/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@hybrid/angular-component-library",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/common": "^8.2.5",
6 | "@angular/core": "^8.2.5"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/libs/angular-component-library/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/angular-component-library.module';
2 | export * from './lib/timer/timer.component';
3 | export * from './lib/hello-world/hello-world.component';
4 |
--------------------------------------------------------------------------------
/libs/angular-component-library/src/lib/angular-component-library.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { TimerComponent } from './timer/timer.component';
4 | import { HelloWorldComponent } from './hello-world/hello-world.component';
5 |
6 | @NgModule({
7 | imports: [CommonModule],
8 | declarations: [TimerComponent, HelloWorldComponent],
9 | exports: [TimerComponent, HelloWorldComponent]
10 | })
11 | export class AngularComponentLibraryModule { }
12 |
--------------------------------------------------------------------------------
/libs/angular-component-library/src/lib/hello-world/hello-world.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Input,
3 | Output,
4 | EventEmitter,
5 | OnInit,
6 | Component,
7 | OnChanges,
8 | } from '@angular/core';
9 |
10 | @Component({ selector: 'hybrid-hello-world', template: 'Hello {{name}}!' })
11 | export class HelloWorldComponent implements OnInit, OnChanges {
12 | @Input() name = 'world';
13 | @Output() stuff = new EventEmitter();
14 |
15 | ngOnInit() {
16 | setTimeout(() => {
17 | this.stuff.next('loaded');
18 | }, 1000);
19 | }
20 |
21 | ngOnChanges(changes){
22 | console.log(changes)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/libs/angular-component-library/src/lib/timer/timer.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component,
3 | OnInit,
4 | OnDestroy,
5 | ɵmarkDirty as markDirty,
6 | ChangeDetectionStrategy
7 | } from '@angular/core';
8 | import { Subscription, timer } from 'rxjs';
9 |
10 | @Component({
11 | selector: 'hybrid-timer',
12 | template: `counter: {{counter}}`,
13 | changeDetection: ChangeDetectionStrategy.OnPush
14 | })
15 | export class TimerComponent implements OnInit, OnDestroy {
16 |
17 | private counterSubscription: Subscription;
18 | public counter: number;
19 |
20 | constructor() { }
21 |
22 | ngOnInit() {
23 | this.counterSubscription = timer(0, 1000)
24 | .subscribe(c => {
25 | this.counter = c;
26 | markDirty(this);
27 | });
28 | }
29 |
30 | ngOnDestroy() {
31 | this.counterSubscription.unsubscribe();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/libs/angular-component-library/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "types": []
5 | },
6 | "include": ["**/*.ts"]
7 | }
8 |
--------------------------------------------------------------------------------
/libs/angular-component-library/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "target": "es2015",
6 | "declaration": true,
7 | "inlineSources": true,
8 | "types": [],
9 | "lib": ["dom", "es2018"]
10 | },
11 | "angularCompilerOptions": {
12 | "annotateForClosureCompiler": true,
13 | "skipTemplateCodegen": true,
14 | "strictMetadataEmit": true,
15 | "fullTemplateTypeCheck": true,
16 | "strictInjectionParameters": true,
17 | "enableResourceInlining": true
18 | },
19 | "exclude": ["src/test.ts", "**/*.spec.ts"]
20 | }
21 |
--------------------------------------------------------------------------------
/libs/angular-component-library/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.json",
3 | "rules": {
4 | "directive-selector": [true, "attribute", "hybrid", "camelCase"],
5 | "component-selector": [true, "element", "hybrid", "kebab-case"]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/README.md:
--------------------------------------------------------------------------------
1 | # TestReact
2 |
3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0.
4 |
5 | ## Code scaffolding
6 |
7 | Run `ng generate component component-name --project angular-wrappers` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project angular-wrappers`.
8 |
9 | > Note: Don't forget to add `--project angular-wrappers` or else it will be added to the default project in your `angular.json` file.
10 |
11 | ## Build
12 |
13 | Run `ng build angular-wrappers` to build the project. The build artifacts will be stored in the `dist/` directory.
14 |
15 | ## Publishing
16 |
17 | After building your library with `ng build angular-wrappers`, go to the dist folder `cd dist/angular-wrappers` and run `npm publish`.
18 |
19 | ## Running unit tests
20 |
21 | Run `ng test angular-wrappers` to execute the unit tests via [Karma](https://karma-runner.github.io).
22 |
23 | ## Further help
24 |
25 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
26 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'angular-wrappers',
3 | preset: '../../jest.config.js',
4 | coverageDirectory: '../../coverage/libs/angular-wrappers'
5 | };
6 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/angular-wrappers",
4 | "lib": {
5 | "entryFile": "src/public_api.ts",
6 | "umdModuleIds": {
7 | "react": "React",
8 | "react-dom": "ReactDOM"
9 | },
10 | "jsx": "react"
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@hybrid/angular-wrappers",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/common": "^8.2.5",
6 | "@angular/core": "^8.2.5"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/src/lib/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/libs/angular-wrappers/src/lib/.gitkeep
--------------------------------------------------------------------------------
/libs/angular-wrappers/src/lib/angular-wrapper.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CommonModule } from '@angular/common';
3 | import { HelloJSXComponent } from './hello-jsx.component';
4 |
5 | @NgModule({
6 | declarations: [HelloJSXComponent],
7 | imports: [CommonModule],
8 | exports: [HelloJSXComponent],
9 | providers: [],
10 | })
11 | export class AngularWrapperModule {}
12 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/src/lib/hello-jsx.component.tsx:
--------------------------------------------------------------------------------
1 | import { Component, AfterViewInit, ElementRef } from '@angular/core';
2 | import * as React from 'react';
3 | import * as ReactDOM from 'react-dom';
4 | import { HelloJSX } from '@hybrid/react-component-library';
5 |
6 | @Component({
7 | selector: 'hybrid-hello-jsx',
8 | template: ``,
9 | styles: [``]
10 | })
11 | export class HelloJSXComponent implements AfterViewInit {
12 |
13 | constructor(private hostRef: ElementRef) { }
14 |
15 | ngAfterViewInit(): void {
16 | const hostElement = this.hostRef.nativeElement;
17 | const LabelToShow = () => (
18 | // Actual use here, might include data-binding in a real world scenario
19 |
20 | );
21 | ReactDOM.render(, hostElement);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/src/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/hello-jsx.component';
2 | export * from './lib/angular-wrapper.module';
3 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "jsx": "react",
5 | "esModuleInterop": true,
6 | "allowSyntheticDefaultImports": true,
7 | "types": ["node", "jest"]
8 | },
9 | "include": ["**/*.ts", "src/lib/index.tsx"]
10 | }
11 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "target": "es2015",
6 | "module": "es2015",
7 | "moduleResolution": "node",
8 | "declaration": true,
9 | "sourceMap": true,
10 | "inlineSources": true,
11 | "emitDecoratorMetadata": true,
12 | "experimentalDecorators": true,
13 | "allowSyntheticDefaultImports": true,
14 | "importHelpers": true,
15 | "types": [],
16 | "lib": ["dom", "es2018"]
17 | },
18 | "exclude": ["src/test.ts", "**/*.spec.ts"]
19 | }
20 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": ["**/*.spec.ts", "**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/libs/angular-wrappers/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.json",
3 | "rules": []
4 | }
5 |
--------------------------------------------------------------------------------
/libs/react-component-library/README.md:
--------------------------------------------------------------------------------
1 | # TestReact
2 |
3 | This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0.
4 |
5 | ## Code scaffolding
6 |
7 | Run `ng generate component component-name --project angular-wrappers` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project angular-wrappers`.
8 |
9 | > Note: Don't forget to add `--project angular-wrappers` or else it will be added to the default project in your `angular.json` file.
10 |
11 | ## Build
12 |
13 | Run `ng build angular-wrappers` to build the project. The build artifacts will be stored in the `dist/` directory.
14 |
15 | ## Publishing
16 |
17 | After building your library with `ng build angular-wrappers`, go to the dist folder `cd dist/angular-wrappers` and run `npm publish`.
18 |
19 | ## Running unit tests
20 |
21 | Run `ng test angular-wrappers` to execute the unit tests via [Karma](https://karma-runner.github.io).
22 |
23 | ## Further help
24 |
25 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
26 |
--------------------------------------------------------------------------------
/libs/react-component-library/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'angular-wrappers',
3 | preset: '../../jest.config.js',
4 | coverageDirectory: '../../coverage/libs/angular-wrappers'
5 | };
6 |
--------------------------------------------------------------------------------
/libs/react-component-library/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/react-component-library",
4 | "lib": {
5 | "entryFile": "src/public_api.ts",
6 | "umdModuleIds": {
7 | "react": "React",
8 | "react-dom": "ReactDOM"
9 | },
10 | "jsx": "react"
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/libs/react-component-library/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@hybrid/react-component-library",
3 | "version": "0.0.1"
4 | }
5 |
--------------------------------------------------------------------------------
/libs/react-component-library/src/lib/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/libs/react-component-library/src/lib/.gitkeep
--------------------------------------------------------------------------------
/libs/react-component-library/src/lib/react.component.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | // Simulating the use of an external library that contains React Components
4 | export class HelloJSX extends React.Component {
5 | render() {
6 | return (
7 |
8 | );
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/libs/react-component-library/src/public_api.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/react.component';
2 |
--------------------------------------------------------------------------------
/libs/react-component-library/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "jsx": "react",
5 | "esModuleInterop": true,
6 | "allowSyntheticDefaultImports": true,
7 | "types": ["node", "jest"]
8 | },
9 | "include": ["**/*.ts", "src/lib/index.tsx"]
10 | }
11 |
--------------------------------------------------------------------------------
/libs/react-component-library/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "target": "es2015",
6 | "module": "es2015",
7 | "moduleResolution": "node",
8 | "declaration": true,
9 | "sourceMap": true,
10 | "inlineSources": true,
11 | "emitDecoratorMetadata": true,
12 | "experimentalDecorators": true,
13 | "allowSyntheticDefaultImports": true,
14 | "importHelpers": true,
15 | "types": [],
16 | "lib": ["dom", "es2018"]
17 | },
18 | "exclude": ["src/test.ts", "**/*.spec.ts"]
19 | }
20 |
--------------------------------------------------------------------------------
/libs/react-component-library/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": ["**/*.spec.ts", "**/*.d.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/libs/react-component-library/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tslint.json",
3 | "rules": []
4 | }
5 |
--------------------------------------------------------------------------------
/libs/react-ng-wrapper/README.md:
--------------------------------------------------------------------------------
1 | # react-ng-wrapper
2 |
3 | This library was generated with [Nx](https://nx.dev).
4 |
5 | ## Running unit tests
6 |
7 | Run `nx test react-ng-wrapper` to execute the unit tests via [Jest](https://jestjs.io).
8 |
--------------------------------------------------------------------------------
/libs/react-ng-wrapper/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/react-ng-wrapper",
4 | "lib": {
5 | "entryFile": "src/index.ts",
6 | "umdModuleIds": {
7 | "react": "React",
8 | "react-dom": "ReactDOM"
9 | },
10 | "jsx": "react"
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/libs/react-ng-wrapper/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@hybrid/react-ng-wrapper",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/common": "^8.2.5",
6 | "@angular/core": "^8.2.5"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/libs/react-ng-wrapper/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/react-ng-wrapper';
2 |
--------------------------------------------------------------------------------
/libs/react-ng-wrapper/src/lib/react-ng-wrapper.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import {
4 | ɵrenderComponent as renderComponent,
5 | ɵmarkDirty as markDirty,
6 | ɵLifecycleHooksFeature as LifecycleHooksFeature,
7 | ɵComponentType as componentType,
8 | ɵComponentDef as ComponentDef,
9 | ɵNG_COMPONENT_DEF as NG_COMPONENT_DEF,
10 | SimpleChange,
11 | SimpleChanges,
12 | OnChanges
13 | } from '@angular/core';
14 | import { Subscription } from 'rxjs';
15 |
16 | declare global {
17 | namespace JSX {
18 | interface IntrinsicElements {
19 | [key: string]: any;
20 | }
21 | }
22 | }
23 |
24 | export class ReactNgWrapper extends React.Component }> {
25 | private _childComponent: T & Partial;
26 | private _componentDef: ComponentDef;
27 | private _subscriptions: Subscription[] = [];
28 |
29 | constructor(props: Readonly, private componentFactory: componentType) {
30 | super(props);
31 |
32 | this._componentDef = componentFactory[NG_COMPONENT_DEF] || null;
33 |
34 | if (!this._componentDef) {
35 | throw new Error(`A component with a ${NG_COMPONENT_DEF} is required`);
36 | }
37 |
38 | this.state = {
39 | selector: this._componentDef.selectors[0][0] as string,
40 | propChanged: new Set()
41 | };
42 | }
43 |
44 | componentWillUnmount() {
45 | this._subscriptions.forEach(subscription => subscription.unsubscribe())
46 | }
47 |
48 | // After the component did mount, we set the state each second.
49 | componentDidMount() {
50 | // render component after selector is in DOM
51 | this._childComponent = renderComponent(this.componentFactory, { hostFeatures: [LifecycleHooksFeature] });
52 |
53 | // listen to outputs
54 | this._subscriptions.push(
55 | ...Object.keys(this._componentDef.outputs).map(
56 | (output) => {
57 | return this._childComponent[output].subscribe((e) => {
58 | if (this.props[output] && typeof this.props[output] === "function") {
59 | this.props[output](e)
60 | }
61 | })
62 | }
63 | )
64 | )
65 |
66 | // bind inputs
67 | this.updateComponent();
68 | }
69 |
70 | componentDidUpdate() {
71 | this.updateComponent();
72 | }
73 |
74 | updateComponent() {
75 | if (this._childComponent) {
76 | const changes: SimpleChanges = {}
77 | // update inputs and detect changes
78 | Object.keys(this.props).forEach(prop => {
79 | if (this._childComponent[prop] &&
80 | Object.keys(this._componentDef.inputs).includes(prop) &&
81 | this._childComponent[prop] !== this.props[prop]) {
82 |
83 | changes[prop] = new SimpleChange(this._childComponent[prop], this.props[prop], !this.state.propChanged.has(prop))
84 | this.state.propChanged.add(prop);
85 | this._childComponent[prop] = this.props[prop]
86 | }
87 | })
88 |
89 | if (typeof this._childComponent.ngOnChanges === "function") {
90 | this._childComponent.ngOnChanges(changes);
91 | }
92 |
93 | markDirty(this._childComponent);
94 | }
95 | }
96 |
97 | // render will know everything!
98 | render() {
99 | const CustomTag = `${this.state.selector}`;
100 |
101 | return (
102 |
103 | )
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/libs/react-ng-wrapper/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "jsx": "react",
5 | "allowJs": false,
6 | "esModuleInterop": true,
7 | "allowSyntheticDefaultImports": true,
8 | "types": []
9 | },
10 | "include": ["**/*.ts", "**/*.tsx"]
11 | }
12 |
--------------------------------------------------------------------------------
/libs/react-ng-wrapper/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": []
6 | },
7 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
8 | "include": ["**/*.ts", "**/*.tsx"]
9 | }
10 |
--------------------------------------------------------------------------------
/libs/react-ng-wrapper/tslint.json:
--------------------------------------------------------------------------------
1 | { "extends": "../../tslint.json", "rules": [] }
2 |
--------------------------------------------------------------------------------
/libs/react-wrappers/README.md:
--------------------------------------------------------------------------------
1 | # react-wrappers
2 |
3 | This library was generated with [Nx](https://nx.dev).
4 |
5 | ## Running unit tests
6 |
7 | Run `nx test react-wrappers` to execute the unit tests via [Jest](https://jestjs.io).
8 |
--------------------------------------------------------------------------------
/libs/react-wrappers/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | name: 'react-wrappers',
3 | preset: '../../jest.config.js',
4 | transform: {
5 | '^.+\\.[tj]sx?$': 'ts-jest'
6 | },
7 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
8 | coverageDirectory: '../../coverage/libs/react-wrappers'
9 | };
10 |
--------------------------------------------------------------------------------
/libs/react-wrappers/ng-package.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3 | "dest": "../../dist/libs/react-wrappers",
4 | "lib": {
5 | "entryFile": "src/index.ts"
6 | }
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/libs/react-wrappers/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@hybrid/react-wrappers",
3 | "version": "0.0.1",
4 | "peerDependencies": {
5 | "@angular/common": "^8.2.5",
6 | "@angular/core": "^8.2.5",
7 | "@hybrid/react-ng-wrapper": "*"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/libs/react-wrappers/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './lib/timer';
2 | export * from './lib/hello';
3 |
--------------------------------------------------------------------------------
/libs/react-wrappers/src/lib/hello.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNgWrapper } from '@hybrid/react-ng-wrapper'
2 | import { HelloWorldComponent } from '@hybrid/angular-component-library';
3 |
4 | export class ReactHelloComponent extends ReactNgWrapper {
5 | constructor(props){
6 | super(props, HelloWorldComponent as any)
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/libs/react-wrappers/src/lib/timer.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNgWrapper } from '@hybrid/react-ng-wrapper'
2 | import { TimerComponent } from '@hybrid/angular-component-library';
3 |
4 | export class ReactTimerComponent extends ReactNgWrapper {
5 | constructor(props) {
6 | super(props, TimerComponent as any)
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/libs/react-wrappers/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "jsx": "react",
5 | "allowJs": false,
6 | "esModuleInterop": true,
7 | "allowSyntheticDefaultImports": true,
8 | "types": ["node", "jest"]
9 | },
10 | "include": ["**/*.ts", "**/*.tsx"]
11 | }
12 |
--------------------------------------------------------------------------------
/libs/react-wrappers/tsconfig.lib.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "types": []
6 | },
7 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
8 | "include": ["**/*.ts", "**/*.tsx"]
9 | }
10 |
--------------------------------------------------------------------------------
/libs/react-wrappers/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../../dist/out-tsc",
5 | "module": "commonjs",
6 | "types": ["jest", "node"]
7 | },
8 | "include": [
9 | "**/*.spec.ts",
10 | "**/*.spec.tsx",
11 | "**/*.spec.js",
12 | "**/*.spec.jsx",
13 | "**/*.d.ts"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/libs/react-wrappers/tslint.json:
--------------------------------------------------------------------------------
1 | { "extends": "../../tslint.json", "rules": [] }
2 |
--------------------------------------------------------------------------------
/nx.json:
--------------------------------------------------------------------------------
1 | {
2 | "npmScope": "hybrid",
3 | "implicitDependencies": {
4 | "angular.json": "*",
5 | "package.json": "*",
6 | "tsconfig.json": "*",
7 | "tslint.json": "*",
8 | "nx.json": "*"
9 | },
10 | "projects": {
11 | "react-app": {
12 | "tags": []
13 | },
14 | "angular-app": {
15 | "tags": []
16 | },
17 | "angular-ivy-app": {
18 | "tags": []
19 | },
20 | "react-ng-wrapper": {
21 | "tags": []
22 | },
23 | "react-wrappers": {
24 | "tags": []
25 | },
26 | "angular-component-library": {
27 | "tags": []
28 | },
29 | "angular-wrappers": {
30 | "tags": []
31 | },
32 | "react-component-library": {
33 | "tags": []
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-react-hybrid",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "ng",
7 | "start": "ng serve",
8 | "start:react": "yarn build:all && ng serve react-app",
9 | "start:angular": "yarn build:all && ng serve angular-app",
10 | "build": "ng build",
11 | "build:reactWrapper": "ng build react-ng-wrapper && ng build angular-component-library && ng build react-wrappers",
12 | "build:angularWrapper": "ng build react-component-library && ng build angular-wrappers",
13 | "build:all": "yarn build:reactWrapper && yarn build:angularWrapper",
14 | "test": "ng test",
15 | "lint": "./node_modules/.bin/nx workspace-lint && ng lint",
16 | "e2e": "ng e2e",
17 | "affected:apps": "./node_modules/.bin/nx affected:apps",
18 | "affected:libs": "./node_modules/.bin/nx affected:libs",
19 | "affected:build": "./node_modules/.bin/nx affected:build",
20 | "affected:e2e": "./node_modules/.bin/nx affected:e2e",
21 | "affected:test": "./node_modules/.bin/nx affected:test",
22 | "affected:lint": "./node_modules/.bin/nx affected:lint",
23 | "affected:dep-graph": "./node_modules/.bin/nx affected:dep-graph",
24 | "affected": "./node_modules/.bin/nx affected",
25 | "format": "./node_modules/.bin/nx format:write",
26 | "format:write": "./node_modules/.bin/nx format:write",
27 | "format:check": "./node_modules/.bin/nx format:check",
28 | "update": "ng update @nrwl/workspace",
29 | "update:check": "ng update",
30 | "workspace-schematic": "./node_modules/.bin/nx workspace-schematic",
31 | "dep-graph": "./node_modules/.bin/nx dep-graph",
32 | "help": "./node_modules/.bin/nx help",
33 | "nx": "nx"
34 | },
35 | "private": true,
36 | "dependencies": {
37 | "@angular/animations": "8.2.11",
38 | "@angular/common": "8.2.11",
39 | "@angular/compiler": "8.2.11",
40 | "@angular/core": "8.2.11",
41 | "@angular/forms": "8.2.11",
42 | "@angular/platform-browser": "8.2.11",
43 | "@angular/platform-browser-dynamic": "8.2.11",
44 | "@angular/router": "8.2.11",
45 | "@nrwl/angular": "8.6.0",
46 | "core-js": "2.6.9",
47 | "document-register-element": "1.13.1",
48 | "react": "16.9.0",
49 | "react-dom": "16.9.0",
50 | "rxjs": "6.5.3",
51 | "zone.js": "0.9.1"
52 | },
53 | "devDependencies": {
54 | "@angular-devkit/build-angular": "0.803.12",
55 | "@angular-devkit/build-ng-packagr": "0.803.12",
56 | "@angular-devkit/core": "8.3.3",
57 | "@angular/cli": "8.3.12",
58 | "@angular/compiler-cli": "8.2.11",
59 | "@angular/language-service": "8.2.11",
60 | "@babel/preset-react": "7.0.0",
61 | "@nrwl/cypress": "8.6.0",
62 | "@nrwl/eslint-plugin-nx": "8.6.0",
63 | "@nrwl/jest": "8.6.0",
64 | "@nrwl/react": "8.6.0",
65 | "@nrwl/web": "8.6.0",
66 | "@nrwl/workspace": "8.6.0",
67 | "@testing-library/react": "8.0.5",
68 | "@types/jest": "24.0.9",
69 | "@types/jquery": "3.3.6",
70 | "@types/node": "8.9.5",
71 | "@types/react": "16.9.1",
72 | "@types/react-dom": "16.8.5",
73 | "@typescript-eslint/eslint-plugin": "2.0.0-alpha.4",
74 | "@typescript-eslint/parser": "2.0.0-alpha.4",
75 | "codelyzer": "4.5.0",
76 | "cypress": "3.4.0",
77 | "dotenv": "6.2.0",
78 | "eslint": "6.3.0",
79 | "eslint-config-prettier": "6.0.0",
80 | "eslint-plugin-import": "2.18.2",
81 | "eslint-plugin-jsx-a11y": "6.2.3",
82 | "eslint-plugin-react": "7.14.3",
83 | "eslint-plugin-react-hooks": "1.6.1",
84 | "jest": "24.1.0",
85 | "jest-preset-angular": "7.0.0",
86 | "ng-packagr": "5.5.0",
87 | "prettier": "1.15.2",
88 | "ts-jest": "24.0.0",
89 | "ts-node": "7.0.1",
90 | "tsickle": "0.37.0",
91 | "tslib": "1.10.0",
92 | "tslint": "5.11.0",
93 | "typescript": "3.5.3"
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base",
4 | "group:all",
5 | ":automergeMinor",
6 | ":maintainLockFilesMonthly"
7 | ],
8 | "lockFileMaintenance": {
9 | "extends": [
10 | "group:all"
11 | ],
12 | "commitMessageAction": "Update"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tools/schematics/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RGunning/Angular-React-hybrid/51034938cc44bbd2dbe0e9356d8833611cea3aef/tools/schematics/.gitkeep
--------------------------------------------------------------------------------
/tools/tsconfig.tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../dist/out-tsc",
5 | "rootDir": ".",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": ["node"]
9 | },
10 | "include": ["**/*.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "sourceMap": true,
5 | "declaration": false,
6 | "moduleResolution": "node",
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "importHelpers": true,
10 | "target": "es2015",
11 | "module": "es2015",
12 | "typeRoots": ["node_modules/@types"],
13 | "lib": ["es2017", "dom"],
14 | "skipLibCheck": true,
15 | "skipDefaultLibCheck": true,
16 | "baseUrl": ".",
17 | "paths": {
18 | "@hybrid/react-ng-wrapper": ["dist/libs/react-ng-wrapper"],
19 | "@hybrid/react-wrappers": ["dist/libs/react-wrappers"],
20 | "@hybrid/angular-wrappers": ["dist/libs/angular-wrappers"],
21 | "@hybrid/angular-component-library": [
22 | "dist/libs/angular-component-library/"
23 | ],
24 | "@hybrid/react-component-library": [
25 | "dist/libs/react-component-library/"
26 | ]
27 | },
28 | "rootDir": "."
29 | },
30 | "angularCompilerOptions": {
31 | "enableIvy": true
32 | },
33 | "exclude": ["node_modules", "tmp"]
34 | }
35 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/@nrwl/workspace/src/tslint",
4 | "node_modules/codelyzer"
5 | ],
6 | "rules": {
7 | "arrow-return-shorthand": true,
8 | "callable-types": true,
9 | "class-name": true,
10 | "deprecation": {
11 | "severity": "warn"
12 | },
13 | "forin": true,
14 | "import-blacklist": [true, "rxjs/Rx"],
15 | "interface-over-type-literal": true,
16 | "member-access": false,
17 | "member-ordering": [
18 | true,
19 | {
20 | "order": [
21 | "static-field",
22 | "instance-field",
23 | "static-method",
24 | "instance-method"
25 | ]
26 | }
27 | ],
28 | "no-arg": true,
29 | "no-bitwise": true,
30 | "no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
31 | "no-construct": true,
32 | "no-debugger": true,
33 | "no-duplicate-super": true,
34 | "no-empty": false,
35 | "no-empty-interface": true,
36 | "no-eval": true,
37 | "no-inferrable-types": [true, "ignore-params"],
38 | "no-misused-new": true,
39 | "no-non-null-assertion": true,
40 | "no-shadowed-variable": true,
41 | "no-string-literal": false,
42 | "no-string-throw": true,
43 | "no-switch-case-fall-through": true,
44 | "no-unnecessary-initializer": true,
45 | "no-unused-expression": true,
46 | "no-use-before-declare": true,
47 | "no-var-keyword": true,
48 | "object-literal-sort-keys": false,
49 | "prefer-const": true,
50 | "radix": true,
51 | "triple-equals": [true, "allow-null-check"],
52 | "unified-signatures": true,
53 | "variable-name": false,
54 | "nx-enforce-module-boundaries": [
55 | true,
56 | {
57 | "allow": [],
58 | "depConstraints": [
59 | {
60 | "sourceTag": "*",
61 | "onlyDependOnLibsWithTags": ["*"]
62 | }
63 | ]
64 | }
65 | ],
66 | "directive-selector": [true, "attribute", "app", "camelCase"],
67 | "component-selector": [true, "element", "app", "kebab-case"],
68 | "no-output-on-prefix": true,
69 | "use-input-property-decorator": true,
70 | "use-output-property-decorator": true,
71 | "use-host-property-decorator": true,
72 | "no-input-rename": true,
73 | "no-output-rename": true,
74 | "use-life-cycle-interface": true,
75 | "use-pipe-transform-interface": true,
76 | "component-class-suffix": true,
77 | "directive-class-suffix": true
78 | }
79 | }
80 |
--------------------------------------------------------------------------------