igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
222 lines (218 loc) • 13.1 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, ViewContainerRef, signal, computed, input, output, effect, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, Directive } from '@angular/core';
import { IgcChatComponent } from 'igniteui-webcomponents';
/**
* Angular wrapper component for the Ignite UI Web Components Chat component.
*
* This component provides an Angular-friendly interface to the igc-chat web component,
* including support for Angular templates, signals, and change detection.
*
* Uses OnPush change detection strategy for optimal performance. All inputs are signals,
* so changes are automatically tracked and propagated to the underlying web component.
*
* @example
* ```typescript
* <igx-chat
* [messages]="messages"
* [draftMessage]="draft"
* [options]="chatOptions"
* [templates]="chatTemplates"
* (messageCreated)="onMessageCreated($event)"
* />
* ```
*/
class IgxChatComponent {
//#endregion
/** @internal */
ngOnInit() {
IgcChatComponent.register();
}
/** @internal */
ngOnDestroy() {
for (const viewSet of this._templateViewRefs.values()) {
viewSet.forEach(viewRef => viewRef.destroy());
}
this._templateViewRefs.clear();
}
constructor() {
//#region Internal state
this._view = inject(ViewContainerRef);
this._templateViewRefs = new Map();
this._oldTemplates = {};
this._transformedTemplates = signal({}, { ...(ngDevMode ? { debugName: "_transformedTemplates" } : {}) });
this._mergedOptions = computed(() => {
const options = this.options();
const transformedTemplates = this._transformedTemplates();
return {
...options,
renderers: transformedTemplates
};
}, { ...(ngDevMode ? { debugName: "_mergedOptions" } : {}) });
//#endregion
//#region Inputs
/** Array of chat messages to display */
this.messages = input([], { ...(ngDevMode ? { debugName: "messages" } : {}) });
/** Draft message with text and optional attachments */
this.draftMessage = input({ text: '' }, { ...(ngDevMode ? { debugName: "draftMessage" } : {}) });
/** Configuration options for the chat component */
this.options = input({}, { ...(ngDevMode ? { debugName: "options" } : {}) });
/** Custom templates for rendering chat elements */
this.templates = input({}, { ...(ngDevMode ? { debugName: "templates" } : {}) });
//#endregion
//#region Outputs
/** Emitted when a new message is created */
this.messageCreated = output();
/** Emitted when a user reacts to a message */
this.messageReact = output();
/** Emitted when an attachment is clicked */
this.attachmentClick = output();
/** Emitted when attachment drag starts */
this.attachmentDrag = output();
/** Emitted when attachment is dropped */
this.attachmentDrop = output();
/** Emitted when typing indicator state changes */
this.typingChange = output();
/** Emitted when the input receives focus */
this.inputFocus = output();
/** Emitted when the input loses focus */
this.inputBlur = output();
/** Emitted when the input value changes */
this.inputChange = output();
// Templates changed - update transformed templates and viewRefs
effect(() => {
const templates = this.templates();
this._setTemplates(templates ?? {});
});
}
_setTemplates(newTemplates) {
const templateCopies = {};
const newTemplateKeys = Object.keys(newTemplates);
const oldTemplates = this._oldTemplates;
const oldTemplateKeys = Object.keys(oldTemplates);
for (const key of oldTemplateKeys) {
const oldRef = oldTemplates[key];
const newRef = newTemplates[key];
if (oldRef && oldRef !== newRef) {
const obsolete = this._templateViewRefs.get(oldRef);
if (obsolete) {
obsolete.forEach(viewRef => viewRef.destroy());
this._templateViewRefs.delete(oldRef);
}
}
}
this._oldTemplates = {};
for (const key of newTemplateKeys) {
const ref = newTemplates[key];
if (ref) {
this._oldTemplates[key] = ref;
templateCopies[key] = this._createTemplateRenderer(ref);
}
}
this._transformedTemplates.set(templateCopies);
}
_createTemplateRenderer(ref) {
if (!this._templateViewRefs.has(ref)) {
this._templateViewRefs.set(ref, new Set());
}
const viewSet = this._templateViewRefs.get(ref);
return (ctx) => {
const context = ctx;
let angularContext;
if ('message' in context && 'attachment' in context) {
angularContext = { $implicit: context.attachment };
}
else if ('message' in context) {
angularContext = { $implicit: context.message };
}
else if ('value' in context) {
angularContext = {
$implicit: context.value,
attachments: context.attachments
};
}
else {
angularContext = { $implicit: { instance: context.instance } };
}
const viewRef = this._view.createEmbeddedView(ref, angularContext);
viewSet.add(viewRef);
return viewRef.rootNodes;
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.2", type: IgxChatComponent, isStandalone: true, selector: "igx-chat", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: false, transformFunction: null }, draftMessage: { classPropertyName: "draftMessage", publicName: "draftMessage", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, templates: { classPropertyName: "templates", publicName: "templates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { messageCreated: "messageCreated", messageReact: "messageReact", attachmentClick: "attachmentClick", attachmentDrag: "attachmentDrag", attachmentDrop: "attachmentDrop", typingChange: "typingChange", inputFocus: "inputFocus", inputBlur: "inputBlur", inputChange: "inputChange" }, ngImport: i0, template: "<igc-chat\n [messages]=\"messages()\"\n [draftMessage]=\"draftMessage()\"\n [options]=\"_mergedOptions()\"\n (igcMessageCreated)=\"messageCreated.emit($event.detail)\"\n (igcMessageReact)=\"messageReact.emit($event.detail)\"\n (igcAttachmentClick)=\"attachmentClick.emit($event.detail)\"\n (igcAttachmentDrag)=\"attachmentDrag.emit()\"\n (igcAttachmentDrop)=\"attachmentDrop.emit()\"\n (igcTypingChange)=\"typingChange.emit($event.detail)\"\n (igcInputFocus)=\"inputFocus.emit()\"\n (igcInputBlur)=\"inputBlur.emit()\"\n (igcInputChange)=\"inputChange.emit($event.detail)\"\n>\n <ng-content></ng-content>\n</igc-chat>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChatComponent, decorators: [{
type: Component,
args: [{ selector: 'igx-chat', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, schemas: [CUSTOM_ELEMENTS_SCHEMA], template: "<igc-chat\n [messages]=\"messages()\"\n [draftMessage]=\"draftMessage()\"\n [options]=\"_mergedOptions()\"\n (igcMessageCreated)=\"messageCreated.emit($event.detail)\"\n (igcMessageReact)=\"messageReact.emit($event.detail)\"\n (igcAttachmentClick)=\"attachmentClick.emit($event.detail)\"\n (igcAttachmentDrag)=\"attachmentDrag.emit()\"\n (igcAttachmentDrop)=\"attachmentDrop.emit()\"\n (igcTypingChange)=\"typingChange.emit($event.detail)\"\n (igcInputFocus)=\"inputFocus.emit()\"\n (igcInputBlur)=\"inputBlur.emit()\"\n (igcInputChange)=\"inputChange.emit($event.detail)\"\n>\n <ng-content></ng-content>\n</igc-chat>\n" }]
}], ctorParameters: () => [], propDecorators: { messages: [{ type: i0.Input, args: [{ isSignal: true, alias: "messages", required: false }] }], draftMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "draftMessage", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], templates: [{ type: i0.Input, args: [{ isSignal: true, alias: "templates", required: false }] }], messageCreated: [{ type: i0.Output, args: ["messageCreated"] }], messageReact: [{ type: i0.Output, args: ["messageReact"] }], attachmentClick: [{ type: i0.Output, args: ["attachmentClick"] }], attachmentDrag: [{ type: i0.Output, args: ["attachmentDrag"] }], attachmentDrop: [{ type: i0.Output, args: ["attachmentDrop"] }], typingChange: [{ type: i0.Output, args: ["typingChange"] }], inputFocus: [{ type: i0.Output, args: ["inputFocus"] }], inputBlur: [{ type: i0.Output, args: ["inputBlur"] }], inputChange: [{ type: i0.Output, args: ["inputChange"] }] } });
/**
* Directive providing type information for chat message template contexts.
* Use this directive on ng-template elements that render chat messages.
*
* @example
* ```html
* <ng-template igxChatMessageContext let-message>
* <div>{{ message.text }}</div>
* </ng-template>
* ```
*/
class IgxChatMessageContextDirective {
static ngTemplateContextGuard(_, ctx) {
return true;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChatMessageContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxChatMessageContextDirective, isStandalone: true, selector: "[igxChatMessageContext]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChatMessageContextDirective, decorators: [{
type: Directive,
args: [{ selector: '[igxChatMessageContext]', standalone: true }]
}] });
/**
* Directive providing type information for chat attachment template contexts.
* Use this directive on ng-template elements that render message attachments.
*
* @example
* ```html
* <ng-template igxChatAttachmentContext let-attachment>
* <img [src]="attachment.url" />
* </ng-template>
* ```
*/
class IgxChatAttachmentContextDirective {
static ngTemplateContextGuard(_, ctx) {
return true;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChatAttachmentContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxChatAttachmentContextDirective, isStandalone: true, selector: "[igxChatAttachmentContext]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChatAttachmentContextDirective, decorators: [{
type: Directive,
args: [{ selector: '[igxChatAttachmentContext]', standalone: true }]
}] });
/**
* Directive providing type information for chat input template contexts.
* Use this directive on ng-template elements that render the chat input.
*
* @example
* ```html
* <ng-template igxChatInputContext let-value let-attachments="attachments">
* <input [value]="value" />
* </ng-template>
* ```
*/
class IgxChatInputContextDirective {
static ngTemplateContextGuard(_, ctx) {
return true;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChatInputContextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxChatInputContextDirective, isStandalone: true, selector: "[igxChatInputContext]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxChatInputContextDirective, decorators: [{
type: Directive,
args: [{ selector: '[igxChatInputContext]', standalone: true }]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { IgxChatAttachmentContextDirective, IgxChatComponent, IgxChatInputContextDirective, IgxChatMessageContextDirective };
//# sourceMappingURL=igniteui-angular-chat.mjs.map