UNPKG

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
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