UNPKG

igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

1 lines • 16.5 kB
{"version":3,"file":"igniteui-angular-chat.mjs","sources":["../../../projects/igniteui-angular/chat/src/chat.component.ts","../../../projects/igniteui-angular/chat/src/chat.component.html","../../../projects/igniteui-angular/chat/src/igniteui-angular-chat.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n CUSTOM_ELEMENTS_SCHEMA,\n Directive,\n effect,\n inject,\n input,\n OnInit,\n output,\n signal,\n TemplateRef,\n ViewContainerRef,\n OnDestroy,\n ViewRef,\n computed,\n} from '@angular/core';\nimport {\n IgcChatComponent,\n type IgcChatMessageAttachment,\n type IgcChatMessage,\n type IgcChatOptions,\n type ChatRenderContext,\n type ChatRenderers,\n type ChatAttachmentRenderContext,\n type ChatInputRenderContext,\n type ChatMessageRenderContext,\n type IgcChatMessageReaction,\n} from 'igniteui-webcomponents';\n\ntype ChatContextUnion =\n | ChatAttachmentRenderContext\n | ChatMessageRenderContext\n | ChatInputRenderContext\n | ChatRenderContext;\n\ntype ChatContextType<T extends ChatContextUnion> =\n T extends ChatAttachmentRenderContext\n ? IgcChatMessageAttachment\n : T extends ChatMessageRenderContext\n ? IgcChatMessage\n : T extends ChatInputRenderContext\n ? string\n : T extends ChatRenderContext\n ? { instance: IgcChatComponent }\n : never;\n\ntype ExtractChatContext<T> = T extends (ctx: infer R) => any ? R : never;\n\ntype ChatTemplatesContextMap = {\n [K in keyof ChatRenderers]: {\n $implicit: ChatContextType<\n ExtractChatContext<NonNullable<ChatRenderers[K]>> & ChatContextUnion\n >;\n };\n};\n\n/**\n * Template references for customizing chat component rendering.\n * Each property corresponds to a specific part of the chat UI that can be customized.\n *\n * @example\n * ```typescript\n * templates = {\n * messageContent: this.customMessageTemplate,\n * attachment: this.customAttachmentTemplate\n * }\n * ```\n */\nexport type IgxChatTemplates = {\n [K in keyof Omit<ChatRenderers, 'typingIndicator'>]?: TemplateRef<ChatTemplatesContextMap[K]>;\n};\n\n/**\n * Configuration options for the chat component.\n */\nexport type IgxChatOptions = Omit<IgcChatOptions, 'renderers'>;\n\n\n/**\n * Angular wrapper component for the Ignite UI Web Components Chat component.\n *\n * This component provides an Angular-friendly interface to the igc-chat web component,\n * including support for Angular templates, signals, and change detection.\n *\n * Uses OnPush change detection strategy for optimal performance. All inputs are signals,\n * so changes are automatically tracked and propagated to the underlying web component.\n *\n * @example\n * ```typescript\n * <igx-chat\n * [messages]=\"messages\"\n * [draftMessage]=\"draft\"\n * [options]=\"chatOptions\"\n * [templates]=\"chatTemplates\"\n * (messageCreated)=\"onMessageCreated($event)\"\n * />\n * ```\n */\n@Component({\n selector: 'igx-chat',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n templateUrl: './chat.component.html'\n})\nexport class IgxChatComponent implements OnInit, OnDestroy {\n //#region Internal state\n\n private readonly _view = inject(ViewContainerRef);\n private readonly _templateViewRefs = new Map<TemplateRef<any>, Set<ViewRef>>();\n private _oldTemplates: IgxChatTemplates = {};\n\n protected readonly _transformedTemplates = signal<ChatRenderers>({});\n\n protected readonly _mergedOptions = computed<IgcChatOptions>(() => {\n const options = this.options();\n const transformedTemplates = this._transformedTemplates();\n return {\n ...options,\n renderers: transformedTemplates\n };\n });\n\n //#endregion\n\n //#region Inputs\n\n /** Array of chat messages to display */\n public readonly messages = input<IgcChatMessage[]>([]);\n\n /** Draft message with text and optional attachments */\n public readonly draftMessage = input<\n { text: string; attachments?: IgcChatMessageAttachment[] } | undefined\n >({ text: '' });\n\n /** Configuration options for the chat component */\n public readonly options = input<IgxChatOptions>({});\n\n /** Custom templates for rendering chat elements */\n public readonly templates = input<IgxChatTemplates>({});\n\n //#endregion\n\n //#region Outputs\n\n /** Emitted when a new message is created */\n public readonly messageCreated = output<IgcChatMessage>();\n\n /** Emitted when a user reacts to a message */\n public readonly messageReact = output<IgcChatMessageReaction>();\n\n /** Emitted when an attachment is clicked */\n public readonly attachmentClick = output<IgcChatMessageAttachment>();\n\n /** Emitted when attachment drag starts */\n public readonly attachmentDrag = output<void>();\n\n /** Emitted when attachment is dropped */\n public readonly attachmentDrop = output<void>();\n\n /** Emitted when typing indicator state changes */\n public readonly typingChange = output<boolean>();\n\n /** Emitted when the input receives focus */\n public readonly inputFocus = output<void>();\n\n /** Emitted when the input loses focus */\n public readonly inputBlur = output<void>();\n\n /** Emitted when the input value changes */\n public readonly inputChange = output<string>();\n\n //#endregion\n\n /** @internal */\n public ngOnInit(): void {\n IgcChatComponent.register();\n }\n\n /** @internal */\n public ngOnDestroy(): void {\n for (const viewSet of this._templateViewRefs.values()) {\n viewSet.forEach(viewRef => viewRef.destroy());\n }\n this._templateViewRefs.clear();\n }\n\n constructor() {\n // Templates changed - update transformed templates and viewRefs\n effect(() => {\n const templates = this.templates();\n this._setTemplates(templates ?? {});\n });\n }\n\n private _setTemplates(newTemplates: IgxChatTemplates): void {\n const templateCopies: ChatRenderers = {};\n const newTemplateKeys = Object.keys(newTemplates) as Array<keyof IgxChatTemplates>;\n\n const oldTemplates = this._oldTemplates;\n const oldTemplateKeys = Object.keys(oldTemplates) as Array<keyof IgxChatTemplates>;\n\n for (const key of oldTemplateKeys) {\n const oldRef = oldTemplates[key];\n const newRef = newTemplates[key];\n\n if (oldRef && oldRef !== newRef) {\n const obsolete = this._templateViewRefs.get(oldRef);\n if (obsolete) {\n obsolete.forEach(viewRef => viewRef.destroy());\n this._templateViewRefs.delete(oldRef);\n }\n }\n }\n\n this._oldTemplates = {};\n\n for (const key of newTemplateKeys) {\n const ref = newTemplates[key];\n if (ref) {\n (this._oldTemplates as Record<string, TemplateRef<unknown>>)[key] = ref;\n templateCopies[key] = this._createTemplateRenderer(ref);\n }\n }\n\n this._transformedTemplates.set(templateCopies);\n }\n\n private _createTemplateRenderer<K extends keyof IgxChatTemplates>(ref: NonNullable<IgxChatTemplates[K]>) {\n type ChatContext = ExtractChatContext<NonNullable<ChatRenderers[K]>>;\n\n if (!this._templateViewRefs.has(ref)) {\n this._templateViewRefs.set(ref, new Set<ViewRef>());\n }\n\n const viewSet = this._templateViewRefs.get(ref)!;\n\n return (ctx: ChatContext) => {\n const context = ctx as ChatContextUnion;\n let angularContext: any;\n\n if ('message' in context && 'attachment' in context) {\n angularContext = { $implicit: context.attachment };\n } else if ('message' in context) {\n angularContext = { $implicit: context.message };\n } else if ('value' in context) {\n angularContext = {\n $implicit: context.value,\n attachments: context.attachments\n };\n } else {\n angularContext = { $implicit: { instance: context.instance } };\n }\n\n const viewRef = this._view.createEmbeddedView(ref, angularContext);\n viewSet.add(viewRef);\n\n return viewRef.rootNodes;\n }\n }\n}\n\n/**\n * Context provided to the chat input template.\n */\nexport interface ChatInputContext {\n /** The current input value */\n $implicit: string;\n /** Array of attachments associated with the input */\n attachments: IgcChatMessageAttachment[];\n}\n\n/**\n * Directive providing type information for chat message template contexts.\n * Use this directive on ng-template elements that render chat messages.\n *\n * @example\n * ```html\n * <ng-template igxChatMessageContext let-message>\n * <div>{{ message.text }}</div>\n * </ng-template>\n * ```\n */\n@Directive({ selector: '[igxChatMessageContext]', standalone: true })\nexport class IgxChatMessageContextDirective {\n\n public static ngTemplateContextGuard(_: IgxChatMessageContextDirective, ctx: unknown): ctx is { $implicit: IgcChatMessage } {\n return true;\n }\n}\n\n/**\n * Directive providing type information for chat attachment template contexts.\n * Use this directive on ng-template elements that render message attachments.\n *\n * @example\n * ```html\n * <ng-template igxChatAttachmentContext let-attachment>\n * <img [src]=\"attachment.url\" />\n * </ng-template>\n * ```\n */\n@Directive({ selector: '[igxChatAttachmentContext]', standalone: true })\nexport class IgxChatAttachmentContextDirective {\n\n public static ngTemplateContextGuard(_: IgxChatAttachmentContextDirective, ctx: unknown): ctx is { $implicit: IgcChatMessageAttachment } {\n return true;\n }\n}\n\n/**\n * Directive providing type information for chat input template contexts.\n * Use this directive on ng-template elements that render the chat input.\n *\n * @example\n * ```html\n * <ng-template igxChatInputContext let-value let-attachments=\"attachments\">\n * <input [value]=\"value\" />\n * </ng-template>\n * ```\n */\n@Directive({ selector: '[igxChatInputContext]', standalone: true })\nexport class IgxChatInputContextDirective {\n\n public static ngTemplateContextGuard(_: IgxChatInputContextDirective, ctx: unknown): ctx is ChatInputContext {\n return true;\n }\n}\n","<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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}