ngx-reactify 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # ngx-reactify
2
+
3
+ > This project is currently in a beta phase and features will be added upon pull requests.
4
+ I will try to minimize breaking changes between minor version revisions but some may be made until we reach 1.0.0.
5
+
6
+ This project aims to make using Angular components in React not suck, and vice-versa. This is a dependency of my other library, ngx-xyflow.
7
+
8
+ ### Getting started:
9
+
10
+ ##### Install React
11
+
12
+ ```bash
13
+ npm i react react-dom
14
+ ```
15
+
16
+ ```bash
17
+ npm i -D @types/react
18
+ ```
19
+
20
+ ##### Install ngx-reactify
21
+
22
+ ```bash
23
+ npm i ngx-reactify
24
+ ```
25
+
26
+ ### Embed React component in Angular
27
+
28
+ ##### Create component Interface
29
+ Next, you.
30
+ > This step is necessary as it creates Angular bindings that can be used.
31
+ > Important: You can't use the normal stylesheet imports from React. Put your styles in the component.scss file.
32
+
33
+ ```ts
34
+ import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
35
+ import * as React from 'react';
36
+
37
+ import { ReactDemoWrappableComponent } from './react-demo'; // tsx file
38
+ import { ReactifyNgComponent } from 'ngx-reactify';
39
+
40
+ @Component({
41
+ selector: 'app-react-demo',
42
+ template: ``,
43
+ styleUrls: ['./react-demo.component.scss'],
44
+ standalone: true,
45
+ encapsulation: ViewEncapsulation.None
46
+ })
47
+ export class ReactDemoComponent extends ReactifyNgComponent {
48
+ override readonly ngReactComponent = ReactDemoWrappableComponent;
49
+
50
+ @Output() onNodeClick = new EventEmitter<[MouseEvent, Node]>();
51
+ @Output() onNodeDoubleClick = new EventEmitter<[MouseEvent, Node]>();
52
+
53
+ @Input() nodeTypes?: NodeTypes | undefined;
54
+ @Input() edgeTypes?: EdgeTypes | undefined;
55
+ }
56
+ ```
57
+
58
+ ##### Using the component
59
+
60
+ Last, import and use `ReactDemoComponent` elsewhere in your application.
61
+
62
+ ```ts
63
+
64
+ import { Component } from '@angular/core';
65
+ import { ReactDemoComponent } from './react-demo.component';
66
+
67
+ @Component({
68
+ selector: 'app-demo',
69
+ template: `
70
+ <app-react-demo
71
+ [nodeTypes]="[1,2,3,4]"
72
+ (onNodeClick)="onNodeClick($event)"
73
+ />
74
+ `,
75
+ imports: [ ReactDemoComponent ],
76
+ standalone: true
77
+ })
78
+ export class DemoComponent {
79
+
80
+ onNodeClick(evt) {
81
+ console.log(evt)
82
+ }
83
+ }
84
+ ```
85
+
86
+ ### Embed Angular component in React
87
+
88
+ > :warn: Under construction.
89
+ <!--
90
+ ```ts
91
+ import React from 'react';
92
+ import { ReactifyReactComponent } from 'ngx-reactify';
93
+ import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
94
+ import { ReactDemoComponent } from './react-demo.component';
95
+
96
+ @Component({
97
+ selector: 'app-demo',
98
+ template: `<div (click)="onNodeClick($event)"></div>`,
99
+ standalone: true
100
+ })
101
+ export class DemoComponent {
102
+ onNodeClick(evt) {
103
+ console.log(evt)
104
+ }
105
+ }
106
+
107
+ const AngularReactComponent = ReactifyReactComponent(DemoComponent)
108
+
109
+ export default function App() {
110
+
111
+ return (
112
+ <img src="https://picsum.photos/200" className={'picture'}></img>
113
+
114
+ <div>
115
+
116
+ </div>
117
+ )
118
+ }
119
+ ``` -->
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './public-api';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXJlYWN0aWZ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL25neC1yZWFjdGlmeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsY0FBYyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBHZW5lcmF0ZWQgYnVuZGxlIGluZGV4LiBEbyBub3QgZWRpdC5cbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL3B1YmxpYy1hcGknO1xuIl19
@@ -0,0 +1,3 @@
1
+ export * from './util/angular-to-react';
2
+ export * from './util/react-to-angular';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMseUJBQXlCLENBQUM7QUFDeEMsY0FBYyx5QkFBeUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vdXRpbC9hbmd1bGFyLXRvLXJlYWN0JztcbmV4cG9ydCAqIGZyb20gJy4vdXRpbC9yZWFjdC10by1hbmd1bGFyJztcbiJdfQ==
@@ -0,0 +1,116 @@
1
+ import { createComponent, EventEmitter } from '@angular/core';
2
+ import { createApplication } from '@angular/platform-browser';
3
+ import * as React from 'react';
4
+ import { firstValueFrom } from 'rxjs';
5
+ // declare const Zone;
6
+ // const zone = Zone ? new Zone(Zone.current, { name: "@dotglitch_menu", properties: {} }) : null;
7
+ /**
8
+ * Wrap an angular component inside of a React memo object.
9
+ * Will attempt to bind @Input and @Output properties if provided,
10
+ * and will bind the react arguments directly as @Input properties.
11
+ *
12
+ * @experimental
13
+ * @param componentClass Angular component
14
+ * @param envInjector An `EnvironmentInjector` instance to be used for the component
15
+ * @param injector An `ElementInjector` instance
16
+ * @param _inputs
17
+ * @param _outputs
18
+ * @returns
19
+ */
20
+ export const ReactifyReactComponent = ({ component, appRef, injector, ngZone, staticInputs, staticOutputs, preSiblings, postSiblings, additionalChildren, rootElementName, containerElementName }) => React.memo((args) => {
21
+ const id = Math.random().toString();
22
+ React.useEffect(() => {
23
+ try {
24
+ const componentInstance = createComponent(component, {
25
+ environmentInjector: appRef.injector,
26
+ elementInjector: injector,
27
+ hostElement: document.getElementById(id)
28
+ });
29
+ appRef.attachView(componentInstance.hostView);
30
+ // @ts-ignore
31
+ // component.hostView = hostView;
32
+ Object.assign(staticInputs, args);
33
+ const { inputs, outputs } = component['ɵcmp'];
34
+ // Returns a list of entries that need to be set
35
+ // This makes it so that unnecessary setters are not invoked.
36
+ const updated = Object.entries(inputs).filter(([parentKey, childKey]) => {
37
+ return componentInstance.instance[childKey] != staticInputs[parentKey];
38
+ });
39
+ updated.forEach(([parentKey, childKey]) => {
40
+ if (staticInputs.hasOwnProperty(parentKey))
41
+ componentInstance.instance[childKey] = staticInputs[parentKey];
42
+ });
43
+ const outputSubscriptions = {};
44
+ // Get a list of unregistered outputs
45
+ const newOutputs = Object.entries(outputs).filter(([parentKey, childKey]) => {
46
+ return !outputSubscriptions[parentKey];
47
+ });
48
+ // Reverse bind via subscription
49
+ newOutputs.forEach(([parentKey, childKey]) => {
50
+ if (!staticOutputs.hasOwnProperty(parentKey))
51
+ return;
52
+ const target = componentInstance.instance[childKey];
53
+ const outputs = staticOutputs;
54
+ const sub = target.subscribe((...args) => {
55
+ // Run the callback in the provided zone
56
+ ngZone.run(() => {
57
+ outputs[parentKey](...args);
58
+ });
59
+ }); // Subscription
60
+ outputSubscriptions[parentKey] = sub;
61
+ });
62
+ // Wrap the destroy method to safely release the subscriptions
63
+ const originalDestroy = componentInstance.onDestroy?.bind(componentInstance);
64
+ componentInstance.onDestroy = (cb) => {
65
+ Object.values(outputSubscriptions).forEach(s => s.unsubscribe());
66
+ originalDestroy?.(cb);
67
+ };
68
+ componentInstance.changeDetectorRef.detectChanges();
69
+ }
70
+ catch (err) {
71
+ console.error(err);
72
+ }
73
+ }, []);
74
+ const elements = [
75
+ ...(preSiblings || []),
76
+ React.createElement(containerElementName || "div", { id }),
77
+ ...(postSiblings || []),
78
+ ...(additionalChildren || [])
79
+ ].filter(e => e);
80
+ return React.createElement(rootElementName || "div", {}, ...elements);
81
+ });
82
+ export const ReactifyAngularComponent2 = (component, props) => {
83
+ const inputRef = React.useRef(null);
84
+ const ctx = this;
85
+ React.useEffect(() => {
86
+ // Is there a better way to do this?
87
+ let subscriptions;
88
+ let app;
89
+ (async () => {
90
+ // Code to run when the component mounts
91
+ app = await createApplication({ providers: [] });
92
+ const base = app.bootstrap(component, inputRef.current);
93
+ const { instance } = base;
94
+ await firstValueFrom(app.isStable);
95
+ // App has now bootstrapped fully.
96
+ subscriptions = [];
97
+ Object.entries(instance).filter(([k, v]) => {
98
+ // @Outputs are always Event Emitters (I think)
99
+ if (v instanceof EventEmitter) {
100
+ subscriptions.push(instance[k]?.subscribe(evt => props[k].call(ctx, evt)));
101
+ }
102
+ else {
103
+ instance[k] = props[k];
104
+ }
105
+ });
106
+ })();
107
+ return () => {
108
+ // Code to run when the component unmounts
109
+ subscriptions?.forEach(s => s?.unsubscribe());
110
+ app?.destroy();
111
+ };
112
+ }, []); // Empty dependency array ensures this effect runs only once on mount and cleanup on unmount
113
+ const obj = {};
114
+ return React.createElement("div");
115
+ };
116
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci10by1yZWFjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlsL2FuZ3VsYXItdG8tcmVhY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUEwQyxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RHLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzlELE9BQU8sS0FBSyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQy9CLE9BQU8sRUFBRSxjQUFjLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBR3BELHNCQUFzQjtBQUN0QixrR0FBa0c7QUFFbEc7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxFQUNuQyxTQUFTLEVBQ1QsTUFBTSxFQUNOLFFBQVEsRUFDUixNQUFNLEVBQ04sWUFBWSxFQUNaLGFBQWEsRUFDYixXQUFXLEVBQ1gsWUFBWSxFQUNaLGtCQUFrQixFQUNsQixlQUFlLEVBQ2Ysb0JBQW9CLEVBYXZCLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtJQUV0QixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDakIsSUFBSSxDQUFDO1lBRUQsTUFBTSxpQkFBaUIsR0FBRyxlQUFlLENBQUMsU0FBUyxFQUFFO2dCQUNqRCxtQkFBbUIsRUFBRSxNQUFNLENBQUMsUUFBUTtnQkFDcEMsZUFBZSxFQUFFLFFBQVE7Z0JBQ3pCLFdBQVcsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQzthQUMzQyxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lB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QUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDdkMsK0NBQStDO2dCQUMvQyxJQUFJLENBQUMsWUFBWSxZQUFZLEVBQUUsQ0FBQztvQkFDNUIsYUFBYSxDQUFDLElBQUksQ0FDZCxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FDekQsQ0FBQztnQkFDTixDQUFDO3FCQUNJLENBQUM7b0JBQ0YsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDM0IsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFBO1FBQ04sQ0FBQyxDQUFDLEVBQUUsQ0FBQTtRQUVKLE9BQU8sR0FBRyxFQUFFO1lBQ1IsMENBQTBDO1lBQzFDLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUM5QyxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDbkIsQ0FBQyxDQUFDO0lBQ04sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsNEZBQTRGO0lBRXBHLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUVmLE9BQU8sS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQTtBQUNyQyxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUeXBlLCBBcHBsaWNhdGlvblJlZiwgSW5qZWN0b3IsIE5nWm9uZSwgY3JlYXRlQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGNyZWF0ZUFwcGxpY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBmaXJzdFZhbHVlRnJvbSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cblxuLy8gZGVjbGFyZSBjb25zdCBab25lO1xuLy8gY29uc3Qgem9uZSA9IFpvbmUgPyBuZXcgWm9uZShab25lLmN1cnJlbnQsIHsgbmFtZTogXCJAZG90Z2xpdGNoX21lbnVcIiwgcHJvcGVydGllczoge30gfSkgOiBudWxsO1xuXG4vKipcbiAqIFdyYXAgYW4gYW5ndWxhciBjb21wb25lbnQgaW5zaWRlIG9mIGEgUmVhY3QgbWVtbyBvYmplY3QuXG4gKiBXaWxsIGF0dGVtcHQgdG8gYmluZCBASW5wdXQgYW5kIEBPdXRwdXQgcHJvcGVydGllcyBpZiBwcm92aWRlZCxcbiAqIGFuZCB3aWxsIGJpbmQgdGhlIHJlYWN0IGFyZ3VtZW50cyBkaXJlY3RseSBhcyBASW5wdXQgcHJvcGVydGllcy5cbiAqXG4gKiBAZXhwZXJpbWVudGFsXG4gKiBAcGFyYW0gY29tcG9uZW50Q2xhc3MgQW5ndWxhciBjb21wb25lbnRcbiAqIEBwYXJhbSBlbnZJbmplY3RvciAgICBBbiBgRW52aXJvbm1lbnRJbmplY3RvcmAgaW5zdGFuY2UgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbXBvbmVudFxuICogQHBhcmFtIGluamVjdG9yICAgICAgIEFuIGBFbGVtZW50SW5qZWN0b3JgIGluc3RhbmNlXG4gKiBAcGFyYW0gX2lucHV0c1xuICogQHBhcmFtIF9vdXRwdXRzXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgY29uc3QgUmVhY3RpZnlSZWFjdENvbXBvbmVudCA9ICh7XG4gICAgY29tcG9uZW50LFxuICAgIGFwcFJlZixcbiAgICBpbmplY3RvcixcbiAgICBuZ1pvbmUsXG4gICAgc3RhdGljSW5wdXRzLFxuICAgIHN0YXRpY091dHB1dHMsXG4gICAgcHJlU2libGluZ3MsXG4gICAgcG9zdFNpYmxpbmdzLFxuICAgIGFkZGl0aW9uYWxDaGlsZHJlbixcbiAgICByb290RWxlbWVudE5hbWUsXG4gICAgY29udGFpbmVyRWxlbWVudE5hbWVcbn06IHtcbiAgICBjb21wb25lbnQ6IFR5cGU8YW55PixcbiAgICBhcHBSZWY6IE9taXQ8QXBwbGljYXRpb25SZWYsICdfcnVubmluZ1RpY2snPixcbiAgICBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgbmdab25lOiBOZ1pvbmUsXG4gICAgc3RhdGljSW5wdXRzPzogeyBba2V5OiBzdHJpbmddOiBhbnk7IH0sXG4gICAgc3RhdGljT3V0cHV0cz86IHsgW2tleTogc3RyaW5nXTogRnVuY3Rpb247IH0sXG4gICAgcHJlU2libGluZ3M/OiBSZWFjdC5SZWFjdE5vZGVbXSxcbiAgICBwb3N0U2libGluZ3M/OiBSZWFjdC5SZWFjdE5vZGVbXSxcbiAgICBhZGRpdGlvbmFsQ2hpbGRyZW4/OiBSZWFjdC5SZWFjdE5vZGVbXSxcbiAgICByb290RWxlbWVudE5hbWU/OiBQYXJhbWV0ZXJzPHR5cGVvZiBSZWFjdC5jcmVhdGVFbGVtZW50PlswXSxcbiAgICBjb250YWluZXJFbGVtZW50TmFtZT86IHN0cmluZztcbn0pID0+IFJlYWN0Lm1lbW8oKGFyZ3MpID0+IHtcblxuICAgIGNvbnN0IGlkID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygpO1xuICAgIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICAgIHRyeSB7XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudEluc3RhbmNlID0gY3JlYXRlQ29tcG9uZW50KGNvbXBvbmVudCwge1xuICAgICAgICAgICAgICAgIGVudmlyb25tZW50SW5qZWN0b3I6IGFwcFJlZi5pbmplY3RvcixcbiAgICAgICAgICAgICAgICBlbGVtZW50SW5qZWN0b3I6IGluamVjdG9yLFxuICAgICAgICAgICAgICAgIGhvc3RFbGVtZW50OiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZClcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBhcHBSZWYuYXR0YWNoVmlldyhjb21wb25lbnRJbnN0YW5jZS5ob3N0Vmlldyk7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAvLyBjb21wb25lbnQuaG9zdFZpZXcgPSBob3N0VmlldztcblxuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihzdGF0aWNJbnB1dHMsIGFyZ3MpO1xuXG4gICAgICAgICAgICBjb25zdCB7IGlucHV0cywgb3V0cHV0cyB9ID0gY29tcG9uZW50WyfJtWNtcCddO1xuXG4gICAgICAgICAgICAvLyBSZXR1cm5zIGEgbGlzdCBvZiBlbnRyaWVzIHRoYXQgbmVlZCB0byBiZSBzZXRcbiAgICAgICAgICAgIC8vIFRoaXMgbWFrZXMgaXQgc28gdGhhdCB1bm5lY2Vzc2FyeSBzZXR0ZXJzIGFyZSBub3QgaW52b2tlZC5cbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWQgPSBPYmplY3QuZW50cmllcyhpbnB1dHMpLmZpbHRlcigoW3BhcmVudEtleSwgY2hpbGRLZXldOiBbc3RyaW5nLCBzdHJpbmddKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbXBvbmVudEluc3RhbmNlLmluc3RhbmNlW2NoaWxkS2V5XSAhPSBzdGF0aWNJbnB1dHNbcGFyZW50S2V5XTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB1cGRhdGVkLmZvckVhY2goKFtwYXJlbnRLZXksIGNoaWxkS2V5XTogW3N0cmluZywgc3RyaW5nXSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0aWNJbnB1dHMuaGFzT3duUHJvcGVydHkocGFyZW50S2V5KSlcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50SW5zdGFuY2UuaW5zdGFuY2VbY2hpbGRLZXldID0gc3RhdGljSW5wdXRzW3BhcmVudEtleV07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY29uc3Qgb3V0cHV0U3Vic2NyaXB0aW9uczogeyBba2V5OiBzdHJpbmddOiBTdWJzY3JpcHRpb247IH0gPSB7fTtcbiAgICAgICAgICAgIC8vIEdldCBhIGxpc3Qgb2YgdW5yZWdpc3RlcmVkIG91dHB1dHNcbiAgICAgICAgICAgIGNvbnN0IG5ld091dHB1dHMgPSBPYmplY3QuZW50cmllcyhvdXRwdXRzKS5maWx0ZXIoKFtwYXJlbnRLZXksIGNoaWxkS2V5XTogW3N0cmluZywgc3RyaW5nXSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiAhb3V0cHV0U3Vic2NyaXB0aW9uc1twYXJlbnRLZXldO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIFJldmVyc2UgYmluZCB2aWEgc3Vic2NyaXB0aW9uXG4gICAgICAgICAgICBuZXdPdXRwdXRzLmZvckVhY2goKFtwYXJlbnRLZXksIGNoaWxkS2V5XTogW3N0cmluZywgc3RyaW5nXSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghc3RhdGljT3V0cHV0cy5oYXNPd25Qcm9wZXJ0eShwYXJlbnRLZXkpKSByZXR1cm47XG5cbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQ6IEV2ZW50RW1pdHRlcjx1bmtub3duPiA9IGNvbXBvbmVudEluc3RhbmNlLmluc3RhbmNlW2NoaWxkS2V5XTtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRzID0gc3RhdGljT3V0cHV0cztcblxuICAgICAgICAgICAgICAgIGNvbnN0IHN1YiA9IHRhcmdldC5zdWJzY3JpYmUoKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUnVuIHRoZSBjYWxsYmFjayBpbiB0aGUgcHJvdmlkZWQgem9uZVxuICAgICAgICAgICAgICAgICAgICBuZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dHNbcGFyZW50S2V5XSguLi5hcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7IC8vIFN1YnNjcmlwdGlvblxuXG4gICAgICAgICAgICAgICAgb3V0cHV0U3Vic2NyaXB0aW9uc1twYXJlbnRLZXldID0gc3ViO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIFdyYXAgdGhlIGRlc3Ryb3kgbWV0aG9kIHRvIHNhZmVseSByZWxlYXNlIHRoZSBzdWJzY3JpcHRpb25zXG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbERlc3Ryb3kgPSBjb21wb25lbnRJbnN0YW5jZS5vbkRlc3Ryb3k/LmJpbmQoY29tcG9uZW50SW5zdGFuY2UpO1xuICAgICAgICAgICAgY29tcG9uZW50SW5zdGFuY2Uub25EZXN0cm95ID0gKGNiKSA9PiB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyhvdXRwdXRTdWJzY3JpcHRpb25zKS5mb3JFYWNoKHMgPT4gcy51bnN1YnNjcmliZSgpKTtcbiAgICAgICAgICAgICAgICBvcmlnaW5hbERlc3Ryb3k/LihjYik7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb21wb25lbnRJbnN0YW5jZS5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICB9XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3QgZWxlbWVudHMgPSBbXG4gICAgICAgIC4uLihwcmVTaWJsaW5ncyB8fCBbXSksXG4gICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoY29udGFpbmVyRWxlbWVudE5hbWUgfHwgXCJkaXZcIiwgeyBpZCB9KSxcbiAgICAgICAgLi4uKHBvc3RTaWJsaW5ncyB8fCBbXSksXG4gICAgICAgIC4uLihhZGRpdGlvbmFsQ2hpbGRyZW4gfHwgW10pXG4gICAgXS5maWx0ZXIoZSA9PiBlKTtcblxuICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KHJvb3RFbGVtZW50TmFtZSB8fCBcImRpdlwiLCB7fSwgLi4uZWxlbWVudHMpO1xufSk7XG5cblxuZXhwb3J0IGNvbnN0IFJlYWN0aWZ5QW5ndWxhckNvbXBvbmVudDIgPSAoXG4gICAgY29tcG9uZW50OiBUeXBlPGFueT4sXG4gICAgcHJvcHM6IGFueVxuKSA9PiB7XG4gICAgY29uc3QgaW5wdXRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gICAgY29uc3QgY3R4ID0gdGhpcztcblxuICAgIFJlYWN0LnVzZUVmZmVjdCgoKSA9PiB7XG4gICAgICAgIC8vIElzIHRoZXJlIGEgYmV0dGVyIHdheSB0byBkbyB0aGlzP1xuICAgICAgICBsZXQgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW107XG4gICAgICAgIGxldCBhcHA6IEFwcGxpY2F0aW9uUmVmO1xuICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gQ29kZSB0byBydW4gd2hlbiB0aGUgY29tcG9uZW50IG1vdW50c1xuICAgICAgICAgICAgYXBwID0gYXdhaXQgY3JlYXRlQXBwbGljYXRpb24oeyBwcm92aWRlcnM6IFtdIH0pO1xuICAgICAgICAgICAgY29uc3QgYmFzZSA9IGFwcC5ib290c3RyYXAoY29tcG9uZW50LCBpbnB1dFJlZi5jdXJyZW50KTtcbiAgICAgICAgICAgIGNvbnN0IHsgaW5zdGFuY2UgfSA9IGJhc2U7XG5cbiAgICAgICAgICAgIGF3YWl0IGZpcnN0VmFsdWVGcm9tKGFwcC5pc1N0YWJsZSk7XG5cbiAgICAgICAgICAgIC8vIEFwcCBoYXMgbm93IGJvb3RzdHJhcHBlZCBmdWxseS5cbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGluc3RhbmNlKS5maWx0ZXIoKFtrLCB2XSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEBPdXRwdXRzIGFyZSBhbHdheXMgRXZlbnQgRW1pdHRlcnMgKEkgdGhpbmspXG4gICAgICAgICAgICAgICAgaWYgKHYgaW5zdGFuY2VvZiBFdmVudEVtaXR0ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2Vba10/LnN1YnNjcmliZShldnQgPT4gcHJvcHNba10uY2FsbChjdHgsIGV2dCkpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZVtrXSA9IHByb3BzW2tdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pKClcblxuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgLy8gQ29kZSB0byBydW4gd2hlbiB0aGUgY29tcG9uZW50IHVubW91bnRzXG4gICAgICAgICAgICBzdWJzY3JpcHRpb25zPy5mb3JFYWNoKHMgPT4gcz8udW5zdWJzY3JpYmUoKSk7XG4gICAgICAgICAgICBhcHA/LmRlc3Ryb3koKTtcbiAgICAgICAgfTtcbiAgICB9LCBbXSk7IC8vIEVtcHR5IGRlcGVuZGVuY3kgYXJyYXkgZW5zdXJlcyB0aGlzIGVmZmVjdCBydW5zIG9ubHkgb25jZSBvbiBtb3VudCBhbmQgY2xlYW51cCBvbiB1bm1vdW50XG5cbiAgICBjb25zdCBvYmogPSB7fTtcblxuICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpXG59XG4iXX0=
@@ -0,0 +1,75 @@
1
+ import { Component } from '@angular/core';
2
+ import * as React from 'react';
3
+ import { createRoot } from 'react-dom/client';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Extend this component to automatically generate
7
+ * bindings to a React component.
8
+ *
9
+ * ! You _must_ override the property `ngReactComponent`
10
+ * Failure to do so will result in errors
11
+ * `override readonly ngReactComponent = ReactFlowWrappableComponent;`
12
+ */
13
+ export class ReactifyNgComponent {
14
+ constructor(ngContainer, ngZone) {
15
+ this.ngContainer = ngContainer;
16
+ this.ngZone = ngZone;
17
+ }
18
+ ngOnInit() {
19
+ if (!this.ngReactComponent) {
20
+ throw new Error("ReactMagicWrapperComponent cannot start without a provided ngReactComponent!");
21
+ }
22
+ }
23
+ ngOnChanges(changes) {
24
+ this._render();
25
+ }
26
+ ngAfterViewInit() {
27
+ this._render();
28
+ }
29
+ ngOnDestroy() {
30
+ this._root?.unmount();
31
+ }
32
+ _render() {
33
+ if (!this.ngReactComponent) {
34
+ console.log("Render no component. May be context issue");
35
+ return;
36
+ }
37
+ ;
38
+ this.ngZone.runOutsideAngular(() => {
39
+ try {
40
+ this._root ??= createRoot(this.ngContainer.element.nativeElement);
41
+ // List all keys that do not start with `_` nor `ng`
42
+ const keys = Object.keys(this).filter(k => !/^(?:_|ng)/.test(k));
43
+ // Get all property keys from the class
44
+ const propKeys = keys.filter(k => !k.startsWith("on"));
45
+ // Get all event handler keys from the class
46
+ const evtKeys = keys.filter(k => k.startsWith("on"));
47
+ const props = {};
48
+ // Project all key properties onto `props`
49
+ propKeys.forEach(k => props[k] = this[k]);
50
+ // Attempt to ensure no zone is lost during the event emitter fires
51
+ this.ngZone.runGuarded(() => {
52
+ // Bind all event handlers.
53
+ // ! important Angular uses EventEmitter, React uses
54
+ // a different method of event binding
55
+ evtKeys.forEach(k => props[k] = (...args) => this[k].next(args));
56
+ });
57
+ this._root.render(React.createElement(this.ngReactComponent, { props: props }));
58
+ }
59
+ catch (err) {
60
+ console.error(err);
61
+ }
62
+ });
63
+ }
64
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ReactifyNgComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
65
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: ReactifyNgComponent, isStandalone: true, selector: "app-react-magic-wrapper", usesOnChanges: true, ngImport: i0, template: ``, isInline: true }); }
66
+ }
67
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ReactifyNgComponent, decorators: [{
68
+ type: Component,
69
+ args: [{
70
+ selector: 'app-react-magic-wrapper',
71
+ template: ``,
72
+ standalone: true
73
+ }]
74
+ }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.NgZone }] });
75
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3QtdG8tYW5ndWxhci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlsL3JlYWN0LXRvLWFuZ3VsYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQyxTQUFTLEVBQXdLLE1BQU0sZUFBZSxDQUFDO0FBQy9PLE9BQU8sS0FBSyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQy9CLE9BQU8sRUFBRSxVQUFVLEVBQVEsTUFBTSxrQkFBa0IsQ0FBQzs7QUFHcEQ7Ozs7Ozs7R0FPRztBQU1ILE1BQU0sT0FBTyxtQkFBbUI7SUFXNUIsWUFDcUIsV0FBNkIsRUFDN0IsTUFBYztRQURkLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjtRQUM3QixXQUFNLEdBQU4sTUFBTSxDQUFRO0lBRW5DLENBQUM7SUFFRCxRQUFRO1FBQ0osSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3pCLE1BQU0sSUFBSSxLQUFLLENBQUMsOEVBQThFLENBQUMsQ0FBQztRQUNwRyxDQUFDO0lBQ0wsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUF1QjtRQUMvQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVELGVBQWU7UUFDWCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVELFdBQVc7UUFDUCxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFTyxPQUFPO1FBQ1gsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkNBQTJDLENBQUMsQ0FBQTtZQUN4RCxPQUFNO1FBQ1YsQ0FBQztRQUFBLENBQUM7UUFFRixJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUMvQixJQUFJLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLEtBQUssS0FBSyxVQUFVLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBRWxFLG9EQUFvRDtnQkFDcEQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFFakUsdUNBQXVDO2dCQUN2QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZELDRDQUE0QztnQkFDNUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFFckQsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO2dCQUNqQiwwQ0FBMEM7Z0JBQzFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRTFDLG1FQUFtRTtnQkFDbkUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO29CQUN4QiwyQkFBMkI7b0JBQzNCLG9EQUFvRDtvQkFDcEQsc0NBQXNDO29CQUN0QyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDckUsQ0FBQyxDQUFDLENBQUE7Z0JBRUYsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNGLENBQUM7WUFDRCxPQUFNLEdBQUcsRUFBRSxDQUFDO2dCQUNSLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDdEIsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQzs4R0F2RVEsbUJBQW1CO2tHQUFuQixtQkFBbUIsd0dBSGxCLEVBQUU7OzJGQUdILG1CQUFtQjtrQkFML0IsU0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUseUJBQXlCO29CQUNuQyxRQUFRLEVBQUUsRUFBRTtvQkFDWixVQUFVLEVBQUUsSUFBSTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZnRlclZpZXdJbml0LCBBcHBsaWNhdGlvblJlZiwgQ29tcG9uZW50LCBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIEVudmlyb25tZW50SW5qZWN0b3IsIEV2ZW50RW1pdHRlciwgSW5qZWN0b3IsIE5nWm9uZSwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIFNpbXBsZUNoYW5nZXMsIFR5cGUsIFZpZXdDb250YWluZXJSZWYsIFZpZXdSZWYsIGNyZWF0ZUNvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgY3JlYXRlUm9vdCwgUm9vdCB9IGZyb20gJ3JlYWN0LWRvbS9jbGllbnQnO1xuXG5cbi8qKlxuICogRXh0ZW5kIHRoaXMgY29tcG9uZW50IHRvIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVcbiAqIGJpbmRpbmdzIHRvIGEgUmVhY3QgY29tcG9uZW50LlxuICpcbiAqICEgWW91IF9tdXN0XyBvdmVycmlkZSB0aGUgcHJvcGVydHkgYG5nUmVhY3RDb21wb25lbnRgXG4gKiBGYWlsdXJlIHRvIGRvIHNvIHdpbGwgcmVzdWx0IGluIGVycm9yc1xuICogYG92ZXJyaWRlIHJlYWRvbmx5IG5nUmVhY3RDb21wb25lbnQgPSBSZWFjdEZsb3dXcmFwcGFibGVDb21wb25lbnQ7YFxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2FwcC1yZWFjdC1tYWdpYy13cmFwcGVyJyxcbiAgICB0ZW1wbGF0ZTogYGAsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZVxufSlcbmV4cG9ydCBjbGFzcyBSZWFjdGlmeU5nQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXQge1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlYWN0IGNvbXBvbmVudCB0byBiZSB3cmFwcGVkLlxuICAgICAqICEgTXVzdCBiZSBvdmVycmlkZGVuIGZvciB0aGlzIHdyYXBwZXIgdG8gd29ya1xuICAgICAqL1xuICAgIG5nUmVhY3RDb21wb25lbnQ6IFJlYWN0LkZ1bmN0aW9uQ29tcG9uZW50PGFueT4gfCBSZWFjdC5Db21wb25lbnRDbGFzczxhbnk+O1xuXG4gICAgcHJpdmF0ZSBfcm9vdDogUm9vdDtcbiAgICBwdWJsaWMgdGhlbWU6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IG5nQ29udGFpbmVyOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZTogTmdab25lXG4gICAgKSB7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIGlmICghdGhpcy5uZ1JlYWN0Q29tcG9uZW50KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWFjdE1hZ2ljV3JhcHBlckNvbXBvbmVudCBjYW5ub3Qgc3RhcnQgd2l0aG91dCBhIHByb3ZpZGVkIG5nUmVhY3RDb21wb25lbnQhXCIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlcz86IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fcmVuZGVyKCk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgICAgICB0aGlzLl9yZW5kZXIoKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5fcm9vdD8udW5tb3VudCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3JlbmRlcigpIHtcbiAgICAgICAgaWYgKCF0aGlzLm5nUmVhY3RDb21wb25lbnQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiUmVuZGVyIG5vIGNvbXBvbmVudC4gTWF5IGJlIGNvbnRleHQgaXNzdWVcIilcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm9vdCA/Pz0gY3JlYXRlUm9vdCh0aGlzLm5nQ29udGFpbmVyLmVsZW1lbnQubmF0aXZlRWxlbWVudCk7XG5cbiAgICAgICAgICAgICAgICAvLyBMaXN0IGFsbCBrZXlzIHRoYXQgZG8gbm90IHN0YXJ0IHdpdGggYF9gIG5vciBgbmdgXG4gICAgICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpLmZpbHRlcihrID0+ICEvXig/Ol98bmcpLy50ZXN0KGspKTtcblxuICAgICAgICAgICAgICAgIC8vIEdldCBhbGwgcHJvcGVydHkga2V5cyBmcm9tIHRoZSBjbGFzc1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb3BLZXlzID0ga2V5cy5maWx0ZXIoayA9PiAhay5zdGFydHNXaXRoKFwib25cIikpO1xuICAgICAgICAgICAgICAgIC8vIEdldCBhbGwgZXZlbnQgaGFuZGxlciBrZXlzIGZyb20gdGhlIGNsYXNzXG4gICAgICAgICAgICAgICAgY29uc3QgZXZ0S2V5cyA9IGtleXMuZmlsdGVyKGsgPT4gay5zdGFydHNXaXRoKFwib25cIikpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgcHJvcHMgPSB7fTtcbiAgICAgICAgICAgICAgICAvLyBQcm9qZWN0IGFsbCBrZXkgcHJvcGVydGllcyBvbnRvIGBwcm9wc2BcbiAgICAgICAgICAgICAgICBwcm9wS2V5cy5mb3JFYWNoKGsgPT4gcHJvcHNba10gPSB0aGlzW2tdKTtcblxuICAgICAgICAgICAgICAgIC8vIEF0dGVtcHQgdG8gZW5zdXJlIG5vIHpvbmUgaXMgbG9zdCBkdXJpbmcgdGhlIGV2ZW50IGVtaXR0ZXIgZmlyZXNcbiAgICAgICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW5HdWFyZGVkKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQmluZCBhbGwgZXZlbnQgaGFuZGxlcnMuXG4gICAgICAgICAgICAgICAgICAgIC8vICEgaW1wb3J0YW50IEFuZ3VsYXIgdXNlcyBFdmVudEVtaXR0ZXIsIFJlYWN0IHVzZXNcbiAgICAgICAgICAgICAgICAgICAgLy8gYSBkaWZmZXJlbnQgbWV0aG9kIG9mIGV2ZW50IGJpbmRpbmdcbiAgICAgICAgICAgICAgICAgICAgZXZ0S2V5cy5mb3JFYWNoKGsgPT4gcHJvcHNba10gPSAoLi4uYXJncykgPT4gdGhpc1trXS5uZXh0KGFyZ3MpKTtcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgdGhpcy5fcm9vdC5yZW5kZXIoUmVhY3QuY3JlYXRlRWxlbWVudCh0aGlzLm5nUmVhY3RDb21wb25lbnQsIHsgcHJvcHM6IHByb3BzIGFzIGFueSB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaChlcnIpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG59XG4iXX0=
@@ -0,0 +1,196 @@
1
+ import * as i0 from '@angular/core';
2
+ import { createComponent, EventEmitter, Component } from '@angular/core';
3
+ import { createApplication } from '@angular/platform-browser';
4
+ import * as React from 'react';
5
+ import { firstValueFrom } from 'rxjs';
6
+ import { createRoot } from 'react-dom/client';
7
+
8
+ // declare const Zone;
9
+ // const zone = Zone ? new Zone(Zone.current, { name: "@dotglitch_menu", properties: {} }) : null;
10
+ /**
11
+ * Wrap an angular component inside of a React memo object.
12
+ * Will attempt to bind @Input and @Output properties if provided,
13
+ * and will bind the react arguments directly as @Input properties.
14
+ *
15
+ * @experimental
16
+ * @param componentClass Angular component
17
+ * @param envInjector An `EnvironmentInjector` instance to be used for the component
18
+ * @param injector An `ElementInjector` instance
19
+ * @param _inputs
20
+ * @param _outputs
21
+ * @returns
22
+ */
23
+ const ReactifyReactComponent = ({ component, appRef, injector, ngZone, staticInputs, staticOutputs, preSiblings, postSiblings, additionalChildren, rootElementName, containerElementName }) => React.memo((args) => {
24
+ const id = Math.random().toString();
25
+ React.useEffect(() => {
26
+ try {
27
+ const componentInstance = createComponent(component, {
28
+ environmentInjector: appRef.injector,
29
+ elementInjector: injector,
30
+ hostElement: document.getElementById(id)
31
+ });
32
+ appRef.attachView(componentInstance.hostView);
33
+ // @ts-ignore
34
+ // component.hostView = hostView;
35
+ Object.assign(staticInputs, args);
36
+ const { inputs, outputs } = component['ɵcmp'];
37
+ // Returns a list of entries that need to be set
38
+ // This makes it so that unnecessary setters are not invoked.
39
+ const updated = Object.entries(inputs).filter(([parentKey, childKey]) => {
40
+ return componentInstance.instance[childKey] != staticInputs[parentKey];
41
+ });
42
+ updated.forEach(([parentKey, childKey]) => {
43
+ if (staticInputs.hasOwnProperty(parentKey))
44
+ componentInstance.instance[childKey] = staticInputs[parentKey];
45
+ });
46
+ const outputSubscriptions = {};
47
+ // Get a list of unregistered outputs
48
+ const newOutputs = Object.entries(outputs).filter(([parentKey, childKey]) => {
49
+ return !outputSubscriptions[parentKey];
50
+ });
51
+ // Reverse bind via subscription
52
+ newOutputs.forEach(([parentKey, childKey]) => {
53
+ if (!staticOutputs.hasOwnProperty(parentKey))
54
+ return;
55
+ const target = componentInstance.instance[childKey];
56
+ const outputs = staticOutputs;
57
+ const sub = target.subscribe((...args) => {
58
+ // Run the callback in the provided zone
59
+ ngZone.run(() => {
60
+ outputs[parentKey](...args);
61
+ });
62
+ }); // Subscription
63
+ outputSubscriptions[parentKey] = sub;
64
+ });
65
+ // Wrap the destroy method to safely release the subscriptions
66
+ const originalDestroy = componentInstance.onDestroy?.bind(componentInstance);
67
+ componentInstance.onDestroy = (cb) => {
68
+ Object.values(outputSubscriptions).forEach(s => s.unsubscribe());
69
+ originalDestroy?.(cb);
70
+ };
71
+ componentInstance.changeDetectorRef.detectChanges();
72
+ }
73
+ catch (err) {
74
+ console.error(err);
75
+ }
76
+ }, []);
77
+ const elements = [
78
+ ...(preSiblings || []),
79
+ React.createElement(containerElementName || "div", { id }),
80
+ ...(postSiblings || []),
81
+ ...(additionalChildren || [])
82
+ ].filter(e => e);
83
+ return React.createElement(rootElementName || "div", {}, ...elements);
84
+ });
85
+ const ReactifyAngularComponent2 = (component, props) => {
86
+ const inputRef = React.useRef(null);
87
+ const ctx = this;
88
+ React.useEffect(() => {
89
+ // Is there a better way to do this?
90
+ let subscriptions;
91
+ let app;
92
+ (async () => {
93
+ // Code to run when the component mounts
94
+ app = await createApplication({ providers: [] });
95
+ const base = app.bootstrap(component, inputRef.current);
96
+ const { instance } = base;
97
+ await firstValueFrom(app.isStable);
98
+ // App has now bootstrapped fully.
99
+ subscriptions = [];
100
+ Object.entries(instance).filter(([k, v]) => {
101
+ // @Outputs are always Event Emitters (I think)
102
+ if (v instanceof EventEmitter) {
103
+ subscriptions.push(instance[k]?.subscribe(evt => props[k].call(ctx, evt)));
104
+ }
105
+ else {
106
+ instance[k] = props[k];
107
+ }
108
+ });
109
+ })();
110
+ return () => {
111
+ // Code to run when the component unmounts
112
+ subscriptions?.forEach(s => s?.unsubscribe());
113
+ app?.destroy();
114
+ };
115
+ }, []); // Empty dependency array ensures this effect runs only once on mount and cleanup on unmount
116
+ const obj = {};
117
+ return React.createElement("div");
118
+ };
119
+
120
+ /**
121
+ * Extend this component to automatically generate
122
+ * bindings to a React component.
123
+ *
124
+ * ! You _must_ override the property `ngReactComponent`
125
+ * Failure to do so will result in errors
126
+ * `override readonly ngReactComponent = ReactFlowWrappableComponent;`
127
+ */
128
+ class ReactifyNgComponent {
129
+ constructor(ngContainer, ngZone) {
130
+ this.ngContainer = ngContainer;
131
+ this.ngZone = ngZone;
132
+ }
133
+ ngOnInit() {
134
+ if (!this.ngReactComponent) {
135
+ throw new Error("ReactMagicWrapperComponent cannot start without a provided ngReactComponent!");
136
+ }
137
+ }
138
+ ngOnChanges(changes) {
139
+ this._render();
140
+ }
141
+ ngAfterViewInit() {
142
+ this._render();
143
+ }
144
+ ngOnDestroy() {
145
+ this._root?.unmount();
146
+ }
147
+ _render() {
148
+ if (!this.ngReactComponent) {
149
+ console.log("Render no component. May be context issue");
150
+ return;
151
+ }
152
+ ;
153
+ this.ngZone.runOutsideAngular(() => {
154
+ try {
155
+ this._root ??= createRoot(this.ngContainer.element.nativeElement);
156
+ // List all keys that do not start with `_` nor `ng`
157
+ const keys = Object.keys(this).filter(k => !/^(?:_|ng)/.test(k));
158
+ // Get all property keys from the class
159
+ const propKeys = keys.filter(k => !k.startsWith("on"));
160
+ // Get all event handler keys from the class
161
+ const evtKeys = keys.filter(k => k.startsWith("on"));
162
+ const props = {};
163
+ // Project all key properties onto `props`
164
+ propKeys.forEach(k => props[k] = this[k]);
165
+ // Attempt to ensure no zone is lost during the event emitter fires
166
+ this.ngZone.runGuarded(() => {
167
+ // Bind all event handlers.
168
+ // ! important Angular uses EventEmitter, React uses
169
+ // a different method of event binding
170
+ evtKeys.forEach(k => props[k] = (...args) => this[k].next(args));
171
+ });
172
+ this._root.render(React.createElement(this.ngReactComponent, { props: props }));
173
+ }
174
+ catch (err) {
175
+ console.error(err);
176
+ }
177
+ });
178
+ }
179
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ReactifyNgComponent, deps: [{ token: i0.ViewContainerRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
180
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: ReactifyNgComponent, isStandalone: true, selector: "app-react-magic-wrapper", usesOnChanges: true, ngImport: i0, template: ``, isInline: true }); }
181
+ }
182
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ReactifyNgComponent, decorators: [{
183
+ type: Component,
184
+ args: [{
185
+ selector: 'app-react-magic-wrapper',
186
+ template: ``,
187
+ standalone: true
188
+ }]
189
+ }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.NgZone }] });
190
+
191
+ /**
192
+ * Generated bundle index. Do not edit.
193
+ */
194
+
195
+ export { ReactifyAngularComponent2, ReactifyNgComponent, ReactifyReactComponent };
196
+ //# sourceMappingURL=ngx-reactify.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-reactify.mjs","sources":["../../../src/util/angular-to-react.ts","../../../src/util/react-to-angular.ts","../../../src/ngx-reactify.ts"],"sourcesContent":["import { Type, ApplicationRef, Injector, NgZone, createComponent, EventEmitter } from '@angular/core';\nimport { createApplication } from '@angular/platform-browser';\nimport * as React from 'react';\nimport { firstValueFrom, Subscription } from 'rxjs';\n\n\n// declare const Zone;\n// const zone = Zone ? new Zone(Zone.current, { name: \"@dotglitch_menu\", properties: {} }) : null;\n\n/**\n * Wrap an angular component inside of a React memo object.\n * Will attempt to bind @Input and @Output properties if provided,\n * and will bind the react arguments directly as @Input properties.\n *\n * @experimental\n * @param componentClass Angular component\n * @param envInjector An `EnvironmentInjector` instance to be used for the component\n * @param injector An `ElementInjector` instance\n * @param _inputs\n * @param _outputs\n * @returns\n */\nexport const ReactifyReactComponent = ({\n component,\n appRef,\n injector,\n ngZone,\n staticInputs,\n staticOutputs,\n preSiblings,\n postSiblings,\n additionalChildren,\n rootElementName,\n containerElementName\n}: {\n component: Type<any>,\n appRef: Omit<ApplicationRef, '_runningTick'>,\n injector: Injector,\n ngZone: NgZone,\n staticInputs?: { [key: string]: any; },\n staticOutputs?: { [key: string]: Function; },\n preSiblings?: React.ReactNode[],\n postSiblings?: React.ReactNode[],\n additionalChildren?: React.ReactNode[],\n rootElementName?: Parameters<typeof React.createElement>[0],\n containerElementName?: string;\n}) => React.memo((args) => {\n\n const id = Math.random().toString();\n React.useEffect(() => {\n try {\n\n const componentInstance = createComponent(component, {\n environmentInjector: appRef.injector,\n elementInjector: injector,\n hostElement: document.getElementById(id)\n });\n\n appRef.attachView(componentInstance.hostView);\n // @ts-ignore\n // component.hostView = hostView;\n\n Object.assign(staticInputs, args);\n\n const { inputs, outputs } = component['ɵcmp'];\n\n // Returns a list of entries that need to be set\n // This makes it so that unnecessary setters are not invoked.\n const updated = Object.entries(inputs).filter(([parentKey, childKey]: [string, string]) => {\n return componentInstance.instance[childKey] != staticInputs[parentKey];\n });\n\n updated.forEach(([parentKey, childKey]: [string, string]) => {\n if (staticInputs.hasOwnProperty(parentKey))\n componentInstance.instance[childKey] = staticInputs[parentKey];\n });\n\n const outputSubscriptions: { [key: string]: Subscription; } = {};\n // Get a list of unregistered outputs\n const newOutputs = Object.entries(outputs).filter(([parentKey, childKey]: [string, string]) => {\n return !outputSubscriptions[parentKey];\n });\n\n // Reverse bind via subscription\n newOutputs.forEach(([parentKey, childKey]: [string, string]) => {\n if (!staticOutputs.hasOwnProperty(parentKey)) return;\n\n const target: EventEmitter<unknown> = componentInstance.instance[childKey];\n const outputs = staticOutputs;\n\n const sub = target.subscribe((...args) => {\n // Run the callback in the provided zone\n ngZone.run(() => {\n outputs[parentKey](...args);\n });\n }); // Subscription\n\n outputSubscriptions[parentKey] = sub;\n });\n\n // Wrap the destroy method to safely release the subscriptions\n const originalDestroy = componentInstance.onDestroy?.bind(componentInstance);\n componentInstance.onDestroy = (cb) => {\n Object.values(outputSubscriptions).forEach(s => s.unsubscribe());\n originalDestroy?.(cb);\n };\n\n componentInstance.changeDetectorRef.detectChanges();\n }\n catch (err) {\n console.error(err);\n }\n }, []);\n\n const elements = [\n ...(preSiblings || []),\n React.createElement(containerElementName || \"div\", { id }),\n ...(postSiblings || []),\n ...(additionalChildren || [])\n ].filter(e => e);\n\n return React.createElement(rootElementName || \"div\", {}, ...elements);\n});\n\n\nexport const ReactifyAngularComponent2 = (\n component: Type<any>,\n props: any\n) => {\n const inputRef = React.useRef(null);\n const ctx = this;\n\n React.useEffect(() => {\n // Is there a better way to do this?\n let subscriptions: Subscription[];\n let app: ApplicationRef;\n (async () => {\n // Code to run when the component mounts\n app = await createApplication({ providers: [] });\n const base = app.bootstrap(component, inputRef.current);\n const { instance } = base;\n\n await firstValueFrom(app.isStable);\n\n // App has now bootstrapped fully.\n subscriptions = [];\n Object.entries(instance).filter(([k, v]) => {\n // @Outputs are always Event Emitters (I think)\n if (v instanceof EventEmitter) {\n subscriptions.push(\n instance[k]?.subscribe(evt => props[k].call(ctx, evt))\n );\n }\n else {\n instance[k] = props[k];\n }\n })\n })()\n\n return () => {\n // Code to run when the component unmounts\n subscriptions?.forEach(s => s?.unsubscribe());\n app?.destroy();\n };\n }, []); // Empty dependency array ensures this effect runs only once on mount and cleanup on unmount\n\n const obj = {};\n\n return React.createElement(\"div\")\n}\n","import { AfterViewInit, ApplicationRef, Component, ComponentFactoryResolver, EnvironmentInjector, EventEmitter, Injector, NgZone, OnChanges, OnDestroy, SimpleChanges, Type, ViewContainerRef, ViewRef, createComponent } from '@angular/core';\nimport * as React from 'react';\nimport { createRoot, Root } from 'react-dom/client';\n\n\n/**\n * Extend this component to automatically generate\n * bindings to a React component.\n *\n * ! You _must_ override the property `ngReactComponent`\n * Failure to do so will result in errors\n * `override readonly ngReactComponent = ReactFlowWrappableComponent;`\n */\n@Component({\n selector: 'app-react-magic-wrapper',\n template: ``,\n standalone: true\n})\nexport class ReactifyNgComponent implements OnChanges, OnDestroy, AfterViewInit {\n\n /**\n * The react component to be wrapped.\n * ! Must be overridden for this wrapper to work\n */\n ngReactComponent: React.FunctionComponent<any> | React.ComponentClass<any>;\n\n private _root: Root;\n public theme: string;\n\n constructor(\n private readonly ngContainer: ViewContainerRef,\n private readonly ngZone: NgZone\n ) {\n }\n\n ngOnInit() {\n if (!this.ngReactComponent) {\n throw new Error(\"ReactMagicWrapperComponent cannot start without a provided ngReactComponent!\");\n }\n }\n\n ngOnChanges(changes?: SimpleChanges): void {\n this._render();\n }\n\n ngAfterViewInit() {\n this._render();\n }\n\n ngOnDestroy() {\n this._root?.unmount();\n }\n\n private _render() {\n if (!this.ngReactComponent) {\n console.log(\"Render no component. May be context issue\")\n return\n };\n\n this.ngZone.runOutsideAngular(() => {\n try {\n this._root ??= createRoot(this.ngContainer.element.nativeElement);\n\n // List all keys that do not start with `_` nor `ng`\n const keys = Object.keys(this).filter(k => !/^(?:_|ng)/.test(k));\n\n // Get all property keys from the class\n const propKeys = keys.filter(k => !k.startsWith(\"on\"));\n // Get all event handler keys from the class\n const evtKeys = keys.filter(k => k.startsWith(\"on\"));\n\n const props = {};\n // Project all key properties onto `props`\n propKeys.forEach(k => props[k] = this[k]);\n\n // Attempt to ensure no zone is lost during the event emitter fires\n this.ngZone.runGuarded(() => {\n // Bind all event handlers.\n // ! important Angular uses EventEmitter, React uses\n // a different method of event binding\n evtKeys.forEach(k => props[k] = (...args) => this[k].next(args));\n })\n\n this._root.render(React.createElement(this.ngReactComponent, { props: props as any }));\n }\n catch(err) {\n console.error(err)\n }\n })\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["this"],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="ngx-reactify" />
5
+ export * from './public-api';
6
+ //# sourceMappingURL=ngx-reactify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-reactify.d.ts","sourceRoot":"","sources":["../../src/ngx-reactify.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAEH,cAAc,cAAc,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "ngx-reactify",
3
+ "version": "0.0.1",
4
+ "repository": {
5
+ "url": "https://github.com/knackstedt/ngx-reactify"
6
+ },
7
+ "license": "MIT",
8
+ "author": {
9
+ "email": "andrewk@vivaldi.net",
10
+ "name": "Andrew G. Knackstedt"
11
+ },
12
+ "private": false,
13
+ "peerDependencies": {
14
+ "@angular/common": ">=17.0.0",
15
+ "@angular/core": ">=17.0.0"
16
+ },
17
+ "dependencies": {
18
+ "react": ">=18.0.0",
19
+ "react-dom": ">=18.0.0",
20
+ "tslib": ">=2.6.0"
21
+ },
22
+ "module": "fesm2022/ngx-reactify.mjs",
23
+ "typings": "index.d.ts",
24
+ "exports": {
25
+ "./package.json": {
26
+ "default": "./package.json"
27
+ },
28
+ ".": {
29
+ "types": "./index.d.ts",
30
+ "esm2022": "./esm2022/ngx-reactify.mjs",
31
+ "esm": "./esm2022/ngx-reactify.mjs",
32
+ "default": "./fesm2022/ngx-reactify.mjs"
33
+ }
34
+ },
35
+ "sideEffects": false
36
+ }
@@ -0,0 +1,3 @@
1
+ export * from './util/angular-to-react';
2
+ export * from './util/react-to-angular';
3
+ //# sourceMappingURL=public-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../src/public-api.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { Type, ApplicationRef, Injector, NgZone } from '@angular/core';
2
+ import * as React from 'react';
3
+ /**
4
+ * Wrap an angular component inside of a React memo object.
5
+ * Will attempt to bind @Input and @Output properties if provided,
6
+ * and will bind the react arguments directly as @Input properties.
7
+ *
8
+ * @experimental
9
+ * @param componentClass Angular component
10
+ * @param envInjector An `EnvironmentInjector` instance to be used for the component
11
+ * @param injector An `ElementInjector` instance
12
+ * @param _inputs
13
+ * @param _outputs
14
+ * @returns
15
+ */
16
+ export declare const ReactifyReactComponent: ({ component, appRef, injector, ngZone, staticInputs, staticOutputs, preSiblings, postSiblings, additionalChildren, rootElementName, containerElementName }: {
17
+ component: Type<any>;
18
+ appRef: Omit<ApplicationRef, '_runningTick'>;
19
+ injector: Injector;
20
+ ngZone: NgZone;
21
+ staticInputs?: {
22
+ [key: string]: any;
23
+ };
24
+ staticOutputs?: {
25
+ [key: string]: Function;
26
+ };
27
+ preSiblings?: React.ReactNode[];
28
+ postSiblings?: React.ReactNode[];
29
+ additionalChildren?: React.ReactNode[];
30
+ rootElementName?: Parameters<typeof React.createElement>[0];
31
+ containerElementName?: string;
32
+ }) => React.NamedExoticComponent<object>;
33
+ export declare const ReactifyAngularComponent2: (component: Type<any>, props: any) => React.DetailedReactHTMLElement<React.HTMLAttributes<HTMLElement>, HTMLElement>;
34
+ //# sourceMappingURL=angular-to-react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"angular-to-react.d.ts","sourceRoot":"","sources":["../../../src/util/angular-to-react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAiC,MAAM,eAAe,CAAC;AAEtG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB;eAapB,KAAK,GAAG,CAAC;YACZ,KAAK,cAAc,EAAE,cAAc,CAAC;cAClC,QAAQ;YACV,MAAM;;;;;;;kBAGA,MAAM,SAAS,EAAE;mBAChB,MAAM,SAAS,EAAE;yBACX,MAAM,SAAS,EAAE;sBACpB,WAAW,OAAO,MAAM,aAAa,CAAC,CAAC,CAAC,CAAC;2BACpC,MAAM;wCA6E/B,CAAC;AAGH,eAAO,MAAM,yBAAyB,cACvB,KAAK,GAAG,CAAC,SACb,GAAG,mFA0Cb,CAAA"}
@@ -0,0 +1,31 @@
1
+ import { AfterViewInit, NgZone, OnChanges, OnDestroy, SimpleChanges, ViewContainerRef } from '@angular/core';
2
+ import * as React from 'react';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Extend this component to automatically generate
6
+ * bindings to a React component.
7
+ *
8
+ * ! You _must_ override the property `ngReactComponent`
9
+ * Failure to do so will result in errors
10
+ * `override readonly ngReactComponent = ReactFlowWrappableComponent;`
11
+ */
12
+ export declare class ReactifyNgComponent implements OnChanges, OnDestroy, AfterViewInit {
13
+ private readonly ngContainer;
14
+ private readonly ngZone;
15
+ /**
16
+ * The react component to be wrapped.
17
+ * ! Must be overridden for this wrapper to work
18
+ */
19
+ ngReactComponent: React.FunctionComponent<any> | React.ComponentClass<any>;
20
+ private _root;
21
+ theme: string;
22
+ constructor(ngContainer: ViewContainerRef, ngZone: NgZone);
23
+ ngOnInit(): void;
24
+ ngOnChanges(changes?: SimpleChanges): void;
25
+ ngAfterViewInit(): void;
26
+ ngOnDestroy(): void;
27
+ private _render;
28
+ static ɵfac: i0.ɵɵFactoryDeclaration<ReactifyNgComponent, never>;
29
+ static ɵcmp: i0.ɵɵComponentDeclaration<ReactifyNgComponent, "app-react-magic-wrapper", never, {}, {}, never, never, true, never>;
30
+ }
31
+ //# sourceMappingURL=react-to-angular.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-to-angular.d.ts","sourceRoot":"","sources":["../../../src/util/react-to-angular.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoG,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAQ,gBAAgB,EAA4B,MAAM,eAAe,CAAC;AAC/O,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;;AAI/B;;;;;;;GAOG;AACH,qBAKa,mBAAoB,YAAW,SAAS,EAAE,SAAS,EAAE,aAAa;IAYvE,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAX3B;;;OAGG;IACH,gBAAgB,EAAE,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IAE3E,OAAO,CAAC,KAAK,CAAO;IACb,KAAK,EAAE,MAAM,CAAC;gBAGA,WAAW,EAAE,gBAAgB,EAC7B,MAAM,EAAE,MAAM;IAInC,QAAQ;IAMR,WAAW,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;IAI1C,eAAe;IAIf,WAAW;IAIX,OAAO,CAAC,OAAO;yCAnCN,mBAAmB;2CAAnB,mBAAmB;CAwE/B"}