@progress/kendo-angular-conversational-ui
Version:
Kendo UI for Angular Conversational UI components
314 lines (299 loc) • 13.8 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* Copyright © 2025 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the project root for more information
*-------------------------------------------------------------------------------------------*/
import { Component, ContentChild, ElementRef, EventEmitter, HostBinding, Input, isDevMode, Output, ViewChild, NgZone } from '@angular/core';
import { AttachmentTemplateDirective } from './attachment-template.directive';
import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
import { makeHandler } from './builtin-actions';
import { MessageTemplateDirective } from './message-template.directive';
import { validatePackage } from '@progress/kendo-licensing';
import { packageMetadata } from '../package-metadata';
import { ChatMessageBoxTemplateDirective } from './message-box.directive';
import { MessageBoxComponent } from './message-box.component';
import { MessageListComponent } from './message-list.component';
import { ScrollAnchorDirective } from './common/scroll-anchor.directive';
import { LocalizedMessagesDirective } from './l10n/localized-messages.directive';
import * as i0 from "@angular/core";
import * as i1 from "@progress/kendo-angular-l10n";
/**
* Represents the [Kendo UI Chat component for Angular](slug:overview_convui).
*
* Provides a conversational UI for chat-based applications.
* Supports message templates, attachments, localization, and user actions.
*
* @example
* ```html
* <kendo-chat
* [messages]="messages"
* [user]="user"
* (sendMessage)="onSendMessage($event)"
* (executeAction)="onExecuteAction($event)">
* </kendo-chat>
* ```
*
* @remarks
* Supported children components are: {@link CustomMessagesComponent}, {@link HeroCardComponent}.
*/
export class ChatComponent {
localization;
zone;
/**
* Defines the array of messages displayed in the Chat.
* Each message can include a timestamp for unique identification.
* For more information, refer to [ngFor - Change Tracking](link:site.data.urls.angular['ngforof']#change-propagation).
*/
messages;
/**
* Specifies the [`User`](slug:api_conversational-ui_user) instance representing the local user.
* The User ID is used to distinguish messages authored by the local user.
*/
user;
/**
* Determines the type of input used in the message box.
* Can be set to `textbox` for a single-line input or `textarea` for multi-line input
* ([see example](slug:message_box#message-box-types)).
* @default 'textbox'
*/
messageBoxType = 'textbox';
/**
* Emits when the user sends a message by clicking the **Send** button or pressing **Enter**.
*
* > The message is not automatically added to the `messages` array.
*/
sendMessage = new EventEmitter();
/**
* Emits when the user clicks a quick action button.
* The Chat internally handles [known actions](slug:api_conversational-ui_actiontype) such as `reply`, `openUrl`, and `call`.
*
* The event is preventable—calling `preventDefault` suppresses the built-in action.
*/
executeAction = new EventEmitter();
get className() {
return 'k-chat';
}
get dirAttr() {
return this.direction;
}
attachmentTemplate;
messageTemplate;
messageBoxTemplate;
messageBox;
/**
* @hidden
*/
messageList;
/**
* @hidden
*/
get localizationText() {
return this.localization;
}
/**
* @hidden
*/
autoScroll = true;
direction;
localizationChangeSubscription;
constructor(localization, zone) {
this.localization = localization;
this.zone = zone;
validatePackage(packageMetadata);
this.direction = localization.rtl ? 'rtl' : 'ltr';
this.localizationChangeSubscription = localization.changes.subscribe(({ rtl }) => {
this.direction = rtl ? 'rtl' : 'ltr';
});
}
ngOnChanges() {
this.zone.runOutsideAngular(() => setTimeout(() => {
this.messageList.nativeElement.style.flex = '1 1 auto';
}));
}
ngAfterViewInit() {
if (!isDevMode()) {
return;
}
if (!this.user) {
throw new Error('User must be set and have a valid id.');
}
}
ngOnDestroy() {
if (this.localizationChangeSubscription) {
this.localizationChangeSubscription.unsubscribe();
}
}
/**
* @hidden
*/
dispatchAction(e) {
this.executeAction.emit(e);
if (!e.isDefaultPrevented()) {
const handler = makeHandler(e.action);
handler(e.action, this);
if (!this.messageBoxTemplate) {
this.messageBox.messageBoxInput.focus();
}
}
}
/**
* @hidden
*/
textFor(key) {
return this.localization.get(key);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChatComponent, deps: [{ token: i1.LocalizationService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", user: "user", messageBoxType: "messageBoxType" }, outputs: { sendMessage: "sendMessage", executeAction: "executeAction" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.chat'
}
], queries: [{ propertyName: "attachmentTemplate", first: true, predicate: AttachmentTemplateDirective, descendants: true }, { propertyName: "messageTemplate", first: true, predicate: MessageTemplateDirective, descendants: true }, { propertyName: "messageBoxTemplate", first: true, predicate: ChatMessageBoxTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "messageBox", first: true, predicate: ["messageBox"], descendants: true }, { propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `
<ng-container kendoChatLocalizedMessages
i18n-messagePlaceholder="kendo.chat.messagePlaceholder|The placholder text of the message text input"
messagePlaceholder="Type a message..."
i18n-send="kendo.chat.send|The text for the Send button"
send="Send..."
i18n-messageListLabel="kendo.chat.messageListLabel|The label text for the Message list"
messageListLabel="Message list"
i18n-messageBoxInputLabel="kendo.chat.messageBoxInputLabel|The label text for the Message input box"
messageBoxInputLabel="Message"
i18n-messageAttachmentLeftArrow="kendo.chat.messageAttachmentLeftArrow|The text for the left arrow of the message attachments"
messageAttachmentLeftArrow="Previous item"
i18n-messageAttachmentRightArrow="kendo.chat.messageAttachmentRightArrow|The text for the right arrow of the message attachments"
messageAttachmentRightArrow="Next item"
i18n-messageAvatarAlt="kendo.chat.messageAvatarAlt|The alt attribute text for the avatar"
messageAvatarAlt="Avatar"
>
</ng-container>
<div
#messageList
class="k-message-list k-avatars"
aria-live="polite"
role="log"
kendoChatScrollAnchor
[attr.aria-label]="textFor('messageListLabel')"
#anchor="scrollAnchor"
[(autoScroll)]="autoScroll"
>
<kendo-chat-message-list
[messages]="messages"
[messageTemplate]="messageTemplate"
[localization]="localizationText"
[attachmentTemplate]="attachmentTemplate"
[user]="user"
(executeAction)="dispatchAction($event)"
(resize)="anchor.scrollToBottom()"
(navigate)="this.autoScroll = false"
>
</kendo-chat-message-list>
</div>
<kendo-message-box
#messageBox
[messageBoxTemplate]="messageBoxTemplate"
[type]="messageBoxType"
[user]="user"
[autoScroll]="autoScroll"
[localization]="localizationText"
(sendMessage)="sendMessage.emit($event)"
>
</kendo-message-box>
`, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoChatLocalizedMessages]" }, { kind: "directive", type: ScrollAnchorDirective, selector: "[kendoChatScrollAnchor]", inputs: ["autoScroll"], outputs: ["autoScrollChange"], exportAs: ["scrollAnchor"] }, { kind: "component", type: MessageListComponent, selector: "kendo-chat-message-list", inputs: ["messages", "attachmentTemplate", "messageTemplate", "localization", "user"], outputs: ["executeAction", "navigate", "resize"] }, { kind: "component", type: MessageBoxComponent, selector: "kendo-message-box", inputs: ["user", "autoScroll", "type", "localization", "messageBoxTemplate"], outputs: ["sendMessage"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ChatComponent, decorators: [{
type: Component,
args: [{
providers: [
LocalizationService,
{
provide: L10N_PREFIX,
useValue: 'kendo.chat'
}
],
selector: 'kendo-chat',
template: `
<ng-container kendoChatLocalizedMessages
i18n-messagePlaceholder="kendo.chat.messagePlaceholder|The placholder text of the message text input"
messagePlaceholder="Type a message..."
i18n-send="kendo.chat.send|The text for the Send button"
send="Send..."
i18n-messageListLabel="kendo.chat.messageListLabel|The label text for the Message list"
messageListLabel="Message list"
i18n-messageBoxInputLabel="kendo.chat.messageBoxInputLabel|The label text for the Message input box"
messageBoxInputLabel="Message"
i18n-messageAttachmentLeftArrow="kendo.chat.messageAttachmentLeftArrow|The text for the left arrow of the message attachments"
messageAttachmentLeftArrow="Previous item"
i18n-messageAttachmentRightArrow="kendo.chat.messageAttachmentRightArrow|The text for the right arrow of the message attachments"
messageAttachmentRightArrow="Next item"
i18n-messageAvatarAlt="kendo.chat.messageAvatarAlt|The alt attribute text for the avatar"
messageAvatarAlt="Avatar"
>
</ng-container>
<div
#messageList
class="k-message-list k-avatars"
aria-live="polite"
role="log"
kendoChatScrollAnchor
[attr.aria-label]="textFor('messageListLabel')"
#anchor="scrollAnchor"
[(autoScroll)]="autoScroll"
>
<kendo-chat-message-list
[messages]="messages"
[messageTemplate]="messageTemplate"
[localization]="localizationText"
[attachmentTemplate]="attachmentTemplate"
[user]="user"
(executeAction)="dispatchAction($event)"
(resize)="anchor.scrollToBottom()"
(navigate)="this.autoScroll = false"
>
</kendo-chat-message-list>
</div>
<kendo-message-box
#messageBox
[messageBoxTemplate]="messageBoxTemplate"
[type]="messageBoxType"
[user]="user"
[autoScroll]="autoScroll"
[localization]="localizationText"
(sendMessage)="sendMessage.emit($event)"
>
</kendo-message-box>
`,
standalone: true,
imports: [LocalizedMessagesDirective, ScrollAnchorDirective, MessageListComponent, MessageBoxComponent]
}]
}], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i0.NgZone }]; }, propDecorators: { messages: [{
type: Input
}], user: [{
type: Input
}], messageBoxType: [{
type: Input
}], sendMessage: [{
type: Output
}], executeAction: [{
type: Output
}], className: [{
type: HostBinding,
args: ['class']
}], dirAttr: [{
type: HostBinding,
args: ['attr.dir']
}], attachmentTemplate: [{
type: ContentChild,
args: [AttachmentTemplateDirective, { static: false }]
}], messageTemplate: [{
type: ContentChild,
args: [MessageTemplateDirective, { static: false }]
}], messageBoxTemplate: [{
type: ContentChild,
args: [ChatMessageBoxTemplateDirective, { static: false }]
}], messageBox: [{
type: ViewChild,
args: ['messageBox', { static: false }]
}], messageList: [{
type: ViewChild,
args: ['messageList', { static: true }]
}] } });