@bbq-chat/widgets-angular 1.0.0 → 1.0.2

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/dist/package.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "name": "@bbq-chat/widgets-angular",
3
- "version": "1.0.0",
4
- "description": "Angular components and services for BbQ ChatWidgets",
5
- "license": "MIT",
6
- "main": "./index.js",
7
- "module": "./index.js",
8
- "types": "./index.d.ts",
9
- "exports": {
10
- ".": {
11
- "import": "./index.js",
12
- "require": "./index.cjs",
13
- "types": "./index.d.ts"
14
- }
15
- }
16
- }
@@ -1,95 +0,0 @@
1
- import { ChatWidget } from '@bbq-chat/widgets';
2
- import { CustomWidgetRenderer } from './custom-widget-renderer.types';
3
- /**
4
- * Service for registering custom widget factories and renderers
5
- *
6
- * This service provides a centralized way to register custom widget types
7
- * that extend the base widget functionality, including support for
8
- * Angular components and templates as custom renderers.
9
- *
10
- * @example
11
- * ```typescript
12
- * constructor(private widgetRegistry: WidgetRegistryService) {
13
- * // Register a widget factory
14
- * this.widgetRegistry.registerFactory('myWidget', (obj) => {
15
- * if (obj.type === 'myWidget') {
16
- * return new MyCustomWidget(obj.label, obj.action);
17
- * }
18
- * return null;
19
- * });
20
- *
21
- * // Register a component-based renderer
22
- * this.widgetRegistry.registerRenderer('myWidget', MyWidgetComponent);
23
- * }
24
- * ```
25
- */
26
- export declare class WidgetRegistryService {
27
- private readonly customRenderers;
28
- /**
29
- * Register a custom widget factory function
30
- *
31
- * @param type - The widget type identifier
32
- * @param factory - Factory function that creates widget instances from plain objects
33
- */
34
- registerFactory(type: string, factory: (obj: unknown) => ChatWidget | null): void;
35
- /**
36
- * Register a widget class with automatic factory creation
37
- *
38
- * @param type - The widget type identifier
39
- * @param ctor - Widget class constructor
40
- */
41
- registerClass(type: string, ctor: any): void;
42
- /**
43
- * Get a factory for a specific widget type
44
- *
45
- * @param type - The widget type identifier
46
- * @returns The factory function if registered, undefined otherwise
47
- */
48
- getFactory(type: string): ((obj: any) => ChatWidget | null) | undefined;
49
- /**
50
- * Register a custom renderer for a specific widget type
51
- *
52
- * The renderer can be:
53
- * - A function that returns HTML string
54
- * - An Angular Component class
55
- * - An Angular TemplateRef
56
- *
57
- * @param type - The widget type identifier
58
- * @param renderer - The custom renderer (function, Component, or TemplateRef)
59
- *
60
- * @example
61
- * ```typescript
62
- * // HTML function renderer
63
- * widgetRegistry.registerRenderer('weather', (widget) => `<div>${widget.label}</div>`);
64
- *
65
- * // Component renderer
66
- * widgetRegistry.registerRenderer('weather', WeatherWidgetComponent);
67
- *
68
- * // Template renderer (from @ViewChild or elsewhere)
69
- * widgetRegistry.registerRenderer('weather', this.weatherTemplate);
70
- * ```
71
- */
72
- registerRenderer(type: string, renderer: CustomWidgetRenderer): void;
73
- /**
74
- * Get a custom renderer for a specific widget type
75
- *
76
- * @param type - The widget type identifier
77
- * @returns The custom renderer if registered, undefined otherwise
78
- */
79
- getRenderer(type: string): CustomWidgetRenderer | undefined;
80
- /**
81
- * Check if a custom renderer is registered for a widget type
82
- *
83
- * @param type - The widget type identifier
84
- * @returns True if a custom renderer is registered, false otherwise
85
- */
86
- hasRenderer(type: string): boolean;
87
- /**
88
- * Unregister a custom renderer for a widget type
89
- *
90
- * @param type - The widget type identifier
91
- * @returns True if a renderer was removed, false if none was registered
92
- */
93
- unregisterRenderer(type: string): boolean;
94
- }
95
- //# sourceMappingURL=widget-registry.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"widget-registry.service.d.ts","sourceRoot":"","sources":["../src/widget-registry.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAGa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA2C;IAC3E;;;;;OAKG;IACH,eAAe,CACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,IAAI,GAC3C,IAAI;IAIP;;;;;OAKG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAI5C;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,UAAU,GAAG,IAAI,CAAC,GAAG,SAAS;IAIvE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAUpE;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAI3D;;;;;OAKG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIlC;;;;;OAKG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAG1C"}
@@ -1,129 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import { Injectable } from '@angular/core';
8
- import { customWidgetRegistry } from '@bbq-chat/widgets';
9
- /**
10
- * Service for registering custom widget factories and renderers
11
- *
12
- * This service provides a centralized way to register custom widget types
13
- * that extend the base widget functionality, including support for
14
- * Angular components and templates as custom renderers.
15
- *
16
- * @example
17
- * ```typescript
18
- * constructor(private widgetRegistry: WidgetRegistryService) {
19
- * // Register a widget factory
20
- * this.widgetRegistry.registerFactory('myWidget', (obj) => {
21
- * if (obj.type === 'myWidget') {
22
- * return new MyCustomWidget(obj.label, obj.action);
23
- * }
24
- * return null;
25
- * });
26
- *
27
- * // Register a component-based renderer
28
- * this.widgetRegistry.registerRenderer('myWidget', MyWidgetComponent);
29
- * }
30
- * ```
31
- */
32
- let WidgetRegistryService = class WidgetRegistryService {
33
- constructor() {
34
- this.customRenderers = new Map();
35
- }
36
- /**
37
- * Register a custom widget factory function
38
- *
39
- * @param type - The widget type identifier
40
- * @param factory - Factory function that creates widget instances from plain objects
41
- */
42
- registerFactory(type, factory) {
43
- customWidgetRegistry.registerFactory(type, factory);
44
- }
45
- /**
46
- * Register a widget class with automatic factory creation
47
- *
48
- * @param type - The widget type identifier
49
- * @param ctor - Widget class constructor
50
- */
51
- registerClass(type, ctor) {
52
- customWidgetRegistry.registerClass(type, ctor);
53
- }
54
- /**
55
- * Get a factory for a specific widget type
56
- *
57
- * @param type - The widget type identifier
58
- * @returns The factory function if registered, undefined otherwise
59
- */
60
- getFactory(type) {
61
- return customWidgetRegistry.getFactory(type);
62
- }
63
- /**
64
- * Register a custom renderer for a specific widget type
65
- *
66
- * The renderer can be:
67
- * - A function that returns HTML string
68
- * - An Angular Component class
69
- * - An Angular TemplateRef
70
- *
71
- * @param type - The widget type identifier
72
- * @param renderer - The custom renderer (function, Component, or TemplateRef)
73
- *
74
- * @example
75
- * ```typescript
76
- * // HTML function renderer
77
- * widgetRegistry.registerRenderer('weather', (widget) => `<div>${widget.label}</div>`);
78
- *
79
- * // Component renderer
80
- * widgetRegistry.registerRenderer('weather', WeatherWidgetComponent);
81
- *
82
- * // Template renderer (from @ViewChild or elsewhere)
83
- * widgetRegistry.registerRenderer('weather', this.weatherTemplate);
84
- * ```
85
- */
86
- registerRenderer(type, renderer) {
87
- if (!type || typeof type !== 'string') {
88
- throw new Error('type must be a non-empty string');
89
- }
90
- if (!renderer) {
91
- throw new Error('renderer is required');
92
- }
93
- this.customRenderers.set(type, renderer);
94
- }
95
- /**
96
- * Get a custom renderer for a specific widget type
97
- *
98
- * @param type - The widget type identifier
99
- * @returns The custom renderer if registered, undefined otherwise
100
- */
101
- getRenderer(type) {
102
- return this.customRenderers.get(type);
103
- }
104
- /**
105
- * Check if a custom renderer is registered for a widget type
106
- *
107
- * @param type - The widget type identifier
108
- * @returns True if a custom renderer is registered, false otherwise
109
- */
110
- hasRenderer(type) {
111
- return this.customRenderers.has(type);
112
- }
113
- /**
114
- * Unregister a custom renderer for a widget type
115
- *
116
- * @param type - The widget type identifier
117
- * @returns True if a renderer was removed, false if none was registered
118
- */
119
- unregisterRenderer(type) {
120
- return this.customRenderers.delete(type);
121
- }
122
- };
123
- WidgetRegistryService = __decorate([
124
- Injectable({
125
- providedIn: 'root',
126
- })
127
- ], WidgetRegistryService);
128
- export { WidgetRegistryService };
129
- //# sourceMappingURL=widget-registry.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"widget-registry.service.js","sourceRoot":"","sources":["../src/widget-registry.service.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAc,MAAM,mBAAmB,CAAC;AAGrE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAII,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAA3B;QACY,oBAAe,GAAG,IAAI,GAAG,EAAgC,CAAC;IAgG7E,CAAC;IA/FC;;;;;OAKG;IACH,eAAe,CACb,IAAY,EACZ,OAA4C;QAE5C,oBAAoB,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,IAAY,EAAE,IAAS;QACnC,oBAAoB,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,IAAY;QACrB,OAAO,oBAAoB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,gBAAgB,CAAC,IAAY,EAAE,QAA8B;QAC3D,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,IAAY;QACtB,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,IAAY;QACtB,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;CACF,CAAA;AAjGY,qBAAqB;IAHjC,UAAU,CAAC;QACV,UAAU,EAAE,MAAM;KACnB,CAAC;GACW,qBAAqB,CAiGjC"}
@@ -1,93 +0,0 @@
1
- import { EventEmitter, ElementRef, AfterViewInit, OnInit, OnDestroy, OnChanges, SimpleChanges, ComponentRef, EmbeddedViewRef, TemplateRef, Injector, EnvironmentInjector } from '@angular/core';
2
- import { SsrWidgetRenderer, WidgetEventManager, ChatWidget } from '@bbq-chat/widgets';
3
- import { WidgetRegistryService } from './widget-registry.service';
4
- import { WidgetTemplateContext } from './custom-widget-renderer.types';
5
- /**
6
- * Angular component for rendering chat widgets
7
- *
8
- * This component handles rendering of chat widgets using the BbQ ChatWidgets library.
9
- * It manages widget lifecycle, event handling, and cleanup.
10
- *
11
- * Supports three types of custom widget renderers:
12
- * 1. HTML function renderers (return HTML strings)
13
- * 2. Angular Component renderers (render as dynamic components)
14
- * 3. Angular TemplateRef renderers (render as embedded views)
15
- *
16
- * @example
17
- * ```typescript
18
- * <bbq-widget-renderer
19
- * [widgets]="messageWidgets"
20
- * (widgetAction)="handleWidgetAction($event)">
21
- * </bbq-widget-renderer>
22
- * ```
23
- */
24
- export declare class WidgetRendererComponent implements OnInit, AfterViewInit, OnDestroy, OnChanges {
25
- /**
26
- * Array of widgets to render
27
- */
28
- widgets: ChatWidget[] | null | undefined;
29
- /**
30
- * Emits when a widget action is triggered
31
- */
32
- widgetAction: EventEmitter<{
33
- actionName: string;
34
- payload: unknown;
35
- }>;
36
- containerRef: ElementRef<HTMLDivElement>;
37
- protected widgetItems: Array<{
38
- index: number;
39
- widget: ChatWidget;
40
- isHtml: boolean;
41
- html?: string;
42
- }>;
43
- protected renderer: SsrWidgetRenderer;
44
- protected eventManager?: WidgetEventManager;
45
- protected isViewInitialized: boolean;
46
- protected widgetRegistry: WidgetRegistryService;
47
- protected injector: Injector;
48
- protected environmentInjector: EnvironmentInjector;
49
- protected dynamicComponents: Array<ComponentRef<any>>;
50
- protected dynamicViews: Array<EmbeddedViewRef<WidgetTemplateContext>>;
51
- ngOnInit(): void;
52
- ngOnChanges(changes: SimpleChanges): void;
53
- ngAfterViewInit(): void;
54
- ngOnDestroy(): void;
55
- /**
56
- * Base implementation for updating the rendered HTML for the current widgets.
57
- *
58
- * Subclasses may override this method to customize how widgets are rendered
59
- * (for example, to inject additional markup or perform preprocessing).
60
- *
61
- * Since this is the base implementation, overriding implementations are not
62
- * required to call `super.updateWidgetHtml()`.
63
- */
64
- protected updateWidgetHtml(): void;
65
- /**
66
- * Render dynamic components and templates for custom widgets
67
- */
68
- protected renderDynamicWidgets(): void;
69
- /**
70
- * Render an Angular component for a custom widget
71
- *
72
- * Note: This method safely assigns properties to component instances
73
- * by checking for property existence at runtime. This approach is necessary
74
- * because we cannot statically verify that all components implement
75
- * the CustomWidgetComponent interface.
76
- */
77
- protected renderComponent(componentType: any, widget: ChatWidget, targetElement: HTMLElement): void;
78
- /**
79
- * Render an Angular template for a custom widget
80
- */
81
- protected renderTemplate(templateRef: TemplateRef<WidgetTemplateContext>, widget: ChatWidget, targetElement: HTMLElement): void;
82
- /**
83
- * Cleanup dynamic components and views
84
- */
85
- protected cleanupDynamicWidgets(): void;
86
- private setupEventHandlers;
87
- handleClick(event: MouseEvent): void;
88
- /**
89
- * Cleanup all resources including event listeners.
90
- */
91
- private cleanup;
92
- }
93
- //# sourceMappingURL=widget-renderer.component.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"widget-renderer.component.d.ts","sourceRoot":"","sources":["../src/widget-renderer.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,YAAY,EACZ,UAAU,EACV,aAAa,EACb,MAAM,EACN,SAAS,EACT,SAAS,EACT,aAAa,EAEb,YAAY,EACZ,eAAe,EACf,WAAW,EAEX,QAAQ,EAER,mBAAmB,EACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EACL,qBAAqB,EAItB,MAAM,gCAAgC,CAAC;AAExC;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBA2Ba,uBACX,YAAW,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS;IAEtD;;OAEG;IACM,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IAElD;;OAEG;IACO,YAAY;oBACR,MAAM;iBACT,OAAO;OACb;IAGL,YAAY,EAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAE1C,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC;QAC3B,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,UAAU,CAAC;QACnB,MAAM,EAAE,OAAO,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC,CAAM;IAER,SAAS,CAAC,QAAQ,oBAA2B;IAC7C,SAAS,CAAC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAC5C,SAAS,CAAC,iBAAiB,UAAS;IACpC,SAAS,CAAC,cAAc,wBAAiC;IACzD,SAAS,CAAC,QAAQ,WAAoB;IACtC,SAAS,CAAC,mBAAmB,sBAA+B;IAC5D,SAAS,CAAC,iBAAiB,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAM;IAC3D,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAAM;IAE3E,QAAQ;IAIR,WAAW,CAAC,OAAO,EAAE,aAAa;IAMlC,eAAe;IAOf,WAAW;IAIX;;;;;;;;OAQG;IACH,SAAS,CAAC,gBAAgB;IAuD1B;;OAEG;IACH,SAAS,CAAC,oBAAoB;IAyC9B;;;;;;;OAOG;IACH,SAAS,CAAC,eAAe,CACvB,aAAa,EAAE,GAAG,EAClB,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,WAAW;IAkC5B;;OAEG;IACH,SAAS,CAAC,cAAc,CACtB,WAAW,EAAE,WAAW,CAAC,qBAAqB,CAAC,EAC/C,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,WAAW;IAwB5B;;OAEG;IACH,SAAS,CAAC,qBAAqB;IAY/B,OAAO,CAAC,kBAAkB;IAoB1B,WAAW,CAAC,KAAK,EAAE,UAAU;IAmB7B;;OAEG;IACH,OAAO,CAAC,OAAO;CAOhB"}
@@ -1,316 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- import { Component, Input, Output, EventEmitter, ElementRef, ViewChild, inject, Injector, createComponent, EnvironmentInjector, } from '@angular/core';
11
- import { CommonModule } from '@angular/common';
12
- import { SsrWidgetRenderer, WidgetEventManager, } from '@bbq-chat/widgets';
13
- import { WidgetRegistryService } from './widget-registry.service';
14
- import { isHtmlRenderer, isComponentRenderer, isTemplateRenderer, } from './custom-widget-renderer.types';
15
- /**
16
- * Angular component for rendering chat widgets
17
- *
18
- * This component handles rendering of chat widgets using the BbQ ChatWidgets library.
19
- * It manages widget lifecycle, event handling, and cleanup.
20
- *
21
- * Supports three types of custom widget renderers:
22
- * 1. HTML function renderers (return HTML strings)
23
- * 2. Angular Component renderers (render as dynamic components)
24
- * 3. Angular TemplateRef renderers (render as embedded views)
25
- *
26
- * @example
27
- * ```typescript
28
- * <bbq-widget-renderer
29
- * [widgets]="messageWidgets"
30
- * (widgetAction)="handleWidgetAction($event)">
31
- * </bbq-widget-renderer>
32
- * ```
33
- */
34
- let WidgetRendererComponent = class WidgetRendererComponent {
35
- constructor() {
36
- /**
37
- * Emits when a widget action is triggered
38
- */
39
- this.widgetAction = new EventEmitter();
40
- this.widgetItems = [];
41
- this.renderer = new SsrWidgetRenderer();
42
- this.isViewInitialized = false;
43
- this.widgetRegistry = inject(WidgetRegistryService);
44
- this.injector = inject(Injector);
45
- this.environmentInjector = inject(EnvironmentInjector);
46
- this.dynamicComponents = [];
47
- this.dynamicViews = [];
48
- }
49
- ngOnInit() {
50
- this.updateWidgetHtml();
51
- }
52
- ngOnChanges(changes) {
53
- if (changes['widgets']) {
54
- this.updateWidgetHtml();
55
- }
56
- }
57
- ngAfterViewInit() {
58
- this.isViewInitialized = true;
59
- this.setupEventHandlers();
60
- // Render dynamic components/templates after view init
61
- this.renderDynamicWidgets();
62
- }
63
- ngOnDestroy() {
64
- this.cleanup();
65
- }
66
- /**
67
- * Base implementation for updating the rendered HTML for the current widgets.
68
- *
69
- * Subclasses may override this method to customize how widgets are rendered
70
- * (for example, to inject additional markup or perform preprocessing).
71
- *
72
- * Since this is the base implementation, overriding implementations are not
73
- * required to call `super.updateWidgetHtml()`.
74
- */
75
- updateWidgetHtml() {
76
- if (!this.widgets || this.widgets.length === 0) {
77
- this.widgetItems = [];
78
- return;
79
- }
80
- this.widgetItems = this.widgets.map((widget, index) => {
81
- const customRenderer = this.widgetRegistry.getRenderer(widget.type);
82
- // Check template renderer first (most specific)
83
- if (customRenderer && isTemplateRenderer(customRenderer)) {
84
- return {
85
- index,
86
- widget,
87
- isHtml: false,
88
- };
89
- }
90
- // Check component renderer second
91
- if (customRenderer && isComponentRenderer(customRenderer)) {
92
- return {
93
- index,
94
- widget,
95
- isHtml: false,
96
- };
97
- }
98
- // Check HTML function renderer last (most general, matches any function)
99
- if (customRenderer && isHtmlRenderer(customRenderer)) {
100
- return {
101
- index,
102
- widget,
103
- isHtml: true,
104
- html: customRenderer(widget),
105
- };
106
- }
107
- // Default: render using the BbQ library renderer
108
- return {
109
- index,
110
- widget,
111
- isHtml: true,
112
- html: this.renderer.renderWidget(widget),
113
- };
114
- });
115
- // After view updates, reinitialize widgets only if view is already initialized
116
- if (this.isViewInitialized) {
117
- setTimeout(() => {
118
- this.setupEventHandlers();
119
- this.renderDynamicWidgets();
120
- }, 0);
121
- }
122
- }
123
- /**
124
- * Render dynamic components and templates for custom widgets
125
- */
126
- renderDynamicWidgets() {
127
- if (!this.containerRef?.nativeElement)
128
- return;
129
- // Use microtask to ensure Angular has completed change detection
130
- Promise.resolve().then(() => {
131
- if (!this.containerRef?.nativeElement)
132
- return;
133
- // Clean up existing dynamic components and views
134
- this.cleanupDynamicWidgets();
135
- const container = this.containerRef.nativeElement;
136
- // Query all widget divs without the data-rendered filter
137
- const dynamicWidgetDivs = Array.from(container.querySelectorAll('.bbq-widget'));
138
- let dynamicIndex = 0;
139
- this.widgetItems.forEach((item) => {
140
- if (!item.isHtml) {
141
- const customRenderer = this.widgetRegistry.getRenderer(item.widget.type);
142
- if (!customRenderer)
143
- return;
144
- const targetDiv = dynamicWidgetDivs[dynamicIndex];
145
- if (!targetDiv)
146
- return;
147
- // Clear the div content before rendering
148
- targetDiv.innerHTML = '';
149
- if (isComponentRenderer(customRenderer)) {
150
- this.renderComponent(customRenderer, item.widget, targetDiv);
151
- }
152
- else if (isTemplateRenderer(customRenderer)) {
153
- this.renderTemplate(customRenderer, item.widget, targetDiv);
154
- }
155
- dynamicIndex++;
156
- }
157
- });
158
- });
159
- }
160
- /**
161
- * Render an Angular component for a custom widget
162
- *
163
- * Note: This method safely assigns properties to component instances
164
- * by checking for property existence at runtime. This approach is necessary
165
- * because we cannot statically verify that all components implement
166
- * the CustomWidgetComponent interface.
167
- */
168
- renderComponent(componentType, widget, targetElement) {
169
- // Create the component using Angular's createComponent API
170
- const componentRef = createComponent(componentType, {
171
- environmentInjector: this.environmentInjector,
172
- elementInjector: this.injector,
173
- });
174
- // Safely set component inputs if they exist
175
- const instance = componentRef.instance;
176
- if (instance && typeof instance === 'object') {
177
- // Set widget property if it exists in the prototype chain
178
- if ('widget' in instance) {
179
- instance.widget = widget;
180
- }
181
- // Set widgetAction callback if it exists in the prototype chain
182
- if ('widgetAction' in instance) {
183
- instance.widgetAction = (actionName, payload) => {
184
- this.widgetAction.emit({ actionName, payload });
185
- };
186
- }
187
- }
188
- // Attach the component's host view to the target element
189
- targetElement.appendChild(componentRef.location.nativeElement);
190
- // Store reference for cleanup
191
- this.dynamicComponents.push(componentRef);
192
- // Trigger change detection (use optional chaining for safety)
193
- componentRef.changeDetectorRef?.detectChanges();
194
- }
195
- /**
196
- * Render an Angular template for a custom widget
197
- */
198
- renderTemplate(templateRef, widget, targetElement) {
199
- const context = {
200
- $implicit: widget,
201
- widget: widget,
202
- emitAction: (actionName, payload) => {
203
- this.widgetAction.emit({ actionName, payload });
204
- },
205
- };
206
- const viewRef = templateRef.createEmbeddedView(context);
207
- // Attach the view's DOM nodes to the target element
208
- viewRef.rootNodes.forEach((node) => {
209
- targetElement.appendChild(node);
210
- });
211
- // Store reference for cleanup
212
- this.dynamicViews.push(viewRef);
213
- // Trigger change detection
214
- viewRef.detectChanges();
215
- }
216
- /**
217
- * Cleanup dynamic components and views
218
- */
219
- cleanupDynamicWidgets() {
220
- this.dynamicComponents.forEach((componentRef) => {
221
- componentRef.destroy();
222
- });
223
- this.dynamicComponents = [];
224
- this.dynamicViews.forEach((viewRef) => {
225
- viewRef.destroy();
226
- });
227
- this.dynamicViews = [];
228
- }
229
- setupEventHandlers() {
230
- if (!this.containerRef?.nativeElement)
231
- return;
232
- // Cleanup old resources before setting up new ones
233
- this.cleanup();
234
- const container = this.containerRef.nativeElement;
235
- // Create a custom action handler that emits events
236
- const actionHandler = {
237
- handle: async (action, payload) => {
238
- this.widgetAction.emit({ actionName: action, payload });
239
- },
240
- };
241
- // Attach event handlers using WidgetEventManager
242
- this.eventManager = new WidgetEventManager(actionHandler);
243
- this.eventManager.attachHandlers(container);
244
- }
245
- handleClick(event) {
246
- const target = event.target;
247
- // Only trigger actions on non-form buttons and clickable elements (cards)
248
- // Don't trigger on input elements or form buttons (let WidgetEventManager handle those)
249
- const button = target.tagName === 'BUTTON' ? target : target.closest('button');
250
- if (button && !button.closest('[data-widget-type="form"]')) {
251
- const actionName = button.getAttribute('data-action');
252
- if (actionName) {
253
- try {
254
- const payloadStr = button.getAttribute('data-payload');
255
- const payload = payloadStr ? JSON.parse(payloadStr) : {};
256
- this.widgetAction.emit({ actionName, payload });
257
- }
258
- catch (err) {
259
- console.error('Failed to parse widget action payload:', err);
260
- }
261
- }
262
- }
263
- }
264
- /**
265
- * Cleanup all resources including event listeners.
266
- */
267
- cleanup() {
268
- // Cleanup dynamic widgets first
269
- this.cleanupDynamicWidgets();
270
- // Cleanup event manager
271
- this.eventManager = undefined;
272
- }
273
- };
274
- __decorate([
275
- Input(),
276
- __metadata("design:type", Object)
277
- ], WidgetRendererComponent.prototype, "widgets", void 0);
278
- __decorate([
279
- Output(),
280
- __metadata("design:type", Object)
281
- ], WidgetRendererComponent.prototype, "widgetAction", void 0);
282
- __decorate([
283
- ViewChild('widgetContainer', { static: false }),
284
- __metadata("design:type", ElementRef)
285
- ], WidgetRendererComponent.prototype, "containerRef", void 0);
286
- WidgetRendererComponent = __decorate([
287
- Component({
288
- selector: 'bbq-widget-renderer',
289
- standalone: true,
290
- imports: [CommonModule],
291
- template: `
292
- <div #widgetContainer class="bbq-widgets-container" (click)="handleClick($event)">
293
- @for (item of widgetItems; track item.index) {
294
- @if (item.isHtml) {
295
- <div class="bbq-widget" [innerHTML]="item.html"></div>
296
- } @else {
297
- <div class="bbq-widget" #dynamicWidget></div>
298
- }
299
- }
300
- </div>
301
- `,
302
- styles: [
303
- `
304
- .bbq-widgets-container {
305
- margin-top: 0.5rem;
306
- }
307
-
308
- .bbq-widget {
309
- margin-bottom: 0.5rem;
310
- }
311
- `,
312
- ],
313
- })
314
- ], WidgetRendererComponent);
315
- export { WidgetRendererComponent };
316
- //# sourceMappingURL=widget-renderer.component.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"widget-renderer.component.js","sourceRoot":"","sources":["../src/widget-renderer.component.ts"],"names":[],"mappings":"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"}