@analogjs/astro-angular 0.2.2 → 0.2.3

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 CHANGED
@@ -174,7 +174,7 @@ export class HelloComponent {
174
174
 
175
175
  Add the Angular component to the Astro component template. This only renders the HTML from the Angular component.
176
176
 
177
- ```ts
177
+ ```tsx
178
178
  ---
179
179
  import { HelloComponent } from '../components/hello.component';
180
180
 
@@ -188,7 +188,7 @@ const helpText = "Helping binding";
188
188
 
189
189
  To hydrate the component on the client, use one of the Astro [client directives](https://docs.astro.build/en/reference/directives-reference/#client-directives):
190
190
 
191
- ```ts
191
+ ```tsx
192
192
  ---
193
193
  import { HelloComponent } from '../components/hello.component';
194
194
  ---
@@ -198,6 +198,37 @@ import { HelloComponent } from '../components/hello.component';
198
198
 
199
199
  Find more information about [Client Directives](https://docs.astro.build/en/reference/directives-reference/#client-directives) in the Astro documentation.
200
200
 
201
+ ### Listening to Component Outputs
202
+
203
+ Outputs can be emitted by the Angular component are forwarded as HTML events to the Astro island.
204
+ To enable this feature, add a client directive and a unique `[data-analog-id]` property to each Angular component:
205
+
206
+ ```tsx
207
+ ---
208
+ import { HelloComponent } from '../components/hello.component';
209
+ ---
210
+
211
+ <HelloComponent client:visible data-analog-id="hello-component-1" />
212
+ ```
213
+
214
+ Then, listen to the event in the Astro component using the `addOutputListener` function:
215
+
216
+ ```tsx
217
+ ---
218
+ import { HelloComponent } from '../components/hello.component';
219
+ ---
220
+
221
+ <HelloComponent client:visible data-analog-id="hello-component-1" />
222
+
223
+ <script>
224
+ import { addOutputListener } from '@analogjs/astro-angular/utils';
225
+
226
+ addOutputListener('hello-component-1', 'outputName', (event) => {
227
+ console.log(event.detail);
228
+ });
229
+ </script>
230
+ ```
231
+
201
232
  ## Adding Component Providers
202
233
 
203
234
  Additional providers can be added to a component for static rendering and client hydration.
@@ -295,4 +326,3 @@ import { HelloComponent } from "../../components/hello.component.ts";
295
326
  ## Current Limitations
296
327
 
297
328
  - Only standalone Angular components in version v14.2+ are supported
298
- - Component Outputs are not supported
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@analogjs/astro-angular",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Use Angular components within Astro",
5
5
  "type": "module",
6
6
  "author": "Brandon Roberts <robertsbt@gmail.com>",
7
7
  "exports": {
8
8
  ".": "./src/index.js",
9
+ "./utils": "./src/utils.js",
9
10
  "./client.js": "./src/client.js",
10
11
  "./server.js": "./src/server.js",
11
12
  "./package.json": "./package.json"
@@ -27,7 +28,7 @@
27
28
  "url": "https://github.com/analogjs/analog.git"
28
29
  },
29
30
  "dependencies": {
30
- "@analogjs/vite-plugin-angular": "^0.2.2"
31
+ "@analogjs/vite-plugin-angular": "^0.2.3"
31
32
  },
32
33
  "peerDependencies": {
33
34
  "@angular-devkit/build-angular": "^16.0.0",
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../packages/astro-angular/src/client.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,QAAQ,EAER,cAAc,IAAI,aAAa,EAChC,MAAM,eAAe,CAAC;kCAIE,WAAW,iBAErB,cAAc,OAAO,CAAC,GAAG;IAClC,eAAe,CAAC,EAAE,CAAC,QAAQ,GAAG,oBAAoB,CAAC,EAAE,CAAC;CACvD,UACO,OAAO,MAAM,EAAE,OAAO,CAAC,eAClB,OAAO;AANxB,wBAoCE"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../packages/astro-angular/src/client.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,QAAQ,EAER,cAAc,IAAI,aAAa,EAChC,MAAM,eAAe,CAAC;kCAKE,WAAW,iBAErB,cAAc,OAAO,CAAC,GAAG;IAClC,eAAe,CAAC,EAAE,CAAC,QAAQ,GAAG,oBAAoB,CAAC,EAAE,CAAC;CACvD,UACO,OAAO,MAAM,EAAE,OAAO,CAAC,eAClB,OAAO;AANxB,wBAoEE"}
package/src/client.js CHANGED
@@ -2,6 +2,7 @@ import 'zone.js/dist/zone.js';
2
2
  import { reflectComponentType, } from '@angular/core';
3
3
  import { NgZone, createComponent } from '@angular/core';
4
4
  import { createApplication } from '@angular/platform-browser';
5
+ import { Subject, takeUntil } from 'rxjs';
5
6
  export default (element) => {
6
7
  return (Component, props, _childHTML) => {
7
8
  createApplication({
@@ -21,6 +22,29 @@ export default (element) => {
21
22
  }
22
23
  }
23
24
  }
25
+ if ((mirror === null || mirror === void 0 ? void 0 : mirror.outputs.length) && (props === null || props === void 0 ? void 0 : props['data-analog-id'])) {
26
+ const destroySubject = new Subject();
27
+ element.setAttribute('data-analog-id', props['data-analog-id']);
28
+ mirror.outputs.forEach(({ templateName, propName }) => {
29
+ const outputName = templateName || propName;
30
+ const component = componentRef.instance;
31
+ component[outputName]
32
+ .pipe(takeUntil(destroySubject))
33
+ .subscribe((detail) => {
34
+ const event = new CustomEvent(outputName, {
35
+ bubbles: true,
36
+ cancelable: true,
37
+ composed: true,
38
+ detail,
39
+ });
40
+ element.dispatchEvent(event);
41
+ });
42
+ });
43
+ appRef.onDestroy(() => {
44
+ destroySubject.next();
45
+ destroySubject.complete();
46
+ });
47
+ }
24
48
  appRef.attachView(componentRef.hostView);
25
49
  });
26
50
  });
package/src/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../packages/astro-angular/src/client.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,EAGL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAkB,MAAM,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,eAAe,CAAC,OAAoB,EAAE,EAAE;IACtC,OAAO,CACL,SAEC,EACD,KAA+B,EAC/B,UAAoB,EACpB,EAAE;QACF,iBAAiB,CAAC;YAChB,SAAS,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;SAClD,CAAC,CAAC,IAAI,CAAC,CAAC,MAAsB,EAAE,EAAE;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE;gBACZ,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,EAAE;oBAC9C,mBAAmB,EAAE,MAAM,CAAC,QAAQ;oBACpC,WAAW,EAAE,OAAO;iBACrB,CAAC,CAAC;gBAEH,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;gBAC/C,IAAI,KAAK,IAAI,MAAM,EAAE;oBACnB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;wBAChD,IACE,MAAM,CAAC,MAAM,CAAC,IAAI,CAChB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE,CAC7B,YAAY,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,CAC3C,EACD;4BACA,YAAY,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;yBACnC;qBACF;iBACF;gBAED,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import 'zone.js/dist/zone.js';\nimport {\n EnvironmentProviders,\n Provider,\n reflectComponentType,\n ɵComponentType as ComponentType,\n} from '@angular/core';\nimport { ApplicationRef, NgZone, createComponent } from '@angular/core';\nimport { createApplication } from '@angular/platform-browser';\n\nexport default (element: HTMLElement) => {\n return (\n Component: ComponentType<unknown> & {\n clientProviders?: (Provider | EnvironmentProviders)[];\n },\n props?: Record<string, unknown>,\n _childHTML?: unknown\n ) => {\n createApplication({\n providers: [...(Component.clientProviders || [])],\n }).then((appRef: ApplicationRef) => {\n const zone = appRef.injector.get(NgZone);\n zone.run(() => {\n const componentRef = createComponent(Component, {\n environmentInjector: appRef.injector,\n hostElement: element,\n });\n\n const mirror = reflectComponentType(Component);\n if (props && mirror) {\n for (const [key, value] of Object.entries(props)) {\n if (\n mirror.inputs.some(\n ({ templateName, propName }) =>\n templateName === key || propName === key\n )\n ) {\n componentRef.setInput(key, value);\n }\n }\n }\n\n appRef.attachView(componentRef.hostView);\n });\n });\n };\n};\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../packages/astro-angular/src/client.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAC9B,OAAO,EAGL,oBAAoB,GAErB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAkB,MAAM,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAc,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEtD,eAAe,CAAC,OAAoB,EAAE,EAAE;IACtC,OAAO,CACL,SAEC,EACD,KAA+B,EAC/B,UAAoB,EACpB,EAAE;QACF,iBAAiB,CAAC;YAChB,SAAS,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;SAClD,CAAC,CAAC,IAAI,CAAC,CAAC,MAAsB,EAAE,EAAE;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE;gBACZ,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,EAAE;oBAC9C,mBAAmB,EAAE,MAAM,CAAC,QAAQ;oBACpC,WAAW,EAAE,OAAO;iBACrB,CAAC,CAAC;gBAEH,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;gBAC/C,IAAI,KAAK,IAAI,MAAM,EAAE;oBACnB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;wBAChD,IACE,MAAM,CAAC,MAAM,CAAC,IAAI,CAChB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE,CAC7B,YAAY,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,CAC3C,EACD;4BACA,YAAY,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;yBACnC;qBACF;iBACF;gBAED,IAAI,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,OAAO,CAAC,MAAM,MAAI,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAG,gBAAgB,CAAC,CAAA,EAAE;oBACvD,MAAM,cAAc,GAAG,IAAI,OAAO,EAAQ,CAAC;oBAC3C,OAAO,CAAC,YAAY,CAClB,gBAAgB,EAChB,KAAK,CAAC,gBAAgB,CAAW,CAClC,CAAC;oBAEF,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,EAAE;wBACpD,MAAM,UAAU,GAAG,YAAY,IAAI,QAAQ,CAAC;wBAC5C,MAAM,SAAS,GAAG,YAAY,CAAC,QAG9B,CAAC;wBACF,SAAS,CAAC,UAAU,CAAC;6BAClB,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;6BAC/B,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;4BACpB,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,UAAU,EAAE;gCACxC,OAAO,EAAE,IAAI;gCACb,UAAU,EAAE,IAAI;gCAChB,QAAQ,EAAE,IAAI;gCACd,MAAM;6BACP,CAAC,CAAC;4BACH,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;wBAC/B,CAAC,CAAC,CAAC;oBACP,CAAC,CAAC,CAAC;oBAEH,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE;wBACpB,cAAc,CAAC,IAAI,EAAE,CAAC;wBACtB,cAAc,CAAC,QAAQ,EAAE,CAAC;oBAC5B,CAAC,CAAC,CAAC;iBACJ;gBAED,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC3C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import 'zone.js/dist/zone.js';\nimport {\n EnvironmentProviders,\n Provider,\n reflectComponentType,\n ɵComponentType as ComponentType,\n} from '@angular/core';\nimport { ApplicationRef, NgZone, createComponent } from '@angular/core';\nimport { createApplication } from '@angular/platform-browser';\nimport { Observable, Subject, takeUntil } from 'rxjs';\n\nexport default (element: HTMLElement) => {\n return (\n Component: ComponentType<unknown> & {\n clientProviders?: (Provider | EnvironmentProviders)[];\n },\n props?: Record<string, unknown>,\n _childHTML?: unknown\n ) => {\n createApplication({\n providers: [...(Component.clientProviders || [])],\n }).then((appRef: ApplicationRef) => {\n const zone = appRef.injector.get(NgZone);\n zone.run(() => {\n const componentRef = createComponent(Component, {\n environmentInjector: appRef.injector,\n hostElement: element,\n });\n\n const mirror = reflectComponentType(Component);\n if (props && mirror) {\n for (const [key, value] of Object.entries(props)) {\n if (\n mirror.inputs.some(\n ({ templateName, propName }) =>\n templateName === key || propName === key\n )\n ) {\n componentRef.setInput(key, value);\n }\n }\n }\n\n if (mirror?.outputs.length && props?.['data-analog-id']) {\n const destroySubject = new Subject<void>();\n element.setAttribute(\n 'data-analog-id',\n props['data-analog-id'] as string\n );\n\n mirror.outputs.forEach(({ templateName, propName }) => {\n const outputName = templateName || propName;\n const component = componentRef.instance as Record<\n string,\n Observable<unknown>\n >;\n component[outputName]\n .pipe(takeUntil(destroySubject))\n .subscribe((detail) => {\n const event = new CustomEvent(outputName, {\n bubbles: true,\n cancelable: true,\n composed: true,\n detail,\n });\n element.dispatchEvent(event);\n });\n });\n\n appRef.onDestroy(() => {\n destroySubject.next();\n destroySubject.complete();\n });\n }\n\n appRef.attachView(componentRef.hostView);\n });\n });\n };\n};\n"]}
package/src/utils.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function addOutputListener(analogId: string, outputName: string, callback: (...args: any[]) => unknown, eventListenerOptions?: EventListenerOptions): () => void;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../packages/astro-angular/src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,EACrC,oBAAoB,GAAE,oBAAyB,cAgBhD"}
package/src/utils.js ADDED
@@ -0,0 +1,13 @@
1
+ export function addOutputListener(analogId, outputName, callback, eventListenerOptions = {}) {
2
+ const observer = new MutationObserver((mutations) => {
3
+ var _a;
4
+ const foundTarget = (_a = mutations.find((mutation) => { var _a; return ((_a = mutation.target.dataset) === null || _a === void 0 ? void 0 : _a['analogId']) === analogId; })) === null || _a === void 0 ? void 0 : _a.target;
5
+ if (foundTarget) {
6
+ foundTarget.addEventListener(outputName, callback, eventListenerOptions);
7
+ observer.disconnect();
8
+ }
9
+ });
10
+ observer.observe(document.body, { attributes: true, subtree: true });
11
+ return () => observer.disconnect();
12
+ }
13
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../packages/astro-angular/src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,UAAkB,EAClB,QAAqC,EACrC,uBAA6C,EAAE;IAE/C,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,CAAC,SAAS,EAAE,EAAE;;QAClD,MAAM,WAAW,GAAG,MAAA,SAAS,CAAC,IAAI,CAChC,CAAC,QAAQ,EAAE,EAAE,WACX,OAAA,CAAA,MAAC,QAAQ,CAAC,MAAsB,CAAC,OAAO,0CAAG,UAAU,CAAC,MAAK,QAAQ,CAAA,EAAA,CACtE,0CAAE,MAAM,CAAC;QAEV,IAAI,WAAW,EAAE;YACf,WAAW,CAAC,gBAAgB,CAAC,UAAU,EAAE,QAAQ,EAAE,oBAAoB,CAAC,CAAC;YACzE,QAAQ,CAAC,UAAU,EAAE,CAAC;SACvB;IACH,CAAC,CAAC,CAAC;IACH,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAErE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;AACrC,CAAC","sourcesContent":["export function addOutputListener(\n analogId: string,\n outputName: string,\n callback: (...args: any[]) => unknown,\n eventListenerOptions: EventListenerOptions = {}\n) {\n const observer = new MutationObserver((mutations) => {\n const foundTarget = mutations.find(\n (mutation) =>\n (mutation.target as HTMLElement).dataset?.['analogId'] === analogId\n )?.target;\n\n if (foundTarget) {\n foundTarget.addEventListener(outputName, callback, eventListenerOptions);\n observer.disconnect();\n }\n });\n observer.observe(document.body, { attributes: true, subtree: true });\n\n return () => observer.disconnect();\n}\n"]}