@bbq-chat/widgets-angular 1.0.0 → 1.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/.eslintrc.json +23 -0
- package/.prettierrc.json +8 -0
- package/EXAMPLES.md +468 -0
- package/ng-package.json +10 -0
- package/package.json +25 -23
- package/scripts/build.mjs +63 -0
- package/src/index.ts +11 -1
- package/src/public_api.ts +75 -0
- package/src/widget-di.tokens.ts +63 -0
- package/src/widget-renderer.component.ts +24 -8
- package/tsconfig.json +34 -0
- package/dist/LICENSE +0 -21
- package/dist/README.md +0 -252
- package/dist/custom-widget-renderer.types.d.ts +0 -79
- package/dist/custom-widget-renderer.types.d.ts.map +0 -1
- package/dist/custom-widget-renderer.types.js +0 -43
- package/dist/custom-widget-renderer.types.js.map +0 -1
- package/dist/index.cjs +0 -38
- package/dist/index.d.ts +0 -20
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -23
- package/dist/index.js.map +0 -1
- package/dist/package.json +0 -16
- package/dist/widget-registry.service.d.ts +0 -95
- package/dist/widget-registry.service.d.ts.map +0 -1
- package/dist/widget-registry.service.js +0 -129
- package/dist/widget-registry.service.js.map +0 -1
- package/dist/widget-renderer.component.d.ts +0 -93
- package/dist/widget-renderer.component.d.ts.map +0 -1
- package/dist/widget-renderer.component.js +0 -316
- package/dist/widget-renderer.component.js.map +0 -1
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
|
|
19
|
+
// Export DI tokens and factories
|
|
20
|
+
export {
|
|
21
|
+
WIDGET_EVENT_MANAGER_FACTORY,
|
|
22
|
+
SSR_WIDGET_RENDERER,
|
|
23
|
+
widgetEventManagerFactoryProvider,
|
|
24
|
+
ssrWidgetRendererFactory,
|
|
25
|
+
} from './widget-di.tokens';
|
|
26
|
+
|
|
27
|
+
export type { WidgetEventManagerFactory } from './widget-di.tokens';
|
|
28
|
+
|
|
29
|
+
// Export custom widget renderer types
|
|
30
|
+
export type {
|
|
31
|
+
CustomWidgetComponent,
|
|
32
|
+
CustomWidgetRenderer,
|
|
33
|
+
CustomWidgetHtmlRenderer,
|
|
34
|
+
CustomWidgetRendererConfig,
|
|
35
|
+
WidgetTemplateContext,
|
|
36
|
+
} from './custom-widget-renderer.types';
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
isHtmlRenderer,
|
|
40
|
+
isComponentRenderer,
|
|
41
|
+
isTemplateRenderer,
|
|
42
|
+
} from './custom-widget-renderer.types';
|
|
43
|
+
|
|
44
|
+
// Re-export commonly used types and classes from core package
|
|
45
|
+
export {
|
|
46
|
+
ChatWidget,
|
|
47
|
+
} from '@bbq-chat/widgets';
|
|
48
|
+
|
|
49
|
+
export type {
|
|
50
|
+
ButtonWidget,
|
|
51
|
+
CardWidget,
|
|
52
|
+
FormWidget,
|
|
53
|
+
InputWidget,
|
|
54
|
+
TextAreaWidget,
|
|
55
|
+
DropdownWidget,
|
|
56
|
+
SliderWidget,
|
|
57
|
+
ToggleWidget,
|
|
58
|
+
FileUploadWidget,
|
|
59
|
+
DatePickerWidget,
|
|
60
|
+
MultiSelectWidget,
|
|
61
|
+
ProgressBarWidget,
|
|
62
|
+
ThemeSwitcherWidget,
|
|
63
|
+
ImageWidget,
|
|
64
|
+
ImageCollectionWidget,
|
|
65
|
+
} from '@bbq-chat/widgets';
|
|
66
|
+
|
|
67
|
+
// Re-export utilities
|
|
68
|
+
export {
|
|
69
|
+
SsrWidgetRenderer,
|
|
70
|
+
WidgetEventManager,
|
|
71
|
+
customWidgetRegistry,
|
|
72
|
+
} from '@bbq-chat/widgets';
|
|
73
|
+
|
|
74
|
+
// Version
|
|
75
|
+
export const VERSION = '1.0.1';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
import { SsrWidgetRenderer, WidgetEventManager, IWidgetActionHandler } from '@bbq-chat/widgets';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Injection token for WidgetEventManager factory
|
|
6
|
+
*
|
|
7
|
+
* Use this token to inject a factory function that creates WidgetEventManager instances.
|
|
8
|
+
* The factory accepts an optional action handler to configure the manager.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* constructor(@Inject(WIDGET_EVENT_MANAGER_FACTORY) private eventManagerFactory: WidgetEventManagerFactory) {
|
|
13
|
+
* const actionHandler = { handle: async (action, payload) => { ... } };
|
|
14
|
+
* this.eventManager = this.eventManagerFactory(actionHandler);
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export type WidgetEventManagerFactory = (actionHandler?: IWidgetActionHandler) => WidgetEventManager;
|
|
19
|
+
|
|
20
|
+
export const WIDGET_EVENT_MANAGER_FACTORY = new InjectionToken<WidgetEventManagerFactory>(
|
|
21
|
+
'WIDGET_EVENT_MANAGER_FACTORY'
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Injection token for SsrWidgetRenderer
|
|
26
|
+
*
|
|
27
|
+
* Use this token to inject a SsrWidgetRenderer instance in your components.
|
|
28
|
+
* By default, WidgetRendererComponent provides this token with a factory that creates
|
|
29
|
+
* a new instance for each component.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* constructor(@Inject(SSR_WIDGET_RENDERER) private renderer: SsrWidgetRenderer) {}
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export const SSR_WIDGET_RENDERER = new InjectionToken<SsrWidgetRenderer>(
|
|
37
|
+
'SSR_WIDGET_RENDERER'
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Factory function for creating WidgetEventManager instances
|
|
42
|
+
*
|
|
43
|
+
* This factory is used by default in WidgetRendererComponent's providers array.
|
|
44
|
+
* You can override this in your own providers if you need custom initialization.
|
|
45
|
+
*
|
|
46
|
+
* @returns A factory function that creates WidgetEventManager instances
|
|
47
|
+
*/
|
|
48
|
+
export function widgetEventManagerFactoryProvider(): WidgetEventManagerFactory {
|
|
49
|
+
return (actionHandler?: IWidgetActionHandler) => new WidgetEventManager(actionHandler);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Factory function for creating SsrWidgetRenderer instances
|
|
54
|
+
*
|
|
55
|
+
* This factory is used by default in WidgetRendererComponent's providers array.
|
|
56
|
+
* You can override this in your own providers if you need custom initialization
|
|
57
|
+
* or custom rendering options.
|
|
58
|
+
*
|
|
59
|
+
* @returns A new SsrWidgetRenderer instance
|
|
60
|
+
*/
|
|
61
|
+
export function ssrWidgetRendererFactory(): SsrWidgetRenderer {
|
|
62
|
+
return new SsrWidgetRenderer();
|
|
63
|
+
}
|
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
ComponentRef,
|
|
14
14
|
EmbeddedViewRef,
|
|
15
15
|
TemplateRef,
|
|
16
|
-
inject,
|
|
17
16
|
Injector,
|
|
18
17
|
createComponent,
|
|
19
18
|
EnvironmentInjector,
|
|
19
|
+
Inject,
|
|
20
20
|
} from '@angular/core';
|
|
21
21
|
import { CommonModule } from '@angular/common';
|
|
22
22
|
import {
|
|
@@ -31,6 +31,13 @@ import {
|
|
|
31
31
|
isComponentRenderer,
|
|
32
32
|
isTemplateRenderer,
|
|
33
33
|
} from './custom-widget-renderer.types';
|
|
34
|
+
import {
|
|
35
|
+
WIDGET_EVENT_MANAGER_FACTORY,
|
|
36
|
+
SSR_WIDGET_RENDERER,
|
|
37
|
+
widgetEventManagerFactoryProvider,
|
|
38
|
+
ssrWidgetRendererFactory,
|
|
39
|
+
WidgetEventManagerFactory,
|
|
40
|
+
} from './widget-di.tokens';
|
|
34
41
|
|
|
35
42
|
/**
|
|
36
43
|
* Angular component for rendering chat widgets
|
|
@@ -55,6 +62,10 @@ import {
|
|
|
55
62
|
selector: 'bbq-widget-renderer',
|
|
56
63
|
standalone: true,
|
|
57
64
|
imports: [CommonModule],
|
|
65
|
+
providers: [
|
|
66
|
+
{ provide: WIDGET_EVENT_MANAGER_FACTORY, useFactory: widgetEventManagerFactoryProvider },
|
|
67
|
+
{ provide: SSR_WIDGET_RENDERER, useFactory: ssrWidgetRendererFactory },
|
|
68
|
+
],
|
|
58
69
|
template: `
|
|
59
70
|
<div #widgetContainer class="bbq-widgets-container" (click)="handleClick($event)">
|
|
60
71
|
@for (item of widgetItems; track item.index) {
|
|
@@ -104,17 +115,21 @@ export class WidgetRendererComponent
|
|
|
104
115
|
html?: string;
|
|
105
116
|
}> = [];
|
|
106
117
|
|
|
107
|
-
protected renderer = new SsrWidgetRenderer();
|
|
108
118
|
protected eventManager?: WidgetEventManager;
|
|
109
119
|
protected isViewInitialized = false;
|
|
110
|
-
protected widgetRegistry = inject(WidgetRegistryService);
|
|
111
|
-
protected injector = inject(Injector);
|
|
112
|
-
protected environmentInjector = inject(EnvironmentInjector);
|
|
113
120
|
protected dynamicComponents: Array<ComponentRef<any>> = [];
|
|
114
121
|
protected dynamicViews: Array<EmbeddedViewRef<WidgetTemplateContext>> = [];
|
|
115
122
|
|
|
123
|
+
constructor(
|
|
124
|
+
@Inject(SSR_WIDGET_RENDERER) protected renderer: SsrWidgetRenderer,
|
|
125
|
+
@Inject(WIDGET_EVENT_MANAGER_FACTORY) protected eventManagerFactory: WidgetEventManagerFactory,
|
|
126
|
+
protected widgetRegistry: WidgetRegistryService,
|
|
127
|
+
protected injector: Injector,
|
|
128
|
+
protected environmentInjector: EnvironmentInjector
|
|
129
|
+
) {}
|
|
130
|
+
|
|
116
131
|
ngOnInit() {
|
|
117
|
-
this.updateWidgetHtml();
|
|
132
|
+
// this.updateWidgetHtml();
|
|
118
133
|
}
|
|
119
134
|
|
|
120
135
|
ngOnChanges(changes: SimpleChanges) {
|
|
@@ -124,6 +139,7 @@ export class WidgetRendererComponent
|
|
|
124
139
|
}
|
|
125
140
|
|
|
126
141
|
ngAfterViewInit() {
|
|
142
|
+
this.updateWidgetHtml();
|
|
127
143
|
this.isViewInitialized = true;
|
|
128
144
|
this.setupEventHandlers();
|
|
129
145
|
// Render dynamic components/templates after view init
|
|
@@ -347,8 +363,8 @@ export class WidgetRendererComponent
|
|
|
347
363
|
},
|
|
348
364
|
};
|
|
349
365
|
|
|
350
|
-
//
|
|
351
|
-
this.eventManager =
|
|
366
|
+
// Use the injected factory to create an event manager with the component-specific action handler
|
|
367
|
+
this.eventManager = this.eventManagerFactory(actionHandler);
|
|
352
368
|
this.eventManager.attachHandlers(container);
|
|
353
369
|
}
|
|
354
370
|
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compileOnSave": false,
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"baseUrl": "./",
|
|
5
|
+
"outDir": "./dist/out-tsc",
|
|
6
|
+
"forceConsistentCasingInFileNames": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noImplicitReturns": true,
|
|
9
|
+
"noFallthroughCasesInSwitch": true,
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"downlevelIteration": true,
|
|
13
|
+
"experimentalDecorators": true,
|
|
14
|
+
"moduleResolution": "node",
|
|
15
|
+
"importHelpers": true,
|
|
16
|
+
"target": "ES2022",
|
|
17
|
+
"module": "ES2022",
|
|
18
|
+
"lib": [
|
|
19
|
+
"ES2022",
|
|
20
|
+
"dom"
|
|
21
|
+
],
|
|
22
|
+
"skipLibCheck": true,
|
|
23
|
+
"skipDefaultLibCheck": true,
|
|
24
|
+
"paths": {
|
|
25
|
+
"@bbq-chat/widgets": ["../js/dist"]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"angularCompilerOptions": {
|
|
29
|
+
"enableI18nLegacyMessageIdFormat": false,
|
|
30
|
+
"strictInjectionParameters": true,
|
|
31
|
+
"strictInputAccessModifiers": true,
|
|
32
|
+
"strictTemplates": true
|
|
33
|
+
}
|
|
34
|
+
}
|
package/dist/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 BbQ ChatWidgets Contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
package/dist/README.md
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
# @bbq-chat/widgets-angular
|
|
2
|
-
|
|
3
|
-
Angular components and services for BbQ ChatWidgets. This package provides Angular-native wrappers for the core [@bbq-chat/widgets](https://www.npmjs.com/package/@bbq-chat/widgets) library.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @bbq-chat/widgets-angular @bbq-chat/widgets
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Peer Dependencies
|
|
12
|
-
|
|
13
|
-
This package requires:
|
|
14
|
-
- `@angular/common` >= 17.0.0
|
|
15
|
-
- `@angular/core` >= 17.0.0
|
|
16
|
-
- `@bbq-chat/widgets` ^1.0.0
|
|
17
|
-
|
|
18
|
-
## Quick Start
|
|
19
|
-
|
|
20
|
-
### 1. Import the component
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
import { Component } from '@angular/core';
|
|
24
|
-
import { WidgetRendererComponent } from '@bbq-chat/widgets-angular';
|
|
25
|
-
import type { ChatWidget } from '@bbq-chat/widgets-angular';
|
|
26
|
-
|
|
27
|
-
@Component({
|
|
28
|
-
selector: 'app-chat',
|
|
29
|
-
standalone: true,
|
|
30
|
-
imports: [WidgetRendererComponent],
|
|
31
|
-
template: `
|
|
32
|
-
<bbq-widget-renderer
|
|
33
|
-
[widgets]="widgets"
|
|
34
|
-
(widgetAction)="handleWidgetAction($event)">
|
|
35
|
-
</bbq-widget-renderer>
|
|
36
|
-
`
|
|
37
|
-
})
|
|
38
|
-
export class ChatComponent {
|
|
39
|
-
widgets: ChatWidget[] = [];
|
|
40
|
-
|
|
41
|
-
handleWidgetAction(event: { actionName: string; payload: any }) {
|
|
42
|
-
console.log('Widget action:', event.actionName, event.payload);
|
|
43
|
-
// Handle the action (e.g., send to backend)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### 2. Import styles
|
|
49
|
-
|
|
50
|
-
In your `styles.css` or `styles.scss`:
|
|
51
|
-
|
|
52
|
-
```css
|
|
53
|
-
@import '@bbq-chat/widgets/styles';
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Or import a specific theme:
|
|
57
|
-
|
|
58
|
-
```css
|
|
59
|
-
@import '@bbq-chat/widgets/styles/light';
|
|
60
|
-
@import '@bbq-chat/widgets/styles/dark';
|
|
61
|
-
@import '@bbq-chat/widgets/styles/corporate';
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## Components
|
|
65
|
-
|
|
66
|
-
### WidgetRendererComponent
|
|
67
|
-
|
|
68
|
-
The main component for rendering chat widgets.
|
|
69
|
-
|
|
70
|
-
**Inputs:**
|
|
71
|
-
- `widgets: ChatWidget[] | null | undefined` - Array of widgets to render
|
|
72
|
-
|
|
73
|
-
**Outputs:**
|
|
74
|
-
- `widgetAction: EventEmitter<{ actionName: string; payload: any }>` - Emits when a widget action is triggered
|
|
75
|
-
|
|
76
|
-
**Example:**
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
<bbq-widget-renderer
|
|
80
|
-
[widgets]="messageWidgets"
|
|
81
|
-
(widgetAction)="onWidgetAction($event)">
|
|
82
|
-
</bbq-widget-renderer>
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Services
|
|
86
|
-
|
|
87
|
-
### WidgetRegistryService
|
|
88
|
-
|
|
89
|
-
Service for registering custom widget types.
|
|
90
|
-
|
|
91
|
-
**Example:**
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
import { Component, OnInit } from '@angular/core';
|
|
95
|
-
import { WidgetRegistryService } from '@bbq-chat/widgets-angular';
|
|
96
|
-
|
|
97
|
-
export class MyCustomWidget {
|
|
98
|
-
type = 'myCustomWidget';
|
|
99
|
-
constructor(public label: string, public action: string) {}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
@Component({
|
|
103
|
-
selector: 'app-root',
|
|
104
|
-
template: '...'
|
|
105
|
-
})
|
|
106
|
-
export class AppComponent implements OnInit {
|
|
107
|
-
constructor(private widgetRegistry: WidgetRegistryService) {}
|
|
108
|
-
|
|
109
|
-
ngOnInit() {
|
|
110
|
-
// Register custom widget factory
|
|
111
|
-
this.widgetRegistry.registerFactory('myCustomWidget', (obj) => {
|
|
112
|
-
if (obj.type === 'myCustomWidget') {
|
|
113
|
-
return new MyCustomWidget(obj.label, obj.action);
|
|
114
|
-
}
|
|
115
|
-
return null;
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Widget Types
|
|
122
|
-
|
|
123
|
-
All standard widget types from `@bbq-chat/widgets` are supported:
|
|
124
|
-
|
|
125
|
-
- `ButtonWidget` - Clickable buttons
|
|
126
|
-
- `CardWidget` - Information cards
|
|
127
|
-
- `FormWidget` - Form containers
|
|
128
|
-
- `InputWidget` - Text input fields
|
|
129
|
-
- `TextAreaWidget` - Multi-line text input
|
|
130
|
-
- `DropdownWidget` - Dropdown selects
|
|
131
|
-
- `SliderWidget` - Range sliders
|
|
132
|
-
- `ToggleWidget` - Toggle switches
|
|
133
|
-
- `FileUploadWidget` - File upload controls
|
|
134
|
-
- `DatePickerWidget` - Date pickers
|
|
135
|
-
- `MultiSelectWidget` - Multi-select dropdowns
|
|
136
|
-
- `ThemeSwitcherWidget` - Theme switcher controls
|
|
137
|
-
- `ProgressBarWidget` - Progress indicators
|
|
138
|
-
- `ImageWidget` - Image displays
|
|
139
|
-
- `ImageCollectionWidget` - Image galleries
|
|
140
|
-
|
|
141
|
-
## Advanced Usage
|
|
142
|
-
|
|
143
|
-
### Handling Widget Actions
|
|
144
|
-
|
|
145
|
-
Widget actions are emitted when users interact with widgets. Handle these actions in your component:
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
async handleWidgetAction(event: { actionName: string; payload: any }) {
|
|
149
|
-
const { actionName, payload } = event;
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
const response = await fetch('/api/chat/action', {
|
|
153
|
-
method: 'POST',
|
|
154
|
-
headers: { 'Content-Type': 'application/json' },
|
|
155
|
-
body: JSON.stringify({ action: actionName, payload })
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
const data = await response.json();
|
|
159
|
-
// Update widgets with response
|
|
160
|
-
this.widgets = data.widgets;
|
|
161
|
-
} catch (error) {
|
|
162
|
-
console.error('Failed to handle widget action:', error);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Custom Widget Renderers
|
|
168
|
-
|
|
169
|
-
The library now supports three types of custom widget renderers for enhanced flexibility:
|
|
170
|
-
|
|
171
|
-
#### 1. HTML Function Renderer
|
|
172
|
-
|
|
173
|
-
Simple function that returns HTML strings:
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
this.widgetRegistry.registerRenderer('myWidget', (widget) => {
|
|
177
|
-
return `<div class="my-widget">${widget.label}</div>`;
|
|
178
|
-
});
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
#### 2. Angular Component Renderer (Recommended)
|
|
182
|
-
|
|
183
|
-
Use Angular components for full framework features including data binding, change detection, and dependency injection:
|
|
184
|
-
|
|
185
|
-
```typescript
|
|
186
|
-
import { Component, Input } from '@angular/core';
|
|
187
|
-
import { CustomWidgetComponent } from '@bbq-chat/widgets-angular';
|
|
188
|
-
|
|
189
|
-
@Component({
|
|
190
|
-
selector: 'app-my-widget',
|
|
191
|
-
standalone: true,
|
|
192
|
-
template: `
|
|
193
|
-
<div class="my-widget">
|
|
194
|
-
<h3>{{ myWidget.title }}</h3>
|
|
195
|
-
<button (click)="onClick()">Action</button>
|
|
196
|
-
</div>
|
|
197
|
-
`
|
|
198
|
-
})
|
|
199
|
-
export class MyWidgetComponent implements CustomWidgetComponent {
|
|
200
|
-
@Input() widget!: ChatWidget;
|
|
201
|
-
widgetAction?: (actionName: string, payload: unknown) => void;
|
|
202
|
-
|
|
203
|
-
get myWidget(): MyCustomWidget {
|
|
204
|
-
return this.widget as MyCustomWidget;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
onClick() {
|
|
208
|
-
this.widgetAction?.('my_action', { data: 'example' });
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Register the component
|
|
213
|
-
this.widgetRegistry.registerRenderer('myWidget', MyWidgetComponent);
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
#### 3. Angular Template Renderer
|
|
217
|
-
|
|
218
|
-
Use inline templates with full Angular template syntax:
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
import { WidgetTemplateContext } from '@bbq-chat/widgets-angular';
|
|
222
|
-
|
|
223
|
-
@Component({
|
|
224
|
-
template: `
|
|
225
|
-
<ng-template #myTemplate let-widget let-emitAction="emitAction">
|
|
226
|
-
<div class="my-widget">
|
|
227
|
-
<h3>{{ widget.title }}</h3>
|
|
228
|
-
<button (click)="emitAction('my_action', { data: 'example' })">
|
|
229
|
-
Action
|
|
230
|
-
</button>
|
|
231
|
-
</div>
|
|
232
|
-
</ng-template>
|
|
233
|
-
`
|
|
234
|
-
})
|
|
235
|
-
export class AppComponent implements OnInit {
|
|
236
|
-
@ViewChild('myTemplate', { static: true }) myTemplate!: TemplateRef<WidgetTemplateContext>;
|
|
237
|
-
|
|
238
|
-
ngOnInit() {
|
|
239
|
-
this.widgetRegistry.registerRenderer('myWidget', this.myTemplate);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
See [EXAMPLES.md](./EXAMPLES.md) for detailed examples and best practices.
|
|
245
|
-
|
|
246
|
-
## License
|
|
247
|
-
|
|
248
|
-
MIT
|
|
249
|
-
|
|
250
|
-
## Repository
|
|
251
|
-
|
|
252
|
-
https://github.com/JeanMarcMbouma/BbQ.ChatWidgets
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { Type, TemplateRef } from '@angular/core';
|
|
2
|
-
import { ChatWidget } from '@bbq-chat/widgets';
|
|
3
|
-
/**
|
|
4
|
-
* Context provided to template-based custom widget renderers
|
|
5
|
-
*/
|
|
6
|
-
export interface WidgetTemplateContext {
|
|
7
|
-
/**
|
|
8
|
-
* The widget instance being rendered
|
|
9
|
-
*/
|
|
10
|
-
$implicit: ChatWidget;
|
|
11
|
-
/**
|
|
12
|
-
* The widget instance (alternative access)
|
|
13
|
-
*/
|
|
14
|
-
widget: ChatWidget;
|
|
15
|
-
/**
|
|
16
|
-
* Emit a widget action
|
|
17
|
-
*/
|
|
18
|
-
emitAction: (actionName: string, payload: unknown) => void;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Interface for component-based custom widget renderers
|
|
22
|
-
*/
|
|
23
|
-
export interface CustomWidgetComponent {
|
|
24
|
-
/**
|
|
25
|
-
* The widget instance to render
|
|
26
|
-
*/
|
|
27
|
-
widget: ChatWidget;
|
|
28
|
-
/**
|
|
29
|
-
* Event emitter for widget actions (optional, will be set by the renderer)
|
|
30
|
-
*/
|
|
31
|
-
widgetAction?: (actionName: string, payload: unknown) => void;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Type for custom widget renderer functions that return HTML strings
|
|
35
|
-
*/
|
|
36
|
-
export type CustomWidgetHtmlRenderer = (widget: ChatWidget) => string;
|
|
37
|
-
/**
|
|
38
|
-
* Type for custom widget renderer configurations
|
|
39
|
-
*/
|
|
40
|
-
export type CustomWidgetRenderer = CustomWidgetHtmlRenderer | Type<CustomWidgetComponent> | TemplateRef<WidgetTemplateContext>;
|
|
41
|
-
/**
|
|
42
|
-
* Configuration for registering a custom widget renderer
|
|
43
|
-
*/
|
|
44
|
-
export interface CustomWidgetRendererConfig {
|
|
45
|
-
/**
|
|
46
|
-
* The widget type identifier
|
|
47
|
-
*/
|
|
48
|
-
type: string;
|
|
49
|
-
/**
|
|
50
|
-
* The renderer: can be a function returning HTML, an Angular Component class, or a TemplateRef
|
|
51
|
-
*/
|
|
52
|
-
renderer: CustomWidgetRenderer;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Type guard to check if a renderer is a TemplateRef
|
|
56
|
-
*/
|
|
57
|
-
export declare function isTemplateRenderer(renderer: CustomWidgetRenderer): renderer is TemplateRef<WidgetTemplateContext>;
|
|
58
|
-
/**
|
|
59
|
-
* Type guard to check if a renderer is an Angular Component
|
|
60
|
-
*
|
|
61
|
-
* Note: This uses a heuristic check based on the following assumptions:
|
|
62
|
-
* 1. Components are constructor functions
|
|
63
|
-
* 2. Components have a prototype with a constructor property
|
|
64
|
-
* 3. Components typically use dependency injection (no required constructor params)
|
|
65
|
-
*
|
|
66
|
-
* Limitation: This may not detect components with required constructor parameters.
|
|
67
|
-
* For edge cases, explicitly check your component's constructor signature.
|
|
68
|
-
*
|
|
69
|
-
* Alternative: You can always register a wrapper component that has no required params.
|
|
70
|
-
*/
|
|
71
|
-
export declare function isComponentRenderer(renderer: CustomWidgetRenderer): renderer is Type<CustomWidgetComponent>;
|
|
72
|
-
/**
|
|
73
|
-
* Type guard to check if a renderer is an HTML function
|
|
74
|
-
*
|
|
75
|
-
* Note: This should be checked AFTER checking for component and template renderers
|
|
76
|
-
* since components are also functions but with additional properties.
|
|
77
|
-
*/
|
|
78
|
-
export declare function isHtmlRenderer(renderer: CustomWidgetRenderer): renderer is CustomWidgetHtmlRenderer;
|
|
79
|
-
//# sourceMappingURL=custom-widget-renderer.types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"custom-widget-renderer.types.d.ts","sourceRoot":"","sources":["../src/custom-widget-renderer.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,SAAS,EAAE,UAAU,CAAC;IAEtB;;OAEG;IACH,MAAM,EAAE,UAAU,CAAC;IAEnB;;OAEG;IACH,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,MAAM,EAAE,UAAU,CAAC;IAEnB;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/D;AAED;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE,UAAU,KAAK,MAAM,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC5B,wBAAwB,GACxB,IAAI,CAAC,qBAAqB,CAAC,GAC3B,WAAW,CAAC,qBAAqB,CAAC,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,oBAAoB,CAAC;CAChC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,oBAAoB,GAC7B,QAAQ,IAAI,WAAW,CAAC,qBAAqB,CAAC,CAMhD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,oBAAoB,GAC7B,QAAQ,IAAI,IAAI,CAAC,qBAAqB,CAAC,CAazC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,oBAAoB,GAC7B,QAAQ,IAAI,wBAAwB,CAEtC"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type guard to check if a renderer is a TemplateRef
|
|
3
|
-
*/
|
|
4
|
-
export function isTemplateRenderer(renderer) {
|
|
5
|
-
return (renderer !== null &&
|
|
6
|
-
typeof renderer === 'object' &&
|
|
7
|
-
'createEmbeddedView' in renderer);
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Type guard to check if a renderer is an Angular Component
|
|
11
|
-
*
|
|
12
|
-
* Note: This uses a heuristic check based on the following assumptions:
|
|
13
|
-
* 1. Components are constructor functions
|
|
14
|
-
* 2. Components have a prototype with a constructor property
|
|
15
|
-
* 3. Components typically use dependency injection (no required constructor params)
|
|
16
|
-
*
|
|
17
|
-
* Limitation: This may not detect components with required constructor parameters.
|
|
18
|
-
* For edge cases, explicitly check your component's constructor signature.
|
|
19
|
-
*
|
|
20
|
-
* Alternative: You can always register a wrapper component that has no required params.
|
|
21
|
-
*/
|
|
22
|
-
export function isComponentRenderer(renderer) {
|
|
23
|
-
// Check if it's a function (constructor) but not a regular function renderer
|
|
24
|
-
if (typeof renderer !== 'function') {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
// Check for Angular component characteristics
|
|
28
|
-
// Components typically have prototype with constructor property
|
|
29
|
-
return (renderer.prototype !== undefined &&
|
|
30
|
-
renderer.prototype.constructor === renderer &&
|
|
31
|
-
renderer.length === 0 // Constructor with no required params (Angular DI)
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Type guard to check if a renderer is an HTML function
|
|
36
|
-
*
|
|
37
|
-
* Note: This should be checked AFTER checking for component and template renderers
|
|
38
|
-
* since components are also functions but with additional properties.
|
|
39
|
-
*/
|
|
40
|
-
export function isHtmlRenderer(renderer) {
|
|
41
|
-
return typeof renderer === 'function';
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=custom-widget-renderer.types.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"custom-widget-renderer.types.js","sourceRoot":"","sources":["../src/custom-widget-renderer.types.ts"],"names":[],"mappings":"AAkEA;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAA8B;IAE9B,OAAO,CACL,QAAQ,KAAK,IAAI;QACjB,OAAO,QAAQ,KAAK,QAAQ;QAC5B,oBAAoB,IAAI,QAAQ,CACjC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAA8B;IAE9B,6EAA6E;IAC7E,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,8CAA8C;IAC9C,gEAAgE;IAChE,OAAO,CACL,QAAQ,CAAC,SAAS,KAAK,SAAS;QAChC,QAAQ,CAAC,SAAS,CAAC,WAAW,KAAK,QAAQ;QAC3C,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,mDAAmD;KAC1E,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,QAA8B;IAE9B,OAAO,OAAO,QAAQ,KAAK,UAAU,CAAC;AACxC,CAAC"}
|