@progress/kendo-angular-conversational-ui 21.1.1-develop.2 → 21.2.0-develop.10

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.
Files changed (27) hide show
  1. package/chat/chat.component.d.ts +2 -0
  2. package/chat/message-list.component.d.ts +2 -2
  3. package/codemods/utils.js +805 -394
  4. package/codemods/v20/chat-user.js +9 -12
  5. package/codemods/v21/chat-messagetoolbarvisibility.js +9 -13
  6. package/codemods/v21/chat-pinnedbyfield.js +1 -2
  7. package/esm2022/ai-prompt/aiprompt.component.mjs +155 -139
  8. package/esm2022/ai-prompt/common/output-card.component.mjs +81 -83
  9. package/esm2022/ai-prompt/common/toolbar-focusable.directive.mjs +2 -2
  10. package/esm2022/ai-prompt/views/output-view.component.mjs +27 -29
  11. package/esm2022/ai-prompt/views/prompt-view.component.mjs +150 -135
  12. package/esm2022/chat/attachment.component.mjs +53 -37
  13. package/esm2022/chat/cards/hero-card.component.mjs +48 -35
  14. package/esm2022/chat/chat-file.component.mjs +32 -29
  15. package/esm2022/chat/chat-view.mjs +2 -2
  16. package/esm2022/chat/chat.component.mjs +259 -242
  17. package/esm2022/chat/message-attachments.component.mjs +60 -55
  18. package/esm2022/chat/message-box.component.mjs +203 -183
  19. package/esm2022/chat/message-list.component.mjs +249 -209
  20. package/esm2022/chat/message-reference-content.component.mjs +30 -19
  21. package/esm2022/chat/message.component.mjs +301 -281
  22. package/esm2022/chat/suggested-actions.component.mjs +142 -134
  23. package/esm2022/inline-ai-prompt/inlineaiprompt-content.component.mjs +205 -179
  24. package/esm2022/package-metadata.mjs +2 -2
  25. package/fesm2022/progress-kendo-angular-conversational-ui.mjs +1988 -1777
  26. package/package.json +14 -14
  27. package/codemods/template-transformer/index.js +0 -93
@@ -7,9 +7,9 @@ import { InjectionToken, Directive, Inject, HostBinding, ViewChild, Input, Injec
7
7
  import { IconWrapperComponent, IconsService } from '@progress/kendo-angular-icons';
8
8
  import * as i1$2 from '@progress/kendo-angular-popup';
9
9
  import { PopupComponent, KENDO_POPUP, PopupService } from '@progress/kendo-angular-popup';
10
- import { isPresent, normalizeNumpadKeys, Keys, focusableSelector, guid, getter, isDocumentAvailable, closest as closest$1, ResizeSensorComponent, isChanged, processCssValue, ResizeBatchService } from '@progress/kendo-angular-common';
10
+ import { isPresent, normalizeKeys, Keys, focusableSelector, guid, getter, isDocumentAvailable, closest as closest$1, ResizeSensorComponent, isChanged, processCssValue, ResizeBatchService } from '@progress/kendo-angular-common';
11
11
  import { DialogContainerService, DialogService, WindowService, WindowContainerService } from '@progress/kendo-angular-dialog';
12
- import { NgFor, NgIf, NgTemplateOutlet, NgClass, NgSwitch, NgSwitchCase } from '@angular/common';
12
+ import { NgTemplateOutlet, NgClass } from '@angular/common';
13
13
  import { Subject, Subscription, fromEvent } from 'rxjs';
14
14
  import { sparklesIcon, commentIcon, moreHorizontalIcon, stopSmIcon, thumbUpIcon, thumbDownOutlineIcon, thumbDownIcon, thumbUpOutlineIcon, copyIcon, arrowRotateCwIcon, chevronUpIcon, chevronDownIcon, paperPlaneIcon, undoIcon, downloadIcon, chevronLeftIcon, chevronRightIcon, xIcon, moreVerticalIcon, paperclipIcon, fileIcon, pinIcon, cancelOutlineIcon, menuIcon } from '@progress/kendo-svg-icons';
15
15
  import * as i1 from '@progress/kendo-angular-l10n';
@@ -216,8 +216,8 @@ const packageMetadata = {
216
216
  productName: 'Kendo UI for Angular',
217
217
  productCode: 'KENDOUIANGULAR',
218
218
  productCodes: ['KENDOUIANGULAR'],
219
- publishDate: 1763729170,
220
- version: '21.1.1-develop.2',
219
+ publishDate: 1764593013,
220
+ version: '21.2.0-develop.10',
221
221
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
222
222
  };
223
223
 
@@ -404,7 +404,7 @@ class AIPromptToolbarFocusableDirective {
404
404
  this.element.focus();
405
405
  }
406
406
  keyDownHandler = (e) => {
407
- const code = normalizeNumpadKeys(e);
407
+ const code = normalizeKeys(e);
408
408
  const targetsSelf = e.target === this.element;
409
409
  const isLeftArrow = code === Keys.ArrowLeft;
410
410
  const isRightArrow = code === Keys.ArrowRight;
@@ -872,7 +872,7 @@ class AIPromptComponent {
872
872
  this.promptRequest.emit(eventArgs);
873
873
  }
874
874
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AIPromptComponent, deps: [{ token: i1.LocalizationService }, { token: AIPromptService }, { token: ToolbarNavigationService }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
875
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AIPromptComponent, isStandalone: true, selector: "kendo-aiprompt", inputs: { activeView: "activeView", promptCommands: "promptCommands", promptSuggestions: "promptSuggestions", promptOutputs: "promptOutputs", showOutputRating: "showOutputRating", streaming: "streaming", speechToTextButton: "speechToTextButton", textAreaSettings: "textAreaSettings", generateButtonSVGIcon: "generateButtonSVGIcon", generateButtonIcon: "generateButtonIcon", disabledGenerateButton: "disabledGenerateButton" }, outputs: { activeViewChange: "activeViewChange", promptRequest: "promptRequest", commandExecute: "commandExecute", outputCopy: "outputCopy", outputRatingChange: "outputRatingChange", promptRequestCancel: "promptRequestCancel" }, host: { properties: { "class.k-prompt": "this.hostClasses", "attr.dir": "this.dirAttr" } }, providers: [
875
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AIPromptComponent, isStandalone: true, selector: "kendo-aiprompt", inputs: { activeView: "activeView", promptCommands: "promptCommands", promptSuggestions: "promptSuggestions", promptOutputs: "promptOutputs", showOutputRating: "showOutputRating", streaming: "streaming", speechToTextButton: "speechToTextButton", textAreaSettings: "textAreaSettings", generateButtonSVGIcon: "generateButtonSVGIcon", generateButtonIcon: "generateButtonIcon", disabledGenerateButton: "disabledGenerateButton" }, outputs: { activeViewChange: "activeViewChange", promptRequest: "promptRequest", commandExecute: "commandExecute", outputCopy: "outputCopy", outputRatingChange: "outputRatingChange", promptRequestCancel: "promptRequestCancel" }, host: { properties: { "class.k-prompt": "this.hostClasses", "attr.dir": "this.dirAttr" } }, providers: [
876
876
  LocalizationService,
877
877
  AIPromptService,
878
878
  ToolbarNavigationService,
@@ -882,82 +882,90 @@ class AIPromptComponent {
882
882
  }
883
883
  ], queries: [{ propertyName: "toolbarActionsTemplate", first: true, predicate: AIPromptToolbarActionsDirective, descendants: true }, { propertyName: "outputTemplate", first: true, predicate: AIPromptOutputTemplateDirective, descendants: true }, { propertyName: "outputBodyTemplate", first: true, predicate: AIPromptOutputBodyTemplateDirective, descendants: true }, { propertyName: "views", predicate: BaseView }], viewQueries: [{ propertyName: "fabButton", first: true, predicate: ["fabButton"], descendants: true }], exportAs: ["kendoAIPrompt"], usesOnChanges: true, ngImport: i0, template: `
884
884
  <ng-container kendoAIPromptLocalizedMessages
885
- i18n-promptView="kendo.aiprompt.promptView|The Toolbar button text for the Prompt view."
886
- promptView="Ask AI"
887
- i18n-outputView="kendo.aiprompt.outputView|The Toolbar button text for the Output view."
888
- outputView="Output"
889
- i18n-generateOutput="kendo.aiprompt.generateOutput|The text for the Generate button in the Prompt view."
890
- generateOutput="Generate"
891
- i18n-promptPlaceholder="kendo.aiprompt.promptPlaceholder|The placeholder text for the Prompt View text area."
892
- promptPlaceholder="Ask or generate content with AI"
893
- i18n-copyOutput="kendo.aiprompt.copyOutput|The Copy button text in each Output view card."
894
- copyOutput="Copy"
895
- i18n-retryGeneration="kendo.aiprompt.retryGeneration|The Retry button text in each Output view card."
896
- retryGeneration="Retry"
897
- i18n-outputTitle="kendo.aiprompt.outputTitle|The title of each Output view card."
898
- outputTitle="Generated with AI"
899
- i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card."
900
- outputRetryTitle="Generated with AI"
901
- i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button."
902
- promptSuggestions="Prompt suggestions"
903
- i18n-speechToTextButton="kendo.aiprompt.speechToTextButton|The aria-label for the Speech to Text button."
904
- speechToTextButton="Voice input">
885
+ i18n-promptView="kendo.aiprompt.promptView|The Toolbar button text for the Prompt view."
886
+ promptView="Ask AI"
887
+ i18n-outputView="kendo.aiprompt.outputView|The Toolbar button text for the Output view."
888
+ outputView="Output"
889
+ i18n-generateOutput="kendo.aiprompt.generateOutput|The text for the Generate button in the Prompt view."
890
+ generateOutput="Generate"
891
+ i18n-promptPlaceholder="kendo.aiprompt.promptPlaceholder|The placeholder text for the Prompt View text area."
892
+ promptPlaceholder="Ask or generate content with AI"
893
+ i18n-copyOutput="kendo.aiprompt.copyOutput|The Copy button text in each Output view card."
894
+ copyOutput="Copy"
895
+ i18n-retryGeneration="kendo.aiprompt.retryGeneration|The Retry button text in each Output view card."
896
+ retryGeneration="Retry"
897
+ i18n-outputTitle="kendo.aiprompt.outputTitle|The title of each Output view card."
898
+ outputTitle="Generated with AI"
899
+ i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card."
900
+ outputRetryTitle="Generated with AI"
901
+ i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button."
902
+ promptSuggestions="Prompt suggestions"
903
+ i18n-speechToTextButton="kendo.aiprompt.speechToTextButton|The aria-label for the Speech to Text button."
904
+ speechToTextButton="Voice input">
905
905
  </ng-container>
906
906
  <div class="k-prompt-header">
907
- <div class="k-toolbar-flat k-toolbar k-toolbar-md"
908
- role="toolbar">
909
- <button *ngFor="let view of viewsArray; let idx = index"
910
- kendoButton
911
- kendoAIPromptToolbarFocusable
912
- type="button"
913
- fillMode="flat"
914
- rounded="full"
915
- themeColor="primary"
916
- [svgIcon]="view.svgIcon"
917
- [icon]="view.icon"
918
- [selected]="idx === activeView"
919
- (click)="viewChange(idx)">
920
- {{view.buttonText}}
921
- </button>
922
-
923
- <ng-template *ngIf="toolbarActionsTemplate"
924
- [ngTemplateOutlet]="toolbarActionsTemplate?.templateRef">
925
- </ng-template>
926
- </div>
907
+ <div class="k-toolbar-flat k-toolbar k-toolbar-md"
908
+ role="toolbar">
909
+ @for (view of viewsArray; track view; let idx = $index) {
910
+ <button
911
+ kendoButton
912
+ kendoAIPromptToolbarFocusable
913
+ type="button"
914
+ fillMode="flat"
915
+ rounded="full"
916
+ themeColor="primary"
917
+ [svgIcon]="view.svgIcon"
918
+ [icon]="view.icon"
919
+ [selected]="idx === activeView"
920
+ (click)="viewChange(idx)">
921
+ {{view.buttonText}}
922
+ </button>
923
+ }
924
+
925
+ @if (toolbarActionsTemplate) {
926
+ <ng-template
927
+ [ngTemplateOutlet]="toolbarActionsTemplate?.templateRef">
928
+ </ng-template>
929
+ }
930
+ </div>
927
931
  </div>
928
932
  <div class="k-prompt-content">
929
- <kendo-floatingactionbutton #fabButton *ngIf="streaming && selectedView?.viewType === 'output'"
930
- class="k-prompt-stop-fab"
931
- buttonClass="k-generating k-active"
932
- [positionMode]="fabPositionMode"
933
- [align]="fabAlignment"
934
- [svgIcon]="fabStopGenerationSVGIcon"
935
- icon="stop"
936
- (click)="promptRequestCancel.emit()"
937
- >
933
+ @if (streaming && selectedView?.viewType === 'output') {
934
+ <kendo-floatingactionbutton #fabButton
935
+ class="k-prompt-stop-fab"
936
+ buttonClass="k-generating k-active"
937
+ [positionMode]="fabPositionMode"
938
+ [align]="fabAlignment"
939
+ [svgIcon]="fabStopGenerationSVGIcon"
940
+ icon="stop"
941
+ (click)="promptRequestCancel.emit()"
942
+ >
938
943
  </kendo-floatingactionbutton>
939
- <div class="k-prompt-view">
940
- <ng-container *ngTemplateOutlet="viewTemplate">
941
- </ng-container>
942
- </div>
944
+ }
945
+ <div class="k-prompt-view">
946
+ <ng-container *ngTemplateOutlet="viewTemplate">
947
+ </ng-container>
948
+ </div>
943
949
  </div>
944
- <div class="k-prompt-footer" *ngIf="selectedView?.viewType === 'prompt'">
950
+ @if (selectedView?.viewType === 'prompt') {
951
+ <div class="k-prompt-footer">
945
952
  <div class="k-actions k-actions-start k-actions-horizontal k-prompt-actions">
946
- <button
947
- kendoButton
948
- type="button"
949
- themeColor="primary"
950
- rounded="full"
951
- [attr.title]="messageFor('generateOutput')"
952
- [attr.aria-label]="messageFor('generateOutput')"
953
- [attr.aria-disabled]="disabledGenerateButton"
954
- [svgIcon]="generateButtonSVGIcon"
955
- [icon]="generateButtonIcon"
956
- [disabled]="disabledGenerateButton"
957
- (click)="handleGenerateOutput()">{{messageFor('generateOutput')}}</button>
953
+ <button
954
+ kendoButton
955
+ type="button"
956
+ themeColor="primary"
957
+ rounded="full"
958
+ [attr.title]="messageFor('generateOutput')"
959
+ [attr.aria-label]="messageFor('generateOutput')"
960
+ [attr.aria-disabled]="disabledGenerateButton"
961
+ [svgIcon]="generateButtonSVGIcon"
962
+ [icon]="generateButtonIcon"
963
+ [disabled]="disabledGenerateButton"
964
+ (click)="handleGenerateOutput()">{{messageFor('generateOutput')}}</button>
958
965
  </div>
959
- </div>
960
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective$2, selector: "[kendoAIPromptLocalizedMessages]" }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: AIPromptToolbarFocusableDirective, selector: "[kendoAIPromptToolbarFocusable]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FloatingActionButtonComponent, selector: "kendo-floatingactionbutton", inputs: ["themeColor", "size", "rounded", "disabled", "align", "offset", "positionMode", "icon", "svgIcon", "iconClass", "buttonClass", "dialClass", "text", "dialItemAnimation", "tabIndex", "dialItems"], outputs: ["blur", "focus", "dialItemClick", "open", "close"] }] });
966
+ </div>
967
+ }
968
+ `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective$2, selector: "[kendoAIPromptLocalizedMessages]" }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: AIPromptToolbarFocusableDirective, selector: "[kendoAIPromptToolbarFocusable]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FloatingActionButtonComponent, selector: "kendo-floatingactionbutton", inputs: ["themeColor", "size", "rounded", "disabled", "align", "offset", "positionMode", "icon", "svgIcon", "iconClass", "buttonClass", "dialClass", "text", "dialItemAnimation", "tabIndex", "dialItems"], outputs: ["blur", "focus", "dialItemClick", "open", "close"] }] });
961
969
  }
962
970
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AIPromptComponent, decorators: [{
963
971
  type: Component,
@@ -975,84 +983,92 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
975
983
  ],
976
984
  template: `
977
985
  <ng-container kendoAIPromptLocalizedMessages
978
- i18n-promptView="kendo.aiprompt.promptView|The Toolbar button text for the Prompt view."
979
- promptView="Ask AI"
980
- i18n-outputView="kendo.aiprompt.outputView|The Toolbar button text for the Output view."
981
- outputView="Output"
982
- i18n-generateOutput="kendo.aiprompt.generateOutput|The text for the Generate button in the Prompt view."
983
- generateOutput="Generate"
984
- i18n-promptPlaceholder="kendo.aiprompt.promptPlaceholder|The placeholder text for the Prompt View text area."
985
- promptPlaceholder="Ask or generate content with AI"
986
- i18n-copyOutput="kendo.aiprompt.copyOutput|The Copy button text in each Output view card."
987
- copyOutput="Copy"
988
- i18n-retryGeneration="kendo.aiprompt.retryGeneration|The Retry button text in each Output view card."
989
- retryGeneration="Retry"
990
- i18n-outputTitle="kendo.aiprompt.outputTitle|The title of each Output view card."
991
- outputTitle="Generated with AI"
992
- i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card."
993
- outputRetryTitle="Generated with AI"
994
- i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button."
995
- promptSuggestions="Prompt suggestions"
996
- i18n-speechToTextButton="kendo.aiprompt.speechToTextButton|The aria-label for the Speech to Text button."
997
- speechToTextButton="Voice input">
986
+ i18n-promptView="kendo.aiprompt.promptView|The Toolbar button text for the Prompt view."
987
+ promptView="Ask AI"
988
+ i18n-outputView="kendo.aiprompt.outputView|The Toolbar button text for the Output view."
989
+ outputView="Output"
990
+ i18n-generateOutput="kendo.aiprompt.generateOutput|The text for the Generate button in the Prompt view."
991
+ generateOutput="Generate"
992
+ i18n-promptPlaceholder="kendo.aiprompt.promptPlaceholder|The placeholder text for the Prompt View text area."
993
+ promptPlaceholder="Ask or generate content with AI"
994
+ i18n-copyOutput="kendo.aiprompt.copyOutput|The Copy button text in each Output view card."
995
+ copyOutput="Copy"
996
+ i18n-retryGeneration="kendo.aiprompt.retryGeneration|The Retry button text in each Output view card."
997
+ retryGeneration="Retry"
998
+ i18n-outputTitle="kendo.aiprompt.outputTitle|The title of each Output view card."
999
+ outputTitle="Generated with AI"
1000
+ i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card."
1001
+ outputRetryTitle="Generated with AI"
1002
+ i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button."
1003
+ promptSuggestions="Prompt suggestions"
1004
+ i18n-speechToTextButton="kendo.aiprompt.speechToTextButton|The aria-label for the Speech to Text button."
1005
+ speechToTextButton="Voice input">
998
1006
  </ng-container>
999
1007
  <div class="k-prompt-header">
1000
- <div class="k-toolbar-flat k-toolbar k-toolbar-md"
1001
- role="toolbar">
1002
- <button *ngFor="let view of viewsArray; let idx = index"
1003
- kendoButton
1004
- kendoAIPromptToolbarFocusable
1005
- type="button"
1006
- fillMode="flat"
1007
- rounded="full"
1008
- themeColor="primary"
1009
- [svgIcon]="view.svgIcon"
1010
- [icon]="view.icon"
1011
- [selected]="idx === activeView"
1012
- (click)="viewChange(idx)">
1013
- {{view.buttonText}}
1014
- </button>
1015
-
1016
- <ng-template *ngIf="toolbarActionsTemplate"
1017
- [ngTemplateOutlet]="toolbarActionsTemplate?.templateRef">
1018
- </ng-template>
1019
- </div>
1008
+ <div class="k-toolbar-flat k-toolbar k-toolbar-md"
1009
+ role="toolbar">
1010
+ @for (view of viewsArray; track view; let idx = $index) {
1011
+ <button
1012
+ kendoButton
1013
+ kendoAIPromptToolbarFocusable
1014
+ type="button"
1015
+ fillMode="flat"
1016
+ rounded="full"
1017
+ themeColor="primary"
1018
+ [svgIcon]="view.svgIcon"
1019
+ [icon]="view.icon"
1020
+ [selected]="idx === activeView"
1021
+ (click)="viewChange(idx)">
1022
+ {{view.buttonText}}
1023
+ </button>
1024
+ }
1025
+
1026
+ @if (toolbarActionsTemplate) {
1027
+ <ng-template
1028
+ [ngTemplateOutlet]="toolbarActionsTemplate?.templateRef">
1029
+ </ng-template>
1030
+ }
1031
+ </div>
1020
1032
  </div>
1021
1033
  <div class="k-prompt-content">
1022
- <kendo-floatingactionbutton #fabButton *ngIf="streaming && selectedView?.viewType === 'output'"
1023
- class="k-prompt-stop-fab"
1024
- buttonClass="k-generating k-active"
1025
- [positionMode]="fabPositionMode"
1026
- [align]="fabAlignment"
1027
- [svgIcon]="fabStopGenerationSVGIcon"
1028
- icon="stop"
1029
- (click)="promptRequestCancel.emit()"
1030
- >
1034
+ @if (streaming && selectedView?.viewType === 'output') {
1035
+ <kendo-floatingactionbutton #fabButton
1036
+ class="k-prompt-stop-fab"
1037
+ buttonClass="k-generating k-active"
1038
+ [positionMode]="fabPositionMode"
1039
+ [align]="fabAlignment"
1040
+ [svgIcon]="fabStopGenerationSVGIcon"
1041
+ icon="stop"
1042
+ (click)="promptRequestCancel.emit()"
1043
+ >
1031
1044
  </kendo-floatingactionbutton>
1032
- <div class="k-prompt-view">
1033
- <ng-container *ngTemplateOutlet="viewTemplate">
1034
- </ng-container>
1035
- </div>
1045
+ }
1046
+ <div class="k-prompt-view">
1047
+ <ng-container *ngTemplateOutlet="viewTemplate">
1048
+ </ng-container>
1049
+ </div>
1036
1050
  </div>
1037
- <div class="k-prompt-footer" *ngIf="selectedView?.viewType === 'prompt'">
1051
+ @if (selectedView?.viewType === 'prompt') {
1052
+ <div class="k-prompt-footer">
1038
1053
  <div class="k-actions k-actions-start k-actions-horizontal k-prompt-actions">
1039
- <button
1040
- kendoButton
1041
- type="button"
1042
- themeColor="primary"
1043
- rounded="full"
1044
- [attr.title]="messageFor('generateOutput')"
1045
- [attr.aria-label]="messageFor('generateOutput')"
1046
- [attr.aria-disabled]="disabledGenerateButton"
1047
- [svgIcon]="generateButtonSVGIcon"
1048
- [icon]="generateButtonIcon"
1049
- [disabled]="disabledGenerateButton"
1050
- (click)="handleGenerateOutput()">{{messageFor('generateOutput')}}</button>
1054
+ <button
1055
+ kendoButton
1056
+ type="button"
1057
+ themeColor="primary"
1058
+ rounded="full"
1059
+ [attr.title]="messageFor('generateOutput')"
1060
+ [attr.aria-label]="messageFor('generateOutput')"
1061
+ [attr.aria-disabled]="disabledGenerateButton"
1062
+ [svgIcon]="generateButtonSVGIcon"
1063
+ [icon]="generateButtonIcon"
1064
+ [disabled]="disabledGenerateButton"
1065
+ (click)="handleGenerateOutput()">{{messageFor('generateOutput')}}</button>
1051
1066
  </div>
1052
- </div>
1053
- `,
1067
+ </div>
1068
+ }
1069
+ `,
1054
1070
  standalone: true,
1055
- imports: [LocalizedMessagesDirective$2, NgFor, ButtonComponent, AIPromptToolbarFocusableDirective, NgIf, NgTemplateOutlet, FloatingActionButtonComponent]
1071
+ imports: [LocalizedMessagesDirective$2, ButtonComponent, AIPromptToolbarFocusableDirective, NgTemplateOutlet, FloatingActionButtonComponent]
1056
1072
  }]
1057
1073
  }], ctorParameters: () => [{ type: i1.LocalizationService }, { type: AIPromptService }, { type: ToolbarNavigationService }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { hostClasses: [{
1058
1074
  type: HostBinding,
@@ -1380,56 +1396,55 @@ class AIPromptOutputCardComponent {
1380
1396
  return this.service.outputBodyTemplate?.templateRef;
1381
1397
  }
1382
1398
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AIPromptOutputCardComponent, deps: [{ token: i1.LocalizationService }, { token: AIPromptService }], target: i0.ɵɵFactoryTarget.Component });
1383
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AIPromptOutputCardComponent, isStandalone: true, selector: "[kendoAIPromptOutputCard]", inputs: { promptOutput: "promptOutput" }, host: { properties: { "class.k-card": "this.hostClass", "attr.role": "this.listItemRole", "attr.tabindex": "this.tabIndex", "attr.aria-describedby": "this.ariaDescribedBy", "attr.aria-keyshortcuts": "this.ariaKeyShortcuts" } }, ngImport: i0, template: `
1399
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AIPromptOutputCardComponent, isStandalone: true, selector: "[kendoAIPromptOutputCard]", inputs: { promptOutput: "promptOutput" }, host: { properties: { "class.k-card": "this.hostClass", "attr.role": "this.listItemRole", "attr.tabindex": "this.tabIndex", "attr.aria-describedby": "this.ariaDescribedBy", "attr.aria-keyshortcuts": "this.ariaKeyShortcuts" } }, ngImport: i0, template: `
1384
1400
  <div class="k-card-header">
1385
- <div
1386
- class="k-card-title"
1387
- [attr.id]="titleId">{{outputTitle}}
1388
- </div>
1389
- <div class="k-card-subtitle">{{promptOutput.prompt}}</div>
1401
+ <div
1402
+ class="k-card-title"
1403
+ [attr.id]="titleId">{{outputTitle}}
1404
+ </div>
1405
+ <div class="k-card-subtitle">{{promptOutput.prompt}}</div>
1390
1406
  </div>
1391
1407
  <div class="k-card-body">
1392
- <ng-container *ngIf="customBodyTemplate; else defaultTemplate">
1393
- <ng-container *ngTemplateOutlet="customBodyTemplate; context: { $implicit: promptOutput }">
1394
- </ng-container>
1408
+ @if (customBodyTemplate) {
1409
+ <ng-container *ngTemplateOutlet="customBodyTemplate; context: { $implicit: promptOutput }">
1395
1410
  </ng-container>
1396
- <ng-template #defaultTemplate>
1397
- <p>{{promptOutput.output}}</p>
1398
- </ng-template>
1411
+ } @else {
1412
+ <p>{{promptOutput.output}}</p>
1413
+ }
1399
1414
  </div>
1400
1415
  <div class="k-actions k-actions-start k-actions-horizontal k-card-actions">
1416
+ <button kendoButton
1417
+ fillMode="flat"
1418
+ themeColor="primary"
1419
+ rounded="full"
1420
+ icon="copy"
1421
+ [svgIcon]="copyIcon"
1422
+ (click)="handleCopy()"
1423
+ >{{messageFor('copyOutput')}}</button>
1424
+ <button kendoButton
1425
+ fillMode="flat"
1426
+ rounded="full"
1427
+ icon="arrow-rotate-cw"
1428
+ [svgIcon]="retryIcon"
1429
+ (click)="handleRetry()"
1430
+ >{{messageFor('retryGeneration')}}</button>
1431
+ @if (showRating) {
1432
+ <span class="k-spacer"></span>
1401
1433
  <button kendoButton
1402
- fillMode="flat"
1403
- themeColor="primary"
1404
- rounded="full"
1405
- icon="copy"
1406
- [svgIcon]="copyIcon"
1407
- (click)="handleCopy()"
1408
- >{{messageFor('copyOutput')}}</button>
1434
+ fillMode="flat"
1435
+ icon="thumb-up-outline"
1436
+ [svgIcon]="positiveRatingIcon"
1437
+ (click)="handleRating('positive')">
1438
+ </button>
1409
1439
  <button kendoButton
1410
- fillMode="flat"
1411
- rounded="full"
1412
- icon="arrow-rotate-cw"
1413
- [svgIcon]="retryIcon"
1414
- (click)="handleRetry()"
1415
- >{{messageFor('retryGeneration')}}</button>
1416
- <ng-container *ngIf="showRating">
1417
- <span class="k-spacer"></span>
1418
- <button kendoButton
1419
- fillMode="flat"
1420
- icon="thumb-up-outline"
1421
- [svgIcon]="positiveRatingIcon"
1422
- (click)="handleRating('positive')">
1423
- </button>
1424
- <button kendoButton
1425
- fillMode="flat"
1426
- icon="thumb-down-outline"
1427
- [svgIcon]="negativeRatingIcon"
1428
- (click)="handleRating('negative')">
1429
- </button>
1430
- </ng-container>
1440
+ fillMode="flat"
1441
+ icon="thumb-down-outline"
1442
+ [svgIcon]="negativeRatingIcon"
1443
+ (click)="handleRating('negative')">
1444
+ </button>
1445
+ }
1431
1446
  </div>
1432
- `, isInline: true, dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1447
+ `, isInline: true, dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1433
1448
  }
1434
1449
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AIPromptOutputCardComponent, decorators: [{
1435
1450
  type: Component,
@@ -1437,56 +1452,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1437
1452
  selector: '[kendoAIPromptOutputCard]',
1438
1453
  template: `
1439
1454
  <div class="k-card-header">
1440
- <div
1441
- class="k-card-title"
1442
- [attr.id]="titleId">{{outputTitle}}
1443
- </div>
1444
- <div class="k-card-subtitle">{{promptOutput.prompt}}</div>
1455
+ <div
1456
+ class="k-card-title"
1457
+ [attr.id]="titleId">{{outputTitle}}
1458
+ </div>
1459
+ <div class="k-card-subtitle">{{promptOutput.prompt}}</div>
1445
1460
  </div>
1446
1461
  <div class="k-card-body">
1447
- <ng-container *ngIf="customBodyTemplate; else defaultTemplate">
1448
- <ng-container *ngTemplateOutlet="customBodyTemplate; context: { $implicit: promptOutput }">
1449
- </ng-container>
1462
+ @if (customBodyTemplate) {
1463
+ <ng-container *ngTemplateOutlet="customBodyTemplate; context: { $implicit: promptOutput }">
1450
1464
  </ng-container>
1451
- <ng-template #defaultTemplate>
1452
- <p>{{promptOutput.output}}</p>
1453
- </ng-template>
1465
+ } @else {
1466
+ <p>{{promptOutput.output}}</p>
1467
+ }
1454
1468
  </div>
1455
1469
  <div class="k-actions k-actions-start k-actions-horizontal k-card-actions">
1470
+ <button kendoButton
1471
+ fillMode="flat"
1472
+ themeColor="primary"
1473
+ rounded="full"
1474
+ icon="copy"
1475
+ [svgIcon]="copyIcon"
1476
+ (click)="handleCopy()"
1477
+ >{{messageFor('copyOutput')}}</button>
1478
+ <button kendoButton
1479
+ fillMode="flat"
1480
+ rounded="full"
1481
+ icon="arrow-rotate-cw"
1482
+ [svgIcon]="retryIcon"
1483
+ (click)="handleRetry()"
1484
+ >{{messageFor('retryGeneration')}}</button>
1485
+ @if (showRating) {
1486
+ <span class="k-spacer"></span>
1456
1487
  <button kendoButton
1457
- fillMode="flat"
1458
- themeColor="primary"
1459
- rounded="full"
1460
- icon="copy"
1461
- [svgIcon]="copyIcon"
1462
- (click)="handleCopy()"
1463
- >{{messageFor('copyOutput')}}</button>
1488
+ fillMode="flat"
1489
+ icon="thumb-up-outline"
1490
+ [svgIcon]="positiveRatingIcon"
1491
+ (click)="handleRating('positive')">
1492
+ </button>
1464
1493
  <button kendoButton
1465
- fillMode="flat"
1466
- rounded="full"
1467
- icon="arrow-rotate-cw"
1468
- [svgIcon]="retryIcon"
1469
- (click)="handleRetry()"
1470
- >{{messageFor('retryGeneration')}}</button>
1471
- <ng-container *ngIf="showRating">
1472
- <span class="k-spacer"></span>
1473
- <button kendoButton
1474
- fillMode="flat"
1475
- icon="thumb-up-outline"
1476
- [svgIcon]="positiveRatingIcon"
1477
- (click)="handleRating('positive')">
1478
- </button>
1479
- <button kendoButton
1480
- fillMode="flat"
1481
- icon="thumb-down-outline"
1482
- [svgIcon]="negativeRatingIcon"
1483
- (click)="handleRating('negative')">
1484
- </button>
1485
- </ng-container>
1494
+ fillMode="flat"
1495
+ icon="thumb-down-outline"
1496
+ [svgIcon]="negativeRatingIcon"
1497
+ (click)="handleRating('negative')">
1498
+ </button>
1499
+ }
1486
1500
  </div>
1487
- `,
1501
+ `,
1488
1502
  standalone: true,
1489
- imports: [ButtonComponent, NgIf, NgTemplateOutlet]
1503
+ imports: [ButtonComponent, NgTemplateOutlet]
1490
1504
  }]
1491
1505
  }], ctorParameters: () => [{ type: i1.LocalizationService }, { type: AIPromptService }], propDecorators: { hostClass: [{
1492
1506
  type: HostBinding,
@@ -1536,26 +1550,25 @@ class OutputViewComponent extends BaseView {
1536
1550
  return this.service.outputTemplate?.templateRef;
1537
1551
  }
1538
1552
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OutputViewComponent, deps: [{ token: i1.LocalizationService }, { token: AIPromptService }], target: i0.ɵɵFactoryTarget.Component });
1539
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: OutputViewComponent, isStandalone: true, selector: "kendo-aiprompt-output-view", providers: [{
1553
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: OutputViewComponent, isStandalone: true, selector: "kendo-aiprompt-output-view", providers: [{
1540
1554
  provide: BaseView,
1541
1555
  useExisting: forwardRef(() => OutputViewComponent)
1542
1556
  }], usesInheritance: true, ngImport: i0, template: `
1543
1557
  <ng-template #content>
1544
- <div
1545
- class="k-card-list"
1546
- role="list">
1547
- <ng-container *ngFor="let output of promptOutputs">
1548
- <ng-container *ngIf="customTemplate; else defaultTemplate">
1549
- <ng-container *ngTemplateOutlet="customTemplate; context: { $implicit: output }">
1550
- </ng-container>
1551
- </ng-container>
1552
- <ng-template #defaultTemplate>
1553
- <div kendoAIPromptOutputCard [promptOutput]="output"></div>
1554
- </ng-template>
1558
+ <div
1559
+ class="k-card-list"
1560
+ role="list">
1561
+ @for (output of promptOutputs; track output) {
1562
+ @if (customTemplate) {
1563
+ <ng-container *ngTemplateOutlet="customTemplate; context: { $implicit: output }">
1555
1564
  </ng-container>
1556
- </div>
1565
+ } @else {
1566
+ <div kendoAIPromptOutputCard [promptOutput]="output"></div>
1567
+ }
1568
+ }
1569
+ </div>
1557
1570
  </ng-template>
1558
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: AIPromptOutputCardComponent, selector: "[kendoAIPromptOutputCard]", inputs: ["promptOutput"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1571
+ `, isInline: true, dependencies: [{ kind: "component", type: AIPromptOutputCardComponent, selector: "[kendoAIPromptOutputCard]", inputs: ["promptOutput"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1559
1572
  }
1560
1573
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: OutputViewComponent, decorators: [{
1561
1574
  type: Component,
@@ -1567,23 +1580,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1567
1580
  }],
1568
1581
  template: `
1569
1582
  <ng-template #content>
1570
- <div
1571
- class="k-card-list"
1572
- role="list">
1573
- <ng-container *ngFor="let output of promptOutputs">
1574
- <ng-container *ngIf="customTemplate; else defaultTemplate">
1575
- <ng-container *ngTemplateOutlet="customTemplate; context: { $implicit: output }">
1576
- </ng-container>
1577
- </ng-container>
1578
- <ng-template #defaultTemplate>
1579
- <div kendoAIPromptOutputCard [promptOutput]="output"></div>
1580
- </ng-template>
1583
+ <div
1584
+ class="k-card-list"
1585
+ role="list">
1586
+ @for (output of promptOutputs; track output) {
1587
+ @if (customTemplate) {
1588
+ <ng-container *ngTemplateOutlet="customTemplate; context: { $implicit: output }">
1581
1589
  </ng-container>
1582
- </div>
1590
+ } @else {
1591
+ <div kendoAIPromptOutputCard [promptOutput]="output"></div>
1592
+ }
1593
+ }
1594
+ </div>
1583
1595
  </ng-template>
1584
- `,
1596
+ `,
1585
1597
  standalone: true,
1586
- imports: [NgFor, AIPromptOutputCardComponent, NgIf, NgTemplateOutlet]
1598
+ imports: [AIPromptOutputCardComponent, NgTemplateOutlet]
1587
1599
  }]
1588
1600
  }], ctorParameters: () => [{ type: i1.LocalizationService }, { type: AIPromptService }] });
1589
1601
 
@@ -1678,84 +1690,92 @@ class PromptViewComponent extends BaseView {
1678
1690
  }
1679
1691
  }
1680
1692
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptViewComponent, deps: [{ token: i1.LocalizationService }, { token: AIPromptService }], target: i0.ɵɵFactoryTarget.Component });
1681
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: PromptViewComponent, isStandalone: true, selector: "kendo-aiprompt-prompt-view", providers: [
1693
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PromptViewComponent, isStandalone: true, selector: "kendo-aiprompt-prompt-view", providers: [
1682
1694
  {
1683
1695
  provide: BaseView,
1684
1696
  useExisting: forwardRef(() => PromptViewComponent)
1685
1697
  }
1686
1698
  ], usesInheritance: true, ngImport: i0, template: `
1687
1699
  <ng-template #content>
1688
- <kendo-textarea
1689
- [cols]="textareaSettings?.cols"
1690
- [disabled]="textareaSettings?.disabled"
1691
- [fillMode]="textareaSettings?.fillMode"
1692
- [flow]="textareaSettings?.flow ?? 'vertical'"
1693
- [inputAttributes]="textareaSettings?.inputAttributes"
1694
- [maxlength]="textareaSettings?.maxlength"
1695
- [placeholder]="textareaSettings?.placeholder ?? messageFor('promptPlaceholder')"
1696
- [readonly]="textareaSettings?.readonly"
1697
- [resizable]="textareaSettings?.resizable ?? 'vertical'"
1698
- [rounded]="textareaSettings?.rounded"
1699
- [rows]="textareaSettings?.rows ?? 1"
1700
- [selectOnFocus]="textareaSettings?.selectOnFocus"
1701
- [showSuffixSeparator]="textareaSettings?.showSuffixSeparator ?? true"
1702
- [size]="textareaSettings?.size"
1703
- [tabIndex]="textareaSettings?.tabindex"
1704
- [title]="textareaSettings?.title"
1705
- [(value)]="textAreaValue"
1700
+ <kendo-textarea
1701
+ [cols]="textareaSettings?.cols"
1702
+ [disabled]="textareaSettings?.disabled"
1703
+ [fillMode]="textareaSettings?.fillMode"
1704
+ [flow]="textareaSettings?.flow ?? 'vertical'"
1705
+ [inputAttributes]="textareaSettings?.inputAttributes"
1706
+ [maxlength]="textareaSettings?.maxlength"
1707
+ [placeholder]="textareaSettings?.placeholder ?? messageFor('promptPlaceholder')"
1708
+ [readonly]="textareaSettings?.readonly"
1709
+ [resizable]="textareaSettings?.resizable ?? 'vertical'"
1710
+ [rounded]="textareaSettings?.rounded"
1711
+ [rows]="textareaSettings?.rows ?? 1"
1712
+ [selectOnFocus]="textareaSettings?.selectOnFocus"
1713
+ [showSuffixSeparator]="textareaSettings?.showSuffixSeparator ?? true"
1714
+ [size]="textareaSettings?.size"
1715
+ [tabIndex]="textareaSettings?.tabindex"
1716
+ [title]="textareaSettings?.title"
1717
+ [(value)]="textAreaValue"
1706
1718
  >
1707
- <kendo-textarea-suffix *ngIf="speechToTextButtonSettings">
1708
- <button kendoSpeechToTextButton
1719
+ @if (speechToTextButtonSettings) {
1720
+ <kendo-textarea-suffix>
1721
+ <button kendoSpeechToTextButton
1722
+ role="button"
1723
+ [continuous]="speechToTextButtonSettings?.continuous"
1724
+ [disabled]="speechToTextButtonSettings?.disabled"
1725
+ [fillMode]="speechToTextButtonSettings?.fillMode ?? 'flat'"
1726
+ [integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
1727
+ [interimResults]="speechToTextButtonSettings?.interimResults"
1728
+ [lang]="speechToTextButtonSettings?.lang"
1729
+ [maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
1730
+ [rounded]="speechToTextButtonSettings?.rounded"
1731
+ [size]="speechToTextButtonSettings?.size"
1732
+ [themeColor]="speechToTextButtonSettings?.themeColor"
1733
+ [attr.aria-label]="messageFor('speechToTextButton')"
1734
+ [attr.title]="messageFor('speechToTextButton')"
1735
+ [attr.aria-disabled]="speechToTextButtonSettings?.disabled"
1736
+ (error)="onSpeechToTextError($event)"
1737
+ (result)="onSpeechToTextResult($event)"
1738
+ ></button>
1739
+ </kendo-textarea-suffix>
1740
+ }
1741
+ </kendo-textarea>
1742
+ @if (promptSuggestions) {
1743
+ <div
1744
+ class="k-prompt-expander">
1745
+ <button kendoButton
1746
+ [attr.aria-controls]="contentId"
1747
+ [attr.aria-expanded]="showSuggestions"
1748
+ fillMode="flat"
1749
+ [icon]="suggestionsIcons.font"
1750
+ [svgIcon]="suggestionsIcons.svg"
1751
+ type="button"
1752
+ (click)="showSuggestions = !showSuggestions">
1753
+ {{messageFor('promptSuggestions')}}
1754
+ </button>
1755
+ @if (showSuggestions) {
1756
+ <div
1757
+ class="k-prompt-expander-content"
1758
+ [attr.id]="contentId">
1759
+ <div class="k-suggestion-group" role="group">
1760
+ @for (suggestion of promptSuggestions; track suggestion) {
1761
+ <div
1762
+ class="k-suggestion"
1709
1763
  role="button"
1710
- [continuous]="speechToTextButtonSettings?.continuous"
1711
- [disabled]="speechToTextButtonSettings?.disabled"
1712
- [fillMode]="speechToTextButtonSettings?.fillMode ?? 'flat'"
1713
- [integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
1714
- [interimResults]="speechToTextButtonSettings?.interimResults"
1715
- [lang]="speechToTextButtonSettings?.lang"
1716
- [maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
1717
- [rounded]="speechToTextButtonSettings?.rounded"
1718
- [size]="speechToTextButtonSettings?.size"
1719
- [themeColor]="speechToTextButtonSettings?.themeColor"
1720
- [attr.aria-label]="messageFor('speechToTextButton')"
1721
- [attr.title]="messageFor('speechToTextButton')"
1722
- [attr.aria-disabled]="speechToTextButtonSettings?.disabled"
1723
- (error)="onSpeechToTextError($event)"
1724
- (result)="onSpeechToTextResult($event)"
1725
- ></button>
1726
- </kendo-textarea-suffix>
1727
- </kendo-textarea>
1728
- <div *ngIf="promptSuggestions"
1729
- class="k-prompt-expander">
1730
- <button kendoButton
1731
- [attr.aria-controls]="contentId"
1732
- [attr.aria-expanded]="showSuggestions"
1733
- fillMode="flat"
1734
- [icon]="suggestionsIcons.font"
1735
- [svgIcon]="suggestionsIcons.svg"
1736
- type="button"
1737
- (click)="showSuggestions = !showSuggestions">
1738
- {{messageFor('promptSuggestions')}}
1739
- </button>
1740
- <div *ngIf="showSuggestions"
1741
- class="k-prompt-expander-content"
1742
- [attr.id]="contentId">
1743
- <div class="k-suggestion-group" role="group">
1744
- <div *ngFor="let suggestion of promptSuggestions"
1745
- class="k-suggestion"
1746
- role="button"
1747
- [attr.tabindex]="0"
1748
- [attr.aria-label]="suggestion"
1749
- [attr.title]="suggestion"
1750
- (click)="suggestionClick(suggestion)"
1751
- (keydown)="suggestionKeydown($event, suggestion)">
1752
- {{suggestion}}
1753
- </div>
1754
- </div>
1764
+ [attr.tabindex]="0"
1765
+ [attr.aria-label]="suggestion"
1766
+ [attr.title]="suggestion"
1767
+ (click)="suggestionClick(suggestion)"
1768
+ (keydown)="suggestionKeydown($event, suggestion)">
1769
+ {{suggestion}}
1770
+ </div>
1771
+ }
1772
+ </div>
1755
1773
  </div>
1774
+ }
1756
1775
  </div>
1776
+ }
1757
1777
  </ng-template>
1758
- `, isInline: true, dependencies: [{ kind: "component", type: TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: TextAreaSuffixComponent, selector: "kendo-textarea-suffix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaSuffix"] }, { kind: "component", type: SpeechToTextButtonComponent, selector: "button[kendoSpeechToTextButton]", inputs: ["disabled", "size", "rounded", "fillMode", "themeColor", "integrationMode", "lang", "continuous", "interimResults", "maxAlternatives"], outputs: ["start", "end", "result", "error", "click"], exportAs: ["kendoSpeechToTextButton"] }] });
1778
+ `, isInline: true, dependencies: [{ kind: "component", type: TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: TextAreaSuffixComponent, selector: "kendo-textarea-suffix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaSuffix"] }, { kind: "component", type: SpeechToTextButtonComponent, selector: "button[kendoSpeechToTextButton]", inputs: ["disabled", "size", "rounded", "fillMode", "themeColor", "integrationMode", "lang", "continuous", "interimResults", "maxAlternatives"], outputs: ["start", "end", "result", "error", "click"], exportAs: ["kendoSpeechToTextButton"] }] });
1759
1779
  }
1760
1780
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PromptViewComponent, decorators: [{
1761
1781
  type: Component,
@@ -1769,79 +1789,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1769
1789
  ],
1770
1790
  template: `
1771
1791
  <ng-template #content>
1772
- <kendo-textarea
1773
- [cols]="textareaSettings?.cols"
1774
- [disabled]="textareaSettings?.disabled"
1775
- [fillMode]="textareaSettings?.fillMode"
1776
- [flow]="textareaSettings?.flow ?? 'vertical'"
1777
- [inputAttributes]="textareaSettings?.inputAttributes"
1778
- [maxlength]="textareaSettings?.maxlength"
1779
- [placeholder]="textareaSettings?.placeholder ?? messageFor('promptPlaceholder')"
1780
- [readonly]="textareaSettings?.readonly"
1781
- [resizable]="textareaSettings?.resizable ?? 'vertical'"
1782
- [rounded]="textareaSettings?.rounded"
1783
- [rows]="textareaSettings?.rows ?? 1"
1784
- [selectOnFocus]="textareaSettings?.selectOnFocus"
1785
- [showSuffixSeparator]="textareaSettings?.showSuffixSeparator ?? true"
1786
- [size]="textareaSettings?.size"
1787
- [tabIndex]="textareaSettings?.tabindex"
1788
- [title]="textareaSettings?.title"
1789
- [(value)]="textAreaValue"
1792
+ <kendo-textarea
1793
+ [cols]="textareaSettings?.cols"
1794
+ [disabled]="textareaSettings?.disabled"
1795
+ [fillMode]="textareaSettings?.fillMode"
1796
+ [flow]="textareaSettings?.flow ?? 'vertical'"
1797
+ [inputAttributes]="textareaSettings?.inputAttributes"
1798
+ [maxlength]="textareaSettings?.maxlength"
1799
+ [placeholder]="textareaSettings?.placeholder ?? messageFor('promptPlaceholder')"
1800
+ [readonly]="textareaSettings?.readonly"
1801
+ [resizable]="textareaSettings?.resizable ?? 'vertical'"
1802
+ [rounded]="textareaSettings?.rounded"
1803
+ [rows]="textareaSettings?.rows ?? 1"
1804
+ [selectOnFocus]="textareaSettings?.selectOnFocus"
1805
+ [showSuffixSeparator]="textareaSettings?.showSuffixSeparator ?? true"
1806
+ [size]="textareaSettings?.size"
1807
+ [tabIndex]="textareaSettings?.tabindex"
1808
+ [title]="textareaSettings?.title"
1809
+ [(value)]="textAreaValue"
1790
1810
  >
1791
- <kendo-textarea-suffix *ngIf="speechToTextButtonSettings">
1792
- <button kendoSpeechToTextButton
1811
+ @if (speechToTextButtonSettings) {
1812
+ <kendo-textarea-suffix>
1813
+ <button kendoSpeechToTextButton
1814
+ role="button"
1815
+ [continuous]="speechToTextButtonSettings?.continuous"
1816
+ [disabled]="speechToTextButtonSettings?.disabled"
1817
+ [fillMode]="speechToTextButtonSettings?.fillMode ?? 'flat'"
1818
+ [integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
1819
+ [interimResults]="speechToTextButtonSettings?.interimResults"
1820
+ [lang]="speechToTextButtonSettings?.lang"
1821
+ [maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
1822
+ [rounded]="speechToTextButtonSettings?.rounded"
1823
+ [size]="speechToTextButtonSettings?.size"
1824
+ [themeColor]="speechToTextButtonSettings?.themeColor"
1825
+ [attr.aria-label]="messageFor('speechToTextButton')"
1826
+ [attr.title]="messageFor('speechToTextButton')"
1827
+ [attr.aria-disabled]="speechToTextButtonSettings?.disabled"
1828
+ (error)="onSpeechToTextError($event)"
1829
+ (result)="onSpeechToTextResult($event)"
1830
+ ></button>
1831
+ </kendo-textarea-suffix>
1832
+ }
1833
+ </kendo-textarea>
1834
+ @if (promptSuggestions) {
1835
+ <div
1836
+ class="k-prompt-expander">
1837
+ <button kendoButton
1838
+ [attr.aria-controls]="contentId"
1839
+ [attr.aria-expanded]="showSuggestions"
1840
+ fillMode="flat"
1841
+ [icon]="suggestionsIcons.font"
1842
+ [svgIcon]="suggestionsIcons.svg"
1843
+ type="button"
1844
+ (click)="showSuggestions = !showSuggestions">
1845
+ {{messageFor('promptSuggestions')}}
1846
+ </button>
1847
+ @if (showSuggestions) {
1848
+ <div
1849
+ class="k-prompt-expander-content"
1850
+ [attr.id]="contentId">
1851
+ <div class="k-suggestion-group" role="group">
1852
+ @for (suggestion of promptSuggestions; track suggestion) {
1853
+ <div
1854
+ class="k-suggestion"
1793
1855
  role="button"
1794
- [continuous]="speechToTextButtonSettings?.continuous"
1795
- [disabled]="speechToTextButtonSettings?.disabled"
1796
- [fillMode]="speechToTextButtonSettings?.fillMode ?? 'flat'"
1797
- [integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
1798
- [interimResults]="speechToTextButtonSettings?.interimResults"
1799
- [lang]="speechToTextButtonSettings?.lang"
1800
- [maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
1801
- [rounded]="speechToTextButtonSettings?.rounded"
1802
- [size]="speechToTextButtonSettings?.size"
1803
- [themeColor]="speechToTextButtonSettings?.themeColor"
1804
- [attr.aria-label]="messageFor('speechToTextButton')"
1805
- [attr.title]="messageFor('speechToTextButton')"
1806
- [attr.aria-disabled]="speechToTextButtonSettings?.disabled"
1807
- (error)="onSpeechToTextError($event)"
1808
- (result)="onSpeechToTextResult($event)"
1809
- ></button>
1810
- </kendo-textarea-suffix>
1811
- </kendo-textarea>
1812
- <div *ngIf="promptSuggestions"
1813
- class="k-prompt-expander">
1814
- <button kendoButton
1815
- [attr.aria-controls]="contentId"
1816
- [attr.aria-expanded]="showSuggestions"
1817
- fillMode="flat"
1818
- [icon]="suggestionsIcons.font"
1819
- [svgIcon]="suggestionsIcons.svg"
1820
- type="button"
1821
- (click)="showSuggestions = !showSuggestions">
1822
- {{messageFor('promptSuggestions')}}
1823
- </button>
1824
- <div *ngIf="showSuggestions"
1825
- class="k-prompt-expander-content"
1826
- [attr.id]="contentId">
1827
- <div class="k-suggestion-group" role="group">
1828
- <div *ngFor="let suggestion of promptSuggestions"
1829
- class="k-suggestion"
1830
- role="button"
1831
- [attr.tabindex]="0"
1832
- [attr.aria-label]="suggestion"
1833
- [attr.title]="suggestion"
1834
- (click)="suggestionClick(suggestion)"
1835
- (keydown)="suggestionKeydown($event, suggestion)">
1836
- {{suggestion}}
1837
- </div>
1838
- </div>
1856
+ [attr.tabindex]="0"
1857
+ [attr.aria-label]="suggestion"
1858
+ [attr.title]="suggestion"
1859
+ (click)="suggestionClick(suggestion)"
1860
+ (keydown)="suggestionKeydown($event, suggestion)">
1861
+ {{suggestion}}
1862
+ </div>
1863
+ }
1864
+ </div>
1839
1865
  </div>
1866
+ }
1840
1867
  </div>
1868
+ }
1841
1869
  </ng-template>
1842
- `,
1870
+ `,
1843
1871
  standalone: true,
1844
- imports: [TextAreaComponent, NgIf, ButtonComponent, NgFor, TextAreaSuffixComponent, SpeechToTextButtonComponent]
1872
+ imports: [TextAreaComponent, ButtonComponent, TextAreaSuffixComponent, SpeechToTextButtonComponent]
1845
1873
  }]
1846
1874
  }], ctorParameters: () => [{ type: i1.LocalizationService }, { type: AIPromptService }] });
1847
1875
 
@@ -2636,13 +2664,13 @@ class SuggestedActionsComponent extends ChatItem {
2636
2664
  this.activeIndex = apply ? index : -1;
2637
2665
  }
2638
2666
  actionKeydown(e, action) {
2639
- const handler = this.actionKeyHandlers[normalizeNumpadKeys(e)];
2667
+ const handler = this.actionKeyHandlers[normalizeKeys(e)];
2640
2668
  if (handler) {
2641
2669
  handler(e, action);
2642
2670
  }
2643
2671
  }
2644
2672
  suggestionKeydown(e, suggestion) {
2645
- const handler = this.suggestionKeyHandlers[normalizeNumpadKeys(e)];
2673
+ const handler = this.suggestionKeyHandlers[normalizeKeys(e)];
2646
2674
  if (handler) {
2647
2675
  handler(e, suggestion);
2648
2676
  }
@@ -2681,96 +2709,100 @@ class SuggestedActionsComponent extends ChatItem {
2681
2709
  this.selectedIndex = Math.max(0, Math.min(prevIndex + offset, this.items.length - 1));
2682
2710
  }
2683
2711
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SuggestedActionsComponent, deps: [{ token: ChatService }, { token: i1.LocalizationService }, { token: SuggestionsScrollService }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
2684
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: SuggestedActionsComponent, isStandalone: true, selector: "kendo-chat-suggested-actions", inputs: { actions: "actions", suggestions: "suggestions", tabbable: "tabbable", type: "type", suggestionTemplate: "suggestionTemplate" }, outputs: { dispatchAction: "dispatchAction", dispatchSuggestion: "dispatchSuggestion" }, host: { properties: { "class.k-suggestion-group": "this.defaultClass", "class.k-suggestion-group-scrollable": "this.scrollableClass", "class.k-suggestion-scrollwrap": "this.scrollButtonsClass", "attr.role": "this.role" } }, providers: [{
2712
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SuggestedActionsComponent, isStandalone: true, selector: "kendo-chat-suggested-actions", inputs: { actions: "actions", suggestions: "suggestions", tabbable: "tabbable", type: "type", suggestionTemplate: "suggestionTemplate" }, outputs: { dispatchAction: "dispatchAction", dispatchSuggestion: "dispatchSuggestion" }, host: { properties: { "class.k-suggestion-group": "this.defaultClass", "class.k-suggestion-group-scrollable": "this.scrollableClass", "class.k-suggestion-scrollwrap": "this.scrollButtonsClass", "attr.role": "this.role" } }, providers: [{
2685
2713
  provide: ChatItem,
2686
2714
  useExisting: forwardRef(() => SuggestedActionsComponent)
2687
2715
  },
2688
2716
  SuggestionsScrollService
2689
2717
  ], viewQueries: [{ propertyName: "suggestionsContainer", first: true, predicate: ["suggestionsContainer"], descendants: true, read: ElementRef }, { propertyName: "prevScrollButton", first: true, predicate: ["prevScrollButton"], descendants: true, read: ElementRef }, { propertyName: "nextScrollButton", first: true, predicate: ["nextScrollButton"], descendants: true, read: ElementRef }, { propertyName: "items", predicate: ["item"], descendants: true }], usesInheritance: true, ngImport: i0, template: `
2690
- <span
2691
- *ngIf="hasScrollButtons"
2718
+ @if (hasScrollButtons) {
2719
+ <span
2692
2720
  #prevScrollButton
2693
2721
  kendoChatScrollableButton
2694
2722
  [prev]="true"
2695
2723
  [title]="getScrollButtonTitle('prev')"
2696
2724
  class="k-button k-button-md k-button-solid k-button-solid-base k-rounded-md k-icon-button"
2697
2725
  (onClick)="scrollSuggestions($event)"
2698
- >
2699
- </span>
2700
- <div class="k-suggestion-group" *ngIf="hasScrollButtons; else noScrollButtons"
2726
+ >
2727
+ </span>
2728
+ }
2729
+ @if (hasScrollButtons) {
2730
+ <div class="k-suggestion-group"
2701
2731
  #suggestionsContainer
2702
2732
  role="group"
2703
2733
  (scroll)="onScroll($event)">
2704
2734
  <ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
2705
- </div>
2706
-
2707
- <ng-template #noScrollButtons>
2708
- <ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
2709
- </ng-template>
2710
-
2735
+ </div>
2736
+ } @else {
2737
+ <ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
2738
+ }
2739
+
2740
+
2711
2741
  <ng-template #suggestionsContent>
2712
- <ng-container *ngIf="actions">
2713
- <span
2714
- #item
2715
- *ngFor="let action of actions; index as index; first as first; last as last"
2716
- class="k-suggestion k-suggestion-primary"
2717
- role="button"
2718
- [class.k-selected]="isSelected(index)"
2719
- [class.k-focus]="isSelected(index)"
2720
- [class.k-active]="isActive(index)"
2721
- [attr.tabindex]="0"
2722
- (click)="actionClick(action, index)"
2723
- (keydown)="actionKeydown($event, action)"
2724
- (mousedown)="toggleActiveState(true, index)"
2725
- (mouseup)="toggleActiveState(false, index)"
2742
+ @if (actions) {
2743
+ @for (action of actions; track action; let index = $index; let first = $first; let last = $last) {
2744
+ <span
2745
+ #item
2746
+ class="k-suggestion k-suggestion-primary"
2747
+ role="button"
2748
+ [class.k-selected]="isSelected(index)"
2749
+ [class.k-focus]="isSelected(index)"
2750
+ [class.k-active]="isActive(index)"
2751
+ [attr.tabindex]="0"
2752
+ (click)="actionClick(action, index)"
2753
+ (keydown)="actionKeydown($event, action)"
2754
+ (mousedown)="toggleActiveState(true, index)"
2755
+ (mouseup)="toggleActiveState(false, index)"
2726
2756
  >
2727
- {{ action.title || action.value }}
2757
+ {{ action.title || action.value }}
2758
+ </span>
2759
+ }
2760
+ }
2761
+
2762
+ @if (suggestions) {
2763
+ @if (!suggestionTemplate?.templateRef) {
2764
+ @for (suggestion of suggestions; track suggestion; let index = $index; let first = $first; let last = $last) {
2765
+ <span
2766
+ #item
2767
+ class="k-suggestion"
2768
+ role="button"
2769
+ [class.k-selected]="isSelected(index)"
2770
+ [class.k-focus]="isSelected(index)"
2771
+ [class.k-active]="isActive(index)"
2772
+ [attr.tabindex]="0"
2773
+ (click)="suggestionClick(suggestion, index)"
2774
+ (keydown)="suggestionKeydown($event, suggestion)"
2775
+ (mousedown)="toggleActiveState(true, index)"
2776
+ (mouseup)="toggleActiveState(false, index)"
2777
+ >
2778
+ {{ suggestion.text }}
2728
2779
  </span>
2729
- </ng-container>
2730
-
2731
- <ng-container *ngIf="suggestions">
2732
- <ng-container *ngIf="!suggestionTemplate?.templateRef">
2733
- <span
2734
- #item
2735
- *ngFor="let suggestion of suggestions; index as index; first as first; last as last"
2736
- class="k-suggestion"
2737
- role="button"
2738
- [class.k-selected]="isSelected(index)"
2739
- [class.k-focus]="isSelected(index)"
2740
- [class.k-active]="isActive(index)"
2741
- [attr.tabindex]="0"
2742
- (click)="suggestionClick(suggestion, index)"
2743
- (keydown)="suggestionKeydown($event, suggestion)"
2744
- (mousedown)="toggleActiveState(true, index)"
2745
- (mouseup)="toggleActiveState(false, index)"
2746
- >
2747
- {{ suggestion.text }}
2748
- </span>
2749
- </ng-container>
2750
-
2751
- <ng-container *ngIf="suggestionTemplate?.templateRef">
2752
- <ng-container *ngFor="let suggestion of suggestions">
2753
- <ng-template
2754
- [ngTemplateOutlet]="suggestionTemplate.templateRef"
2755
- [ngTemplateOutletContext]="{ $implicit: suggestion }"
2756
- >
2757
- </ng-template>
2758
- </ng-container>
2759
- </ng-container>
2760
- </ng-container>
2780
+ }
2781
+ }
2782
+ @if (suggestionTemplate?.templateRef) {
2783
+ @for (suggestion of suggestions; track suggestion) {
2784
+ <ng-template
2785
+ [ngTemplateOutlet]="suggestionTemplate.templateRef"
2786
+ [ngTemplateOutletContext]="{ $implicit: suggestion }"
2787
+ >
2788
+ </ng-template>
2789
+ }
2790
+ }
2791
+ }
2761
2792
  </ng-template>
2762
-
2763
- <span
2764
- *ngIf="hasScrollButtons"
2793
+
2794
+ @if (hasScrollButtons) {
2795
+ <span
2765
2796
  #nextScrollButton
2766
2797
  kendoChatScrollableButton
2767
2798
  [prev]="false"
2768
2799
  [title]="getScrollButtonTitle('next')"
2769
2800
  class="k-button k-button-md k-button-solid k-button-solid-base k-rounded-md k-icon-button"
2770
2801
  (onClick)="scrollSuggestions($event)"
2771
- >
2772
- </span>
2773
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ChatScrollableButtonComponent, selector: "[kendoChatScrollableButton]", inputs: ["prev"], outputs: ["onClick"] }] });
2802
+ >
2803
+ </span>
2804
+ }
2805
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ChatScrollableButtonComponent, selector: "[kendoChatScrollableButton]", inputs: ["prev"], outputs: ["onClick"] }] });
2774
2806
  }
2775
2807
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SuggestedActionsComponent, decorators: [{
2776
2808
  type: Component,
@@ -2782,92 +2814,96 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
2782
2814
  },
2783
2815
  SuggestionsScrollService],
2784
2816
  template: `
2785
- <span
2786
- *ngIf="hasScrollButtons"
2817
+ @if (hasScrollButtons) {
2818
+ <span
2787
2819
  #prevScrollButton
2788
2820
  kendoChatScrollableButton
2789
2821
  [prev]="true"
2790
2822
  [title]="getScrollButtonTitle('prev')"
2791
2823
  class="k-button k-button-md k-button-solid k-button-solid-base k-rounded-md k-icon-button"
2792
2824
  (onClick)="scrollSuggestions($event)"
2793
- >
2794
- </span>
2795
- <div class="k-suggestion-group" *ngIf="hasScrollButtons; else noScrollButtons"
2825
+ >
2826
+ </span>
2827
+ }
2828
+ @if (hasScrollButtons) {
2829
+ <div class="k-suggestion-group"
2796
2830
  #suggestionsContainer
2797
2831
  role="group"
2798
2832
  (scroll)="onScroll($event)">
2799
2833
  <ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
2800
- </div>
2801
-
2802
- <ng-template #noScrollButtons>
2803
- <ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
2804
- </ng-template>
2805
-
2834
+ </div>
2835
+ } @else {
2836
+ <ng-container *ngTemplateOutlet="suggestionsContent"></ng-container>
2837
+ }
2838
+
2839
+
2806
2840
  <ng-template #suggestionsContent>
2807
- <ng-container *ngIf="actions">
2808
- <span
2809
- #item
2810
- *ngFor="let action of actions; index as index; first as first; last as last"
2811
- class="k-suggestion k-suggestion-primary"
2812
- role="button"
2813
- [class.k-selected]="isSelected(index)"
2814
- [class.k-focus]="isSelected(index)"
2815
- [class.k-active]="isActive(index)"
2816
- [attr.tabindex]="0"
2817
- (click)="actionClick(action, index)"
2818
- (keydown)="actionKeydown($event, action)"
2819
- (mousedown)="toggleActiveState(true, index)"
2820
- (mouseup)="toggleActiveState(false, index)"
2841
+ @if (actions) {
2842
+ @for (action of actions; track action; let index = $index; let first = $first; let last = $last) {
2843
+ <span
2844
+ #item
2845
+ class="k-suggestion k-suggestion-primary"
2846
+ role="button"
2847
+ [class.k-selected]="isSelected(index)"
2848
+ [class.k-focus]="isSelected(index)"
2849
+ [class.k-active]="isActive(index)"
2850
+ [attr.tabindex]="0"
2851
+ (click)="actionClick(action, index)"
2852
+ (keydown)="actionKeydown($event, action)"
2853
+ (mousedown)="toggleActiveState(true, index)"
2854
+ (mouseup)="toggleActiveState(false, index)"
2821
2855
  >
2822
- {{ action.title || action.value }}
2856
+ {{ action.title || action.value }}
2857
+ </span>
2858
+ }
2859
+ }
2860
+
2861
+ @if (suggestions) {
2862
+ @if (!suggestionTemplate?.templateRef) {
2863
+ @for (suggestion of suggestions; track suggestion; let index = $index; let first = $first; let last = $last) {
2864
+ <span
2865
+ #item
2866
+ class="k-suggestion"
2867
+ role="button"
2868
+ [class.k-selected]="isSelected(index)"
2869
+ [class.k-focus]="isSelected(index)"
2870
+ [class.k-active]="isActive(index)"
2871
+ [attr.tabindex]="0"
2872
+ (click)="suggestionClick(suggestion, index)"
2873
+ (keydown)="suggestionKeydown($event, suggestion)"
2874
+ (mousedown)="toggleActiveState(true, index)"
2875
+ (mouseup)="toggleActiveState(false, index)"
2876
+ >
2877
+ {{ suggestion.text }}
2823
2878
  </span>
2824
- </ng-container>
2825
-
2826
- <ng-container *ngIf="suggestions">
2827
- <ng-container *ngIf="!suggestionTemplate?.templateRef">
2828
- <span
2829
- #item
2830
- *ngFor="let suggestion of suggestions; index as index; first as first; last as last"
2831
- class="k-suggestion"
2832
- role="button"
2833
- [class.k-selected]="isSelected(index)"
2834
- [class.k-focus]="isSelected(index)"
2835
- [class.k-active]="isActive(index)"
2836
- [attr.tabindex]="0"
2837
- (click)="suggestionClick(suggestion, index)"
2838
- (keydown)="suggestionKeydown($event, suggestion)"
2839
- (mousedown)="toggleActiveState(true, index)"
2840
- (mouseup)="toggleActiveState(false, index)"
2841
- >
2842
- {{ suggestion.text }}
2843
- </span>
2844
- </ng-container>
2845
-
2846
- <ng-container *ngIf="suggestionTemplate?.templateRef">
2847
- <ng-container *ngFor="let suggestion of suggestions">
2848
- <ng-template
2849
- [ngTemplateOutlet]="suggestionTemplate.templateRef"
2850
- [ngTemplateOutletContext]="{ $implicit: suggestion }"
2851
- >
2852
- </ng-template>
2853
- </ng-container>
2854
- </ng-container>
2855
- </ng-container>
2879
+ }
2880
+ }
2881
+ @if (suggestionTemplate?.templateRef) {
2882
+ @for (suggestion of suggestions; track suggestion) {
2883
+ <ng-template
2884
+ [ngTemplateOutlet]="suggestionTemplate.templateRef"
2885
+ [ngTemplateOutletContext]="{ $implicit: suggestion }"
2886
+ >
2887
+ </ng-template>
2888
+ }
2889
+ }
2890
+ }
2856
2891
  </ng-template>
2857
-
2858
- <span
2859
- *ngIf="hasScrollButtons"
2892
+
2893
+ @if (hasScrollButtons) {
2894
+ <span
2860
2895
  #nextScrollButton
2861
2896
  kendoChatScrollableButton
2862
2897
  [prev]="false"
2863
2898
  [title]="getScrollButtonTitle('next')"
2864
2899
  class="k-button k-button-md k-button-solid k-button-solid-base k-rounded-md k-icon-button"
2865
2900
  (onClick)="scrollSuggestions($event)"
2866
- >
2867
- </span>
2868
- `,
2901
+ >
2902
+ </span>
2903
+ }
2904
+ `,
2869
2905
  standalone: true,
2870
- imports: [NgFor, NgIf, NgTemplateOutlet, ChatScrollableButtonComponent]
2906
+ imports: [NgTemplateOutlet, ChatScrollableButtonComponent]
2871
2907
  }]
2872
2908
  }], ctorParameters: () => [{ type: ChatService }, { type: i1.LocalizationService }, { type: SuggestionsScrollService }, { type: i0.NgZone }, { type: i0.Renderer2 }], propDecorators: { defaultClass: [{
2873
2909
  type: HostBinding,
@@ -2942,30 +2978,31 @@ class ChatFileComponent extends ChatItem {
2942
2978
  }
2943
2979
  focus() { }
2944
2980
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatFileComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
2945
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatFileComponent, isStandalone: true, selector: "li[chatFile]", inputs: { chatFile: "chatFile", removable: "removable", fileActions: "fileActions" }, outputs: { remove: "remove", actionClick: "actionClick", actionsToggle: "actionsToggle", actionButtonClick: "actionButtonClick" }, providers: [{
2981
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ChatFileComponent, isStandalone: true, selector: "li[chatFile]", inputs: { chatFile: "chatFile", removable: "removable", fileActions: "fileActions" }, outputs: { remove: "remove", actionClick: "actionClick", actionsToggle: "actionsToggle", actionButtonClick: "actionButtonClick" }, providers: [{
2946
2982
  provide: ChatItem,
2947
2983
  useExisting: forwardRef(() => ChatFileComponent)
2948
2984
  }], usesInheritance: true, ngImport: i0, template: `
2949
2985
  <kendo-icon-wrapper
2950
- size="xlarge"
2951
- [name]="fileGroupClass(chatFile.extension)"
2952
- [svgIcon]="fileThumbnail(chatFile.extension)"
2953
- >
2986
+ size="xlarge"
2987
+ [name]="fileGroupClass(chatFile.extension)"
2988
+ [svgIcon]="fileThumbnail(chatFile.extension)"
2989
+ >
2954
2990
  </kendo-icon-wrapper>
2955
2991
  <div class="k-chat-file-info">
2956
- <span class="k-chat-file-name">{{chatFile.name}}</span>
2957
- <span class="k-chat-file-size">{{getTotalFilesSizeMessage(chatFile)}}</span>
2992
+ <span class="k-chat-file-name">{{chatFile.name}}</span>
2993
+ <span class="k-chat-file-size">{{getTotalFilesSizeMessage(chatFile)}}</span>
2958
2994
  </div>
2959
- <button
2995
+ @if (removable) {
2996
+ <button
2960
2997
  kendoButton
2961
- *ngIf="removable"
2962
2998
  [attr.title]="textFor('removeFileTitle')"
2963
2999
  [svgIcon]="deleteIcon"
2964
3000
  (click)="remove.emit(chatFile)"
2965
3001
  fillMode="flat"
2966
- ></button>
2967
- <kendo-dropdownbutton
2968
- *ngIf="fileActions && fileActions.length > 0"
3002
+ ></button>
3003
+ }
3004
+ @if (fileActions && fileActions.length > 0) {
3005
+ <kendo-dropdownbutton
2969
3006
  [data]="fileActions"
2970
3007
  [attr.title]="textFor('fileActionsTitle')"
2971
3008
  fillMode="flat"
@@ -2975,8 +3012,9 @@ class ChatFileComponent extends ChatItem {
2975
3012
  (click)="$event.preventDefault()"
2976
3013
  (open)="actionsToggle.emit(true)"
2977
3014
  (close)="actionsToggle.emit(false)"
2978
- ></kendo-dropdownbutton>
2979
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: DropDownButtonComponent, selector: "kendo-dropdownbutton", inputs: ["arrowIcon", "icon", "svgIcon", "iconClass", "imageUrl", "textField", "data", "size", "rounded", "fillMode", "themeColor", "buttonAttributes"], outputs: ["itemClick", "focus", "blur"], exportAs: ["kendoDropDownButton"] }] });
3015
+ ></kendo-dropdownbutton>
3016
+ }
3017
+ `, isInline: true, dependencies: [{ kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: DropDownButtonComponent, selector: "kendo-dropdownbutton", inputs: ["arrowIcon", "icon", "svgIcon", "iconClass", "imageUrl", "textField", "data", "size", "rounded", "fillMode", "themeColor", "buttonAttributes"], outputs: ["itemClick", "focus", "blur"], exportAs: ["kendoDropDownButton"] }] });
2980
3018
  }
2981
3019
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatFileComponent, decorators: [{
2982
3020
  type: Component,
@@ -2988,25 +3026,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
2988
3026
  }],
2989
3027
  template: `
2990
3028
  <kendo-icon-wrapper
2991
- size="xlarge"
2992
- [name]="fileGroupClass(chatFile.extension)"
2993
- [svgIcon]="fileThumbnail(chatFile.extension)"
2994
- >
3029
+ size="xlarge"
3030
+ [name]="fileGroupClass(chatFile.extension)"
3031
+ [svgIcon]="fileThumbnail(chatFile.extension)"
3032
+ >
2995
3033
  </kendo-icon-wrapper>
2996
3034
  <div class="k-chat-file-info">
2997
- <span class="k-chat-file-name">{{chatFile.name}}</span>
2998
- <span class="k-chat-file-size">{{getTotalFilesSizeMessage(chatFile)}}</span>
3035
+ <span class="k-chat-file-name">{{chatFile.name}}</span>
3036
+ <span class="k-chat-file-size">{{getTotalFilesSizeMessage(chatFile)}}</span>
2999
3037
  </div>
3000
- <button
3038
+ @if (removable) {
3039
+ <button
3001
3040
  kendoButton
3002
- *ngIf="removable"
3003
3041
  [attr.title]="textFor('removeFileTitle')"
3004
3042
  [svgIcon]="deleteIcon"
3005
3043
  (click)="remove.emit(chatFile)"
3006
3044
  fillMode="flat"
3007
- ></button>
3008
- <kendo-dropdownbutton
3009
- *ngIf="fileActions && fileActions.length > 0"
3045
+ ></button>
3046
+ }
3047
+ @if (fileActions && fileActions.length > 0) {
3048
+ <kendo-dropdownbutton
3010
3049
  [data]="fileActions"
3011
3050
  [attr.title]="textFor('fileActionsTitle')"
3012
3051
  fillMode="flat"
@@ -3016,10 +3055,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
3016
3055
  (click)="$event.preventDefault()"
3017
3056
  (open)="actionsToggle.emit(true)"
3018
3057
  (close)="actionsToggle.emit(false)"
3019
- ></kendo-dropdownbutton>
3020
- `,
3058
+ ></kendo-dropdownbutton>
3059
+ }
3060
+ `,
3021
3061
  standalone: true,
3022
- imports: [NgIf, IconWrapperComponent, ButtonComponent, DropDownButtonComponent]
3062
+ imports: [IconWrapperComponent, ButtonComponent, DropDownButtonComponent]
3023
3063
  }]
3024
3064
  }], ctorParameters: () => [{ type: i1.LocalizationService }], propDecorators: { chatFile: [{
3025
3065
  type: Input
@@ -3095,7 +3135,7 @@ const groupItems = (total) => (acc, msg, index) => {
3095
3135
  attachments: msg.attachments,
3096
3136
  attachmentLayout: msg.attachmentLayout,
3097
3137
  timestamp: msg.timestamp,
3098
- trackBy: msg
3138
+ trackBy: 'attachment-group' + msg.id
3099
3139
  });
3100
3140
  }
3101
3141
  if (msg.suggestedActions && isLastMessage) {
@@ -3103,7 +3143,7 @@ const groupItems = (total) => (acc, msg, index) => {
3103
3143
  type: 'action-group',
3104
3144
  actions: msg.suggestedActions,
3105
3145
  timestamp: msg.timestamp,
3106
- trackBy: msg
3146
+ trackBy: 'action-group' + msg.id
3107
3147
  });
3108
3148
  }
3109
3149
  return acc;
@@ -3135,18 +3175,24 @@ class MessageReferenceComponent extends ChatItem {
3135
3175
  }
3136
3176
  focus() { }
3137
3177
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageReferenceComponent, deps: [{ token: i1.LocalizationService }, { token: ChatService }], target: i0.ɵɵFactoryTarget.Component });
3138
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MessageReferenceComponent, isStandalone: true, selector: "chat-message-reference-content", inputs: { message: "message" }, host: { properties: { "class.k-message-reference-content": "this.hostClass" } }, providers: [{
3178
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MessageReferenceComponent, isStandalone: true, selector: "chat-message-reference-content", inputs: { message: "message" }, host: { properties: { "class.k-message-reference-content": "this.hostClass" } }, providers: [{
3139
3179
  provide: ChatItem,
3140
3180
  useExisting: forwardRef(() => MessageReferenceComponent)
3141
3181
  }], usesInheritance: true, ngImport: i0, template: `
3142
- <ng-container *ngIf="message.text && !message.isDeleted">{{message.text}}</ng-container>
3143
- <ng-container *ngIf="!message.text && !message.isDeleted && message.files && message.files.length > 0">
3144
- <li class="k-chat-file" [chatFile]="message.files[0]">
3145
- </li>
3146
- </ng-container>
3147
- <ng-container *ngIf="message.isDeleted && isOwnMessage(message)">{{ textFor('deletedMessageSenderText') }}</ng-container>
3148
- <ng-container *ngIf="message.isDeleted && !isOwnMessage(message)">{{ textFor('deletedMessageReceiverText') }}</ng-container>
3149
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
3182
+ @if (message.text && !message.isDeleted) {
3183
+ {{message.text}}
3184
+ }
3185
+ @if (!message.text && !message.isDeleted && message.files && message.files.length > 0) {
3186
+ <li class="k-chat-file" [chatFile]="message.files[0]">
3187
+ </li>
3188
+ }
3189
+ @if (message.isDeleted && isOwnMessage(message)) {
3190
+ {{ textFor('deletedMessageSenderText') }}
3191
+ }
3192
+ @if (message.isDeleted && !isOwnMessage(message)) {
3193
+ {{ textFor('deletedMessageReceiverText') }}
3194
+ }
3195
+ `, isInline: true, dependencies: [{ kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
3150
3196
  }
3151
3197
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageReferenceComponent, decorators: [{
3152
3198
  type: Component,
@@ -3157,16 +3203,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
3157
3203
  useExisting: forwardRef(() => MessageReferenceComponent)
3158
3204
  }],
3159
3205
  template: `
3160
- <ng-container *ngIf="message.text && !message.isDeleted">{{message.text}}</ng-container>
3161
- <ng-container *ngIf="!message.text && !message.isDeleted && message.files && message.files.length > 0">
3162
- <li class="k-chat-file" [chatFile]="message.files[0]">
3163
- </li>
3164
- </ng-container>
3165
- <ng-container *ngIf="message.isDeleted && isOwnMessage(message)">{{ textFor('deletedMessageSenderText') }}</ng-container>
3166
- <ng-container *ngIf="message.isDeleted && !isOwnMessage(message)">{{ textFor('deletedMessageReceiverText') }}</ng-container>
3167
- `,
3206
+ @if (message.text && !message.isDeleted) {
3207
+ {{message.text}}
3208
+ }
3209
+ @if (!message.text && !message.isDeleted && message.files && message.files.length > 0) {
3210
+ <li class="k-chat-file" [chatFile]="message.files[0]">
3211
+ </li>
3212
+ }
3213
+ @if (message.isDeleted && isOwnMessage(message)) {
3214
+ {{ textFor('deletedMessageSenderText') }}
3215
+ }
3216
+ @if (message.isDeleted && !isOwnMessage(message)) {
3217
+ {{ textFor('deletedMessageReceiverText') }}
3218
+ }
3219
+ `,
3168
3220
  standalone: true,
3169
- imports: [NgIf, ChatFileComponent]
3221
+ imports: [ChatFileComponent]
3170
3222
  }]
3171
3223
  }], ctorParameters: () => [{ type: i1.LocalizationService }, { type: ChatService }], propDecorators: { hostClass: [{
3172
3224
  type: HostBinding,
@@ -3371,9 +3423,9 @@ class MessageBoxComponent {
3371
3423
  this.executeSuggestion.emit(suggestion);
3372
3424
  }
3373
3425
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageBoxComponent, deps: [{ token: ChatService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
3374
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MessageBoxComponent, isStandalone: true, selector: "kendo-message-box", inputs: { authorId: "authorId", autoScroll: "autoScroll", suggestions: "suggestions", placeholder: "placeholder", inputValue: "inputValue", localization: "localization", messageBoxTemplate: "messageBoxTemplate", suggestionTemplate: "suggestionTemplate" }, outputs: { sendMessage: "sendMessage", executeSuggestion: "executeSuggestion", fileSelect: "fileSelect", fileRemove: "fileRemove" }, host: { properties: { "style.border-color": "this.borderColor", "class.k-message-box-wrapper": "this.messageBoxWrapperClass" } }, viewQueries: [{ propertyName: "messageBoxInput", first: true, predicate: ["messageBoxInput"], descendants: true }, { propertyName: "fileSelectComponent", first: true, predicate: ["fileSelect"], descendants: true }, { propertyName: "suggestedActionsComponent", first: true, predicate: SuggestedActionsComponent, descendants: true }], ngImport: i0, template: `
3375
- <kendo-chat-suggested-actions
3376
- *ngIf="suggestions?.length > 0"
3426
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MessageBoxComponent, isStandalone: true, selector: "kendo-message-box", inputs: { authorId: "authorId", autoScroll: "autoScroll", suggestions: "suggestions", placeholder: "placeholder", inputValue: "inputValue", localization: "localization", messageBoxTemplate: "messageBoxTemplate", suggestionTemplate: "suggestionTemplate" }, outputs: { sendMessage: "sendMessage", executeSuggestion: "executeSuggestion", fileSelect: "fileSelect", fileRemove: "fileRemove" }, host: { properties: { "style.border-color": "this.borderColor", "class.k-message-box-wrapper": "this.messageBoxWrapperClass" } }, viewQueries: [{ propertyName: "messageBoxInput", first: true, predicate: ["messageBoxInput"], descendants: true }, { propertyName: "fileSelectComponent", first: true, predicate: ["fileSelect"], descendants: true }, { propertyName: "suggestedActionsComponent", first: true, predicate: SuggestedActionsComponent, descendants: true }], ngImport: i0, template: `
3427
+ @if (suggestions?.length > 0) {
3428
+ <kendo-chat-suggested-actions
3377
3429
  #suggestedActions
3378
3430
  [suggestions]="suggestions"
3379
3431
  type="suggestion"
@@ -3382,110 +3434,120 @@ class MessageBoxComponent {
3382
3434
  (dispatchSuggestion)="dispatchSuggestion($event)"
3383
3435
  (click)="select(suggestedActions, $event)"
3384
3436
  (focus)="select(suggestedActions, $event)"
3385
- ></kendo-chat-suggested-actions>
3386
-
3387
- <ng-container *ngIf="!messageBoxTemplate?.templateRef">
3388
- <kendo-textarea
3389
- #messageBoxInput
3390
- class="k-message-box"
3391
- resizable="none"
3392
- [rows]="3"
3437
+ ></kendo-chat-suggested-actions>
3438
+ }
3439
+
3440
+ @if (!messageBoxTemplate?.templateRef) {
3441
+ <kendo-textarea
3442
+ #messageBoxInput
3443
+ class="k-message-box"
3444
+ resizable="none"
3445
+ [rows]="3"
3393
3446
  [inputAttributes]="{
3394
3447
  'aria-label': textFor('messageBoxInputLabel')
3395
3448
  }"
3396
- [placeholder]="placeholder || textFor('messagePlaceholder')"
3397
- [showSuffixSeparator]="false"
3398
- (keydown)="textAreaKeydown($event)"
3399
- [value]="inputValue"
3400
- (valueChange)="onInputValueChange($event)"
3449
+ [placeholder]="placeholder || textFor('messagePlaceholder')"
3450
+ [showSuffixSeparator]="false"
3451
+ (keydown)="textAreaKeydown($event)"
3452
+ [value]="inputValue"
3453
+ (valueChange)="onInputValueChange($event)"
3401
3454
  >
3402
- <kendo-textarea-prefix *ngIf="reply || (files && files.length > 0)">
3403
- <div class="k-message-reference k-message-reference-sender" *ngIf="reply" (click)="onReplyReferenceClick($event)">
3404
- <chat-message-reference-content [message]="reply"></chat-message-reference-content>
3405
- <span class="k-spacer"></span>
3406
- <button
3407
- kendoButton
3408
- [attr.title]="textFor('removeReplyTitle')"
3409
- [svgIcon]="deleteIcon"
3410
- (click)="removeReply()"
3411
- fillMode="flat"
3412
- ></button>
3413
- </div>
3414
- <ul class="k-chat-file-wrapper">
3415
- <li class="k-chat-file"
3416
- *ngFor="let file of files; let i = index"
3417
- [chatFile]="file"
3418
- [removable]="true"
3419
- (remove)="removeFile(i)"
3420
- ></li>
3421
- </ul>
3422
- </kendo-textarea-prefix>
3423
-
3424
- <kendo-textarea-suffix>
3425
- <button *ngIf="speechToTextButtonSettings"
3426
- kendoSpeechToTextButton
3427
- [attr.title]="textFor('speechToTextButtonTitle')"
3428
- [continuous]="speechToTextButtonSettings?.continuous"
3429
- [disabled]="speechToTextButtonSettings?.disabled"
3430
- [fillMode]="speechToTextButtonSettings?.fillMode ?? 'clear'"
3431
- [integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
3432
- [interimResults]="speechToTextButtonSettings?.interimResults"
3433
- [lang]="speechToTextButtonSettings?.lang"
3434
- [maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
3435
- [rounded]="speechToTextButtonSettings?.rounded"
3436
- [size]="speechToTextButtonSettings?.size"
3437
- [themeColor]="speechToTextButtonSettings?.themeColor"
3438
- (result)="handleSpeechResult($event)"
3439
- (start)="isListening = true"
3440
- (end)="isListening = false"
3441
- ></button>
3455
+ @if (reply || (files && files.length > 0)) {
3456
+ <kendo-textarea-prefix>
3457
+ @if (reply) {
3458
+ <div class="k-message-reference k-message-reference-sender" (click)="onReplyReferenceClick($event)">
3459
+ <chat-message-reference-content [message]="reply"></chat-message-reference-content>
3460
+ <span class="k-spacer"></span>
3442
3461
  <button
3443
- kendoButton
3444
- *ngIf="enableFileSelect"
3445
- [attr.title]="textFor('fileSelectButtonTitle')"
3446
- [svgIcon]="attachmentIcon"
3447
- icon="attachment"
3448
- fillMode="clear"
3449
- (click)="selectFiles()"
3462
+ kendoButton
3463
+ [attr.title]="textFor('removeReplyTitle')"
3464
+ [svgIcon]="deleteIcon"
3465
+ (click)="removeReply()"
3466
+ fillMode="flat"
3450
3467
  ></button>
3451
- <kendo-input-spacer></kendo-input-spacer>
3452
- <button
3453
- kendoButton
3454
- [fillMode]="sendButtonSettings?.fillMode"
3455
- [themeColor]="sendButtonSettings?.themeColor"
3456
- [rounded]="sendButtonSettings?.rounded"
3457
- [class]="sendButtonSettings?.buttonClass || 'k-chat-send'"
3458
- [icon]="sendButtonSettings?.icon"
3459
- [svgIcon]="sendButtonSettings?.svgIcon"
3460
- [tabindex]="0"
3461
- [attr.title]="textFor('send')"
3462
- [class.k-disabled]="isDisabledSendButton"
3463
- [attr.aria-disabled]="isDisabledSendButton"
3464
- (click)="sendClick()"
3465
- >
3466
- </button>
3467
- </kendo-textarea-suffix>
3468
- </kendo-textarea>
3469
- </ng-container>
3470
-
3471
- <ng-template *ngIf="messageBoxTemplate?.templateRef" [ngTemplateOutlet]="messageBoxTemplate?.templateRef"></ng-template>
3472
-
3468
+ </div>
3469
+ }
3470
+ <ul class="k-chat-file-wrapper">
3471
+ @for (file of files; track file; let i = $index) {
3472
+ <li class="k-chat-file"
3473
+ [chatFile]="file"
3474
+ [removable]="true"
3475
+ (remove)="removeFile(i)"
3476
+ ></li>
3477
+ }
3478
+ </ul>
3479
+ </kendo-textarea-prefix>
3480
+ }
3481
+ <kendo-textarea-suffix>
3482
+ @if (speechToTextButtonSettings) {
3483
+ <button
3484
+ kendoSpeechToTextButton
3485
+ [attr.title]="textFor('speechToTextButtonTitle')"
3486
+ [continuous]="speechToTextButtonSettings?.continuous"
3487
+ [disabled]="speechToTextButtonSettings?.disabled"
3488
+ [fillMode]="speechToTextButtonSettings?.fillMode ?? 'clear'"
3489
+ [integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
3490
+ [interimResults]="speechToTextButtonSettings?.interimResults"
3491
+ [lang]="speechToTextButtonSettings?.lang"
3492
+ [maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
3493
+ [rounded]="speechToTextButtonSettings?.rounded"
3494
+ [size]="speechToTextButtonSettings?.size"
3495
+ [themeColor]="speechToTextButtonSettings?.themeColor"
3496
+ (result)="handleSpeechResult($event)"
3497
+ (start)="isListening = true"
3498
+ (end)="isListening = false"
3499
+ ></button>
3500
+ }
3501
+ @if (enableFileSelect) {
3502
+ <button
3503
+ kendoButton
3504
+ [attr.title]="textFor('fileSelectButtonTitle')"
3505
+ [svgIcon]="attachmentIcon"
3506
+ icon="attachment"
3507
+ fillMode="clear"
3508
+ (click)="selectFiles()"
3509
+ ></button>
3510
+ }
3511
+ <kendo-input-spacer></kendo-input-spacer>
3512
+ <button
3513
+ kendoButton
3514
+ [fillMode]="sendButtonSettings?.fillMode"
3515
+ [themeColor]="sendButtonSettings?.themeColor"
3516
+ [rounded]="sendButtonSettings?.rounded"
3517
+ [class]="sendButtonSettings?.buttonClass || 'k-chat-send'"
3518
+ [icon]="sendButtonSettings?.icon"
3519
+ [svgIcon]="sendButtonSettings?.svgIcon"
3520
+ [tabindex]="0"
3521
+ [attr.title]="textFor('send')"
3522
+ [class.k-disabled]="isDisabledSendButton"
3523
+ [attr.aria-disabled]="isDisabledSendButton"
3524
+ (click)="sendClick()"
3525
+ >
3526
+ </button>
3527
+ </kendo-textarea-suffix>
3528
+ </kendo-textarea>
3529
+ }
3530
+
3531
+ @if (messageBoxTemplate?.templateRef) {
3532
+ <ng-template [ngTemplateOutlet]="messageBoxTemplate?.templateRef"></ng-template>
3533
+ }
3534
+
3473
3535
  <kendo-fileselect
3474
- #fileSelect
3475
- class="k-hidden"
3476
- [multiple]="true"
3477
- [showFileList]="false"
3478
- (select)="handleFileSelect($event)"
3536
+ #fileSelect
3537
+ class="k-hidden"
3538
+ [multiple]="true"
3539
+ [showFileList]="false"
3540
+ (select)="handleFileSelect($event)"
3479
3541
  ></kendo-fileselect>
3480
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: TextAreaSuffixComponent, selector: "kendo-textarea-suffix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaSuffix"] }, { kind: "component", type: TextAreaPrefixComponent, selector: "kendo-textarea-prefix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaPrefix"] }, { kind: "component", type: SpeechToTextButtonComponent, selector: "button[kendoSpeechToTextButton]", inputs: ["disabled", "size", "rounded", "fillMode", "themeColor", "integrationMode", "lang", "continuous", "interimResults", "maxAlternatives"], outputs: ["start", "end", "result", "error", "click"], exportAs: ["kendoSpeechToTextButton"] }, { kind: "component", type: InputSpacerComponent, selector: "kendo-input-spacer, kendo-textbox-spacer", inputs: ["width"] }, { kind: "component", type: FileSelectComponent, selector: "kendo-fileselect", inputs: ["name"], outputs: ["valueChange"], exportAs: ["kendoFileSelect"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "type", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
3542
+ `, isInline: true, dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: TextAreaSuffixComponent, selector: "kendo-textarea-suffix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaSuffix"] }, { kind: "component", type: TextAreaPrefixComponent, selector: "kendo-textarea-prefix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaPrefix"] }, { kind: "component", type: SpeechToTextButtonComponent, selector: "button[kendoSpeechToTextButton]", inputs: ["disabled", "size", "rounded", "fillMode", "themeColor", "integrationMode", "lang", "continuous", "interimResults", "maxAlternatives"], outputs: ["start", "end", "result", "error", "click"], exportAs: ["kendoSpeechToTextButton"] }, { kind: "component", type: InputSpacerComponent, selector: "kendo-input-spacer, kendo-textbox-spacer", inputs: ["width"] }, { kind: "component", type: FileSelectComponent, selector: "kendo-fileselect", inputs: ["name"], outputs: ["valueChange"], exportAs: ["kendoFileSelect"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "type", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }] });
3481
3543
  }
3482
3544
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageBoxComponent, decorators: [{
3483
3545
  type: Component,
3484
3546
  args: [{
3485
3547
  selector: 'kendo-message-box',
3486
3548
  template: `
3487
- <kendo-chat-suggested-actions
3488
- *ngIf="suggestions?.length > 0"
3549
+ @if (suggestions?.length > 0) {
3550
+ <kendo-chat-suggested-actions
3489
3551
  #suggestedActions
3490
3552
  [suggestions]="suggestions"
3491
3553
  type="suggestion"
@@ -3494,104 +3556,114 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
3494
3556
  (dispatchSuggestion)="dispatchSuggestion($event)"
3495
3557
  (click)="select(suggestedActions, $event)"
3496
3558
  (focus)="select(suggestedActions, $event)"
3497
- ></kendo-chat-suggested-actions>
3498
-
3499
- <ng-container *ngIf="!messageBoxTemplate?.templateRef">
3500
- <kendo-textarea
3501
- #messageBoxInput
3502
- class="k-message-box"
3503
- resizable="none"
3504
- [rows]="3"
3559
+ ></kendo-chat-suggested-actions>
3560
+ }
3561
+
3562
+ @if (!messageBoxTemplate?.templateRef) {
3563
+ <kendo-textarea
3564
+ #messageBoxInput
3565
+ class="k-message-box"
3566
+ resizable="none"
3567
+ [rows]="3"
3505
3568
  [inputAttributes]="{
3506
3569
  'aria-label': textFor('messageBoxInputLabel')
3507
3570
  }"
3508
- [placeholder]="placeholder || textFor('messagePlaceholder')"
3509
- [showSuffixSeparator]="false"
3510
- (keydown)="textAreaKeydown($event)"
3511
- [value]="inputValue"
3512
- (valueChange)="onInputValueChange($event)"
3571
+ [placeholder]="placeholder || textFor('messagePlaceholder')"
3572
+ [showSuffixSeparator]="false"
3573
+ (keydown)="textAreaKeydown($event)"
3574
+ [value]="inputValue"
3575
+ (valueChange)="onInputValueChange($event)"
3513
3576
  >
3514
- <kendo-textarea-prefix *ngIf="reply || (files && files.length > 0)">
3515
- <div class="k-message-reference k-message-reference-sender" *ngIf="reply" (click)="onReplyReferenceClick($event)">
3516
- <chat-message-reference-content [message]="reply"></chat-message-reference-content>
3517
- <span class="k-spacer"></span>
3518
- <button
3519
- kendoButton
3520
- [attr.title]="textFor('removeReplyTitle')"
3521
- [svgIcon]="deleteIcon"
3522
- (click)="removeReply()"
3523
- fillMode="flat"
3524
- ></button>
3525
- </div>
3526
- <ul class="k-chat-file-wrapper">
3527
- <li class="k-chat-file"
3528
- *ngFor="let file of files; let i = index"
3529
- [chatFile]="file"
3530
- [removable]="true"
3531
- (remove)="removeFile(i)"
3532
- ></li>
3533
- </ul>
3534
- </kendo-textarea-prefix>
3535
-
3536
- <kendo-textarea-suffix>
3537
- <button *ngIf="speechToTextButtonSettings"
3538
- kendoSpeechToTextButton
3539
- [attr.title]="textFor('speechToTextButtonTitle')"
3540
- [continuous]="speechToTextButtonSettings?.continuous"
3541
- [disabled]="speechToTextButtonSettings?.disabled"
3542
- [fillMode]="speechToTextButtonSettings?.fillMode ?? 'clear'"
3543
- [integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
3544
- [interimResults]="speechToTextButtonSettings?.interimResults"
3545
- [lang]="speechToTextButtonSettings?.lang"
3546
- [maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
3547
- [rounded]="speechToTextButtonSettings?.rounded"
3548
- [size]="speechToTextButtonSettings?.size"
3549
- [themeColor]="speechToTextButtonSettings?.themeColor"
3550
- (result)="handleSpeechResult($event)"
3551
- (start)="isListening = true"
3552
- (end)="isListening = false"
3553
- ></button>
3577
+ @if (reply || (files && files.length > 0)) {
3578
+ <kendo-textarea-prefix>
3579
+ @if (reply) {
3580
+ <div class="k-message-reference k-message-reference-sender" (click)="onReplyReferenceClick($event)">
3581
+ <chat-message-reference-content [message]="reply"></chat-message-reference-content>
3582
+ <span class="k-spacer"></span>
3554
3583
  <button
3555
- kendoButton
3556
- *ngIf="enableFileSelect"
3557
- [attr.title]="textFor('fileSelectButtonTitle')"
3558
- [svgIcon]="attachmentIcon"
3559
- icon="attachment"
3560
- fillMode="clear"
3561
- (click)="selectFiles()"
3584
+ kendoButton
3585
+ [attr.title]="textFor('removeReplyTitle')"
3586
+ [svgIcon]="deleteIcon"
3587
+ (click)="removeReply()"
3588
+ fillMode="flat"
3562
3589
  ></button>
3563
- <kendo-input-spacer></kendo-input-spacer>
3564
- <button
3565
- kendoButton
3566
- [fillMode]="sendButtonSettings?.fillMode"
3567
- [themeColor]="sendButtonSettings?.themeColor"
3568
- [rounded]="sendButtonSettings?.rounded"
3569
- [class]="sendButtonSettings?.buttonClass || 'k-chat-send'"
3570
- [icon]="sendButtonSettings?.icon"
3571
- [svgIcon]="sendButtonSettings?.svgIcon"
3572
- [tabindex]="0"
3573
- [attr.title]="textFor('send')"
3574
- [class.k-disabled]="isDisabledSendButton"
3575
- [attr.aria-disabled]="isDisabledSendButton"
3576
- (click)="sendClick()"
3577
- >
3578
- </button>
3579
- </kendo-textarea-suffix>
3580
- </kendo-textarea>
3581
- </ng-container>
3582
-
3583
- <ng-template *ngIf="messageBoxTemplate?.templateRef" [ngTemplateOutlet]="messageBoxTemplate?.templateRef"></ng-template>
3584
-
3590
+ </div>
3591
+ }
3592
+ <ul class="k-chat-file-wrapper">
3593
+ @for (file of files; track file; let i = $index) {
3594
+ <li class="k-chat-file"
3595
+ [chatFile]="file"
3596
+ [removable]="true"
3597
+ (remove)="removeFile(i)"
3598
+ ></li>
3599
+ }
3600
+ </ul>
3601
+ </kendo-textarea-prefix>
3602
+ }
3603
+ <kendo-textarea-suffix>
3604
+ @if (speechToTextButtonSettings) {
3605
+ <button
3606
+ kendoSpeechToTextButton
3607
+ [attr.title]="textFor('speechToTextButtonTitle')"
3608
+ [continuous]="speechToTextButtonSettings?.continuous"
3609
+ [disabled]="speechToTextButtonSettings?.disabled"
3610
+ [fillMode]="speechToTextButtonSettings?.fillMode ?? 'clear'"
3611
+ [integrationMode]="speechToTextButtonSettings?.integrationMode ?? 'webSpeech'"
3612
+ [interimResults]="speechToTextButtonSettings?.interimResults"
3613
+ [lang]="speechToTextButtonSettings?.lang"
3614
+ [maxAlternatives]="speechToTextButtonSettings?.maxAlternatives"
3615
+ [rounded]="speechToTextButtonSettings?.rounded"
3616
+ [size]="speechToTextButtonSettings?.size"
3617
+ [themeColor]="speechToTextButtonSettings?.themeColor"
3618
+ (result)="handleSpeechResult($event)"
3619
+ (start)="isListening = true"
3620
+ (end)="isListening = false"
3621
+ ></button>
3622
+ }
3623
+ @if (enableFileSelect) {
3624
+ <button
3625
+ kendoButton
3626
+ [attr.title]="textFor('fileSelectButtonTitle')"
3627
+ [svgIcon]="attachmentIcon"
3628
+ icon="attachment"
3629
+ fillMode="clear"
3630
+ (click)="selectFiles()"
3631
+ ></button>
3632
+ }
3633
+ <kendo-input-spacer></kendo-input-spacer>
3634
+ <button
3635
+ kendoButton
3636
+ [fillMode]="sendButtonSettings?.fillMode"
3637
+ [themeColor]="sendButtonSettings?.themeColor"
3638
+ [rounded]="sendButtonSettings?.rounded"
3639
+ [class]="sendButtonSettings?.buttonClass || 'k-chat-send'"
3640
+ [icon]="sendButtonSettings?.icon"
3641
+ [svgIcon]="sendButtonSettings?.svgIcon"
3642
+ [tabindex]="0"
3643
+ [attr.title]="textFor('send')"
3644
+ [class.k-disabled]="isDisabledSendButton"
3645
+ [attr.aria-disabled]="isDisabledSendButton"
3646
+ (click)="sendClick()"
3647
+ >
3648
+ </button>
3649
+ </kendo-textarea-suffix>
3650
+ </kendo-textarea>
3651
+ }
3652
+
3653
+ @if (messageBoxTemplate?.templateRef) {
3654
+ <ng-template [ngTemplateOutlet]="messageBoxTemplate?.templateRef"></ng-template>
3655
+ }
3656
+
3585
3657
  <kendo-fileselect
3586
- #fileSelect
3587
- class="k-hidden"
3588
- [multiple]="true"
3589
- [showFileList]="false"
3590
- (select)="handleFileSelect($event)"
3658
+ #fileSelect
3659
+ class="k-hidden"
3660
+ [multiple]="true"
3661
+ [showFileList]="false"
3662
+ (select)="handleFileSelect($event)"
3591
3663
  ></kendo-fileselect>
3592
- `,
3664
+ `,
3593
3665
  standalone: true,
3594
- imports: [NgIf, NgFor, ButtonComponent, FormsModule, NgTemplateOutlet, TextAreaComponent, MessageReferenceComponent, TextAreaSuffixComponent, TextAreaPrefixComponent, SpeechToTextButtonComponent, InputSpacerComponent, FileSelectComponent, SuggestedActionsComponent, ChatFileComponent]
3666
+ imports: [ButtonComponent, FormsModule, NgTemplateOutlet, TextAreaComponent, MessageReferenceComponent, TextAreaSuffixComponent, TextAreaPrefixComponent, SpeechToTextButtonComponent, InputSpacerComponent, FileSelectComponent, SuggestedActionsComponent, ChatFileComponent]
3595
3667
  }]
3596
3668
  }], ctorParameters: () => [{ type: ChatService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { borderColor: [{
3597
3669
  type: HostBinding,
@@ -4098,7 +4170,7 @@ class MessageComponent extends ChatItem {
4098
4170
  this.chatService.toggleMessageState = false;
4099
4171
  }
4100
4172
  onExpandableKeydown(event) {
4101
- const key = normalizeNumpadKeys(event);
4173
+ const key = normalizeKeys(event);
4102
4174
  const isFileActionButton = event.target.closest(FILE_ACTION_BTN_SELECTOR) || event.target.closest(DOWNLOAD_ALL_SELECTOR);
4103
4175
  if (!isFileActionButton && (key === Keys.Enter || key === Keys.Space)) {
4104
4176
  event.preventDefault();
@@ -4203,178 +4275,188 @@ class MessageComponent extends ChatItem {
4203
4275
  return transformActions(actions);
4204
4276
  }
4205
4277
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageComponent, deps: [{ token: i0.ElementRef }, { token: i1$1.IntlService }, { token: ChatService }, { token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4206
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MessageComponent, isStandalone: true, selector: "kendo-chat-message", inputs: { message: "message", tabbable: "tabbable", authorMessageContentTemplate: "authorMessageContentTemplate", receiverMessageContentTemplate: "receiverMessageContentTemplate", messageContentTemplate: "messageContentTemplate", authorMessageTemplate: "authorMessageTemplate", receiverMessageTemplate: "receiverMessageTemplate", messageTemplate: "messageTemplate", statusTemplate: "statusTemplate", showMessageTime: "showMessageTime", authorId: "authorId" }, host: { listeners: { "keydown": "onKeyDown($event)" }, properties: { "class.k-message": "this.cssClass", "class.k-message-removed": "this.removedClass", "attr.tabIndex": "this.tabIndex" } }, providers: [
4278
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MessageComponent, isStandalone: true, selector: "kendo-chat-message", inputs: { message: "message", tabbable: "tabbable", authorMessageContentTemplate: "authorMessageContentTemplate", receiverMessageContentTemplate: "receiverMessageContentTemplate", messageContentTemplate: "messageContentTemplate", authorMessageTemplate: "authorMessageTemplate", receiverMessageTemplate: "receiverMessageTemplate", messageTemplate: "messageTemplate", statusTemplate: "statusTemplate", showMessageTime: "showMessageTime", authorId: "authorId" }, host: { listeners: { "keydown": "onKeyDown($event)" }, properties: { "class.k-message": "this.cssClass", "class.k-message-removed": "this.removedClass", "attr.tabIndex": "this.tabIndex" } }, providers: [
4207
4279
  {
4208
4280
  provide: ChatItem,
4209
4281
  useExisting: forwardRef(() => MessageComponent)
4210
4282
  }
4211
4283
  ], usesInheritance: true, ngImport: i0, template: `
4212
- <ng-container *ngIf="useCustomBubbleTemplate">
4213
- <ng-container *ngTemplateOutlet="getActiveBubbleTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
4214
- </ng-container>
4284
+ @if (useCustomBubbleTemplate) {
4285
+ <ng-container *ngTemplateOutlet="getActiveBubbleTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
4286
+ }
4215
4287
 
4216
- <ng-container *ngIf="!useCustomBubbleTemplate">
4288
+ @if (!useCustomBubbleTemplate) {
4289
+ @if (chatService.timestampVisibility === 'focus' && message.timestamp) {
4217
4290
  <time
4218
- [attr.aria-hidden]="!selected"
4219
- class="k-message-time"
4220
- *ngIf="chatService.timestampVisibility === 'focus' && message.timestamp"
4221
- >
4222
- {{ formatTimeStamp(message.timestamp) }}
4291
+ [attr.aria-hidden]="!selected"
4292
+ class="k-message-time"
4293
+ >
4294
+ {{ formatTimeStamp(message.timestamp) }}
4223
4295
  </time>
4224
-
4225
- <ng-container *ngIf="message.typing">
4226
- <div class="k-chat-bubble k-bubble">
4227
- <div class="k-typing-indicator" [attr.tabindex]="'-1'">
4228
- <span></span>
4229
- <span></span>
4230
- <span></span>
4231
- </div>
4232
- </div>
4233
- </ng-container>
4234
-
4235
- <ng-container *ngIf="!message.typing">
4236
- <div
4237
- class="k-chat-bubble k-bubble"
4238
- *ngIf="useCustomContentTemplate"
4239
- [attr.tabindex]="0"
4296
+ }
4297
+ @if (message.typing) {
4298
+ <div class="k-chat-bubble k-bubble">
4299
+ <div class="k-typing-indicator" [attr.tabindex]="'-1'">
4300
+ <span></span>
4301
+ <span></span>
4302
+ <span></span>
4303
+ </div>
4304
+ </div>
4305
+ }
4306
+ @if (!message.typing) {
4307
+ @if (useCustomContentTemplate) {
4308
+ <div
4309
+ class="k-chat-bubble k-bubble"
4310
+ [attr.tabindex]="0"
4240
4311
  [ngClass]="{
4241
- 'k-bubble-expandable': isMessageExpandable,
4312
+ 'k-bubble-expandable': isMessageExpandable,
4242
4313
  'k-expanded': isMessageExpanded,
4243
- 'k-selected': selected,
4314
+ 'k-selected': selected,
4244
4315
  'k-focus': selected,
4245
4316
  'k-active': isActiveMessage
4246
4317
  }"
4247
4318
  >
4248
- <div class="k-bubble-content">
4249
- <ng-container *ngTemplateOutlet="getActiveContentTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
4250
- </div>
4251
- <span
4252
- class="k-bubble-expandable-indicator"
4253
- *ngIf="isMessageExpandable && showExpandCollapseIcon"
4254
- [attr.tabindex]="'0'"
4255
- [attr.role]="'button'"
4256
- [attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
4257
- (mousedown)="chatService.toggleMessageState = true"
4258
- (click)="toggleMessageState($event)"
4259
- >
4260
- <kendo-icon-wrapper
4261
- [name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
4262
- [svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
4263
- >
4264
- </kendo-icon-wrapper>
4265
- </span>
4319
+ <div class="k-bubble-content">
4320
+ <ng-container *ngTemplateOutlet="getActiveContentTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
4266
4321
  </div>
4267
-
4268
- <div
4269
- class="k-chat-bubble k-bubble"
4270
- *ngIf="!useCustomContentTemplate && hasMessageContent"
4271
- [attr.tabindex]="0"
4322
+ @if (isMessageExpandable && showExpandCollapseIcon) {
4323
+ <span
4324
+ class="k-bubble-expandable-indicator"
4325
+ [attr.tabindex]="'0'"
4326
+ [attr.role]="'button'"
4327
+ [attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
4328
+ (mousedown)="chatService.toggleMessageState = true"
4329
+ (click)="toggleMessageState($event)"
4330
+ >
4331
+ <kendo-icon-wrapper
4332
+ [name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
4333
+ [svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
4334
+ >
4335
+ </kendo-icon-wrapper>
4336
+ </span>
4337
+ }
4338
+ </div>
4339
+ }
4340
+ @if (!useCustomContentTemplate && hasMessageContent) {
4341
+ <div
4342
+ class="k-chat-bubble k-bubble"
4343
+ [attr.tabindex]="0"
4272
4344
  [ngClass]="{
4273
- 'k-bubble-expandable': isMessageExpandable,
4274
- 'k-expanded': isMessageExpanded,
4275
- 'k-selected': selected,
4345
+ 'k-bubble-expandable': isMessageExpandable,
4346
+ 'k-expanded': isMessageExpanded,
4347
+ 'k-selected': selected,
4276
4348
  'k-focus': selected,
4277
4349
  'k-active': isActiveMessage
4278
4350
  }"
4279
4351
  >
4280
- <div class="k-bubble-content">
4281
- <ng-container *ngIf="message.text || message.isDeleted">
4282
- <div
4283
- class="k-message-reference k-message-reference-receiver"
4284
- *ngIf="message.replyToId && !message.isDeleted"
4285
- (click)="onReplyReferenceClick($event, message.replyToId)"
4286
- >
4287
- <chat-message-reference-content [message]="getMessageById(message.replyToId)"></chat-message-reference-content>
4288
- </div>
4289
-
4290
- <span class="k-chat-bubble-text" *ngIf="message.isDeleted">
4291
- {{ getDeletedMessageText() }}
4292
- </span>
4293
-
4294
- <span class="k-chat-bubble-text" *ngIf="!message.isDeleted && parts.length > 0">
4295
- <ng-container *ngFor="let part of parts">
4296
- <ng-container *ngIf="part.type === 'text'">{{part.content}}</ng-container>
4297
- <a *ngIf="part.type === 'link'" [href]="part.href" target="_blank">{{part.content}}</a>
4298
- </ng-container>
4299
- </span>
4300
- </ng-container>
4301
-
4302
- <ul
4303
- class="k-chat-file-wrapper"
4304
- *ngIf="hasFiles && !message.isDeleted"
4352
+ <div class="k-bubble-content">
4353
+ @if (message.text || message.isDeleted) {
4354
+ @if (message.replyToId && !message.isDeleted) {
4355
+ <div
4356
+ class="k-message-reference k-message-reference-receiver"
4357
+ (click)="onReplyReferenceClick($event, message.replyToId)"
4358
+ >
4359
+ <chat-message-reference-content [message]="getMessageById(message.replyToId)"></chat-message-reference-content>
4360
+ </div>
4361
+ }
4362
+ @if (message.isDeleted) {
4363
+ <span class="k-chat-bubble-text">
4364
+ {{ getDeletedMessageText() }}
4365
+ </span>
4366
+ }
4367
+ @if (!message.isDeleted && parts.length > 0) {
4368
+ <span class="k-chat-bubble-text">
4369
+ @for (part of parts; track part) {
4370
+ @if (part.type === 'text') {{{part.content}}}
4371
+ @if (part.type === 'link') {<a [href]="part.href" target="_blank">{{part.content}}</a>}
4372
+ }
4373
+ </span>
4374
+ }
4375
+ }
4376
+ @if (hasFiles && !message.isDeleted) {
4377
+ <ul
4378
+ class="k-chat-file-wrapper"
4305
4379
  [ngClass]="{
4306
- 'k-chat-files-wrap': chatService.messageFilesLayout === 'wrap',
4380
+ 'k-chat-files-wrap': chatService.messageFilesLayout === 'wrap',
4307
4381
  'k-chat-files-horizontal': chatService.messageFilesLayout === 'horizontal'
4308
4382
  }"
4309
- >
4310
- <li
4311
- *ngFor="let file of message.files"
4312
- class="k-chat-file"
4313
- [chatFile]="file"
4314
- [fileActions]="fileActions"
4315
- (actionClick)="onFileAction($event, file)"
4316
- (actionsToggle)="onActionPopupChange($event)"
4317
- (actionButtonClick)="onActionButtonClick($event)"
4318
- ></li>
4319
- </ul>
4320
-
4321
- <div class="k-chat-download-button-wrapper" *ngIf="hasMultipleFiles && !message.isDeleted">
4322
- <button
4323
- kendoButton
4324
- class="k-chat-download-button"
4325
- fillMode="flat"
4326
- icon="download"
4327
- [svgIcon]="downloadIcon"
4328
- [attr.title]="textFor('downloadAllFilesText')"
4329
- (click)="onDownloadAll()"
4330
- >{{ textFor('downloadAllFilesText') }}</button>
4331
- </div>
4383
+ >
4384
+ @for (file of message.files; track file) {
4385
+ <li
4386
+ class="k-chat-file"
4387
+ [chatFile]="file"
4388
+ [fileActions]="fileActions"
4389
+ (actionClick)="onFileAction($event, file)"
4390
+ (actionsToggle)="onActionPopupChange($event)"
4391
+ (actionButtonClick)="onActionButtonClick($event)"
4392
+ ></li>
4393
+ }
4394
+ </ul>
4395
+ }
4396
+ @if (hasMultipleFiles && !message.isDeleted) {
4397
+ <div class="k-chat-download-button-wrapper">
4398
+ <button
4399
+ kendoButton
4400
+ class="k-chat-download-button"
4401
+ fillMode="flat"
4402
+ icon="download"
4403
+ [svgIcon]="downloadIcon"
4404
+ [attr.title]="textFor('downloadAllFilesText')"
4405
+ (click)="onDownloadAll()"
4406
+ >{{ textFor('downloadAllFilesText') }}</button>
4332
4407
  </div>
4333
-
4334
- <span
4335
- class="k-bubble-expandable-indicator"
4336
- *ngIf="isMessageExpandable && showExpandCollapseIcon"
4337
- [attr.tabindex]="'0'"
4338
- [attr.role]="'button'"
4339
- [attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
4340
- (mousedown)="chatService.toggleMessageState = true"
4341
- (click)="toggleMessageState($event)"
4342
- >
4343
- <kendo-icon-wrapper
4344
- [name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
4345
- [svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
4346
- >
4347
- </kendo-icon-wrapper>
4348
- </span>
4408
+ }
4349
4409
  </div>
4350
- </ng-container>
4351
-
4352
- <span class="k-message-status" *ngIf="message.status">
4353
- <ng-container *ngIf="statusTemplate?.templateRef">
4354
- <ng-template
4355
- [ngTemplateOutlet]="statusTemplate.templateRef"
4356
- [ngTemplateOutletContext]="{ $implicit: message.status, message }"
4410
+ @if (isMessageExpandable && showExpandCollapseIcon) {
4411
+ <span
4412
+ class="k-bubble-expandable-indicator"
4413
+ [attr.tabindex]="'0'"
4414
+ [attr.role]="'button'"
4415
+ [attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
4416
+ (mousedown)="chatService.toggleMessageState = true"
4417
+ (click)="toggleMessageState($event)"
4357
4418
  >
4358
- </ng-template>
4359
- </ng-container>
4360
- <ng-container *ngIf="!statusTemplate?.templateRef">
4361
- {{ message.status }}
4362
- </ng-container>
4419
+ <kendo-icon-wrapper
4420
+ [name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
4421
+ [svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
4422
+ >
4423
+ </kendo-icon-wrapper>
4424
+ </span>
4425
+ }
4426
+ </div>
4427
+ }
4428
+ }
4429
+ @if (message.status) {
4430
+ <span class="k-message-status">
4431
+ @if (statusTemplate?.templateRef) {
4432
+ <ng-template
4433
+ [ngTemplateOutlet]="statusTemplate.templateRef"
4434
+ [ngTemplateOutletContext]="{ $implicit: message.status, message }"
4435
+ >
4436
+ </ng-template>
4437
+ }
4438
+ @if (!statusTemplate?.templateRef) {
4439
+ {{ message.status }}
4440
+ }
4363
4441
  </span>
4364
- </ng-container>
4365
- <kendo-toolbar *ngIf="showToolbar" class="k-chat-message-toolbar" fillMode="flat">
4366
- <kendo-toolbar-button
4367
- *ngFor="let action of toolbarActions"
4442
+ }
4443
+ }
4444
+ @if (showToolbar) {
4445
+ <kendo-toolbar class="k-chat-message-toolbar" fillMode="flat">
4446
+ @for (action of toolbarActions; track action) {
4447
+ <kendo-toolbar-button
4368
4448
  fillMode="flat"
4369
4449
  [icon]="action.icon"
4370
4450
  [svgIcon]="action.svgIcon"
4371
4451
  [disabled]="action.disabled"
4372
4452
  [title]="action.label"
4373
4453
  (click)="onToolbarAction($event, action, message)"
4374
- >
4375
- </kendo-toolbar-button>
4376
- </kendo-toolbar>
4377
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }, { kind: "component", type: ToolBarComponent, selector: "kendo-toolbar", inputs: ["overflow", "resizable", "popupSettings", "fillMode", "tabindex", "size", "tabIndex", "showIcon", "showText"], outputs: ["open", "close"], exportAs: ["kendoToolBar"] }, { kind: "component", type: ToolBarButtonComponent, selector: "kendo-toolbar-button", inputs: ["showText", "showIcon", "text", "style", "className", "title", "disabled", "toggleable", "look", "togglable", "selected", "fillMode", "rounded", "themeColor", "icon", "iconClass", "svgIcon", "imageUrl"], outputs: ["click", "pointerdown", "selectedChange"], exportAs: ["kendoToolBarButton"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }] });
4454
+ >
4455
+ </kendo-toolbar-button>
4456
+ }
4457
+ </kendo-toolbar>
4458
+ }
4459
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: ChatFileComponent, selector: "li[chatFile]", inputs: ["chatFile", "removable", "fileActions"], outputs: ["remove", "actionClick", "actionsToggle", "actionButtonClick"] }, { kind: "component", type: ToolBarComponent, selector: "kendo-toolbar", inputs: ["overflow", "resizable", "popupSettings", "fillMode", "tabindex", "size", "tabIndex", "showIcon", "showText"], outputs: ["open", "close"], exportAs: ["kendoToolBar"] }, { kind: "component", type: ToolBarButtonComponent, selector: "kendo-toolbar-button", inputs: ["showText", "showIcon", "text", "style", "className", "title", "disabled", "toggleable", "look", "togglable", "selected", "fillMode", "rounded", "themeColor", "icon", "iconClass", "svgIcon", "imageUrl"], outputs: ["click", "pointerdown", "selectedChange"], exportAs: ["kendoToolBarButton"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }] });
4378
4460
  }
4379
4461
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageComponent, decorators: [{
4380
4462
  type: Component,
@@ -4387,174 +4469,184 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
4387
4469
  }
4388
4470
  ],
4389
4471
  template: `
4390
- <ng-container *ngIf="useCustomBubbleTemplate">
4391
- <ng-container *ngTemplateOutlet="getActiveBubbleTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
4392
- </ng-container>
4472
+ @if (useCustomBubbleTemplate) {
4473
+ <ng-container *ngTemplateOutlet="getActiveBubbleTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
4474
+ }
4393
4475
 
4394
- <ng-container *ngIf="!useCustomBubbleTemplate">
4476
+ @if (!useCustomBubbleTemplate) {
4477
+ @if (chatService.timestampVisibility === 'focus' && message.timestamp) {
4395
4478
  <time
4396
- [attr.aria-hidden]="!selected"
4397
- class="k-message-time"
4398
- *ngIf="chatService.timestampVisibility === 'focus' && message.timestamp"
4399
- >
4400
- {{ formatTimeStamp(message.timestamp) }}
4479
+ [attr.aria-hidden]="!selected"
4480
+ class="k-message-time"
4481
+ >
4482
+ {{ formatTimeStamp(message.timestamp) }}
4401
4483
  </time>
4402
-
4403
- <ng-container *ngIf="message.typing">
4404
- <div class="k-chat-bubble k-bubble">
4405
- <div class="k-typing-indicator" [attr.tabindex]="'-1'">
4406
- <span></span>
4407
- <span></span>
4408
- <span></span>
4409
- </div>
4410
- </div>
4411
- </ng-container>
4412
-
4413
- <ng-container *ngIf="!message.typing">
4414
- <div
4415
- class="k-chat-bubble k-bubble"
4416
- *ngIf="useCustomContentTemplate"
4417
- [attr.tabindex]="0"
4484
+ }
4485
+ @if (message.typing) {
4486
+ <div class="k-chat-bubble k-bubble">
4487
+ <div class="k-typing-indicator" [attr.tabindex]="'-1'">
4488
+ <span></span>
4489
+ <span></span>
4490
+ <span></span>
4491
+ </div>
4492
+ </div>
4493
+ }
4494
+ @if (!message.typing) {
4495
+ @if (useCustomContentTemplate) {
4496
+ <div
4497
+ class="k-chat-bubble k-bubble"
4498
+ [attr.tabindex]="0"
4418
4499
  [ngClass]="{
4419
- 'k-bubble-expandable': isMessageExpandable,
4500
+ 'k-bubble-expandable': isMessageExpandable,
4420
4501
  'k-expanded': isMessageExpanded,
4421
- 'k-selected': selected,
4502
+ 'k-selected': selected,
4422
4503
  'k-focus': selected,
4423
4504
  'k-active': isActiveMessage
4424
4505
  }"
4425
4506
  >
4426
- <div class="k-bubble-content">
4427
- <ng-container *ngTemplateOutlet="getActiveContentTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
4428
- </div>
4429
- <span
4430
- class="k-bubble-expandable-indicator"
4431
- *ngIf="isMessageExpandable && showExpandCollapseIcon"
4432
- [attr.tabindex]="'0'"
4433
- [attr.role]="'button'"
4434
- [attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
4435
- (mousedown)="chatService.toggleMessageState = true"
4436
- (click)="toggleMessageState($event)"
4437
- >
4438
- <kendo-icon-wrapper
4439
- [name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
4440
- [svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
4441
- >
4442
- </kendo-icon-wrapper>
4443
- </span>
4507
+ <div class="k-bubble-content">
4508
+ <ng-container *ngTemplateOutlet="getActiveContentTemplate()?.templateRef; context: { $implicit: message };"></ng-container>
4444
4509
  </div>
4445
-
4446
- <div
4447
- class="k-chat-bubble k-bubble"
4448
- *ngIf="!useCustomContentTemplate && hasMessageContent"
4449
- [attr.tabindex]="0"
4510
+ @if (isMessageExpandable && showExpandCollapseIcon) {
4511
+ <span
4512
+ class="k-bubble-expandable-indicator"
4513
+ [attr.tabindex]="'0'"
4514
+ [attr.role]="'button'"
4515
+ [attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
4516
+ (mousedown)="chatService.toggleMessageState = true"
4517
+ (click)="toggleMessageState($event)"
4518
+ >
4519
+ <kendo-icon-wrapper
4520
+ [name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
4521
+ [svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
4522
+ >
4523
+ </kendo-icon-wrapper>
4524
+ </span>
4525
+ }
4526
+ </div>
4527
+ }
4528
+ @if (!useCustomContentTemplate && hasMessageContent) {
4529
+ <div
4530
+ class="k-chat-bubble k-bubble"
4531
+ [attr.tabindex]="0"
4450
4532
  [ngClass]="{
4451
- 'k-bubble-expandable': isMessageExpandable,
4452
- 'k-expanded': isMessageExpanded,
4453
- 'k-selected': selected,
4533
+ 'k-bubble-expandable': isMessageExpandable,
4534
+ 'k-expanded': isMessageExpanded,
4535
+ 'k-selected': selected,
4454
4536
  'k-focus': selected,
4455
4537
  'k-active': isActiveMessage
4456
4538
  }"
4457
4539
  >
4458
- <div class="k-bubble-content">
4459
- <ng-container *ngIf="message.text || message.isDeleted">
4460
- <div
4461
- class="k-message-reference k-message-reference-receiver"
4462
- *ngIf="message.replyToId && !message.isDeleted"
4463
- (click)="onReplyReferenceClick($event, message.replyToId)"
4464
- >
4465
- <chat-message-reference-content [message]="getMessageById(message.replyToId)"></chat-message-reference-content>
4466
- </div>
4467
-
4468
- <span class="k-chat-bubble-text" *ngIf="message.isDeleted">
4469
- {{ getDeletedMessageText() }}
4470
- </span>
4471
-
4472
- <span class="k-chat-bubble-text" *ngIf="!message.isDeleted && parts.length > 0">
4473
- <ng-container *ngFor="let part of parts">
4474
- <ng-container *ngIf="part.type === 'text'">{{part.content}}</ng-container>
4475
- <a *ngIf="part.type === 'link'" [href]="part.href" target="_blank">{{part.content}}</a>
4476
- </ng-container>
4477
- </span>
4478
- </ng-container>
4479
-
4480
- <ul
4481
- class="k-chat-file-wrapper"
4482
- *ngIf="hasFiles && !message.isDeleted"
4540
+ <div class="k-bubble-content">
4541
+ @if (message.text || message.isDeleted) {
4542
+ @if (message.replyToId && !message.isDeleted) {
4543
+ <div
4544
+ class="k-message-reference k-message-reference-receiver"
4545
+ (click)="onReplyReferenceClick($event, message.replyToId)"
4546
+ >
4547
+ <chat-message-reference-content [message]="getMessageById(message.replyToId)"></chat-message-reference-content>
4548
+ </div>
4549
+ }
4550
+ @if (message.isDeleted) {
4551
+ <span class="k-chat-bubble-text">
4552
+ {{ getDeletedMessageText() }}
4553
+ </span>
4554
+ }
4555
+ @if (!message.isDeleted && parts.length > 0) {
4556
+ <span class="k-chat-bubble-text">
4557
+ @for (part of parts; track part) {
4558
+ @if (part.type === 'text') {{{part.content}}}
4559
+ @if (part.type === 'link') {<a [href]="part.href" target="_blank">{{part.content}}</a>}
4560
+ }
4561
+ </span>
4562
+ }
4563
+ }
4564
+ @if (hasFiles && !message.isDeleted) {
4565
+ <ul
4566
+ class="k-chat-file-wrapper"
4483
4567
  [ngClass]="{
4484
- 'k-chat-files-wrap': chatService.messageFilesLayout === 'wrap',
4568
+ 'k-chat-files-wrap': chatService.messageFilesLayout === 'wrap',
4485
4569
  'k-chat-files-horizontal': chatService.messageFilesLayout === 'horizontal'
4486
4570
  }"
4487
- >
4488
- <li
4489
- *ngFor="let file of message.files"
4490
- class="k-chat-file"
4491
- [chatFile]="file"
4492
- [fileActions]="fileActions"
4493
- (actionClick)="onFileAction($event, file)"
4494
- (actionsToggle)="onActionPopupChange($event)"
4495
- (actionButtonClick)="onActionButtonClick($event)"
4496
- ></li>
4497
- </ul>
4498
-
4499
- <div class="k-chat-download-button-wrapper" *ngIf="hasMultipleFiles && !message.isDeleted">
4500
- <button
4501
- kendoButton
4502
- class="k-chat-download-button"
4503
- fillMode="flat"
4504
- icon="download"
4505
- [svgIcon]="downloadIcon"
4506
- [attr.title]="textFor('downloadAllFilesText')"
4507
- (click)="onDownloadAll()"
4508
- >{{ textFor('downloadAllFilesText') }}</button>
4509
- </div>
4571
+ >
4572
+ @for (file of message.files; track file) {
4573
+ <li
4574
+ class="k-chat-file"
4575
+ [chatFile]="file"
4576
+ [fileActions]="fileActions"
4577
+ (actionClick)="onFileAction($event, file)"
4578
+ (actionsToggle)="onActionPopupChange($event)"
4579
+ (actionButtonClick)="onActionButtonClick($event)"
4580
+ ></li>
4581
+ }
4582
+ </ul>
4583
+ }
4584
+ @if (hasMultipleFiles && !message.isDeleted) {
4585
+ <div class="k-chat-download-button-wrapper">
4586
+ <button
4587
+ kendoButton
4588
+ class="k-chat-download-button"
4589
+ fillMode="flat"
4590
+ icon="download"
4591
+ [svgIcon]="downloadIcon"
4592
+ [attr.title]="textFor('downloadAllFilesText')"
4593
+ (click)="onDownloadAll()"
4594
+ >{{ textFor('downloadAllFilesText') }}</button>
4510
4595
  </div>
4511
-
4512
- <span
4513
- class="k-bubble-expandable-indicator"
4514
- *ngIf="isMessageExpandable && showExpandCollapseIcon"
4515
- [attr.tabindex]="'0'"
4516
- [attr.role]="'button'"
4517
- [attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
4518
- (mousedown)="chatService.toggleMessageState = true"
4519
- (click)="toggleMessageState($event)"
4520
- >
4521
- <kendo-icon-wrapper
4522
- [name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
4523
- [svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
4524
- >
4525
- </kendo-icon-wrapper>
4526
- </span>
4596
+ }
4527
4597
  </div>
4528
- </ng-container>
4529
-
4530
- <span class="k-message-status" *ngIf="message.status">
4531
- <ng-container *ngIf="statusTemplate?.templateRef">
4532
- <ng-template
4533
- [ngTemplateOutlet]="statusTemplate.templateRef"
4534
- [ngTemplateOutletContext]="{ $implicit: message.status, message }"
4598
+ @if (isMessageExpandable && showExpandCollapseIcon) {
4599
+ <span
4600
+ class="k-bubble-expandable-indicator"
4601
+ [attr.tabindex]="'0'"
4602
+ [attr.role]="'button'"
4603
+ [attr.title]="isMessageExpanded ? textFor('collapseTitle') : textFor('expandTitle')"
4604
+ (mousedown)="chatService.toggleMessageState = true"
4605
+ (click)="toggleMessageState($event)"
4535
4606
  >
4536
- </ng-template>
4537
- </ng-container>
4538
- <ng-container *ngIf="!statusTemplate?.templateRef">
4539
- {{ message.status }}
4540
- </ng-container>
4607
+ <kendo-icon-wrapper
4608
+ [name]="isMessageExpanded ? 'chevron-up' : 'chevron-down'"
4609
+ [svgIcon]="isMessageExpanded ? collapseIcon : expandIcon"
4610
+ >
4611
+ </kendo-icon-wrapper>
4612
+ </span>
4613
+ }
4614
+ </div>
4615
+ }
4616
+ }
4617
+ @if (message.status) {
4618
+ <span class="k-message-status">
4619
+ @if (statusTemplate?.templateRef) {
4620
+ <ng-template
4621
+ [ngTemplateOutlet]="statusTemplate.templateRef"
4622
+ [ngTemplateOutletContext]="{ $implicit: message.status, message }"
4623
+ >
4624
+ </ng-template>
4625
+ }
4626
+ @if (!statusTemplate?.templateRef) {
4627
+ {{ message.status }}
4628
+ }
4541
4629
  </span>
4542
- </ng-container>
4543
- <kendo-toolbar *ngIf="showToolbar" class="k-chat-message-toolbar" fillMode="flat">
4544
- <kendo-toolbar-button
4545
- *ngFor="let action of toolbarActions"
4630
+ }
4631
+ }
4632
+ @if (showToolbar) {
4633
+ <kendo-toolbar class="k-chat-message-toolbar" fillMode="flat">
4634
+ @for (action of toolbarActions; track action) {
4635
+ <kendo-toolbar-button
4546
4636
  fillMode="flat"
4547
4637
  [icon]="action.icon"
4548
4638
  [svgIcon]="action.svgIcon"
4549
4639
  [disabled]="action.disabled"
4550
4640
  [title]="action.label"
4551
4641
  (click)="onToolbarAction($event, action, message)"
4552
- >
4553
- </kendo-toolbar-button>
4554
- </kendo-toolbar>
4555
- `,
4642
+ >
4643
+ </kendo-toolbar-button>
4644
+ }
4645
+ </kendo-toolbar>
4646
+ }
4647
+ `,
4556
4648
  standalone: true,
4557
- imports: [NgIf, NgClass, NgFor, NgTemplateOutlet, IconWrapperComponent, KENDO_BUTTONS, ChatFileComponent, ToolBarComponent, ToolBarButtonComponent, MessageReferenceComponent],
4649
+ imports: [NgClass, NgTemplateOutlet, IconWrapperComponent, KENDO_BUTTONS, ChatFileComponent, ToolBarComponent, ToolBarButtonComponent, MessageReferenceComponent],
4558
4650
  }]
4559
4651
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1$1.IntlService }, { type: ChatService }, { type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }], propDecorators: { message: [{
4560
4652
  type: Input
@@ -4618,55 +4710,71 @@ class AttachmentComponent {
4618
4710
  }
4619
4711
  _attachment;
4620
4712
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AttachmentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4621
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AttachmentComponent, isStandalone: true, selector: "kendo-chat-attachment", inputs: { attachment: "attachment", template: "template" }, ngImport: i0, template: `
4622
- <ng-container *ngIf="template">
4623
- <ng-container *ngTemplateOutlet="template.templateRef; context: context;">
4624
- </ng-container>
4625
- </ng-container>
4626
-
4627
- <div *ngIf="!template" class="k-card">
4713
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AttachmentComponent, isStandalone: true, selector: "kendo-chat-attachment", inputs: { attachment: "attachment", template: "template" }, ngImport: i0, template: `
4714
+ @if (template) {
4715
+ <ng-container *ngTemplateOutlet="template.templateRef; context: context;">
4716
+ </ng-container>
4717
+ }
4718
+
4719
+ @if (!template) {
4720
+ <div class="k-card">
4628
4721
  <div class="k-card-body">
4629
- <h5 class="k-card-title" *ngIf="attachment.title">
4630
- {{ attachment.title }}
4631
- </h5>
4632
- <h6 class="k-card-subtitle" *ngIf="attachment.subtitle">
4633
- {{ attachment.subtitle }}
4634
- </h6>
4635
- <img *ngIf="image" [attr.src]="attachment.content" />
4636
- <ng-container *ngIf="unknown">
4722
+ @if (attachment.title) {
4723
+ <h5 class="k-card-title">
4724
+ {{ attachment.title }}
4725
+ </h5>
4726
+ }
4727
+ @if (attachment.subtitle) {
4728
+ <h6 class="k-card-subtitle">
4729
+ {{ attachment.subtitle }}
4730
+ </h6>
4731
+ }
4732
+ @if (image) {
4733
+ <img [attr.src]="attachment.content" />
4734
+ }
4735
+ @if (unknown) {
4637
4736
  {{ attachment.content }}
4638
- </ng-container>
4737
+ }
4639
4738
  </div>
4640
- </div>
4641
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
4739
+ </div>
4740
+ }
4741
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
4642
4742
  }
4643
4743
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AttachmentComponent, decorators: [{
4644
4744
  type: Component,
4645
4745
  args: [{
4646
4746
  selector: 'kendo-chat-attachment',
4647
4747
  template: `
4648
- <ng-container *ngIf="template">
4649
- <ng-container *ngTemplateOutlet="template.templateRef; context: context;">
4650
- </ng-container>
4651
- </ng-container>
4652
-
4653
- <div *ngIf="!template" class="k-card">
4748
+ @if (template) {
4749
+ <ng-container *ngTemplateOutlet="template.templateRef; context: context;">
4750
+ </ng-container>
4751
+ }
4752
+
4753
+ @if (!template) {
4754
+ <div class="k-card">
4654
4755
  <div class="k-card-body">
4655
- <h5 class="k-card-title" *ngIf="attachment.title">
4656
- {{ attachment.title }}
4657
- </h5>
4658
- <h6 class="k-card-subtitle" *ngIf="attachment.subtitle">
4659
- {{ attachment.subtitle }}
4660
- </h6>
4661
- <img *ngIf="image" [attr.src]="attachment.content" />
4662
- <ng-container *ngIf="unknown">
4756
+ @if (attachment.title) {
4757
+ <h5 class="k-card-title">
4758
+ {{ attachment.title }}
4759
+ </h5>
4760
+ }
4761
+ @if (attachment.subtitle) {
4762
+ <h6 class="k-card-subtitle">
4763
+ {{ attachment.subtitle }}
4764
+ </h6>
4765
+ }
4766
+ @if (image) {
4767
+ <img [attr.src]="attachment.content" />
4768
+ }
4769
+ @if (unknown) {
4663
4770
  {{ attachment.content }}
4664
- </ng-container>
4771
+ }
4665
4772
  </div>
4666
- </div>
4667
- `,
4773
+ </div>
4774
+ }
4775
+ `,
4668
4776
  standalone: true,
4669
- imports: [NgIf, NgTemplateOutlet]
4777
+ imports: [NgTemplateOutlet]
4670
4778
  }]
4671
4779
  }], propDecorators: { attachment: [{
4672
4780
  type: Input
@@ -4741,7 +4849,7 @@ class MessageAttachmentsComponent extends ChatItem {
4741
4849
  itemKeydown(e, attachment) {
4742
4850
  const keyHandlers = this.layout === 'list' ?
4743
4851
  this.listKeyHandlers : this.carouselKeyHandlers;
4744
- const code = normalizeNumpadKeys(e);
4852
+ const code = normalizeKeys(e);
4745
4853
  const handler = keyHandlers[code];
4746
4854
  if (handler) {
4747
4855
  handler(e, attachment);
@@ -4791,51 +4899,54 @@ class MessageAttachmentsComponent extends ChatItem {
4791
4899
  return this.localization.get(key);
4792
4900
  }
4793
4901
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageAttachmentsComponent, deps: [{ token: i0.NgZone }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
4794
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MessageAttachmentsComponent, isStandalone: true, selector: "kendo-chat-message-attachments", inputs: { attachments: "attachments", layout: "layout", tabbable: "tabbable", template: "template", localization: "localization" }, host: { properties: { "class.k-card-deck-scrollwrap": "this.carousel" } }, providers: [{
4902
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MessageAttachmentsComponent, isStandalone: true, selector: "kendo-chat-message-attachments", inputs: { attachments: "attachments", layout: "layout", tabbable: "tabbable", template: "template", localization: "localization" }, host: { properties: { "class.k-card-deck-scrollwrap": "this.carousel" } }, providers: [{
4795
4903
  provide: ChatItem,
4796
4904
  useExisting: forwardRef(() => MessageAttachmentsComponent)
4797
4905
  }], viewQueries: [{ propertyName: "deck", first: true, predicate: ["deck"], descendants: true, read: ElementRef, static: true }, { propertyName: "items", predicate: ["item"], descendants: true, read: ElementRef }], usesInheritance: true, ngImport: i0, template: `
4798
- <button
4799
- *ngIf="showLeftArrow"
4906
+ @if (showLeftArrow) {
4907
+ <button
4800
4908
  (click)="scrollTo(-1)"
4801
4909
  kendoButton
4802
4910
  tabindex="-1"
4803
4911
  [attr.title]="textFor('messageAttachmentLeftArrow')"
4804
4912
  [svgIcon]="chevronLeftIcon"
4805
4913
  icon="chevron-left"
4806
- >
4807
- </button>
4914
+ >
4915
+ </button>
4916
+ }
4808
4917
  <div
4809
- #deck
4810
- [class.k-card-deck]="carousel"
4811
- [class.k-card-list]="!carousel"
4812
- >
4918
+ #deck
4919
+ [class.k-card-deck]="carousel"
4920
+ [class.k-card-list]="!carousel"
4921
+ >
4922
+ @for (att of attachments; track att; let index = $index; let first = $first; let last = $last) {
4813
4923
  <kendo-chat-attachment #item
4814
- *ngFor="let att of attachments; index as index; first as first; last as last"
4815
- [attachment]="att"
4816
- [template]="template"
4817
- [class.k-selected]="isSelected(index)"
4818
- [class.k-focus]="isSelected(index)"
4819
- [class.k-card-wrap]="true"
4820
- [class.k-first]="first"
4821
- [class.k-last]="last"
4822
- [attr.tabindex]="tabbable && isSelected(index) ? '0' : '-1'"
4823
- (click)="itemClick(index)"
4824
- (keydown)="itemKeydown($event, att)"
4825
- >
4924
+ [attachment]="att"
4925
+ [template]="template"
4926
+ [class.k-selected]="isSelected(index)"
4927
+ [class.k-focus]="isSelected(index)"
4928
+ [class.k-card-wrap]="true"
4929
+ [class.k-first]="first"
4930
+ [class.k-last]="last"
4931
+ [attr.tabindex]="tabbable && isSelected(index) ? '0' : '-1'"
4932
+ (click)="itemClick(index)"
4933
+ (keydown)="itemKeydown($event, att)"
4934
+ >
4826
4935
  </kendo-chat-attachment>
4936
+ }
4827
4937
  </div>
4828
- <button
4829
- *ngIf="showRightArrow"
4938
+ @if (showRightArrow) {
4939
+ <button
4830
4940
  (click)="scrollTo(1)"
4831
4941
  kendoButton
4832
4942
  tabindex="-1"
4833
4943
  [attr.title]="textFor('messageAttachmentRightArrow')"
4834
4944
  [svgIcon]="chevronRightIcon"
4835
4945
  icon="chevron-right"
4836
- >
4837
- </button>
4838
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: AttachmentComponent, selector: "kendo-chat-attachment", inputs: ["attachment", "template"] }] });
4946
+ >
4947
+ </button>
4948
+ }
4949
+ `, isInline: true, dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: AttachmentComponent, selector: "kendo-chat-attachment", inputs: ["attachment", "template"] }] });
4839
4950
  }
4840
4951
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageAttachmentsComponent, decorators: [{
4841
4952
  type: Component,
@@ -4846,49 +4957,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
4846
4957
  }],
4847
4958
  selector: 'kendo-chat-message-attachments',
4848
4959
  template: `
4849
- <button
4850
- *ngIf="showLeftArrow"
4960
+ @if (showLeftArrow) {
4961
+ <button
4851
4962
  (click)="scrollTo(-1)"
4852
4963
  kendoButton
4853
4964
  tabindex="-1"
4854
4965
  [attr.title]="textFor('messageAttachmentLeftArrow')"
4855
4966
  [svgIcon]="chevronLeftIcon"
4856
4967
  icon="chevron-left"
4857
- >
4858
- </button>
4968
+ >
4969
+ </button>
4970
+ }
4859
4971
  <div
4860
- #deck
4861
- [class.k-card-deck]="carousel"
4862
- [class.k-card-list]="!carousel"
4863
- >
4972
+ #deck
4973
+ [class.k-card-deck]="carousel"
4974
+ [class.k-card-list]="!carousel"
4975
+ >
4976
+ @for (att of attachments; track att; let index = $index; let first = $first; let last = $last) {
4864
4977
  <kendo-chat-attachment #item
4865
- *ngFor="let att of attachments; index as index; first as first; last as last"
4866
- [attachment]="att"
4867
- [template]="template"
4868
- [class.k-selected]="isSelected(index)"
4869
- [class.k-focus]="isSelected(index)"
4870
- [class.k-card-wrap]="true"
4871
- [class.k-first]="first"
4872
- [class.k-last]="last"
4873
- [attr.tabindex]="tabbable && isSelected(index) ? '0' : '-1'"
4874
- (click)="itemClick(index)"
4875
- (keydown)="itemKeydown($event, att)"
4876
- >
4978
+ [attachment]="att"
4979
+ [template]="template"
4980
+ [class.k-selected]="isSelected(index)"
4981
+ [class.k-focus]="isSelected(index)"
4982
+ [class.k-card-wrap]="true"
4983
+ [class.k-first]="first"
4984
+ [class.k-last]="last"
4985
+ [attr.tabindex]="tabbable && isSelected(index) ? '0' : '-1'"
4986
+ (click)="itemClick(index)"
4987
+ (keydown)="itemKeydown($event, att)"
4988
+ >
4877
4989
  </kendo-chat-attachment>
4990
+ }
4878
4991
  </div>
4879
- <button
4880
- *ngIf="showRightArrow"
4992
+ @if (showRightArrow) {
4993
+ <button
4881
4994
  (click)="scrollTo(1)"
4882
4995
  kendoButton
4883
4996
  tabindex="-1"
4884
4997
  [attr.title]="textFor('messageAttachmentRightArrow')"
4885
4998
  [svgIcon]="chevronRightIcon"
4886
4999
  icon="chevron-right"
4887
- >
4888
- </button>
4889
- `,
5000
+ >
5001
+ </button>
5002
+ }
5003
+ `,
4890
5004
  standalone: true,
4891
- imports: [NgIf, ButtonComponent, NgFor, AttachmentComponent]
5005
+ imports: [ButtonComponent, AttachmentComponent]
4892
5006
  }]
4893
5007
  }], ctorParameters: () => [{ type: i0.NgZone }, { type: i1.LocalizationService }], propDecorators: { attachments: [{
4894
5008
  type: Input
@@ -5035,20 +5149,6 @@ class MessageListComponent {
5035
5149
  onClick(message, event) {
5036
5150
  this.select(message, event);
5037
5151
  }
5038
- showGroupAuthor(group) {
5039
- const messageSettings = this.isOwnMessage(group.messages[0]) ? this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
5040
- if (isPresent(messageSettings?.showUsername)) {
5041
- return messageSettings.showUsername && group.author.name;
5042
- }
5043
- return this.chatService.showUsername && group.author.name;
5044
- }
5045
- showGroupAvatar(group) {
5046
- const messageSettings = this.isOwnMessage(group.messages[0]) ? this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
5047
- if (isPresent(messageSettings?.showAvatar)) {
5048
- return messageSettings.showAvatar && group.author.avatarUrl;
5049
- }
5050
- return this.chatService.showAvatar && group.author.avatarUrl;
5051
- }
5052
5152
  onContextMenuClick(message, event, messageElement) {
5053
5153
  this.chatService.calculateContextMenuActions(this.isOwnMessage(message));
5054
5154
  if (this.chatService.calculatedContextMenuActions.length > 0) {
@@ -5076,7 +5176,7 @@ class MessageListComponent {
5076
5176
  }
5077
5177
  onKeydown(e) {
5078
5178
  // On some keyboards Numpad keys are used for Home/End/PageUp/PageDown.
5079
- const code = normalizeNumpadKeys(e);
5179
+ const code = normalizeKeys(e);
5080
5180
  const action = this.keyActions[code];
5081
5181
  if (action) {
5082
5182
  action(e);
@@ -5093,6 +5193,22 @@ class MessageListComponent {
5093
5193
  isOwnMessage(msg) {
5094
5194
  return isAuthor(this.authorId, msg);
5095
5195
  }
5196
+ showGroupAuthor(group) {
5197
+ const messageSettings = this.isOwnMessage(group.messages[0]) ?
5198
+ this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
5199
+ if (isPresent(messageSettings?.showUsername)) {
5200
+ return messageSettings.showUsername && group.author.name;
5201
+ }
5202
+ return this.chatService.showUsername && group.author.name;
5203
+ }
5204
+ showGroupAvatar(group) {
5205
+ const messageSettings = this.isOwnMessage(group.messages[0]) ?
5206
+ this.chatService.authorMessageSettings : this.chatService.receiverMessageSettings;
5207
+ if (isPresent(messageSettings?.showAvatar)) {
5208
+ return messageSettings.showAvatar && group.author.avatarUrl;
5209
+ }
5210
+ return this.chatService.showAvatar && group.author.avatarUrl;
5211
+ }
5096
5212
  dispatchAction(action, message) {
5097
5213
  const args = new ExecuteActionEvent(action, message);
5098
5214
  this.executeAction.emit(args);
@@ -5224,231 +5340,269 @@ class MessageListComponent {
5224
5340
  });
5225
5341
  }
5226
5342
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageListComponent, deps: [{ token: i0.ElementRef }, { token: i1$1.IntlService }, { token: i0.Renderer2 }, { token: ChatService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
5227
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: MessageListComponent, isStandalone: true, selector: "kendo-chat-message-list", inputs: { messages: "messages", attachmentTemplate: "attachmentTemplate", authorMessageContentTemplate: "authorMessageContentTemplate", receiverMessageContentTemplate: "receiverMessageContentTemplate", messageContentTemplate: "messageContentTemplate", authorMessageTemplate: "authorMessageTemplate", receiverMessageTemplate: "receiverMessageTemplate", messageTemplate: "messageTemplate", timestampTemplate: "timestampTemplate", statusTemplate: "statusTemplate", userStatusTemplate: "userStatusTemplate", localization: "localization", authorId: "authorId" }, outputs: { executeAction: "executeAction", navigate: "navigate", resize: "resize" }, host: { properties: { "class.k-message-list-content": "this.cssClass" } }, viewQueries: [{ propertyName: "items", predicate: ChatItem, descendants: true }], ngImport: i0, template: `
5228
- <ng-container *ngFor="let group of view; last as lastGroup; trackBy: trackGroup">
5229
- <ng-container [ngSwitch]="group.type">
5230
- <div
5231
- *ngSwitchCase="'date-marker'"
5232
- class="k-timestamp"
5343
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MessageListComponent, isStandalone: true, selector: "kendo-chat-message-list", inputs: { messages: "messages", attachmentTemplate: "attachmentTemplate", authorMessageContentTemplate: "authorMessageContentTemplate", receiverMessageContentTemplate: "receiverMessageContentTemplate", messageContentTemplate: "messageContentTemplate", authorMessageTemplate: "authorMessageTemplate", receiverMessageTemplate: "receiverMessageTemplate", messageTemplate: "messageTemplate", timestampTemplate: "timestampTemplate", statusTemplate: "statusTemplate", userStatusTemplate: "userStatusTemplate", localization: "localization", authorId: "authorId" }, outputs: { executeAction: "executeAction", navigate: "navigate", resize: "resize" }, host: { properties: { "class.k-message-list-content": "this.cssClass" } }, viewQueries: [{ propertyName: "items", predicate: ChatItem, descendants: true }], ngImport: i0, template: `
5344
+ @for (group of view; track trackGroup($index, group); let lastGroup = $last) {
5345
+ @switch (group.type) {
5346
+ @case ('date-marker') {
5347
+ <div
5348
+ class="k-timestamp"
5233
5349
  >
5234
- <ng-container
5235
- *ngIf="timestampTemplate?.templateRef"
5236
- [ngTemplateOutlet]="timestampTemplate.templateRef"
5237
- [ngTemplateOutletContext]="{ $implicit: group.timestamp }"
5350
+ @if (timestampTemplate?.templateRef) {
5351
+ <ng-container
5352
+ [ngTemplateOutlet]="timestampTemplate.templateRef"
5353
+ [ngTemplateOutletContext]="{ $implicit: group.timestamp }"
5238
5354
  >
5239
- </ng-container>
5240
- <ng-container *ngIf="!timestampTemplate?.templateRef">{{ formatTimeStamp(group.timestamp) }}</ng-container>
5241
- </div>
5242
- <div
5243
- *ngSwitchCase="'message-group'"
5244
- class="k-message-group"
5245
- [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
5246
- [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
5247
- [class.k-no-avatar]="!showGroupAvatar(group)"
5248
- [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
5355
+ </ng-container>
5356
+ }
5357
+ @if (!timestampTemplate?.templateRef) {
5358
+ {{ formatTimeStamp(group.timestamp) }}
5359
+ }
5360
+ </div>
5361
+ }
5362
+ @case ('message-group') {
5363
+ <div
5364
+ class="k-message-group"
5365
+ [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
5366
+ [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
5367
+ [class.k-no-avatar]="!showGroupAvatar(group)"
5368
+ [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
5249
5369
  >
5370
+ @if (!userStatusTemplate?.templateRef && showGroupAvatar(group)) {
5371
+ <div
5372
+ class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5373
+ >
5374
+ <span class="k-avatar-image">
5375
+ <img
5376
+ [attr.src]="group.author.avatarUrl"
5377
+ [alt]="group.author.avatarAltText"
5378
+ />
5379
+ </span>
5380
+ </div>
5381
+ }
5382
+ @if (showGroupAvatar(group) && userStatusTemplate?.templateRef) {
5383
+ <div class="k-chat-user-status-wrapper">
5250
5384
  <div
5251
- *ngIf="!userStatusTemplate?.templateRef && showGroupAvatar(group)"
5385
+ class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5386
+ >
5387
+ <span class="k-avatar-image">
5388
+ <img
5389
+ [attr.src]="group.author.avatarUrl"
5390
+ [alt]="group.author.avatarAltText"
5391
+ />
5392
+ </span>
5393
+ </div>
5394
+ @if (userStatusTemplate?.templateRef) {
5395
+ <div class="k-chat-user-status">
5396
+ <ng-template
5397
+ [ngTemplateOutlet]="userStatusTemplate.templateRef"
5398
+ [ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
5399
+ >
5400
+ </ng-template>
5401
+ </div>
5402
+ }
5403
+ </div>
5404
+ }
5405
+ <div class="k-message-group-content">
5406
+ @if (showGroupAuthor(group)) {
5407
+ <p class="k-message-author">{{ group.author.name }}</p>
5408
+ }
5409
+ @for (msg of group.messages; track msg; let firstMessage = $first; let lastMessage = $last) {
5410
+ @if (msg.user?.avatarUrl) {
5411
+ <div
5252
5412
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5253
- >
5413
+ >
5254
5414
  <span class="k-avatar-image">
5255
- <img
5256
- [attr.src]="group.author.avatarUrl"
5257
- [alt]="group.author.avatarAltText"
5258
- />
5415
+ <img [src]="msg.user?.avatarUrl">
5259
5416
  </span>
5260
- </div>
5261
- <div class="k-chat-user-status-wrapper" *ngIf="userStatusTemplate?.templateRef && showGroupAvatar(group)">
5262
- <div
5263
- class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5264
- >
5265
- <span class="k-avatar-image">
5266
- <img
5267
- [attr.src]="group.author.avatarUrl"
5268
- [alt]="group.author.avatarAltText"
5269
- />
5270
- </span>
5271
- </div>
5272
- <div class="k-chat-user-status" *ngIf="userStatusTemplate?.templateRef">
5273
- <ng-template
5274
- [ngTemplateOutlet]="userStatusTemplate.templateRef"
5275
- [ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
5276
- >
5277
- </ng-template>
5278
- </div>
5279
- </div>
5280
- <div class="k-message-group-content">
5281
- <p *ngIf="showGroupAuthor(group)" class="k-message-author">{{ group.author.name }}</p>
5282
- <ng-container
5283
- *ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
5417
+ </div>
5418
+ }
5419
+ <kendo-chat-message #message
5420
+ [message]="msg"
5421
+ [tabbable]="lastGroup && lastMessage"
5422
+ [authorMessageContentTemplate]="authorMessageContentTemplate"
5423
+ [receiverMessageContentTemplate]="receiverMessageContentTemplate"
5424
+ [messageContentTemplate]="messageContentTemplate"
5425
+ [authorMessageTemplate]="authorMessageTemplate"
5426
+ [receiverMessageTemplate]="receiverMessageTemplate"
5427
+ [messageTemplate]="messageTemplate"
5428
+ [statusTemplate]="statusTemplate"
5429
+ [authorId]="authorId"
5430
+ >
5431
+ </kendo-chat-message>
5432
+ @if (msg.attachments && msg.attachments.length === 1) {
5433
+ <kendo-chat-attachment
5434
+ [attachment]="msg.attachments[0]"
5435
+ [template]="attachmentTemplate"
5284
5436
  >
5285
- <kendo-chat-message #message
5286
- [message]="msg"
5287
- [tabbable]="lastGroup && lastMessage"
5288
- [authorMessageContentTemplate]="authorMessageContentTemplate"
5289
- [receiverMessageContentTemplate]="receiverMessageContentTemplate"
5290
- [messageContentTemplate]="messageContentTemplate"
5291
- [authorMessageTemplate]="authorMessageTemplate"
5292
- [receiverMessageTemplate]="receiverMessageTemplate"
5293
- [messageTemplate]="messageTemplate"
5294
- [statusTemplate]="statusTemplate"
5295
- [authorId]="authorId"
5296
- >
5297
- </kendo-chat-message>
5298
-
5299
- <kendo-chat-attachment
5300
- *ngIf="msg.attachments && msg.attachments.length === 1"
5301
- [attachment]="msg.attachments[0]"
5302
- [template]="attachmentTemplate"
5303
- >
5304
- </kendo-chat-attachment>
5305
- </ng-container>
5306
- </div>
5437
+ </kendo-chat-attachment>
5438
+ }
5439
+ }
5307
5440
  </div>
5308
-
5309
- <kendo-chat-message-attachments #attachments
5310
- *ngSwitchCase="'attachment-group'"
5311
- [attachments]="group.attachments"
5312
- [layout]="group.attachmentLayout"
5313
- [localization]="localization"
5314
- [tabbable]="lastGroup"
5315
- [template]="attachmentTemplate"
5316
- (click)="select(attachments)"
5317
- (focus)="select(attachments)"
5441
+ </div>
5442
+ }
5443
+ @case ('attachment-group') {
5444
+ <kendo-chat-message-attachments #attachments
5445
+ [attachments]="group.attachments"
5446
+ [layout]="group.attachmentLayout"
5447
+ [localization]="localization"
5448
+ [tabbable]="lastGroup"
5449
+ [template]="attachmentTemplate"
5450
+ (click)="select(attachments)"
5451
+ (focus)="select(attachments)"
5318
5452
  >
5319
- </kendo-chat-message-attachments>
5320
-
5321
- <kendo-chat-suggested-actions #actions
5322
- *ngSwitchCase="'action-group'"
5323
- [actions]="group.actions"
5324
- type="action"
5325
- [tabbable]="lastGroup"
5326
- (dispatchAction)="dispatchAction($event, last(view))"
5327
- (click)="select(actions, $event)"
5328
- (focus)="select(actions, $event)"
5453
+ </kendo-chat-message-attachments>
5454
+ }
5455
+ @case ('action-group') {
5456
+ <kendo-chat-suggested-actions #actions
5457
+ [actions]="group.actions"
5458
+ type="action"
5459
+ [tabbable]="lastGroup"
5460
+ (dispatchAction)="dispatchAction($event, last(view))"
5461
+ (click)="select(actions, $event)"
5462
+ (focus)="select(actions, $event)"
5329
5463
  >
5330
- </kendo-chat-suggested-actions>
5331
- </ng-container>
5332
- </ng-container>
5464
+ </kendo-chat-suggested-actions>
5465
+ }
5466
+ }
5467
+ }
5333
5468
  <kendo-resize-sensor (resize)="onResize()">
5334
5469
  </kendo-resize-sensor>
5335
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MessageComponent, selector: "kendo-chat-message", inputs: ["message", "tabbable", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "statusTemplate", "showMessageTime", "authorId"] }, { kind: "component", type: AttachmentComponent, selector: "kendo-chat-attachment", inputs: ["attachment", "template"] }, { kind: "component", type: MessageAttachmentsComponent, selector: "kendo-chat-message-attachments", inputs: ["attachments", "layout", "tabbable", "template", "localization"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "type", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }] });
5470
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MessageComponent, selector: "kendo-chat-message", inputs: ["message", "tabbable", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "statusTemplate", "showMessageTime", "authorId"] }, { kind: "component", type: AttachmentComponent, selector: "kendo-chat-attachment", inputs: ["attachment", "template"] }, { kind: "component", type: MessageAttachmentsComponent, selector: "kendo-chat-message-attachments", inputs: ["attachments", "layout", "tabbable", "template", "localization"] }, { kind: "component", type: SuggestedActionsComponent, selector: "kendo-chat-suggested-actions", inputs: ["actions", "suggestions", "tabbable", "type", "suggestionTemplate"], outputs: ["dispatchAction", "dispatchSuggestion"] }, { kind: "component", type: ResizeSensorComponent, selector: "kendo-resize-sensor", inputs: ["rateLimit"], outputs: ["resize"] }] });
5336
5471
  }
5337
5472
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MessageListComponent, decorators: [{
5338
5473
  type: Component,
5339
5474
  args: [{
5340
5475
  selector: 'kendo-chat-message-list',
5341
5476
  template: `
5342
- <ng-container *ngFor="let group of view; last as lastGroup; trackBy: trackGroup">
5343
- <ng-container [ngSwitch]="group.type">
5344
- <div
5345
- *ngSwitchCase="'date-marker'"
5346
- class="k-timestamp"
5477
+ @for (group of view; track trackGroup($index, group); let lastGroup = $last) {
5478
+ @switch (group.type) {
5479
+ @case ('date-marker') {
5480
+ <div
5481
+ class="k-timestamp"
5347
5482
  >
5348
- <ng-container
5349
- *ngIf="timestampTemplate?.templateRef"
5350
- [ngTemplateOutlet]="timestampTemplate.templateRef"
5351
- [ngTemplateOutletContext]="{ $implicit: group.timestamp }"
5483
+ @if (timestampTemplate?.templateRef) {
5484
+ <ng-container
5485
+ [ngTemplateOutlet]="timestampTemplate.templateRef"
5486
+ [ngTemplateOutletContext]="{ $implicit: group.timestamp }"
5352
5487
  >
5353
- </ng-container>
5354
- <ng-container *ngIf="!timestampTemplate?.templateRef">{{ formatTimeStamp(group.timestamp) }}</ng-container>
5355
- </div>
5356
- <div
5357
- *ngSwitchCase="'message-group'"
5358
- class="k-message-group"
5359
- [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
5360
- [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
5361
- [class.k-no-avatar]="!showGroupAvatar(group)"
5362
- [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
5488
+ </ng-container>
5489
+ }
5490
+ @if (!timestampTemplate?.templateRef) {
5491
+ {{ formatTimeStamp(group.timestamp) }}
5492
+ }
5493
+ </div>
5494
+ }
5495
+ @case ('message-group') {
5496
+ <div
5497
+ class="k-message-group"
5498
+ [class.k-message-group-sender]="isOwnMessage(group.messages[0])"
5499
+ [class.k-message-group-receiver]="!isOwnMessage(group.messages[0])"
5500
+ [class.k-no-avatar]="!showGroupAvatar(group)"
5501
+ [class.k-message-group-full-width]="calculateMessageWidthMode(group.messages[0])"
5363
5502
  >
5503
+ @if (!userStatusTemplate?.templateRef && showGroupAvatar(group)) {
5504
+ <div
5505
+ class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5506
+ >
5507
+ <span class="k-avatar-image">
5508
+ <img
5509
+ [attr.src]="group.author.avatarUrl"
5510
+ [alt]="group.author.avatarAltText"
5511
+ />
5512
+ </span>
5513
+ </div>
5514
+ }
5515
+ @if (showGroupAvatar(group) && userStatusTemplate?.templateRef) {
5516
+ <div class="k-chat-user-status-wrapper">
5364
5517
  <div
5365
- *ngIf="!userStatusTemplate?.templateRef && showGroupAvatar(group)"
5518
+ class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5519
+ >
5520
+ <span class="k-avatar-image">
5521
+ <img
5522
+ [attr.src]="group.author.avatarUrl"
5523
+ [alt]="group.author.avatarAltText"
5524
+ />
5525
+ </span>
5526
+ </div>
5527
+ @if (userStatusTemplate?.templateRef) {
5528
+ <div class="k-chat-user-status">
5529
+ <ng-template
5530
+ [ngTemplateOutlet]="userStatusTemplate.templateRef"
5531
+ [ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
5532
+ >
5533
+ </ng-template>
5534
+ </div>
5535
+ }
5536
+ </div>
5537
+ }
5538
+ <div class="k-message-group-content">
5539
+ @if (showGroupAuthor(group)) {
5540
+ <p class="k-message-author">{{ group.author.name }}</p>
5541
+ }
5542
+ @for (msg of group.messages; track msg; let firstMessage = $first; let lastMessage = $last) {
5543
+ @if (msg.user?.avatarUrl) {
5544
+ <div
5366
5545
  class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5367
- >
5546
+ >
5368
5547
  <span class="k-avatar-image">
5369
- <img
5370
- [attr.src]="group.author.avatarUrl"
5371
- [alt]="group.author.avatarAltText"
5372
- />
5548
+ <img [src]="msg.user?.avatarUrl">
5373
5549
  </span>
5374
- </div>
5375
- <div class="k-chat-user-status-wrapper" *ngIf="userStatusTemplate?.templateRef && showGroupAvatar(group)">
5376
- <div
5377
- class="k-avatar k-avatar-md k-avatar-solid k-avatar-solid-primary k-rounded-full"
5378
- >
5379
- <span class="k-avatar-image">
5380
- <img
5381
- [attr.src]="group.author.avatarUrl"
5382
- [alt]="group.author.avatarAltText"
5383
- />
5384
- </span>
5385
- </div>
5386
- <div class="k-chat-user-status" *ngIf="userStatusTemplate?.templateRef">
5387
- <ng-template
5388
- [ngTemplateOutlet]="userStatusTemplate.templateRef"
5389
- [ngTemplateOutletContext]="{ $implicit: group.messages.at(-1) }"
5390
- >
5391
- </ng-template>
5392
- </div>
5393
- </div>
5394
- <div class="k-message-group-content">
5395
- <p *ngIf="showGroupAuthor(group)" class="k-message-author">{{ group.author.name }}</p>
5396
- <ng-container
5397
- *ngFor="let msg of group.messages; first as firstMessage; last as lastMessage"
5550
+ </div>
5551
+ }
5552
+ <kendo-chat-message #message
5553
+ [message]="msg"
5554
+ [tabbable]="lastGroup && lastMessage"
5555
+ [authorMessageContentTemplate]="authorMessageContentTemplate"
5556
+ [receiverMessageContentTemplate]="receiverMessageContentTemplate"
5557
+ [messageContentTemplate]="messageContentTemplate"
5558
+ [authorMessageTemplate]="authorMessageTemplate"
5559
+ [receiverMessageTemplate]="receiverMessageTemplate"
5560
+ [messageTemplate]="messageTemplate"
5561
+ [statusTemplate]="statusTemplate"
5562
+ [authorId]="authorId"
5563
+ >
5564
+ </kendo-chat-message>
5565
+ @if (msg.attachments && msg.attachments.length === 1) {
5566
+ <kendo-chat-attachment
5567
+ [attachment]="msg.attachments[0]"
5568
+ [template]="attachmentTemplate"
5398
5569
  >
5399
- <kendo-chat-message #message
5400
- [message]="msg"
5401
- [tabbable]="lastGroup && lastMessage"
5402
- [authorMessageContentTemplate]="authorMessageContentTemplate"
5403
- [receiverMessageContentTemplate]="receiverMessageContentTemplate"
5404
- [messageContentTemplate]="messageContentTemplate"
5405
- [authorMessageTemplate]="authorMessageTemplate"
5406
- [receiverMessageTemplate]="receiverMessageTemplate"
5407
- [messageTemplate]="messageTemplate"
5408
- [statusTemplate]="statusTemplate"
5409
- [authorId]="authorId"
5410
- >
5411
- </kendo-chat-message>
5412
-
5413
- <kendo-chat-attachment
5414
- *ngIf="msg.attachments && msg.attachments.length === 1"
5415
- [attachment]="msg.attachments[0]"
5416
- [template]="attachmentTemplate"
5417
- >
5418
- </kendo-chat-attachment>
5419
- </ng-container>
5420
- </div>
5570
+ </kendo-chat-attachment>
5571
+ }
5572
+ }
5421
5573
  </div>
5422
-
5423
- <kendo-chat-message-attachments #attachments
5424
- *ngSwitchCase="'attachment-group'"
5425
- [attachments]="group.attachments"
5426
- [layout]="group.attachmentLayout"
5427
- [localization]="localization"
5428
- [tabbable]="lastGroup"
5429
- [template]="attachmentTemplate"
5430
- (click)="select(attachments)"
5431
- (focus)="select(attachments)"
5574
+ </div>
5575
+ }
5576
+ @case ('attachment-group') {
5577
+ <kendo-chat-message-attachments #attachments
5578
+ [attachments]="group.attachments"
5579
+ [layout]="group.attachmentLayout"
5580
+ [localization]="localization"
5581
+ [tabbable]="lastGroup"
5582
+ [template]="attachmentTemplate"
5583
+ (click)="select(attachments)"
5584
+ (focus)="select(attachments)"
5432
5585
  >
5433
- </kendo-chat-message-attachments>
5434
-
5435
- <kendo-chat-suggested-actions #actions
5436
- *ngSwitchCase="'action-group'"
5437
- [actions]="group.actions"
5438
- type="action"
5439
- [tabbable]="lastGroup"
5440
- (dispatchAction)="dispatchAction($event, last(view))"
5441
- (click)="select(actions, $event)"
5442
- (focus)="select(actions, $event)"
5586
+ </kendo-chat-message-attachments>
5587
+ }
5588
+ @case ('action-group') {
5589
+ <kendo-chat-suggested-actions #actions
5590
+ [actions]="group.actions"
5591
+ type="action"
5592
+ [tabbable]="lastGroup"
5593
+ (dispatchAction)="dispatchAction($event, last(view))"
5594
+ (click)="select(actions, $event)"
5595
+ (focus)="select(actions, $event)"
5443
5596
  >
5444
- </kendo-chat-suggested-actions>
5445
- </ng-container>
5446
- </ng-container>
5597
+ </kendo-chat-suggested-actions>
5598
+ }
5599
+ }
5600
+ }
5447
5601
  <kendo-resize-sensor (resize)="onResize()">
5448
5602
  </kendo-resize-sensor>
5449
- `,
5603
+ `,
5450
5604
  standalone: true,
5451
- imports: [NgFor, NgSwitch, NgSwitchCase, NgIf, NgTemplateOutlet, MessageComponent, AttachmentComponent, MessageAttachmentsComponent, SuggestedActionsComponent, ResizeSensorComponent]
5605
+ imports: [NgTemplateOutlet, MessageComponent, AttachmentComponent, MessageAttachmentsComponent, SuggestedActionsComponent, ResizeSensorComponent]
5452
5606
  }]
5453
5607
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1$1.IntlService }, { type: i0.Renderer2 }, { type: ChatService }, { type: i0.ChangeDetectorRef }], propDecorators: { messages: [{
5454
5608
  type: Input
@@ -6096,7 +6250,12 @@ class ChatComponent {
6096
6250
  * @hidden
6097
6251
  */
6098
6252
  get contextMenuActions() {
6099
- return transformActions(this.chatService.calculatedContextMenuActions);
6253
+ const currentActions = this.chatService.calculatedContextMenuActions;
6254
+ if (currentActions !== this._lastContextMenuActionsReference) {
6255
+ this._cachedContextMenuActions = transformActions(currentActions);
6256
+ this._lastContextMenuActionsReference = currentActions;
6257
+ }
6258
+ return this._cachedContextMenuActions;
6100
6259
  }
6101
6260
  /**
6102
6261
  * @hidden
@@ -6128,6 +6287,8 @@ class ChatComponent {
6128
6287
  _cachedProcessedMessages = [];
6129
6288
  _lastMessagesReference = null;
6130
6289
  _lastModelFields = null;
6290
+ _cachedContextMenuActions = [];
6291
+ _lastContextMenuActionsReference = null;
6131
6292
  constructor(localization, zone, renderer, element, chatService) {
6132
6293
  this.localization = localization;
6133
6294
  this.zone = zone;
@@ -6317,7 +6478,7 @@ class ChatComponent {
6317
6478
  });
6318
6479
  }
6319
6480
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatComponent, deps: [{ token: i1.LocalizationService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: ChatService }], target: i0.ɵɵFactoryTarget.Component });
6320
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", authorId: "authorId", messageBoxType: "messageBoxType", height: "height", width: "width", placeholder: "placeholder", messageWidthMode: "messageWidthMode", timestampVisibility: "timestampVisibility", showUsername: "showUsername", showAvatar: "showAvatar", allowMessageCollapse: "allowMessageCollapse", enableSpeechToText: "enableSpeechToText", enableFileSelect: "enableFileSelect", messageToolbarActions: "messageToolbarActions", inputValue: "inputValue", authorMessageSettings: "authorMessageSettings", receiverMessageSettings: "receiverMessageSettings", messageContextMenuActions: "messageContextMenuActions", fileActions: "fileActions", messageFilesLayout: "messageFilesLayout", suggestionsLayout: "suggestionsLayout", quickActionsLayout: "quickActionsLayout", suggestions: "suggestions", sendButtonSettings: "sendButtonSettings", modelFields: "modelFields" }, outputs: { sendMessage: "sendMessage", toolbarActionClick: "toolbarActionClick", contextMenuActionClick: "contextMenuActionClick", fileActionClick: "fileActionClick", download: "download", executeAction: "executeAction", suggestionExecute: "suggestionExecute", fileSelect: "fileSelect", fileRemove: "fileRemove", unpin: "unpin", inputValueChange: "inputValueChange" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
6481
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ChatComponent, isStandalone: true, selector: "kendo-chat", inputs: { messages: "messages", authorId: "authorId", messageBoxType: "messageBoxType", height: "height", width: "width", placeholder: "placeholder", messageWidthMode: "messageWidthMode", timestampVisibility: "timestampVisibility", showUsername: "showUsername", showAvatar: "showAvatar", allowMessageCollapse: "allowMessageCollapse", enableSpeechToText: "enableSpeechToText", enableFileSelect: "enableFileSelect", messageToolbarActions: "messageToolbarActions", inputValue: "inputValue", authorMessageSettings: "authorMessageSettings", receiverMessageSettings: "receiverMessageSettings", messageContextMenuActions: "messageContextMenuActions", fileActions: "fileActions", messageFilesLayout: "messageFilesLayout", suggestionsLayout: "suggestionsLayout", quickActionsLayout: "quickActionsLayout", suggestions: "suggestions", sendButtonSettings: "sendButtonSettings", modelFields: "modelFields" }, outputs: { sendMessage: "sendMessage", toolbarActionClick: "toolbarActionClick", contextMenuActionClick: "contextMenuActionClick", fileActionClick: "fileActionClick", download: "download", executeAction: "executeAction", suggestionExecute: "suggestionExecute", fileSelect: "fileSelect", fileRemove: "fileRemove", unpin: "unpin", inputValueChange: "inputValueChange" }, host: { properties: { "class": "this.className", "attr.dir": "this.dirAttr" } }, providers: [
6321
6482
  LocalizationService,
6322
6483
  ChatService,
6323
6484
  SuggestionsScrollService,
@@ -6327,139 +6488,144 @@ class ChatComponent {
6327
6488
  }
6328
6489
  ], queries: [{ propertyName: "attachmentTemplate", first: true, predicate: AttachmentTemplateDirective, descendants: true }, { propertyName: "chatHeaderTemplate", first: true, predicate: ChatHeaderTemplateDirective, descendants: true }, { propertyName: "chatNoDataTemplate", first: true, predicate: NoDataTemplateDirective, descendants: true }, { propertyName: "authorMessageContentTemplate", first: true, predicate: AuthorMessageContentTemplateDirective, descendants: true }, { propertyName: "receiverMessageContentTemplate", first: true, predicate: ReceiverMessageContentTemplateDirective, descendants: true }, { propertyName: "messageContentTemplate", first: true, predicate: MessageContentTemplateDirective, descendants: true }, { propertyName: "authorMessageTemplate", first: true, predicate: AuthorMessageTemplateDirective, descendants: true }, { propertyName: "receiverMessageTemplate", first: true, predicate: ReceiverMessageTemplateDirective, descendants: true }, { propertyName: "messageTemplate", first: true, predicate: MessageTemplateDirective, descendants: true }, { propertyName: "timestampTemplate", first: true, predicate: ChatTimestampTemplateDirective, descendants: true }, { propertyName: "suggestionTemplate", first: true, predicate: ChatSuggestionTemplateDirective, descendants: true }, { propertyName: "statusTemplate", first: true, predicate: ChatStatusTemplateDirective, descendants: true }, { propertyName: "messageBoxTemplate", first: true, predicate: ChatMessageBoxTemplateDirective, descendants: true }, { propertyName: "userStatusTemplate", first: true, predicate: ChatUserStatusTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "messagesContextMenu", first: true, predicate: ["messagesContextMenu"], descendants: true }, { propertyName: "messageBox", first: true, predicate: ["messageBox"], descendants: true }, { propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `
6329
6490
  <ng-container kendoChatLocalizedMessages
6330
- i18n-deletedMessageSenderText="kendo.chat.deletedMessageSenderText|The text that is displayed when the sender deletes a message"
6331
- deletedMessageSenderText="You removed this message."
6332
-
6333
- i18n-deletedMessageReceiverText="kendo.chat.deletedMessageReceiverText|The text that is displayed when the receiver deletes a message"
6334
- deletedMessageReceiverText="This message was removed by its sender."
6335
-
6336
- i18n-messagePlaceholder="kendo.chat.messagePlaceholder|The placholder text of the message text input"
6337
- messagePlaceholder="Type a message..."
6338
-
6339
- i18n-send="kendo.chat.send|The text for the Send button"
6340
- send="Send..."
6341
-
6342
- i18n-messageListLabel="kendo.chat.messageListLabel|The label text for the Message list"
6343
- messageListLabel="Message list"
6344
-
6345
- i18n-messageBoxInputLabel="kendo.chat.messageBoxInputLabel|The label text for the Message input box"
6346
- messageBoxInputLabel="Message"
6347
-
6348
- i18n-messageAttachmentLeftArrow="kendo.chat.messageAttachmentLeftArrow|The text for the left arrow of the message attachments"
6349
- messageAttachmentLeftArrow="Previous item"
6350
-
6351
- i18n-messageAttachmentRightArrow="kendo.chat.messageAttachmentRightArrow|The text for the right arrow of the message attachments"
6352
- messageAttachmentRightArrow="Next item"
6353
-
6354
- i18n-speechToTextButtonTitle="kendo.chat.speechToTextButtonTitle|Sets the Speech to Text button title."
6355
- speechToTextButtonTitle="Speech to Text"
6356
-
6357
- i18n-fileSelectButtonTitle="kendo.chat.fileSelectButtonTitle|Sets the File Select button title."
6358
- fileSelectButtonTitle="Select files"
6359
-
6360
- i18n-removeReplyTitle="kendo.chat.removeReplyTitle|Sets the title of the icon which removes the reply reference in the Message Box."
6361
- removeReplyTitle="Remove reply"
6362
-
6363
- i18n-removeFileTitle="kendo.chat.removeFileTitle|Sets the title of the icon which removes a selected file in the Message Box."
6364
- removeFileTitle="Remove file"
6365
-
6366
- i18n-expandTitle="kendo.chat.expandTitle|Sets the title of the icon which demonstrates that the message can be expanded."
6367
- expandTitle="Expand message"
6368
-
6369
- i18n-collapseTitle="kendo.chat.collapseTitle|Sets the title of the icon which demonstrates that the message can be collapsed."
6370
- collapseTitle="Collapse message"
6371
-
6372
- i18n-fileActionsTitle="kendo.chat.fileActionsTitle|Sets the title of the DropDownButton which opens the File actions."
6373
- fileActionsTitle="File actions"
6374
-
6375
- i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
6376
- downloadAllFilesText="Download all"
6377
-
6378
- i18n-previousSuggestionsButtonTitle="kendo.chat.previousSuggestionsButtonTitle|The title of the button that scrolls to the previous suggestions"
6379
- previousSuggestionsButtonTitle="Scroll left"
6380
-
6381
- i18n-nextSuggestionsButtonTitle="kendo.chat.nextSuggestionsButtonTitle|The title of the button that scrolls to the next suggestions"
6382
- nextSuggestionsButtonTitle="Scroll right"
6383
- >
6491
+ i18n-deletedMessageSenderText="kendo.chat.deletedMessageSenderText|The text that is displayed when the sender deletes a message"
6492
+ deletedMessageSenderText="You removed this message."
6493
+
6494
+ i18n-deletedMessageReceiverText="kendo.chat.deletedMessageReceiverText|The text that is displayed when the receiver deletes a message"
6495
+ deletedMessageReceiverText="This message was removed by its sender."
6496
+
6497
+ i18n-messagePlaceholder="kendo.chat.messagePlaceholder|The placholder text of the message text input"
6498
+ messagePlaceholder="Type a message..."
6499
+
6500
+ i18n-send="kendo.chat.send|The text for the Send button"
6501
+ send="Send..."
6502
+
6503
+ i18n-messageListLabel="kendo.chat.messageListLabel|The label text for the Message list"
6504
+ messageListLabel="Message list"
6505
+
6506
+ i18n-messageBoxInputLabel="kendo.chat.messageBoxInputLabel|The label text for the Message input box"
6507
+ messageBoxInputLabel="Message"
6508
+
6509
+ i18n-messageAttachmentLeftArrow="kendo.chat.messageAttachmentLeftArrow|The text for the left arrow of the message attachments"
6510
+ messageAttachmentLeftArrow="Previous item"
6511
+
6512
+ i18n-messageAttachmentRightArrow="kendo.chat.messageAttachmentRightArrow|The text for the right arrow of the message attachments"
6513
+ messageAttachmentRightArrow="Next item"
6514
+
6515
+ i18n-speechToTextButtonTitle="kendo.chat.speechToTextButtonTitle|Sets the Speech to Text button title."
6516
+ speechToTextButtonTitle="Speech to Text"
6517
+
6518
+ i18n-fileSelectButtonTitle="kendo.chat.fileSelectButtonTitle|Sets the File Select button title."
6519
+ fileSelectButtonTitle="Select files"
6520
+
6521
+ i18n-removeReplyTitle="kendo.chat.removeReplyTitle|Sets the title of the icon which removes the reply reference in the Message Box."
6522
+ removeReplyTitle="Remove reply"
6523
+
6524
+ i18n-removeFileTitle="kendo.chat.removeFileTitle|Sets the title of the icon which removes a selected file in the Message Box."
6525
+ removeFileTitle="Remove file"
6526
+
6527
+ i18n-expandTitle="kendo.chat.expandTitle|Sets the title of the icon which demonstrates that the message can be expanded."
6528
+ expandTitle="Expand message"
6529
+
6530
+ i18n-collapseTitle="kendo.chat.collapseTitle|Sets the title of the icon which demonstrates that the message can be collapsed."
6531
+ collapseTitle="Collapse message"
6532
+
6533
+ i18n-fileActionsTitle="kendo.chat.fileActionsTitle|Sets the title of the DropDownButton which opens the File actions."
6534
+ fileActionsTitle="File actions"
6535
+
6536
+ i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
6537
+ downloadAllFilesText="Download all"
6538
+
6539
+ i18n-previousSuggestionsButtonTitle="kendo.chat.previousSuggestionsButtonTitle|The title of the button that scrolls to the previous suggestions"
6540
+ previousSuggestionsButtonTitle="Scroll left"
6541
+
6542
+ i18n-nextSuggestionsButtonTitle="kendo.chat.nextSuggestionsButtonTitle|The title of the button that scrolls to the next suggestions"
6543
+ nextSuggestionsButtonTitle="Scroll right"
6544
+ >
6384
6545
  </ng-container>
6385
-
6386
- <kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky" themeColor="inherit">
6546
+
6547
+ @if (chatHeaderTemplate) {
6548
+ <kendo-appbar class="k-chat-header" positionMode="sticky" themeColor="inherit">
6387
6549
  <ng-container *ngTemplateOutlet="chatHeaderTemplate.templateRef"></ng-container>
6388
- </kendo-appbar>
6389
- <div class="k-message-reference k-message-reference-receiver k-message-pinned" *ngIf="pinnedMessage" (click)="scrollToPinnedMessage()">
6550
+ </kendo-appbar>
6551
+ }
6552
+ @if (pinnedMessage) {
6553
+ <div class="k-message-reference k-message-reference-receiver k-message-pinned" (click)="scrollToPinnedMessage()">
6390
6554
  <kendo-icon-wrapper
6391
- size="xlarge"
6392
- name="pin"
6393
- [svgIcon]="pinIcon"
6394
- >
6555
+ size="xlarge"
6556
+ name="pin"
6557
+ [svgIcon]="pinIcon"
6558
+ >
6395
6559
  </kendo-icon-wrapper>
6396
6560
  <chat-message-reference-content [message]="pinnedMessage"></chat-message-reference-content>
6397
6561
  <span class="k-spacer"></span>
6398
6562
  <button kendoButton [svgIcon]="deleteIcon" (click)="unpin.emit(pinnedMessage)" fillMode="flat"></button>
6399
- </div>
6563
+ </div>
6564
+ }
6400
6565
  <div
6401
- #messageList
6402
- class="k-message-list"
6403
- aria-live="polite"
6404
- role="log"
6405
- kendoChatScrollAnchor
6406
- [attr.aria-label]="textFor('messageListLabel')"
6407
- #anchor="scrollAnchor"
6408
- [(autoScroll)]="autoScroll"
6409
- >
6410
- <div *ngIf="processedMessages && processedMessages.length === 0; else chatMessageList" class="k-message-list-content k-message-list-content-empty">
6411
- <ng-template
6412
- [ngTemplateOutlet]="chatNoDataTemplate?.templateRef">
6413
- </ng-template>
6566
+ #messageList
6567
+ class="k-message-list"
6568
+ aria-live="polite"
6569
+ role="log"
6570
+ kendoChatScrollAnchor
6571
+ [attr.aria-label]="textFor('messageListLabel')"
6572
+ #anchor="scrollAnchor"
6573
+ [(autoScroll)]="autoScroll"
6574
+ >
6575
+ @if (processedMessages && processedMessages.length === 0) {
6576
+ <div class="k-message-list-content k-message-list-content-empty">
6577
+ <ng-template
6578
+ [ngTemplateOutlet]="chatNoDataTemplate?.templateRef">
6579
+ </ng-template>
6414
6580
  </div>
6415
- <ng-template #chatMessageList>
6416
- <kendo-chat-message-list
6417
- [messages]="processedMessages"
6418
- [authorMessageContentTemplate]="authorMessageContentTemplate"
6419
- [receiverMessageContentTemplate]="receiverMessageContentTemplate"
6420
- [messageContentTemplate]="messageContentTemplate"
6421
- [authorMessageTemplate]="authorMessageTemplate"
6422
- [receiverMessageTemplate]="receiverMessageTemplate"
6423
- [messageTemplate]="messageTemplate"
6424
- [timestampTemplate]="timestampTemplate"
6425
- [statusTemplate]="statusTemplate"
6426
- [userStatusTemplate]="userStatusTemplate"
6427
- [localization]="localizationText"
6428
- [attachmentTemplate]="attachmentTemplate"
6429
- [authorId]="authorId"
6430
- (executeAction)="dispatchAction($event)"
6431
- (resize)="anchor.scrollToBottom()"
6432
- (navigate)="this.autoScroll = false"
6433
- >
6434
- </kendo-chat-message-list>
6435
- </ng-template>
6581
+ } @else {
6582
+ <kendo-chat-message-list
6583
+ [messages]="processedMessages"
6584
+ [authorMessageContentTemplate]="authorMessageContentTemplate"
6585
+ [receiverMessageContentTemplate]="receiverMessageContentTemplate"
6586
+ [messageContentTemplate]="messageContentTemplate"
6587
+ [authorMessageTemplate]="authorMessageTemplate"
6588
+ [receiverMessageTemplate]="receiverMessageTemplate"
6589
+ [messageTemplate]="messageTemplate"
6590
+ [timestampTemplate]="timestampTemplate"
6591
+ [statusTemplate]="statusTemplate"
6592
+ [userStatusTemplate]="userStatusTemplate"
6593
+ [localization]="localizationText"
6594
+ [attachmentTemplate]="attachmentTemplate"
6595
+ [authorId]="authorId"
6596
+ (executeAction)="dispatchAction($event)"
6597
+ (resize)="anchor.scrollToBottom()"
6598
+ (navigate)="this.autoScroll = false"
6599
+ >
6600
+ </kendo-chat-message-list>
6601
+ }
6436
6602
  </div>
6437
6603
  <kendo-message-box
6438
- #messageBox
6439
- [messageBoxTemplate]="messageBoxTemplate"
6440
- [suggestionTemplate]="suggestionTemplate"
6441
- [suggestions]="suggestions"
6442
- [placeholder]="placeholder"
6443
- [authorId]="authorId"
6444
- [autoScroll]="autoScroll"
6445
- [inputValue]="inputValue"
6446
- [localization]="localizationText"
6447
- (sendMessage)="sendMessage.emit($event)"
6448
- (executeSuggestion)="suggestionExecute.emit($event)"
6449
- (fileSelect)="fileSelect.emit($event)"
6450
- (fileRemove)="fileRemove.emit($event)"
6451
- >
6604
+ #messageBox
6605
+ [messageBoxTemplate]="messageBoxTemplate"
6606
+ [suggestionTemplate]="suggestionTemplate"
6607
+ [suggestions]="suggestions"
6608
+ [placeholder]="placeholder"
6609
+ [authorId]="authorId"
6610
+ [autoScroll]="autoScroll"
6611
+ [inputValue]="inputValue"
6612
+ [localization]="localizationText"
6613
+ (sendMessage)="sendMessage.emit($event)"
6614
+ (executeSuggestion)="suggestionExecute.emit($event)"
6615
+ (fileSelect)="fileSelect.emit($event)"
6616
+ (fileRemove)="fileRemove.emit($event)"
6617
+ >
6452
6618
  </kendo-message-box>
6453
-
6619
+
6454
6620
  <kendo-contextmenu
6455
- #messagesContextMenu
6456
- [items]="contextMenuActions"
6457
- [popupAlign]="{ horizontal: 'right', vertical: 'top' }"
6458
- [collision]="{ horizontal: 'flip', vertical: 'flip'}"
6459
- (popupClose)="handleMenuClose($event)"
6460
- (select)="onContextMenuAction($event.item.originalAction)"
6621
+ #messagesContextMenu
6622
+ [items]="contextMenuActions"
6623
+ [popupAlign]="{ horizontal: 'right', vertical: 'top' }"
6624
+ [collision]="{ horizontal: 'flip', vertical: 'flip'}"
6625
+ (popupClose)="handleMenuClose($event)"
6626
+ (select)="onContextMenuAction($event.item.originalAction)"
6461
6627
  ></kendo-contextmenu>
6462
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective$1, 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", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "timestampTemplate", "statusTemplate", "userStatusTemplate", "localization", "authorId"], outputs: ["executeAction", "navigate", "resize"] }, { kind: "component", type: MessageBoxComponent, selector: "kendo-message-box", inputs: ["authorId", "autoScroll", "suggestions", "placeholder", "inputValue", "localization", "messageBoxTemplate", "suggestionTemplate"], outputs: ["sendMessage", "executeSuggestion", "fileSelect", "fileRemove"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: AppBarComponent, selector: "kendo-appbar", inputs: ["position", "positionMode", "themeColor"], exportAs: ["kendoAppBar"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: ContextMenuComponent, selector: "kendo-contextmenu", inputs: ["showOn", "target", "filter", "alignToAnchor", "vertical", "popupAnimate", "popupAlign", "anchorAlign", "collision", "appendTo", "ariaLabel"], outputs: ["popupOpen", "popupClose", "select", "open", "close"], exportAs: ["kendoContextMenu"] }] });
6628
+ `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective$1, 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", "authorMessageContentTemplate", "receiverMessageContentTemplate", "messageContentTemplate", "authorMessageTemplate", "receiverMessageTemplate", "messageTemplate", "timestampTemplate", "statusTemplate", "userStatusTemplate", "localization", "authorId"], outputs: ["executeAction", "navigate", "resize"] }, { kind: "component", type: MessageBoxComponent, selector: "kendo-message-box", inputs: ["authorId", "autoScroll", "suggestions", "placeholder", "inputValue", "localization", "messageBoxTemplate", "suggestionTemplate"], outputs: ["sendMessage", "executeSuggestion", "fileSelect", "fileRemove"] }, { kind: "component", type: MessageReferenceComponent, selector: "chat-message-reference-content", inputs: ["message"] }, { kind: "component", type: AppBarComponent, selector: "kendo-appbar", inputs: ["position", "positionMode", "themeColor"], exportAs: ["kendoAppBar"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: ContextMenuComponent, selector: "kendo-contextmenu", inputs: ["showOn", "target", "filter", "alignToAnchor", "vertical", "popupAnimate", "popupAlign", "anchorAlign", "collision", "appendTo", "ariaLabel"], outputs: ["popupOpen", "popupClose", "select", "open", "close"], exportAs: ["kendoContextMenu"] }] });
6463
6629
  }
6464
6630
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChatComponent, decorators: [{
6465
6631
  type: Component,
@@ -6476,141 +6642,146 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
6476
6642
  selector: 'kendo-chat',
6477
6643
  template: `
6478
6644
  <ng-container kendoChatLocalizedMessages
6479
- i18n-deletedMessageSenderText="kendo.chat.deletedMessageSenderText|The text that is displayed when the sender deletes a message"
6480
- deletedMessageSenderText="You removed this message."
6481
-
6482
- i18n-deletedMessageReceiverText="kendo.chat.deletedMessageReceiverText|The text that is displayed when the receiver deletes a message"
6483
- deletedMessageReceiverText="This message was removed by its sender."
6484
-
6485
- i18n-messagePlaceholder="kendo.chat.messagePlaceholder|The placholder text of the message text input"
6486
- messagePlaceholder="Type a message..."
6487
-
6488
- i18n-send="kendo.chat.send|The text for the Send button"
6489
- send="Send..."
6490
-
6491
- i18n-messageListLabel="kendo.chat.messageListLabel|The label text for the Message list"
6492
- messageListLabel="Message list"
6493
-
6494
- i18n-messageBoxInputLabel="kendo.chat.messageBoxInputLabel|The label text for the Message input box"
6495
- messageBoxInputLabel="Message"
6496
-
6497
- i18n-messageAttachmentLeftArrow="kendo.chat.messageAttachmentLeftArrow|The text for the left arrow of the message attachments"
6498
- messageAttachmentLeftArrow="Previous item"
6499
-
6500
- i18n-messageAttachmentRightArrow="kendo.chat.messageAttachmentRightArrow|The text for the right arrow of the message attachments"
6501
- messageAttachmentRightArrow="Next item"
6502
-
6503
- i18n-speechToTextButtonTitle="kendo.chat.speechToTextButtonTitle|Sets the Speech to Text button title."
6504
- speechToTextButtonTitle="Speech to Text"
6505
-
6506
- i18n-fileSelectButtonTitle="kendo.chat.fileSelectButtonTitle|Sets the File Select button title."
6507
- fileSelectButtonTitle="Select files"
6508
-
6509
- i18n-removeReplyTitle="kendo.chat.removeReplyTitle|Sets the title of the icon which removes the reply reference in the Message Box."
6510
- removeReplyTitle="Remove reply"
6511
-
6512
- i18n-removeFileTitle="kendo.chat.removeFileTitle|Sets the title of the icon which removes a selected file in the Message Box."
6513
- removeFileTitle="Remove file"
6514
-
6515
- i18n-expandTitle="kendo.chat.expandTitle|Sets the title of the icon which demonstrates that the message can be expanded."
6516
- expandTitle="Expand message"
6517
-
6518
- i18n-collapseTitle="kendo.chat.collapseTitle|Sets the title of the icon which demonstrates that the message can be collapsed."
6519
- collapseTitle="Collapse message"
6520
-
6521
- i18n-fileActionsTitle="kendo.chat.fileActionsTitle|Sets the title of the DropDownButton which opens the File actions."
6522
- fileActionsTitle="File actions"
6523
-
6524
- i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
6525
- downloadAllFilesText="Download all"
6526
-
6527
- i18n-previousSuggestionsButtonTitle="kendo.chat.previousSuggestionsButtonTitle|The title of the button that scrolls to the previous suggestions"
6528
- previousSuggestionsButtonTitle="Scroll left"
6529
-
6530
- i18n-nextSuggestionsButtonTitle="kendo.chat.nextSuggestionsButtonTitle|The title of the button that scrolls to the next suggestions"
6531
- nextSuggestionsButtonTitle="Scroll right"
6532
- >
6645
+ i18n-deletedMessageSenderText="kendo.chat.deletedMessageSenderText|The text that is displayed when the sender deletes a message"
6646
+ deletedMessageSenderText="You removed this message."
6647
+
6648
+ i18n-deletedMessageReceiverText="kendo.chat.deletedMessageReceiverText|The text that is displayed when the receiver deletes a message"
6649
+ deletedMessageReceiverText="This message was removed by its sender."
6650
+
6651
+ i18n-messagePlaceholder="kendo.chat.messagePlaceholder|The placholder text of the message text input"
6652
+ messagePlaceholder="Type a message..."
6653
+
6654
+ i18n-send="kendo.chat.send|The text for the Send button"
6655
+ send="Send..."
6656
+
6657
+ i18n-messageListLabel="kendo.chat.messageListLabel|The label text for the Message list"
6658
+ messageListLabel="Message list"
6659
+
6660
+ i18n-messageBoxInputLabel="kendo.chat.messageBoxInputLabel|The label text for the Message input box"
6661
+ messageBoxInputLabel="Message"
6662
+
6663
+ i18n-messageAttachmentLeftArrow="kendo.chat.messageAttachmentLeftArrow|The text for the left arrow of the message attachments"
6664
+ messageAttachmentLeftArrow="Previous item"
6665
+
6666
+ i18n-messageAttachmentRightArrow="kendo.chat.messageAttachmentRightArrow|The text for the right arrow of the message attachments"
6667
+ messageAttachmentRightArrow="Next item"
6668
+
6669
+ i18n-speechToTextButtonTitle="kendo.chat.speechToTextButtonTitle|Sets the Speech to Text button title."
6670
+ speechToTextButtonTitle="Speech to Text"
6671
+
6672
+ i18n-fileSelectButtonTitle="kendo.chat.fileSelectButtonTitle|Sets the File Select button title."
6673
+ fileSelectButtonTitle="Select files"
6674
+
6675
+ i18n-removeReplyTitle="kendo.chat.removeReplyTitle|Sets the title of the icon which removes the reply reference in the Message Box."
6676
+ removeReplyTitle="Remove reply"
6677
+
6678
+ i18n-removeFileTitle="kendo.chat.removeFileTitle|Sets the title of the icon which removes a selected file in the Message Box."
6679
+ removeFileTitle="Remove file"
6680
+
6681
+ i18n-expandTitle="kendo.chat.expandTitle|Sets the title of the icon which demonstrates that the message can be expanded."
6682
+ expandTitle="Expand message"
6683
+
6684
+ i18n-collapseTitle="kendo.chat.collapseTitle|Sets the title of the icon which demonstrates that the message can be collapsed."
6685
+ collapseTitle="Collapse message"
6686
+
6687
+ i18n-fileActionsTitle="kendo.chat.fileActionsTitle|Sets the title of the DropDownButton which opens the File actions."
6688
+ fileActionsTitle="File actions"
6689
+
6690
+ i18n-downloadAllFilesText="kendo.chat.downloadAllFilesText|Sets the text that is displayed in the download section of the message."
6691
+ downloadAllFilesText="Download all"
6692
+
6693
+ i18n-previousSuggestionsButtonTitle="kendo.chat.previousSuggestionsButtonTitle|The title of the button that scrolls to the previous suggestions"
6694
+ previousSuggestionsButtonTitle="Scroll left"
6695
+
6696
+ i18n-nextSuggestionsButtonTitle="kendo.chat.nextSuggestionsButtonTitle|The title of the button that scrolls to the next suggestions"
6697
+ nextSuggestionsButtonTitle="Scroll right"
6698
+ >
6533
6699
  </ng-container>
6534
-
6535
- <kendo-appbar *ngIf="chatHeaderTemplate" class="k-chat-header" positionMode="sticky" themeColor="inherit">
6700
+
6701
+ @if (chatHeaderTemplate) {
6702
+ <kendo-appbar class="k-chat-header" positionMode="sticky" themeColor="inherit">
6536
6703
  <ng-container *ngTemplateOutlet="chatHeaderTemplate.templateRef"></ng-container>
6537
- </kendo-appbar>
6538
- <div class="k-message-reference k-message-reference-receiver k-message-pinned" *ngIf="pinnedMessage" (click)="scrollToPinnedMessage()">
6704
+ </kendo-appbar>
6705
+ }
6706
+ @if (pinnedMessage) {
6707
+ <div class="k-message-reference k-message-reference-receiver k-message-pinned" (click)="scrollToPinnedMessage()">
6539
6708
  <kendo-icon-wrapper
6540
- size="xlarge"
6541
- name="pin"
6542
- [svgIcon]="pinIcon"
6543
- >
6709
+ size="xlarge"
6710
+ name="pin"
6711
+ [svgIcon]="pinIcon"
6712
+ >
6544
6713
  </kendo-icon-wrapper>
6545
6714
  <chat-message-reference-content [message]="pinnedMessage"></chat-message-reference-content>
6546
6715
  <span class="k-spacer"></span>
6547
6716
  <button kendoButton [svgIcon]="deleteIcon" (click)="unpin.emit(pinnedMessage)" fillMode="flat"></button>
6548
- </div>
6717
+ </div>
6718
+ }
6549
6719
  <div
6550
- #messageList
6551
- class="k-message-list"
6552
- aria-live="polite"
6553
- role="log"
6554
- kendoChatScrollAnchor
6555
- [attr.aria-label]="textFor('messageListLabel')"
6556
- #anchor="scrollAnchor"
6557
- [(autoScroll)]="autoScroll"
6558
- >
6559
- <div *ngIf="processedMessages && processedMessages.length === 0; else chatMessageList" class="k-message-list-content k-message-list-content-empty">
6560
- <ng-template
6561
- [ngTemplateOutlet]="chatNoDataTemplate?.templateRef">
6562
- </ng-template>
6720
+ #messageList
6721
+ class="k-message-list"
6722
+ aria-live="polite"
6723
+ role="log"
6724
+ kendoChatScrollAnchor
6725
+ [attr.aria-label]="textFor('messageListLabel')"
6726
+ #anchor="scrollAnchor"
6727
+ [(autoScroll)]="autoScroll"
6728
+ >
6729
+ @if (processedMessages && processedMessages.length === 0) {
6730
+ <div class="k-message-list-content k-message-list-content-empty">
6731
+ <ng-template
6732
+ [ngTemplateOutlet]="chatNoDataTemplate?.templateRef">
6733
+ </ng-template>
6563
6734
  </div>
6564
- <ng-template #chatMessageList>
6565
- <kendo-chat-message-list
6566
- [messages]="processedMessages"
6567
- [authorMessageContentTemplate]="authorMessageContentTemplate"
6568
- [receiverMessageContentTemplate]="receiverMessageContentTemplate"
6569
- [messageContentTemplate]="messageContentTemplate"
6570
- [authorMessageTemplate]="authorMessageTemplate"
6571
- [receiverMessageTemplate]="receiverMessageTemplate"
6572
- [messageTemplate]="messageTemplate"
6573
- [timestampTemplate]="timestampTemplate"
6574
- [statusTemplate]="statusTemplate"
6575
- [userStatusTemplate]="userStatusTemplate"
6576
- [localization]="localizationText"
6577
- [attachmentTemplate]="attachmentTemplate"
6578
- [authorId]="authorId"
6579
- (executeAction)="dispatchAction($event)"
6580
- (resize)="anchor.scrollToBottom()"
6581
- (navigate)="this.autoScroll = false"
6582
- >
6583
- </kendo-chat-message-list>
6584
- </ng-template>
6735
+ } @else {
6736
+ <kendo-chat-message-list
6737
+ [messages]="processedMessages"
6738
+ [authorMessageContentTemplate]="authorMessageContentTemplate"
6739
+ [receiverMessageContentTemplate]="receiverMessageContentTemplate"
6740
+ [messageContentTemplate]="messageContentTemplate"
6741
+ [authorMessageTemplate]="authorMessageTemplate"
6742
+ [receiverMessageTemplate]="receiverMessageTemplate"
6743
+ [messageTemplate]="messageTemplate"
6744
+ [timestampTemplate]="timestampTemplate"
6745
+ [statusTemplate]="statusTemplate"
6746
+ [userStatusTemplate]="userStatusTemplate"
6747
+ [localization]="localizationText"
6748
+ [attachmentTemplate]="attachmentTemplate"
6749
+ [authorId]="authorId"
6750
+ (executeAction)="dispatchAction($event)"
6751
+ (resize)="anchor.scrollToBottom()"
6752
+ (navigate)="this.autoScroll = false"
6753
+ >
6754
+ </kendo-chat-message-list>
6755
+ }
6585
6756
  </div>
6586
6757
  <kendo-message-box
6587
- #messageBox
6588
- [messageBoxTemplate]="messageBoxTemplate"
6589
- [suggestionTemplate]="suggestionTemplate"
6590
- [suggestions]="suggestions"
6591
- [placeholder]="placeholder"
6592
- [authorId]="authorId"
6593
- [autoScroll]="autoScroll"
6594
- [inputValue]="inputValue"
6595
- [localization]="localizationText"
6596
- (sendMessage)="sendMessage.emit($event)"
6597
- (executeSuggestion)="suggestionExecute.emit($event)"
6598
- (fileSelect)="fileSelect.emit($event)"
6599
- (fileRemove)="fileRemove.emit($event)"
6600
- >
6758
+ #messageBox
6759
+ [messageBoxTemplate]="messageBoxTemplate"
6760
+ [suggestionTemplate]="suggestionTemplate"
6761
+ [suggestions]="suggestions"
6762
+ [placeholder]="placeholder"
6763
+ [authorId]="authorId"
6764
+ [autoScroll]="autoScroll"
6765
+ [inputValue]="inputValue"
6766
+ [localization]="localizationText"
6767
+ (sendMessage)="sendMessage.emit($event)"
6768
+ (executeSuggestion)="suggestionExecute.emit($event)"
6769
+ (fileSelect)="fileSelect.emit($event)"
6770
+ (fileRemove)="fileRemove.emit($event)"
6771
+ >
6601
6772
  </kendo-message-box>
6602
-
6773
+
6603
6774
  <kendo-contextmenu
6604
- #messagesContextMenu
6605
- [items]="contextMenuActions"
6606
- [popupAlign]="{ horizontal: 'right', vertical: 'top' }"
6607
- [collision]="{ horizontal: 'flip', vertical: 'flip'}"
6608
- (popupClose)="handleMenuClose($event)"
6609
- (select)="onContextMenuAction($event.item.originalAction)"
6775
+ #messagesContextMenu
6776
+ [items]="contextMenuActions"
6777
+ [popupAlign]="{ horizontal: 'right', vertical: 'top' }"
6778
+ [collision]="{ horizontal: 'flip', vertical: 'flip'}"
6779
+ (popupClose)="handleMenuClose($event)"
6780
+ (select)="onContextMenuAction($event.item.originalAction)"
6610
6781
  ></kendo-contextmenu>
6611
- `,
6782
+ `,
6612
6783
  standalone: true,
6613
- imports: [LocalizedMessagesDirective$1, ScrollAnchorDirective, MessageListComponent, MessageBoxComponent, MessageReferenceComponent, AppBarComponent, NgTemplateOutlet, NgIf, IconWrapperComponent, KENDO_BUTTON, ContextMenuComponent]
6784
+ imports: [LocalizedMessagesDirective$1, ScrollAnchorDirective, MessageListComponent, MessageBoxComponent, MessageReferenceComponent, AppBarComponent, NgTemplateOutlet, IconWrapperComponent, KENDO_BUTTON, ContextMenuComponent]
6614
6785
  }]
6615
6786
  }], ctorParameters: () => [{ type: i1.LocalizationService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: ChatService }], propDecorators: { messages: [{
6616
6787
  type: Input
@@ -6832,59 +7003,73 @@ class HeroCardComponent {
6832
7003
  this.executeAction.next(action);
6833
7004
  }
6834
7005
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HeroCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6835
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: HeroCardComponent, isStandalone: true, selector: "kendo-chat-hero-card", inputs: { imageUrl: "imageUrl", title: "title", subtitle: "subtitle", actions: "actions" }, outputs: { executeAction: "executeAction" }, host: { properties: { "class.k-card": "this.cssClass" } }, ngImport: i0, template: `
6836
- <img class="k-card-image" [src]="imageUrl" *ngIf="imageUrl" />
7006
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: HeroCardComponent, isStandalone: true, selector: "kendo-chat-hero-card", inputs: { imageUrl: "imageUrl", title: "title", subtitle: "subtitle", actions: "actions" }, outputs: { executeAction: "executeAction" }, host: { properties: { "class.k-card": "this.cssClass" } }, ngImport: i0, template: `
7007
+ @if (imageUrl) {
7008
+ <img class="k-card-image" [src]="imageUrl" />
7009
+ }
6837
7010
  <div class="k-card-body">
6838
- <h5 class="k-card-title" *ngIf="title">
6839
- {{ title }}
6840
- </h5>
6841
- <h6 class="k-card-subtitle" *ngIf="subtitle">
6842
- {{ subtitle }}
6843
- </h6>
7011
+ @if (title) {
7012
+ <h5 class="k-card-title">
7013
+ {{ title }}
7014
+ </h5>
7015
+ }
7016
+ @if (subtitle) {
7017
+ <h6 class="k-card-subtitle">
7018
+ {{ subtitle }}
7019
+ </h6>
7020
+ }
6844
7021
  </div>
6845
7022
  <div class="k-card-actions k-card-actions-vertical">
6846
- <span class="k-card-action"
6847
- *ngFor="let act of actions"
6848
- >
6849
- <button
7023
+ @for (act of actions; track act) {
7024
+ <span class="k-card-action"
7025
+ >
7026
+ <button
6850
7027
  kendoButton fillMode="flat"
6851
7028
  (click)="onClick(act)"
6852
- >
6853
- {{ act.title }}
6854
- </button>
6855
- </span>
7029
+ >
7030
+ {{ act.title }}
7031
+ </button>
7032
+ </span>
7033
+ }
6856
7034
  </div>
6857
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
7035
+ `, isInline: true, dependencies: [{ kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
6858
7036
  }
6859
7037
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: HeroCardComponent, decorators: [{
6860
7038
  type: Component,
6861
7039
  args: [{
6862
7040
  selector: 'kendo-chat-hero-card',
6863
7041
  template: `
6864
- <img class="k-card-image" [src]="imageUrl" *ngIf="imageUrl" />
7042
+ @if (imageUrl) {
7043
+ <img class="k-card-image" [src]="imageUrl" />
7044
+ }
6865
7045
  <div class="k-card-body">
6866
- <h5 class="k-card-title" *ngIf="title">
6867
- {{ title }}
6868
- </h5>
6869
- <h6 class="k-card-subtitle" *ngIf="subtitle">
6870
- {{ subtitle }}
6871
- </h6>
7046
+ @if (title) {
7047
+ <h5 class="k-card-title">
7048
+ {{ title }}
7049
+ </h5>
7050
+ }
7051
+ @if (subtitle) {
7052
+ <h6 class="k-card-subtitle">
7053
+ {{ subtitle }}
7054
+ </h6>
7055
+ }
6872
7056
  </div>
6873
7057
  <div class="k-card-actions k-card-actions-vertical">
6874
- <span class="k-card-action"
6875
- *ngFor="let act of actions"
6876
- >
6877
- <button
7058
+ @for (act of actions; track act) {
7059
+ <span class="k-card-action"
7060
+ >
7061
+ <button
6878
7062
  kendoButton fillMode="flat"
6879
7063
  (click)="onClick(act)"
6880
- >
6881
- {{ act.title }}
6882
- </button>
6883
- </span>
7064
+ >
7065
+ {{ act.title }}
7066
+ </button>
7067
+ </span>
7068
+ }
6884
7069
  </div>
6885
- `,
7070
+ `,
6886
7071
  standalone: true,
6887
- imports: [NgIf, NgFor, ButtonComponent]
7072
+ imports: [ButtonComponent]
6888
7073
  }]
6889
7074
  }], propDecorators: { imageUrl: [{
6890
7075
  type: Input
@@ -7238,7 +7423,7 @@ class InlineAIPromptContentComponent {
7238
7423
  }
7239
7424
  }
7240
7425
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: InlineAIPromptContentComponent, deps: [{ token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i1.LocalizationService, optional: true, skipSelf: true }], target: i0.ɵɵFactoryTarget.Component });
7241
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: InlineAIPromptContentComponent, isStandalone: true, selector: "kendo-inlineaiprompt-content", inputs: { popupElement: "popupElement", promptValue: "promptValue", placeholder: "placeholder", promptOutput: "promptOutput", enableSpeechToText: "enableSpeechToText", streaming: "streaming", width: "width", maxHeight: "maxHeight", appendTo: "appendTo", outputActions: "outputActions", promptCommands: "promptCommands", outputTemplate: "outputTemplate" }, outputs: { promptRequest: "promptRequest", commandExecute: "commandExecute", outputActionClick: "outputActionClick", promptRequestCancel: "promptRequestCancel", close: "close", promptValueChange: "promptValueChange" }, host: { listeners: { "keydown": "onEscapeKey($event)" }, properties: { "class.k-prompt": "this.className", "attr.dir": "this.dirAttr", "style.max-height": "this.maxHeightStyle", "style.width": "this.widthStyle" } }, providers: [
7426
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: InlineAIPromptContentComponent, isStandalone: true, selector: "kendo-inlineaiprompt-content", inputs: { popupElement: "popupElement", promptValue: "promptValue", placeholder: "placeholder", promptOutput: "promptOutput", enableSpeechToText: "enableSpeechToText", streaming: "streaming", width: "width", maxHeight: "maxHeight", appendTo: "appendTo", outputActions: "outputActions", promptCommands: "promptCommands", outputTemplate: "outputTemplate" }, outputs: { promptRequest: "promptRequest", commandExecute: "commandExecute", outputActionClick: "outputActionClick", promptRequestCancel: "promptRequestCancel", close: "close", promptValueChange: "promptValueChange" }, host: { listeners: { "keydown": "onEscapeKey($event)" }, properties: { "class.k-prompt": "this.className", "attr.dir": "this.dirAttr", "style.max-height": "this.maxHeightStyle", "style.width": "this.widthStyle" } }, providers: [
7242
7427
  LocalizationService,
7243
7428
  {
7244
7429
  provide: L10N_PREFIX,
@@ -7246,99 +7431,112 @@ class InlineAIPromptContentComponent {
7246
7431
  },
7247
7432
  ], viewQueries: [{ propertyName: "textArea", first: true, predicate: TextAreaComponent, descendants: true }, { propertyName: "contextMenu", first: true, predicate: ["kendoContextMenu"], descendants: true }], exportAs: ["kendoInlineAIPromptContent"], ngImport: i0, template: `
7248
7433
  <ng-container kendoInlineAIPromptLocalizedMessages
7249
- i18n-commandsButtonTitle="kendo.inlineaiprompt.commandsButtonTitle|Sets the Commands button title."
7250
- commandsButtonTitle="Command Menu"
7251
- i18n-generateButtonTitle="kendo.inlineaiprompt.generateButtonTitle|Sets the Generate button title."
7252
- generateButtonTitle="Generate"
7253
- i18n-speechToTextButtonTitle="kendo.inlineaiprompt.speechToTextButtonTitle|Sets the Speech to Text button title."
7254
- speechToTextButtonTitle="Speech to Text"
7255
- >
7434
+ i18n-commandsButtonTitle="kendo.inlineaiprompt.commandsButtonTitle|Sets the Commands button title."
7435
+ commandsButtonTitle="Command Menu"
7436
+ i18n-generateButtonTitle="kendo.inlineaiprompt.generateButtonTitle|Sets the Generate button title."
7437
+ generateButtonTitle="Generate"
7438
+ i18n-speechToTextButtonTitle="kendo.inlineaiprompt.speechToTextButtonTitle|Sets the Speech to Text button title."
7439
+ speechToTextButtonTitle="Speech to Text"
7440
+ >
7256
7441
  </ng-container>
7257
7442
  <div class="k-prompt-content">
7258
- <div class="k-prompt-view">
7259
- <kendo-card *ngIf="promptOutput" width="100%">
7260
- <kendo-card-body>
7261
- <ng-container
7262
- *ngIf="outputTemplate"
7263
- [ngTemplateOutlet]="outputTemplate"
7264
- [ngTemplateOutletContext]="{ $implicit: promptOutput }"
7265
- >
7266
- </ng-container>
7267
- <ng-container *ngIf="!outputTemplate">{{promptOutput.output}}</ng-container>
7268
- </kendo-card-body>
7269
- <kendo-card-actions *ngIf="outputActions && outputActions.length > 0">
7270
- <ng-container *ngFor="let action of outputActions">
7271
- <button kendoButton *ngIf="action.type === 'button'"
7272
- [attr.title]="action?.title"
7273
- [fillMode]="action?.fillMode"
7274
- [themeColor]="action?.themeColor"
7275
- [rounded]="action?.rounded"
7276
- [icon]="action?.icon"
7277
- [svgIcon]="action?.svgIcon"
7278
- (click)="onActionClick(action)"
7279
- >{{action?.text}}</button>
7280
- <div *ngIf="action.type === 'spacer'" class="k-spacer"></div>
7281
- </ng-container>
7282
- </kendo-card-actions>
7283
- </kendo-card>
7284
- <kendo-textarea
7285
- [value]="promptValue ? promptValue : null"
7286
- (valueChange)="handlePromptValueChange($event)"
7287
- [rows]="initialRows"
7288
- resizable="auto"
7289
- flow="horizontal"
7290
- [placeholder]="placeholder"
7291
- [showPrefixSeparator]="true"
7292
- [selectOnFocus]="true"
7293
- [maxResizableRows]="maxRows"
7294
- (keydown)="handleTextAreaKeydown($event)"
7295
- >
7296
- <kendo-textarea-prefix>
7297
- <button
7298
- kendoButton
7299
- #commandMenuButton
7300
- *ngIf="promptCommands && promptCommands.length > 0"
7301
- [attr.title]="messageFor('commandsButtonTitle')"
7302
- fillMode="flat"
7303
- icon="menu"
7304
- [svgIcon]="commandMenuIcon"
7305
- (click)="onCommandButtonClick($event)"
7306
- ></button>
7307
- <button
7308
- kendoSpeechToTextButton
7309
- *ngIf="enableSpeechToText"
7310
- [attr.title]="messageFor('speechToTextButtonTitle')"
7311
- fillMode="flat"
7312
- (result)="handleSpeechResult($event)"
7313
- (start)="isListening = true"
7314
- (end)="isListening = false"
7315
- ></button>
7316
- </kendo-textarea-prefix>
7317
- <kendo-textarea-suffix>
7318
- <button
7319
- kendoButton
7320
- [attr.title]="messageFor('generateButtonTitle')"
7321
- fillMode="flat"
7322
- class="k-prompt-send"
7323
- [ngClass]="{ 'k-generating': streaming, 'k-active': streaming }"
7324
- (click)="handlePromptRequest()"
7325
- [disabled]="!streaming && (!promptValue?.trim() || isListening)"
7326
- [svgIcon]="streaming ? stopGenerationIcon : sendIcon"
7327
- [icon]="streaming ? 'stop-sm' : 'paper-plane'"
7328
- ></button>
7329
- </kendo-textarea-suffix>
7330
- </kendo-textarea>
7331
- </div>
7443
+ <div class="k-prompt-view">
7444
+ @if (promptOutput) {
7445
+ <kendo-card width="100%">
7446
+ <kendo-card-body>
7447
+ @if (outputTemplate) {
7448
+ <ng-container
7449
+ [ngTemplateOutlet]="outputTemplate"
7450
+ [ngTemplateOutletContext]="{ $implicit: promptOutput }"
7451
+ >
7452
+ </ng-container>
7453
+ }
7454
+ @if (!outputTemplate) {
7455
+ {{promptOutput.output}}
7456
+ }
7457
+ </kendo-card-body>
7458
+ @if (outputActions && outputActions.length > 0) {
7459
+ <kendo-card-actions>
7460
+ @for (action of outputActions; track action) {
7461
+ @if (action.type === 'button') {
7462
+ <button kendoButton
7463
+ [attr.title]="action?.title"
7464
+ [fillMode]="action?.fillMode"
7465
+ [themeColor]="action?.themeColor"
7466
+ [rounded]="action?.rounded"
7467
+ [icon]="action?.icon"
7468
+ [svgIcon]="action?.svgIcon"
7469
+ (click)="onActionClick(action)"
7470
+ >{{action?.text}}</button>
7471
+ }
7472
+ @if (action.type === 'spacer') {
7473
+ <div class="k-spacer"></div>
7474
+ }
7475
+ }
7476
+ </kendo-card-actions>
7477
+ }
7478
+ </kendo-card>
7479
+ }
7480
+ <kendo-textarea
7481
+ [value]="promptValue ? promptValue : null"
7482
+ (valueChange)="handlePromptValueChange($event)"
7483
+ [rows]="initialRows"
7484
+ resizable="auto"
7485
+ flow="horizontal"
7486
+ [placeholder]="placeholder"
7487
+ [showPrefixSeparator]="true"
7488
+ [selectOnFocus]="true"
7489
+ [maxResizableRows]="maxRows"
7490
+ (keydown)="handleTextAreaKeydown($event)"
7491
+ >
7492
+ <kendo-textarea-prefix>
7493
+ @if (promptCommands && promptCommands.length > 0) {
7494
+ <button
7495
+ kendoButton
7496
+ #commandMenuButton
7497
+ [attr.title]="messageFor('commandsButtonTitle')"
7498
+ fillMode="flat"
7499
+ icon="menu"
7500
+ [svgIcon]="commandMenuIcon"
7501
+ (click)="onCommandButtonClick($event)"
7502
+ ></button>
7503
+ }
7504
+ @if (enableSpeechToText) {
7505
+ <button
7506
+ kendoSpeechToTextButton
7507
+ [attr.title]="messageFor('speechToTextButtonTitle')"
7508
+ fillMode="flat"
7509
+ (result)="handleSpeechResult($event)"
7510
+ (start)="isListening = true"
7511
+ (end)="isListening = false"
7512
+ ></button>
7513
+ }
7514
+ </kendo-textarea-prefix>
7515
+ <kendo-textarea-suffix>
7516
+ <button
7517
+ kendoButton
7518
+ [attr.title]="messageFor('generateButtonTitle')"
7519
+ fillMode="flat"
7520
+ class="k-prompt-send"
7521
+ [ngClass]="{ 'k-generating': streaming, 'k-active': streaming }"
7522
+ (click)="handlePromptRequest()"
7523
+ [disabled]="!streaming && (!promptValue?.trim() || isListening)"
7524
+ [svgIcon]="streaming ? stopGenerationIcon : sendIcon"
7525
+ [icon]="streaming ? 'stop-sm' : 'paper-plane'"
7526
+ ></button>
7527
+ </kendo-textarea-suffix>
7528
+ </kendo-textarea>
7529
+ </div>
7332
7530
  </div>
7333
7531
  <kendo-contextmenu
7334
- #kendoContextMenu
7335
- [alignToAnchor]="true"
7336
- [items]="commandMenuItems"
7337
- [appendTo]="appendTo"
7338
- class="k-hidden"
7339
- (select)="onCommandClick($event)">
7532
+ #kendoContextMenu
7533
+ [alignToAnchor]="true"
7534
+ [items]="commandMenuItems"
7535
+ [appendTo]="appendTo"
7536
+ class="k-hidden"
7537
+ (select)="onCommandClick($event)">
7340
7538
  </kendo-contextmenu>
7341
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoInlineAIPromptLocalizedMessages]" }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: i2.SpeechToTextButtonComponent, selector: "button[kendoSpeechToTextButton]", inputs: ["disabled", "size", "rounded", "fillMode", "themeColor", "integrationMode", "lang", "continuous", "interimResults", "maxAlternatives"], outputs: ["start", "end", "result", "error", "click"], exportAs: ["kendoSpeechToTextButton"] }, { kind: "component", type: i3.TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "component", type: i3.TextAreaPrefixComponent, selector: "kendo-textarea-prefix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaPrefix"] }, { kind: "component", type: i3.TextAreaSuffixComponent, selector: "kendo-textarea-suffix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaSuffix"] }, { kind: "component", type: i4.ContextMenuComponent, selector: "kendo-contextmenu", inputs: ["showOn", "target", "filter", "alignToAnchor", "vertical", "popupAnimate", "popupAlign", "anchorAlign", "collision", "appendTo", "ariaLabel"], outputs: ["popupOpen", "popupClose", "select", "open", "close"], exportAs: ["kendoContextMenu"] }, { kind: "component", type: i5.CardComponent, selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i5.CardActionsComponent, selector: "kendo-card-actions", inputs: ["orientation", "layout", "actions"], outputs: ["action"] }, { kind: "component", type: i5.CardBodyComponent, selector: "kendo-card-body" }] });
7539
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoInlineAIPromptLocalizedMessages]" }, { kind: "component", type: i2.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "component", type: i2.SpeechToTextButtonComponent, selector: "button[kendoSpeechToTextButton]", inputs: ["disabled", "size", "rounded", "fillMode", "themeColor", "integrationMode", "lang", "continuous", "interimResults", "maxAlternatives"], outputs: ["start", "end", "result", "error", "click"], exportAs: ["kendoSpeechToTextButton"] }, { kind: "component", type: i3.TextAreaComponent, selector: "kendo-textarea", inputs: ["focusableId", "flow", "inputAttributes", "adornmentsOrientation", "rows", "cols", "maxlength", "maxResizableRows", "tabindex", "tabIndex", "resizable", "size", "rounded", "fillMode", "showPrefixSeparator", "showSuffixSeparator"], outputs: ["focus", "blur", "valueChange"], exportAs: ["kendoTextArea"] }, { kind: "component", type: i3.TextAreaPrefixComponent, selector: "kendo-textarea-prefix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaPrefix"] }, { kind: "component", type: i3.TextAreaSuffixComponent, selector: "kendo-textarea-suffix", inputs: ["flow", "orientation"], exportAs: ["kendoTextAreaSuffix"] }, { kind: "component", type: i4.ContextMenuComponent, selector: "kendo-contextmenu", inputs: ["showOn", "target", "filter", "alignToAnchor", "vertical", "popupAnimate", "popupAlign", "anchorAlign", "collision", "appendTo", "ariaLabel"], outputs: ["popupOpen", "popupClose", "select", "open", "close"], exportAs: ["kendoContextMenu"] }, { kind: "component", type: i5.CardComponent, selector: "kendo-card", inputs: ["orientation", "width"] }, { kind: "component", type: i5.CardActionsComponent, selector: "kendo-card-actions", inputs: ["orientation", "layout", "actions"], outputs: ["action"] }, { kind: "component", type: i5.CardBodyComponent, selector: "kendo-card-body" }] });
7342
7540
  }
7343
7541
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: InlineAIPromptContentComponent, decorators: [{
7344
7542
  type: Component,
@@ -7354,101 +7552,114 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
7354
7552
  ],
7355
7553
  template: `
7356
7554
  <ng-container kendoInlineAIPromptLocalizedMessages
7357
- i18n-commandsButtonTitle="kendo.inlineaiprompt.commandsButtonTitle|Sets the Commands button title."
7358
- commandsButtonTitle="Command Menu"
7359
- i18n-generateButtonTitle="kendo.inlineaiprompt.generateButtonTitle|Sets the Generate button title."
7360
- generateButtonTitle="Generate"
7361
- i18n-speechToTextButtonTitle="kendo.inlineaiprompt.speechToTextButtonTitle|Sets the Speech to Text button title."
7362
- speechToTextButtonTitle="Speech to Text"
7363
- >
7555
+ i18n-commandsButtonTitle="kendo.inlineaiprompt.commandsButtonTitle|Sets the Commands button title."
7556
+ commandsButtonTitle="Command Menu"
7557
+ i18n-generateButtonTitle="kendo.inlineaiprompt.generateButtonTitle|Sets the Generate button title."
7558
+ generateButtonTitle="Generate"
7559
+ i18n-speechToTextButtonTitle="kendo.inlineaiprompt.speechToTextButtonTitle|Sets the Speech to Text button title."
7560
+ speechToTextButtonTitle="Speech to Text"
7561
+ >
7364
7562
  </ng-container>
7365
7563
  <div class="k-prompt-content">
7366
- <div class="k-prompt-view">
7367
- <kendo-card *ngIf="promptOutput" width="100%">
7368
- <kendo-card-body>
7369
- <ng-container
7370
- *ngIf="outputTemplate"
7371
- [ngTemplateOutlet]="outputTemplate"
7372
- [ngTemplateOutletContext]="{ $implicit: promptOutput }"
7373
- >
7374
- </ng-container>
7375
- <ng-container *ngIf="!outputTemplate">{{promptOutput.output}}</ng-container>
7376
- </kendo-card-body>
7377
- <kendo-card-actions *ngIf="outputActions && outputActions.length > 0">
7378
- <ng-container *ngFor="let action of outputActions">
7379
- <button kendoButton *ngIf="action.type === 'button'"
7380
- [attr.title]="action?.title"
7381
- [fillMode]="action?.fillMode"
7382
- [themeColor]="action?.themeColor"
7383
- [rounded]="action?.rounded"
7384
- [icon]="action?.icon"
7385
- [svgIcon]="action?.svgIcon"
7386
- (click)="onActionClick(action)"
7387
- >{{action?.text}}</button>
7388
- <div *ngIf="action.type === 'spacer'" class="k-spacer"></div>
7389
- </ng-container>
7390
- </kendo-card-actions>
7391
- </kendo-card>
7392
- <kendo-textarea
7393
- [value]="promptValue ? promptValue : null"
7394
- (valueChange)="handlePromptValueChange($event)"
7395
- [rows]="initialRows"
7396
- resizable="auto"
7397
- flow="horizontal"
7398
- [placeholder]="placeholder"
7399
- [showPrefixSeparator]="true"
7400
- [selectOnFocus]="true"
7401
- [maxResizableRows]="maxRows"
7402
- (keydown)="handleTextAreaKeydown($event)"
7403
- >
7404
- <kendo-textarea-prefix>
7405
- <button
7406
- kendoButton
7407
- #commandMenuButton
7408
- *ngIf="promptCommands && promptCommands.length > 0"
7409
- [attr.title]="messageFor('commandsButtonTitle')"
7410
- fillMode="flat"
7411
- icon="menu"
7412
- [svgIcon]="commandMenuIcon"
7413
- (click)="onCommandButtonClick($event)"
7414
- ></button>
7415
- <button
7416
- kendoSpeechToTextButton
7417
- *ngIf="enableSpeechToText"
7418
- [attr.title]="messageFor('speechToTextButtonTitle')"
7419
- fillMode="flat"
7420
- (result)="handleSpeechResult($event)"
7421
- (start)="isListening = true"
7422
- (end)="isListening = false"
7423
- ></button>
7424
- </kendo-textarea-prefix>
7425
- <kendo-textarea-suffix>
7426
- <button
7427
- kendoButton
7428
- [attr.title]="messageFor('generateButtonTitle')"
7429
- fillMode="flat"
7430
- class="k-prompt-send"
7431
- [ngClass]="{ 'k-generating': streaming, 'k-active': streaming }"
7432
- (click)="handlePromptRequest()"
7433
- [disabled]="!streaming && (!promptValue?.trim() || isListening)"
7434
- [svgIcon]="streaming ? stopGenerationIcon : sendIcon"
7435
- [icon]="streaming ? 'stop-sm' : 'paper-plane'"
7436
- ></button>
7437
- </kendo-textarea-suffix>
7438
- </kendo-textarea>
7439
- </div>
7564
+ <div class="k-prompt-view">
7565
+ @if (promptOutput) {
7566
+ <kendo-card width="100%">
7567
+ <kendo-card-body>
7568
+ @if (outputTemplate) {
7569
+ <ng-container
7570
+ [ngTemplateOutlet]="outputTemplate"
7571
+ [ngTemplateOutletContext]="{ $implicit: promptOutput }"
7572
+ >
7573
+ </ng-container>
7574
+ }
7575
+ @if (!outputTemplate) {
7576
+ {{promptOutput.output}}
7577
+ }
7578
+ </kendo-card-body>
7579
+ @if (outputActions && outputActions.length > 0) {
7580
+ <kendo-card-actions>
7581
+ @for (action of outputActions; track action) {
7582
+ @if (action.type === 'button') {
7583
+ <button kendoButton
7584
+ [attr.title]="action?.title"
7585
+ [fillMode]="action?.fillMode"
7586
+ [themeColor]="action?.themeColor"
7587
+ [rounded]="action?.rounded"
7588
+ [icon]="action?.icon"
7589
+ [svgIcon]="action?.svgIcon"
7590
+ (click)="onActionClick(action)"
7591
+ >{{action?.text}}</button>
7592
+ }
7593
+ @if (action.type === 'spacer') {
7594
+ <div class="k-spacer"></div>
7595
+ }
7596
+ }
7597
+ </kendo-card-actions>
7598
+ }
7599
+ </kendo-card>
7600
+ }
7601
+ <kendo-textarea
7602
+ [value]="promptValue ? promptValue : null"
7603
+ (valueChange)="handlePromptValueChange($event)"
7604
+ [rows]="initialRows"
7605
+ resizable="auto"
7606
+ flow="horizontal"
7607
+ [placeholder]="placeholder"
7608
+ [showPrefixSeparator]="true"
7609
+ [selectOnFocus]="true"
7610
+ [maxResizableRows]="maxRows"
7611
+ (keydown)="handleTextAreaKeydown($event)"
7612
+ >
7613
+ <kendo-textarea-prefix>
7614
+ @if (promptCommands && promptCommands.length > 0) {
7615
+ <button
7616
+ kendoButton
7617
+ #commandMenuButton
7618
+ [attr.title]="messageFor('commandsButtonTitle')"
7619
+ fillMode="flat"
7620
+ icon="menu"
7621
+ [svgIcon]="commandMenuIcon"
7622
+ (click)="onCommandButtonClick($event)"
7623
+ ></button>
7624
+ }
7625
+ @if (enableSpeechToText) {
7626
+ <button
7627
+ kendoSpeechToTextButton
7628
+ [attr.title]="messageFor('speechToTextButtonTitle')"
7629
+ fillMode="flat"
7630
+ (result)="handleSpeechResult($event)"
7631
+ (start)="isListening = true"
7632
+ (end)="isListening = false"
7633
+ ></button>
7634
+ }
7635
+ </kendo-textarea-prefix>
7636
+ <kendo-textarea-suffix>
7637
+ <button
7638
+ kendoButton
7639
+ [attr.title]="messageFor('generateButtonTitle')"
7640
+ fillMode="flat"
7641
+ class="k-prompt-send"
7642
+ [ngClass]="{ 'k-generating': streaming, 'k-active': streaming }"
7643
+ (click)="handlePromptRequest()"
7644
+ [disabled]="!streaming && (!promptValue?.trim() || isListening)"
7645
+ [svgIcon]="streaming ? stopGenerationIcon : sendIcon"
7646
+ [icon]="streaming ? 'stop-sm' : 'paper-plane'"
7647
+ ></button>
7648
+ </kendo-textarea-suffix>
7649
+ </kendo-textarea>
7650
+ </div>
7440
7651
  </div>
7441
7652
  <kendo-contextmenu
7442
- #kendoContextMenu
7443
- [alignToAnchor]="true"
7444
- [items]="commandMenuItems"
7445
- [appendTo]="appendTo"
7446
- class="k-hidden"
7447
- (select)="onCommandClick($event)">
7653
+ #kendoContextMenu
7654
+ [alignToAnchor]="true"
7655
+ [items]="commandMenuItems"
7656
+ [appendTo]="appendTo"
7657
+ class="k-hidden"
7658
+ (select)="onCommandClick($event)">
7448
7659
  </kendo-contextmenu>
7449
- `,
7660
+ `,
7450
7661
  standalone: true,
7451
- imports: [NgClass, NgIf, NgFor, NgTemplateOutlet, LocalizedMessagesDirective, KENDO_BUTTONS, KENDO_TEXTAREA, KENDO_CONTEXTMENU, KENDO_CARD],
7662
+ imports: [NgClass, NgTemplateOutlet, LocalizedMessagesDirective, KENDO_BUTTONS, KENDO_TEXTAREA, KENDO_CONTEXTMENU, KENDO_CARD],
7452
7663
  }]
7453
7664
  }], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.LocalizationService, decorators: [{
7454
7665
  type: Optional