@progress/kendo-angular-conversational-ui 19.3.0-develop.24 → 19.3.0-develop.26

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 (45) hide show
  1. package/conversational-ui.module.d.ts +4 -1
  2. package/directives.d.ts +5 -1
  3. package/esm2022/ai-prompt/views/prompt-view.component.mjs +1 -1
  4. package/esm2022/chat/message-box.component.mjs +1 -1
  5. package/esm2022/conversational-ui.module.mjs +5 -2
  6. package/esm2022/directives.mjs +10 -1
  7. package/esm2022/index.mjs +5 -0
  8. package/esm2022/inline-ai-prompt/inlineaiprompt-content.component.mjs +549 -0
  9. package/esm2022/inline-ai-prompt/inlineaiprompt.component.mjs +342 -0
  10. package/esm2022/inline-ai-prompt/inlineaiprompt.service.mjs +85 -0
  11. package/esm2022/inline-ai-prompt/localization/custom-messages.component.mjs +53 -0
  12. package/esm2022/inline-ai-prompt/localization/localized-messages.directive.mjs +39 -0
  13. package/esm2022/inline-ai-prompt/localization/messages.mjs +35 -0
  14. package/esm2022/inline-ai-prompt/models/command.interface.mjs +5 -0
  15. package/esm2022/inline-ai-prompt/models/index.mjs +5 -0
  16. package/esm2022/inline-ai-prompt/models/inlineaiprompt-popupsettings.mjs +5 -0
  17. package/esm2022/inline-ai-prompt/models/inlineaiprompt-settings.mjs +59 -0
  18. package/esm2022/inline-ai-prompt/models/messages.mjs +8 -0
  19. package/esm2022/inline-ai-prompt/models/output-action-click-event.mjs +5 -0
  20. package/esm2022/inline-ai-prompt/models/output-action.interface.mjs +5 -0
  21. package/esm2022/inline-ai-prompt/models/prompt-output.interface.mjs +5 -0
  22. package/esm2022/inline-ai-prompt/models/prompt-request-event.mjs +5 -0
  23. package/esm2022/inline-ai-prompt/output-template.directive.mjs +38 -0
  24. package/esm2022/inline-ai-prompt/utils.mjs +22 -0
  25. package/esm2022/package-metadata.mjs +2 -2
  26. package/fesm2022/progress-kendo-angular-conversational-ui.mjs +1195 -42
  27. package/index.d.ts +5 -0
  28. package/inline-ai-prompt/inlineaiprompt-content.component.d.ts +82 -0
  29. package/inline-ai-prompt/inlineaiprompt.component.d.ts +150 -0
  30. package/inline-ai-prompt/inlineaiprompt.service.d.ts +41 -0
  31. package/inline-ai-prompt/localization/custom-messages.component.d.ts +27 -0
  32. package/inline-ai-prompt/localization/localized-messages.directive.d.ts +16 -0
  33. package/inline-ai-prompt/localization/messages.d.ts +25 -0
  34. package/inline-ai-prompt/models/command.interface.d.ts +38 -0
  35. package/inline-ai-prompt/models/index.d.ts +12 -0
  36. package/inline-ai-prompt/models/inlineaiprompt-popupsettings.d.ts +10 -0
  37. package/inline-ai-prompt/models/inlineaiprompt-settings.d.ts +66 -0
  38. package/inline-ai-prompt/models/messages.d.ts +21 -0
  39. package/inline-ai-prompt/models/output-action-click-event.d.ts +19 -0
  40. package/inline-ai-prompt/models/output-action.interface.d.ts +52 -0
  41. package/inline-ai-prompt/models/prompt-output.interface.d.ts +25 -0
  42. package/inline-ai-prompt/models/prompt-request-event.d.ts +17 -0
  43. package/inline-ai-prompt/output-template.directive.d.ts +27 -0
  44. package/inline-ai-prompt/utils.d.ts +13 -0
  45. package/package.json +12 -11
@@ -0,0 +1,549 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ import { Component, ElementRef, EventEmitter, HostBinding, HostListener, Input, NgZone, Output, Renderer2, ViewChild, ViewContainerRef, Optional, SkipSelf, inject, TemplateRef } from '@angular/core';
6
+ import { NgIf, NgClass, NgTemplateOutlet, NgFor } from '@angular/common';
7
+ import { Subscription } from 'rxjs';
8
+ import { menuIcon, paperPlaneIcon, stopSmIcon, copyIcon, cancelOutlineIcon, arrowRotateCwIcon } from '@progress/kendo-svg-icons';
9
+ import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
10
+ import { validatePackage } from '@progress/kendo-licensing';
11
+ import { KENDO_BUTTONS } from '@progress/kendo-angular-buttons';
12
+ import { packageMetadata } from '../package-metadata';
13
+ import { TextAreaComponent, KENDO_TEXTAREA } from '@progress/kendo-angular-inputs';
14
+ import { ContextMenuComponent, KENDO_CONTEXTMENU } from '@progress/kendo-angular-menu';
15
+ import { LocalizedMessagesDirective } from './localization/localized-messages.directive';
16
+ import { isDocumentAvailable } from '@progress/kendo-angular-common';
17
+ import { calculateMeasurement } from './utils';
18
+ import { KENDO_CARD } from '@progress/kendo-angular-layout';
19
+ import * as i0 from "@angular/core";
20
+ import * as i1 from "@progress/kendo-angular-l10n";
21
+ import * as i2 from "@progress/kendo-angular-buttons";
22
+ import * as i3 from "@progress/kendo-angular-inputs";
23
+ import * as i4 from "@progress/kendo-angular-menu";
24
+ import * as i5 from "@progress/kendo-angular-layout";
25
+ const TEXTAREA_MAX_ROWS = 5;
26
+ const TEXTAREA_INITIAL_ROWS = 1;
27
+ /**
28
+ * @hidden
29
+ */
30
+ export class InlineAIPromptContentComponent {
31
+ ngZone;
32
+ renderer;
33
+ element;
34
+ localization;
35
+ className = true;
36
+ get dirAttr() {
37
+ return this.direction;
38
+ }
39
+ get maxHeightStyle() {
40
+ return this.calculateMeasurement(this.maxHeight);
41
+ }
42
+ get widthStyle() {
43
+ return this.calculateMeasurement(this.width);
44
+ }
45
+ popupElement;
46
+ promptValue;
47
+ placeholder;
48
+ promptOutput;
49
+ enableTextToSpeech = true;
50
+ streaming = false;
51
+ width = 550;
52
+ maxHeight;
53
+ appendTo;
54
+ defaultOutputActions = [{
55
+ name: 'copy',
56
+ type: 'button',
57
+ icon: 'copy',
58
+ svgIcon: copyIcon,
59
+ text: 'Copy',
60
+ fillMode: 'flat',
61
+ themeColor: 'primary',
62
+ rounded: 'medium',
63
+ },
64
+ {
65
+ name: 'retry',
66
+ type: 'button',
67
+ icon: 'arrow-rotate-cw',
68
+ svgIcon: arrowRotateCwIcon,
69
+ text: 'Retry',
70
+ fillMode: 'flat',
71
+ themeColor: 'primary',
72
+ rounded: 'medium',
73
+ },
74
+ {
75
+ name: 'discard',
76
+ type: 'button',
77
+ icon: 'cancel-outline',
78
+ svgIcon: cancelOutlineIcon,
79
+ text: 'Discard',
80
+ fillMode: 'flat',
81
+ themeColor: 'base',
82
+ rounded: 'medium',
83
+ }
84
+ ];
85
+ set outputActions(actions) {
86
+ this._outputActions = this.mergeWithDefaultActions(actions);
87
+ }
88
+ get outputActions() {
89
+ return this._outputActions;
90
+ }
91
+ set promptCommands(commands) {
92
+ this._promptCommands = commands || [];
93
+ this.commandMenuItems = this.transformCommands(commands || []);
94
+ }
95
+ get promptCommands() {
96
+ return this._promptCommands;
97
+ }
98
+ outputTemplate;
99
+ promptRequest = new EventEmitter();
100
+ executeCommand = new EventEmitter();
101
+ outputActionClick = new EventEmitter();
102
+ promptRequestCancel = new EventEmitter();
103
+ close = new EventEmitter();
104
+ promptValueChange = new EventEmitter();
105
+ onEscapeKey(event) {
106
+ if (event.key === 'Escape') {
107
+ if (this.streaming) {
108
+ event.stopPropagation();
109
+ this.promptRequestCancel.emit();
110
+ }
111
+ else {
112
+ this.close.emit();
113
+ }
114
+ }
115
+ }
116
+ textArea;
117
+ contextMenu;
118
+ calculateMeasurement = calculateMeasurement;
119
+ commandMenuIcon = menuIcon;
120
+ sendIcon = paperPlaneIcon;
121
+ stopGenerationIcon = stopSmIcon;
122
+ isListening = false;
123
+ commandMenuItems = [];
124
+ messages = {};
125
+ maxRows = TEXTAREA_MAX_ROWS;
126
+ initialRows = TEXTAREA_INITIAL_ROWS;
127
+ _outputActions = this.defaultOutputActions;
128
+ _promptCommands = [];
129
+ direction;
130
+ localizationSubs = new Subscription();
131
+ subs = new Subscription();
132
+ constructor(ngZone, renderer, element, localization) {
133
+ this.ngZone = ngZone;
134
+ this.renderer = renderer;
135
+ this.element = element;
136
+ this.localization = localization;
137
+ validatePackage(packageMetadata);
138
+ if (!this.localization) {
139
+ this.localization = inject(LocalizationService);
140
+ }
141
+ this.direction = this.localization?.rtl ? 'rtl' : 'ltr';
142
+ this.localizationSubs.add(this.localization.changes.subscribe(({ rtl }) => {
143
+ this.direction = rtl ? 'rtl' : 'ltr';
144
+ }));
145
+ }
146
+ ngAfterViewInit() {
147
+ this.ngZone.runOutsideAngular(() => {
148
+ if (!isDocumentAvailable()) {
149
+ return;
150
+ }
151
+ // add a delay to avoid catching the same click event that triggered the component opening
152
+ setTimeout(() => {
153
+ this.subs.add(this.renderer.listen('document', 'click', (e) => {
154
+ this.outsideClickClose(e);
155
+ }));
156
+ });
157
+ });
158
+ }
159
+ ngOnDestroy() {
160
+ this.subs.unsubscribe();
161
+ this.localizationSubs.unsubscribe();
162
+ this.contextMenu?.hide();
163
+ }
164
+ focus() {
165
+ if (this.textArea) {
166
+ this.textArea.focus();
167
+ }
168
+ }
169
+ onActionClick(event) {
170
+ const eventArgs = {
171
+ action: event,
172
+ output: this.promptOutput,
173
+ };
174
+ this.outputActionClick.emit(eventArgs);
175
+ this.handleDefaultActions(event);
176
+ }
177
+ handleDefaultActions(event) {
178
+ switch (event.name) {
179
+ case 'copy':
180
+ navigator.clipboard.writeText(this.promptOutput.output);
181
+ break;
182
+ case 'retry':
183
+ this.promptRequest.emit({
184
+ prompt: this.promptOutput?.prompt,
185
+ isRetry: true
186
+ });
187
+ break;
188
+ case 'discard':
189
+ this.close.emit();
190
+ break;
191
+ }
192
+ }
193
+ handleSpeechResult(event) {
194
+ if (event.alternatives && event.alternatives.length > 0) {
195
+ this.promptValue += event.alternatives[0].transcript + ' ';
196
+ }
197
+ }
198
+ onClick(action) {
199
+ this.executeCommand.next(action);
200
+ }
201
+ handlePromptValueChange(value) {
202
+ this.promptValue = value;
203
+ this.promptValueChange.emit(value);
204
+ }
205
+ handleTextAreaKeydown(event) {
206
+ if (event.key === 'Enter' && !event.shiftKey && !this.streaming) {
207
+ event.preventDefault();
208
+ this.handlePromptRequest();
209
+ }
210
+ }
211
+ onCommandButtonClick(event) {
212
+ event.preventDefault();
213
+ event.stopPropagation();
214
+ if (this.contextMenu) {
215
+ this.contextMenu.show(this.popupElement);
216
+ }
217
+ }
218
+ onCommandClick(event) {
219
+ // avoid triggering the document click listener to keep the popup open
220
+ if (event.originalEvent) {
221
+ event.originalEvent.stopPropagation();
222
+ event.originalEvent.preventDefault();
223
+ }
224
+ const eventArgs = {
225
+ ...event.item.originalCommand
226
+ };
227
+ this.executeCommand.emit(eventArgs);
228
+ }
229
+ messageFor(text) {
230
+ if (this.messages?.[text]) {
231
+ return this.messages[text];
232
+ }
233
+ return this.localization?.get(text);
234
+ }
235
+ handlePromptRequest() {
236
+ if (this.streaming) {
237
+ this.promptRequestCancel.emit();
238
+ return;
239
+ }
240
+ if (!this.promptValue) {
241
+ return;
242
+ }
243
+ const eventArgs = {
244
+ prompt: this.promptValue
245
+ };
246
+ this.promptRequest.emit(eventArgs);
247
+ }
248
+ mergeWithDefaultActions(userActions) {
249
+ if (!userActions || userActions.length === 0) {
250
+ return [];
251
+ }
252
+ return userActions.map(userAction => {
253
+ const defaultAction = this.defaultOutputActions.find(action => action.name === userAction?.name);
254
+ if (defaultAction) {
255
+ return { ...defaultAction, ...userAction };
256
+ }
257
+ return userAction;
258
+ });
259
+ }
260
+ transformCommands = (commands) => commands.map(command => ({
261
+ text: command.text,
262
+ icon: command.icon,
263
+ svgIcon: command.svgIcon,
264
+ disabled: command.disabled,
265
+ originalCommand: command,
266
+ items: command.children ? this.transformCommands(command.children) : undefined
267
+ }));
268
+ outsideClickClose(e) {
269
+ if (!this.element.nativeElement.contains(e.target)) {
270
+ this.ngZone.run(() => {
271
+ this.close.emit();
272
+ });
273
+ }
274
+ }
275
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", 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 });
276
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: InlineAIPromptContentComponent, isStandalone: true, selector: "kendo-inlineaiprompt-content", inputs: { popupElement: "popupElement", promptValue: "promptValue", placeholder: "placeholder", promptOutput: "promptOutput", enableTextToSpeech: "enableTextToSpeech", streaming: "streaming", width: "width", maxHeight: "maxHeight", appendTo: "appendTo", outputActions: "outputActions", promptCommands: "promptCommands", outputTemplate: "outputTemplate" }, outputs: { promptRequest: "promptRequest", executeCommand: "executeCommand", 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: [
277
+ LocalizationService,
278
+ {
279
+ provide: L10N_PREFIX,
280
+ useValue: 'kendo.inlineaiprompt',
281
+ },
282
+ ], viewQueries: [{ propertyName: "textArea", first: true, predicate: TextAreaComponent, descendants: true }, { propertyName: "contextMenu", first: true, predicate: ["kendoContextMenu"], descendants: true }], exportAs: ["kendoInlineAIPromptContent"], ngImport: i0, template: `
283
+ <ng-container kendoInlineAIPromptLocalizedMessages
284
+ i18n-commandsButtonTitle="kendo.inlineaiprompt.commandsButtonTitle|Sets the Commands button title."
285
+ commandsButtonTitle="Command Menu"
286
+ i18n-generateButtonTitle="kendo.inlineaiprompt.generateButtonTitle|Sets the Generate button title."
287
+ generateButtonTitle="Generate"
288
+ i18n-speechToTextButtonTitle="kendo.inlineaiprompt.speechToTextButtonTitle|Sets the Speech to Text button title."
289
+ speechToTextButtonTitle="Speech to Text"
290
+ >
291
+ </ng-container>
292
+ <div class="k-prompt-content">
293
+ <div class="k-prompt-view">
294
+ <kendo-card *ngIf="promptOutput" width="100%">
295
+ <kendo-card-body>
296
+ <ng-container
297
+ *ngIf="outputTemplate"
298
+ [ngTemplateOutlet]="outputTemplate"
299
+ [ngTemplateOutletContext]="{ $implicit: promptOutput }"
300
+ >
301
+ </ng-container>
302
+ <ng-container *ngIf="!outputTemplate">{{promptOutput.output}}</ng-container>
303
+ </kendo-card-body>
304
+ <kendo-card-actions *ngIf="outputActions && outputActions.length > 0">
305
+ <ng-container *ngFor="let action of outputActions">
306
+ <button kendoButton *ngIf="action.type === 'button'"
307
+ [attr.title]="action?.title"
308
+ [fillMode]="action?.fillMode"
309
+ [themeColor]="action?.themeColor"
310
+ [rounded]="action?.rounded"
311
+ [icon]="action?.icon"
312
+ [svgIcon]="action?.svgIcon"
313
+ (click)="onActionClick(action)"
314
+ >{{action?.text}}</button>
315
+ <div *ngIf="action.type === 'spacer'" class="k-spacer"></div>
316
+ </ng-container>
317
+ </kendo-card-actions>
318
+ </kendo-card>
319
+ <kendo-textarea
320
+ [value]="promptValue ? promptValue : null"
321
+ (valueChange)="handlePromptValueChange($event)"
322
+ [rows]="initialRows"
323
+ resizable="auto"
324
+ flow="horizontal"
325
+ [placeholder]="placeholder"
326
+ [showPrefixSeparator]="true"
327
+ [selectOnFocus]="true"
328
+ [maxResizableRows]="maxRows"
329
+ (keydown)="handleTextAreaKeydown($event)"
330
+ >
331
+ <kendo-textarea-prefix>
332
+ <button
333
+ kendoButton
334
+ #commandMenuButton
335
+ *ngIf="promptCommands && promptCommands.length > 0"
336
+ [attr.title]="messageFor('commandsButtonTitle')"
337
+ fillMode="flat"
338
+ icon="menu"
339
+ [svgIcon]="commandMenuIcon"
340
+ (click)="onCommandButtonClick($event)"
341
+ ></button>
342
+ <button
343
+ kendoSpeechToTextButton
344
+ *ngIf="enableTextToSpeech"
345
+ [attr.title]="messageFor('speechToTextButtonTitle')"
346
+ fillMode="flat"
347
+ (result)="handleSpeechResult($event)"
348
+ (start)="isListening = true"
349
+ (end)="isListening = false"
350
+ ></button>
351
+ </kendo-textarea-prefix>
352
+ <kendo-textarea-suffix>
353
+ <button
354
+ kendoButton
355
+ [attr.title]="messageFor('generateButtonTitle')"
356
+ fillMode="flat"
357
+ class="k-prompt-send"
358
+ [ngClass]="{ 'k-generating': streaming, 'k-active': streaming }"
359
+ (click)="handlePromptRequest()"
360
+ [disabled]="!streaming && (!promptValue?.trim() || isListening)"
361
+ [svgIcon]="streaming ? stopGenerationIcon : sendIcon"
362
+ [icon]="streaming ? 'stop-sm' : 'paper-plane'"
363
+ ></button>
364
+ </kendo-textarea-suffix>
365
+ </kendo-textarea>
366
+ </div>
367
+ </div>
368
+ <kendo-contextmenu
369
+ #kendoContextMenu
370
+ [alignToAnchor]="true"
371
+ [items]="commandMenuItems"
372
+ [appendTo]="appendTo"
373
+ class="k-hidden"
374
+ (select)="onCommandClick($event)">
375
+ </kendo-contextmenu>
376
+ `, 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" }] });
377
+ }
378
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: InlineAIPromptContentComponent, decorators: [{
379
+ type: Component,
380
+ args: [{
381
+ exportAs: 'kendoInlineAIPromptContent',
382
+ selector: 'kendo-inlineaiprompt-content',
383
+ providers: [
384
+ LocalizationService,
385
+ {
386
+ provide: L10N_PREFIX,
387
+ useValue: 'kendo.inlineaiprompt',
388
+ },
389
+ ],
390
+ template: `
391
+ <ng-container kendoInlineAIPromptLocalizedMessages
392
+ i18n-commandsButtonTitle="kendo.inlineaiprompt.commandsButtonTitle|Sets the Commands button title."
393
+ commandsButtonTitle="Command Menu"
394
+ i18n-generateButtonTitle="kendo.inlineaiprompt.generateButtonTitle|Sets the Generate button title."
395
+ generateButtonTitle="Generate"
396
+ i18n-speechToTextButtonTitle="kendo.inlineaiprompt.speechToTextButtonTitle|Sets the Speech to Text button title."
397
+ speechToTextButtonTitle="Speech to Text"
398
+ >
399
+ </ng-container>
400
+ <div class="k-prompt-content">
401
+ <div class="k-prompt-view">
402
+ <kendo-card *ngIf="promptOutput" width="100%">
403
+ <kendo-card-body>
404
+ <ng-container
405
+ *ngIf="outputTemplate"
406
+ [ngTemplateOutlet]="outputTemplate"
407
+ [ngTemplateOutletContext]="{ $implicit: promptOutput }"
408
+ >
409
+ </ng-container>
410
+ <ng-container *ngIf="!outputTemplate">{{promptOutput.output}}</ng-container>
411
+ </kendo-card-body>
412
+ <kendo-card-actions *ngIf="outputActions && outputActions.length > 0">
413
+ <ng-container *ngFor="let action of outputActions">
414
+ <button kendoButton *ngIf="action.type === 'button'"
415
+ [attr.title]="action?.title"
416
+ [fillMode]="action?.fillMode"
417
+ [themeColor]="action?.themeColor"
418
+ [rounded]="action?.rounded"
419
+ [icon]="action?.icon"
420
+ [svgIcon]="action?.svgIcon"
421
+ (click)="onActionClick(action)"
422
+ >{{action?.text}}</button>
423
+ <div *ngIf="action.type === 'spacer'" class="k-spacer"></div>
424
+ </ng-container>
425
+ </kendo-card-actions>
426
+ </kendo-card>
427
+ <kendo-textarea
428
+ [value]="promptValue ? promptValue : null"
429
+ (valueChange)="handlePromptValueChange($event)"
430
+ [rows]="initialRows"
431
+ resizable="auto"
432
+ flow="horizontal"
433
+ [placeholder]="placeholder"
434
+ [showPrefixSeparator]="true"
435
+ [selectOnFocus]="true"
436
+ [maxResizableRows]="maxRows"
437
+ (keydown)="handleTextAreaKeydown($event)"
438
+ >
439
+ <kendo-textarea-prefix>
440
+ <button
441
+ kendoButton
442
+ #commandMenuButton
443
+ *ngIf="promptCommands && promptCommands.length > 0"
444
+ [attr.title]="messageFor('commandsButtonTitle')"
445
+ fillMode="flat"
446
+ icon="menu"
447
+ [svgIcon]="commandMenuIcon"
448
+ (click)="onCommandButtonClick($event)"
449
+ ></button>
450
+ <button
451
+ kendoSpeechToTextButton
452
+ *ngIf="enableTextToSpeech"
453
+ [attr.title]="messageFor('speechToTextButtonTitle')"
454
+ fillMode="flat"
455
+ (result)="handleSpeechResult($event)"
456
+ (start)="isListening = true"
457
+ (end)="isListening = false"
458
+ ></button>
459
+ </kendo-textarea-prefix>
460
+ <kendo-textarea-suffix>
461
+ <button
462
+ kendoButton
463
+ [attr.title]="messageFor('generateButtonTitle')"
464
+ fillMode="flat"
465
+ class="k-prompt-send"
466
+ [ngClass]="{ 'k-generating': streaming, 'k-active': streaming }"
467
+ (click)="handlePromptRequest()"
468
+ [disabled]="!streaming && (!promptValue?.trim() || isListening)"
469
+ [svgIcon]="streaming ? stopGenerationIcon : sendIcon"
470
+ [icon]="streaming ? 'stop-sm' : 'paper-plane'"
471
+ ></button>
472
+ </kendo-textarea-suffix>
473
+ </kendo-textarea>
474
+ </div>
475
+ </div>
476
+ <kendo-contextmenu
477
+ #kendoContextMenu
478
+ [alignToAnchor]="true"
479
+ [items]="commandMenuItems"
480
+ [appendTo]="appendTo"
481
+ class="k-hidden"
482
+ (select)="onCommandClick($event)">
483
+ </kendo-contextmenu>
484
+ `,
485
+ standalone: true,
486
+ imports: [NgClass, NgIf, NgFor, NgTemplateOutlet, LocalizedMessagesDirective, KENDO_BUTTONS, KENDO_TEXTAREA, KENDO_CONTEXTMENU, KENDO_CARD],
487
+ }]
488
+ }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.LocalizationService, decorators: [{
489
+ type: Optional
490
+ }, {
491
+ type: SkipSelf
492
+ }] }]; }, propDecorators: { className: [{
493
+ type: HostBinding,
494
+ args: ['class.k-prompt']
495
+ }], dirAttr: [{
496
+ type: HostBinding,
497
+ args: ['attr.dir']
498
+ }], maxHeightStyle: [{
499
+ type: HostBinding,
500
+ args: ['style.max-height']
501
+ }], widthStyle: [{
502
+ type: HostBinding,
503
+ args: ['style.width']
504
+ }], popupElement: [{
505
+ type: Input
506
+ }], promptValue: [{
507
+ type: Input
508
+ }], placeholder: [{
509
+ type: Input
510
+ }], promptOutput: [{
511
+ type: Input
512
+ }], enableTextToSpeech: [{
513
+ type: Input
514
+ }], streaming: [{
515
+ type: Input
516
+ }], width: [{
517
+ type: Input
518
+ }], maxHeight: [{
519
+ type: Input
520
+ }], appendTo: [{
521
+ type: Input
522
+ }], outputActions: [{
523
+ type: Input
524
+ }], promptCommands: [{
525
+ type: Input
526
+ }], outputTemplate: [{
527
+ type: Input
528
+ }], promptRequest: [{
529
+ type: Output
530
+ }], executeCommand: [{
531
+ type: Output
532
+ }], outputActionClick: [{
533
+ type: Output
534
+ }], promptRequestCancel: [{
535
+ type: Output
536
+ }], close: [{
537
+ type: Output
538
+ }], promptValueChange: [{
539
+ type: Output
540
+ }], onEscapeKey: [{
541
+ type: HostListener,
542
+ args: ['keydown', ['$event']]
543
+ }], textArea: [{
544
+ type: ViewChild,
545
+ args: [TextAreaComponent]
546
+ }], contextMenu: [{
547
+ type: ViewChild,
548
+ args: ['kendoContextMenu']
549
+ }] } });