@bbq-chat/widgets-angular 1.0.9 → 1.0.10

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.
Files changed (42) hide show
  1. package/fesm2022/index.mjs +2132 -0
  2. package/fesm2022/index.mjs.map +1 -0
  3. package/package.json +15 -20
  4. package/types/index.d.ts +659 -0
  5. package/.angular/cache/21.0.5/ng-packagr/97cbacd0e5e4cb18d1fead4d7f3aee1c3863ba3ffbe7cb7dd7780f237a848a5c +0 -1
  6. package/.angular/cache/21.0.5/ng-packagr/tsbuildinfo/index.tsbuildinfo +0 -1
  7. package/.eslintrc.json +0 -23
  8. package/.prettierrc.json +0 -8
  9. package/EXAMPLES.md +0 -484
  10. package/angular.json +0 -36
  11. package/ng-package.json +0 -9
  12. package/src/angular-widget-renderer.spec.ts +0 -157
  13. package/src/components/button.component.ts +0 -35
  14. package/src/components/card.component.ts +0 -52
  15. package/src/components/datepicker.component.ts +0 -63
  16. package/src/components/dropdown.component.ts +0 -65
  17. package/src/components/fileupload.component.ts +0 -71
  18. package/src/components/form.component.ts +0 -433
  19. package/src/components/image.component.ts +0 -33
  20. package/src/components/imagecollection.component.ts +0 -39
  21. package/src/components/index.ts +0 -20
  22. package/src/components/input.component.ts +0 -63
  23. package/src/components/multiselect.component.ts +0 -67
  24. package/src/components/progressbar.component.ts +0 -50
  25. package/src/components/slider.component.ts +0 -67
  26. package/src/components/textarea.component.ts +0 -63
  27. package/src/components/themeswitcher.component.ts +0 -46
  28. package/src/components/toggle.component.ts +0 -63
  29. package/src/custom-widget-renderer.types.ts +0 -120
  30. package/src/examples/form-validation-listener.component.ts +0 -41
  31. package/src/public_api.ts +0 -107
  32. package/src/renderers/AngularWidgetRenderer.ts +0 -100
  33. package/src/renderers/built-in-components.ts +0 -41
  34. package/src/renderers/index.ts +0 -7
  35. package/src/services/form-validation.service.ts +0 -21
  36. package/src/widget-di.tokens.ts +0 -95
  37. package/src/widget-registry.service.ts +0 -128
  38. package/src/widget-renderer.component.ts +0 -421
  39. package/tsconfig.json +0 -37
  40. package/tsconfig.lib.json +0 -18
  41. package/tsconfig.lib.prod.json +0 -11
  42. package/tsconfig.spec.json +0 -13
@@ -1,50 +0,0 @@
1
- import { Component, Input, OnInit } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import type { ProgressBarWidget } from '@bbq-chat/widgets';
4
- import { CustomWidgetComponent } from '../custom-widget-renderer.types';
5
-
6
- @Component({
7
- selector: 'bbq-progressbar-widget',
8
- standalone: true,
9
- imports: [CommonModule],
10
- template: `
11
- <div
12
- class="bbq-widget bbq-progress-bar"
13
- [attr.data-widget-type]="'progressbar'">
14
- <label class="bbq-progress-bar-label" [attr.for]="progressId">
15
- {{ progressBarWidget.label }}
16
- </label>
17
- <progress
18
- [id]="progressId"
19
- class="bbq-progress-bar-element"
20
- [value]="progressBarWidget.value"
21
- [max]="progressBarWidget.max"
22
- [attr.data-action]="progressBarWidget.action"
23
- [attr.aria-label]="progressBarWidget.label"
24
- [attr.aria-valuenow]="progressBarWidget.value"
25
- [attr.aria-valuemin]="0"
26
- [attr.aria-valuemax]="progressBarWidget.max">
27
- {{ percentage }}%
28
- </progress>
29
- <span class="bbq-progress-bar-value" aria-live="polite">{{ percentage }}%</span>
30
- </div>
31
- `,
32
- styles: []
33
- })
34
- export class ProgressBarWidgetComponent implements CustomWidgetComponent, OnInit {
35
- @Input() widget!: any;
36
- widgetAction?: (actionName: string, payload: unknown) => void;
37
-
38
- progressId = '';
39
- percentage = 0;
40
-
41
- get progressBarWidget(): ProgressBarWidget {
42
- return this.widget as ProgressBarWidget;
43
- }
44
-
45
- ngOnInit() {
46
- this.progressId = `bbq-${this.progressBarWidget.action.replace(/\s+/g, '-').toLowerCase()}-progress`;
47
- const max = this.progressBarWidget.max;
48
- this.percentage = max > 0 ? Math.floor((this.progressBarWidget.value * 100) / max) : 0;
49
- }
50
- }
@@ -1,67 +0,0 @@
1
- import { Component, Input, OnInit } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { FormsModule } from '@angular/forms';
4
- import type { SliderWidget } from '@bbq-chat/widgets';
5
- import { CustomWidgetComponent } from '../custom-widget-renderer.types';
6
-
7
- @Component({
8
- selector: 'bbq-slider-widget',
9
- standalone: true,
10
- imports: [CommonModule, FormsModule],
11
- template: `
12
- <div
13
- class="bbq-widget bbq-slider"
14
- [attr.data-widget-type]="'slider'">
15
- <label *ngIf="showLabel" class="bbq-slider-label" [attr.for]="sliderId">
16
- {{ sliderWidget.label }}
17
- </label>
18
- <input
19
- type="range"
20
- [id]="sliderId"
21
- [ngClass]="sliderClasses"
22
- [min]="sliderWidget.min"
23
- [max]="sliderWidget.max"
24
- [step]="sliderWidget.step"
25
- [attr.data-action]="sliderWidget.action"
26
- [attr.aria-label]="sliderWidget.label"
27
- [(ngModel)]="value" />
28
- <span class="bbq-slider-value" aria-live="polite">{{ value }}</span>
29
- </div>
30
- `,
31
- styles: []
32
- })
33
- export class SliderWidgetComponent implements CustomWidgetComponent, OnInit {
34
- @Input() widget!: any;
35
- widgetAction?: (actionName: string, payload: unknown) => void;
36
-
37
- value: number = 0;
38
- sliderId = '';
39
-
40
- get sliderWidget(): SliderWidget {
41
- return this.widget as SliderWidget;
42
- }
43
-
44
- get showLabel(): boolean {
45
- const widget = this.sliderWidget as any;
46
- if (widget.hideLabel === true) {
47
- return false;
48
- }
49
- if (widget.showLabel === false) {
50
- return false;
51
- }
52
- return true;
53
- }
54
-
55
- get sliderClasses(): string[] {
56
- return this.isFormAppearance ? ['bbq-form-slider'] : ['bbq-slider'];
57
- }
58
-
59
- private get isFormAppearance(): boolean {
60
- return (this.sliderWidget as any).appearance === 'form';
61
- }
62
-
63
- ngOnInit() {
64
- this.sliderId = `bbq-${this.sliderWidget.action.replace(/\s+/g, '-').toLowerCase()}-slider`;
65
- this.value = this.sliderWidget.defaultValue ?? this.sliderWidget.min;
66
- }
67
- }
@@ -1,63 +0,0 @@
1
- import { Component, Input, OnInit } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { FormsModule } from '@angular/forms';
4
- import type { TextAreaWidget } from '@bbq-chat/widgets';
5
- import { CustomWidgetComponent } from '../custom-widget-renderer.types';
6
-
7
- @Component({
8
- selector: 'bbq-textarea-widget',
9
- standalone: true,
10
- imports: [CommonModule, FormsModule],
11
- template: `
12
- <div
13
- class="bbq-widget bbq-textarea"
14
- [attr.data-widget-type]="'textarea'">
15
- <label *ngIf="showLabel" class="bbq-textarea-label" [attr.for]="textareaId">
16
- {{ textareaWidget.label }}
17
- </label>
18
- <textarea
19
- [id]="textareaId"
20
- [ngClass]="textareaClasses"
21
- [attr.data-action]="textareaWidget.action"
22
- [placeholder]="textareaWidget.placeholder || ''"
23
- [maxLength]="textareaWidget.maxLength || 0"
24
- [rows]="textareaWidget.rows || 4"
25
- [(ngModel)]="value"></textarea>
26
- </div>
27
- `,
28
- styles: []
29
- })
30
- export class TextAreaWidgetComponent implements CustomWidgetComponent, OnInit {
31
- @Input() widget!: any;
32
- widgetAction?: (actionName: string, payload: unknown) => void;
33
-
34
- value = '';
35
- textareaId = '';
36
-
37
- get textareaWidget(): TextAreaWidget {
38
- return this.widget as TextAreaWidget;
39
- }
40
-
41
- get showLabel(): boolean {
42
- const widget = this.textareaWidget as any;
43
- if (widget.hideLabel === true) {
44
- return false;
45
- }
46
- if (widget.showLabel === false) {
47
- return false;
48
- }
49
- return true;
50
- }
51
-
52
- get textareaClasses(): string[] {
53
- return this.isFormAppearance ? ['bbq-form-textarea'] : ['bbq-form-textarea', 'bbq-input'];
54
- }
55
-
56
- private get isFormAppearance(): boolean {
57
- return (this.textareaWidget as any).appearance === 'form';
58
- }
59
-
60
- ngOnInit() {
61
- this.textareaId = `bbq-${this.textareaWidget.action.replace(/\s+/g, '-').toLowerCase()}-textarea`;
62
- }
63
- }
@@ -1,46 +0,0 @@
1
- import { Component, Input, OnInit } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { FormsModule } from '@angular/forms';
4
- import type { ThemeSwitcherWidget } from '@bbq-chat/widgets';
5
- import { CustomWidgetComponent } from '../custom-widget-renderer.types';
6
-
7
- @Component({
8
- selector: 'bbq-themeswitcher-widget',
9
- standalone: true,
10
- imports: [CommonModule, FormsModule],
11
- template: `
12
- <div
13
- class="bbq-widget bbq-theme-switcher"
14
- [attr.data-widget-type]="'themeswitcher'">
15
- <label class="bbq-theme-switcher-label" [attr.for]="selectId">
16
- {{ themeSwitcherWidget.label }}
17
- </label>
18
- <select
19
- [id]="selectId"
20
- class="bbq-theme-switcher-select"
21
- [attr.data-action]="themeSwitcherWidget.action"
22
- [(ngModel)]="value">
23
- @for (theme of themeSwitcherWidget.themes; track theme) {
24
- <option [value]="theme">{{ theme }}</option>
25
- }
26
- </select>
27
- </div>
28
- `,
29
- styles: []
30
- })
31
- export class ThemeSwitcherWidgetComponent implements CustomWidgetComponent, OnInit {
32
- @Input() widget!: any;
33
- widgetAction?: (actionName: string, payload: unknown) => void;
34
-
35
- value = '';
36
- selectId = '';
37
-
38
- get themeSwitcherWidget(): ThemeSwitcherWidget {
39
- return this.widget as ThemeSwitcherWidget;
40
- }
41
-
42
- ngOnInit() {
43
- this.selectId = `bbq-${this.themeSwitcherWidget.action.replace(/\s+/g, '-').toLowerCase()}-select`;
44
- this.value = this.themeSwitcherWidget.themes[0] || '';
45
- }
46
- }
@@ -1,63 +0,0 @@
1
- import { Component, Input, OnInit } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { FormsModule } from '@angular/forms';
4
- import type { ToggleWidget } from '@bbq-chat/widgets';
5
- import { CustomWidgetComponent } from '../custom-widget-renderer.types';
6
-
7
- @Component({
8
- selector: 'bbq-toggle-widget',
9
- standalone: true,
10
- imports: [CommonModule, FormsModule],
11
- template: `
12
- <div
13
- class="bbq-widget bbq-toggle"
14
- [attr.data-widget-type]="'toggle'">
15
- <label class="bbq-toggle-label" [attr.for]="checkboxId">
16
- <input
17
- type="checkbox"
18
- [id]="checkboxId"
19
- [ngClass]="checkboxClasses"
20
- [attr.data-action]="toggleWidget.action"
21
- [attr.aria-label]="toggleWidget.label"
22
- [(ngModel)]="checked" />
23
- <span *ngIf="showLabel" class="bbq-toggle-text">{{ toggleWidget.label }}</span>
24
- </label>
25
- </div>
26
- `,
27
- styles: []
28
- })
29
- export class ToggleWidgetComponent implements CustomWidgetComponent, OnInit {
30
- @Input() widget!: any;
31
- widgetAction?: (actionName: string, payload: unknown) => void;
32
-
33
- checked = false;
34
- checkboxId = '';
35
-
36
- get toggleWidget(): ToggleWidget {
37
- return this.widget as ToggleWidget;
38
- }
39
-
40
- get showLabel(): boolean {
41
- const widget = this.toggleWidget as any;
42
- if (widget.hideLabel === true) {
43
- return false;
44
- }
45
- if (widget.showLabel === false) {
46
- return false;
47
- }
48
- return true;
49
- }
50
-
51
- get checkboxClasses(): string[] {
52
- return this.isFormAppearance ? ['bbq-toggle-input', 'bbq-form-toggle'] : ['bbq-toggle-input'];
53
- }
54
-
55
- private get isFormAppearance(): boolean {
56
- return (this.toggleWidget as any).appearance === 'form';
57
- }
58
-
59
- ngOnInit() {
60
- this.checkboxId = `bbq-${this.toggleWidget.action.replace(/\s+/g, '-').toLowerCase()}-checkbox`;
61
- this.checked = this.toggleWidget.defaultValue ?? false;
62
- }
63
- }
@@ -1,120 +0,0 @@
1
- import { Type, TemplateRef } from '@angular/core';
2
- import { ChatWidget } from '@bbq-chat/widgets';
3
-
4
- /**
5
- * Context provided to template-based custom widget renderers
6
- */
7
- export interface WidgetTemplateContext {
8
- /**
9
- * The widget instance being rendered
10
- */
11
- $implicit: ChatWidget;
12
-
13
- /**
14
- * The widget instance (alternative access)
15
- */
16
- widget: ChatWidget;
17
-
18
- /**
19
- * Emit a widget action
20
- */
21
- emitAction: (actionName: string, payload: unknown) => void;
22
- }
23
-
24
- /**
25
- * Interface for component-based custom widget renderers
26
- */
27
- export interface CustomWidgetComponent {
28
- /**
29
- * The widget instance to render
30
- */
31
- widget: ChatWidget;
32
-
33
- /**
34
- * Event emitter for widget actions (optional, will be set by the renderer)
35
- */
36
- widgetAction?: (actionName: string, payload: unknown) => void;
37
- }
38
-
39
- /**
40
- * Type for custom widget renderer functions that return HTML strings
41
- */
42
- export type CustomWidgetHtmlRenderer = (widget: ChatWidget) => string;
43
-
44
- /**
45
- * Type for custom widget renderer configurations
46
- */
47
- export type CustomWidgetRenderer =
48
- | CustomWidgetHtmlRenderer
49
- | Type<CustomWidgetComponent>
50
- | TemplateRef<WidgetTemplateContext>;
51
-
52
- /**
53
- * Configuration for registering a custom widget renderer
54
- */
55
- export interface CustomWidgetRendererConfig {
56
- /**
57
- * The widget type identifier
58
- */
59
- type: string;
60
-
61
- /**
62
- * The renderer: can be a function returning HTML, an Angular Component class, or a TemplateRef
63
- */
64
- renderer: CustomWidgetRenderer;
65
- }
66
-
67
- /**
68
- * Type guard to check if a renderer is a TemplateRef
69
- */
70
- export function isTemplateRenderer(
71
- renderer: CustomWidgetRenderer
72
- ): renderer is TemplateRef<WidgetTemplateContext> {
73
- return (
74
- renderer !== null &&
75
- typeof renderer === 'object' &&
76
- 'createEmbeddedView' in renderer
77
- );
78
- }
79
-
80
- /**
81
- * Type guard to check if a renderer is an Angular Component
82
- *
83
- * Note: This uses a heuristic check based on the following assumptions:
84
- * 1. Components are constructor functions
85
- * 2. Components have a prototype with a constructor property
86
- * 3. Components typically use dependency injection (no required constructor params)
87
- *
88
- * Limitation: This may not detect components with required constructor parameters.
89
- * For edge cases, explicitly check your component's constructor signature.
90
- *
91
- * Alternative: You can always register a wrapper component that has no required params.
92
- */
93
- export function isComponentRenderer(
94
- renderer: CustomWidgetRenderer
95
- ): renderer is Type<CustomWidgetComponent> {
96
- // Check if it's a function (constructor) but not a regular function renderer
97
- if (typeof renderer !== 'function') {
98
- return false;
99
- }
100
-
101
- // Check for Angular component characteristics
102
- // Components typically have prototype with constructor property
103
- return (
104
- renderer.prototype !== undefined &&
105
- renderer.prototype.constructor === renderer &&
106
- renderer.length === 0 // Constructor with no required params (Angular DI)
107
- );
108
- }
109
-
110
- /**
111
- * Type guard to check if a renderer is an HTML function
112
- *
113
- * Note: This should be checked AFTER checking for component and template renderers
114
- * since components are also functions but with additional properties.
115
- */
116
- export function isHtmlRenderer(
117
- renderer: CustomWidgetRenderer
118
- ): renderer is CustomWidgetHtmlRenderer {
119
- return typeof renderer === 'function';
120
- }
@@ -1,41 +0,0 @@
1
- import { Component, Input, OnDestroy, OnInit } from '@angular/core';
2
- import { JsonPipe } from '@angular/common';
3
- import { Subscription } from 'rxjs';
4
- import { FormValidationService, FormValidationEvent } from '../services/form-validation.service';
5
-
6
- @Component({
7
- selector: 'bbq-form-validation-listener',
8
- standalone: true,
9
- imports: [JsonPipe],
10
- template: `
11
- <div class="bbq-validation-listener">
12
- @if (lastEvent) {
13
- <div>
14
- <strong>Last validation (formId: {{ lastEvent.formId }})</strong>
15
- <pre>{{ lastEvent | json }}</pre>
16
- </div>
17
- } @else {
18
- <small>No validation events yet.</small>
19
- }
20
- </div>
21
- `,
22
- })
23
- export class FormValidationListenerComponent implements OnInit, OnDestroy {
24
- @Input() formId?: string;
25
- lastEvent?: FormValidationEvent | null = null;
26
- private sub?: Subscription;
27
-
28
- constructor(private svc: FormValidationService) {}
29
-
30
- ngOnInit() {
31
- this.sub = this.svc.validation$.subscribe(ev => {
32
- if (!this.formId || ev.formId === this.formId) {
33
- this.lastEvent = ev;
34
- }
35
- });
36
- }
37
-
38
- ngOnDestroy() {
39
- this.sub?.unsubscribe();
40
- }
41
- }
package/src/public_api.ts DELETED
@@ -1,107 +0,0 @@
1
- /**
2
- * @bbq-chat/widgets-angular
3
- *
4
- * Angular components and services for BbQ ChatWidgets
5
- *
6
- * This package provides Angular-native components and services that wrap
7
- * the core @bbq-chat/widgets library, making it easy to integrate chat
8
- * widgets into Angular applications.
9
- *
10
- * @packageDocumentation
11
- */
12
-
13
- // Export components
14
- export { WidgetRendererComponent } from './widget-renderer.component';
15
-
16
- // Export services
17
- export { WidgetRegistryService } from './widget-registry.service';
18
- export { FormValidationService } from './services/form-validation.service';
19
-
20
- // Export DI tokens and factories
21
- export {
22
- WIDGET_EVENT_MANAGER_FACTORY,
23
- SSR_WIDGET_RENDERER,
24
- ANGULAR_WIDGET_RENDERER,
25
- widgetEventManagerFactoryProvider,
26
- ssrWidgetRendererFactory,
27
- angularWidgetRendererFactory,
28
- } from './widget-di.tokens';
29
-
30
- export type { WidgetEventManagerFactory } from './widget-di.tokens';
31
-
32
- // Export custom widget renderer types
33
- export type {
34
- CustomWidgetComponent,
35
- CustomWidgetRenderer,
36
- CustomWidgetHtmlRenderer,
37
- CustomWidgetRendererConfig,
38
- WidgetTemplateContext,
39
- } from './custom-widget-renderer.types';
40
-
41
- export {
42
- isHtmlRenderer,
43
- isComponentRenderer,
44
- isTemplateRenderer,
45
- } from './custom-widget-renderer.types';
46
-
47
- // Export Angular renderer and built-in components
48
- export {
49
- AngularWidgetRenderer,
50
- ButtonWidgetComponent,
51
- CardWidgetComponent,
52
- InputWidgetComponent,
53
- TextAreaWidgetComponent,
54
- DropdownWidgetComponent,
55
- SliderWidgetComponent,
56
- ToggleWidgetComponent,
57
- FileUploadWidgetComponent,
58
- ThemeSwitcherWidgetComponent,
59
- DatePickerWidgetComponent,
60
- MultiSelectWidgetComponent,
61
- ProgressBarWidgetComponent,
62
- FormWidgetComponent,
63
- ImageWidgetComponent,
64
- ImageCollectionWidgetComponent,
65
- } from './renderers';
66
-
67
- export type {
68
- AngularRendererOptions,
69
- } from './renderers';
70
-
71
- export { BUILT_IN_WIDGET_COMPONENTS } from './renderers/built-in-components';
72
-
73
- // Re-export commonly used types and classes from core package
74
- export {
75
- ChatWidget,
76
- } from '@bbq-chat/widgets';
77
-
78
- export type {
79
- ButtonWidget,
80
- CardWidget,
81
- FormWidget,
82
- InputWidget,
83
- TextAreaWidget,
84
- DropdownWidget,
85
- SliderWidget,
86
- ToggleWidget,
87
- FileUploadWidget,
88
- DatePickerWidget,
89
- MultiSelectWidget,
90
- ProgressBarWidget,
91
- ThemeSwitcherWidget,
92
- ImageWidget,
93
- ImageCollectionWidget,
94
- } from '@bbq-chat/widgets';
95
-
96
- // Re-export utilities
97
- export {
98
- SsrWidgetRenderer,
99
- WidgetEventManager,
100
- customWidgetRegistry,
101
- } from '@bbq-chat/widgets';
102
-
103
- // Examples
104
- export { FormValidationListenerComponent } from './examples/form-validation-listener.component';
105
-
106
- // Version
107
- export const VERSION = '1.0.9';
@@ -1,100 +0,0 @@
1
- import { Type } from '@angular/core';
2
- import { IWidgetRenderer } from '@bbq-chat/widgets';
3
- import type { ChatWidget } from '@bbq-chat/widgets';
4
- import { CustomWidgetComponent } from '../custom-widget-renderer.types';
5
-
6
- /**
7
- * Options for configuring the Angular widget renderer
8
- */
9
- export interface AngularRendererOptions {
10
- /**
11
- * Per-widget-type component overrides. Key is widget.type.
12
- */
13
- components?: Partial<Record<string, Type<CustomWidgetComponent>>>;
14
- }
15
-
16
- /**
17
- * Angular widget renderer
18
- * Returns Angular component types for dynamic rendering
19
- * Provides feature parity with SsrWidgetRenderer but uses Angular components
20
- */
21
- export class AngularWidgetRenderer implements IWidgetRenderer {
22
- readonly framework = 'Angular';
23
- private overrides: AngularRendererOptions['components'] | undefined;
24
- private componentRegistry: Map<string, Type<CustomWidgetComponent>> = new Map();
25
-
26
- constructor(options?: AngularRendererOptions) {
27
- this.overrides = options?.components;
28
- }
29
-
30
- /**
31
- * Register all built-in widget components
32
- * Must be called after components are imported to avoid circular dependencies
33
- */
34
- registerBuiltInComponents(components: Record<string, Type<CustomWidgetComponent>>) {
35
- for (const [type, component] of Object.entries(components)) {
36
- this.componentRegistry.set(type, component);
37
- }
38
- }
39
-
40
- /**
41
- * Register or override a widget component
42
- * Use this to replace built-in components or add custom ones
43
- *
44
- * @example
45
- * ```typescript
46
- * renderer.registerComponent('button', MyCustomButtonComponent);
47
- * ```
48
- */
49
- registerComponent(type: string, component: Type<CustomWidgetComponent>) {
50
- this.componentRegistry.set(type, component);
51
- }
52
-
53
- /**
54
- * Register multiple widget components at once
55
- *
56
- * @example
57
- * ```typescript
58
- * renderer.registerComponents({
59
- * button: MyButtonComponent,
60
- * card: MyCardComponent
61
- * });
62
- * ```
63
- */
64
- registerComponents(components: Record<string, Type<CustomWidgetComponent>>) {
65
- for (const [type, component] of Object.entries(components)) {
66
- this.componentRegistry.set(type, component);
67
- }
68
- }
69
-
70
- /**
71
- * Get the Angular component type for a given widget
72
- * Returns the component class that should be dynamically instantiated
73
- */
74
- getComponentType(widget: ChatWidget): Type<CustomWidgetComponent> | null {
75
- const type = widget.type;
76
-
77
- // Check for custom override first
78
- if (this.overrides && this.overrides[type]) {
79
- return this.overrides[type] as Type<CustomWidgetComponent>;
80
- }
81
-
82
- // Check built-in registry
83
- if (this.componentRegistry.has(type)) {
84
- return this.componentRegistry.get(type)!;
85
- }
86
-
87
- return null;
88
- }
89
-
90
- /**
91
- * Legacy method for IWidgetRenderer interface compatibility
92
- * Not used in Angular rendering but required by interface
93
- * @deprecated Use getComponentType() instead for Angular rendering
94
- */
95
- renderWidget(widget: ChatWidget): string {
96
- // This method is not used in Angular rendering
97
- // It's only here for interface compatibility
98
- return `<!-- Angular component rendering for ${widget.type} -->`;
99
- }
100
- }