@progress/kendo-angular-conversational-ui 19.3.0-develop.21 → 19.3.0-develop.23

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.
@@ -2,10 +2,10 @@
2
2
  * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { AfterContentChecked, AfterViewInit, EventEmitter, NgZone, OnDestroy, QueryList, TemplateRef } from "@angular/core";
5
+ import { AfterContentChecked, AfterViewInit, ElementRef, EventEmitter, NgZone, OnChanges, OnDestroy, OnInit, QueryList, Renderer2, SimpleChanges, TemplateRef } from "@angular/core";
6
6
  import { SVGIcon } from "@progress/kendo-svg-icons";
7
7
  import { LocalizationService } from '@progress/kendo-angular-l10n';
8
- import { FabAlign, FabPositionMode, SpeechToTextButtonSettings } from "@progress/kendo-angular-buttons";
8
+ import { FabAlign, FabPositionMode, FloatingActionButtonComponent, SpeechToTextButtonSettings } from "@progress/kendo-angular-buttons";
9
9
  import { BaseView } from "./views/base-view";
10
10
  import { AIPromptService } from "./common/aiprompt.service";
11
11
  import { PromptCommand, PromptOutput, CommandExecuteEvent, PromptRequestEvent, OutputRatingChangeEvent } from "./models";
@@ -32,14 +32,20 @@ import * as i0 from "@angular/core";
32
32
  * @remarks
33
33
  * Supported children components are: {@link AIPromptCustomMessagesComponent}, {@link CustomViewComponent}, {@link CommandViewComponent}, {@link PromptViewComponent}, {@link OutputViewComponent}.
34
34
  */
35
- export declare class AIPromptComponent implements AfterContentChecked, AfterViewInit, OnDestroy {
35
+ export declare class AIPromptComponent implements OnInit, OnChanges, AfterContentChecked, AfterViewInit, OnDestroy {
36
36
  private localization;
37
37
  private service;
38
38
  private navigationService;
39
39
  private ngZone;
40
+ private element;
41
+ private renderer;
40
42
  hostClasses: boolean;
41
43
  get dirAttr(): string;
42
- constructor(localization: LocalizationService, service: AIPromptService, navigationService: ToolbarNavigationService, ngZone: NgZone);
44
+ constructor(localization: LocalizationService, service: AIPromptService, navigationService: ToolbarNavigationService, ngZone: NgZone, element: ElementRef, renderer: Renderer2);
45
+ /**
46
+ * @hidden
47
+ */
48
+ fabButton: FloatingActionButtonComponent;
43
49
  /**
44
50
  * @hidden
45
51
  */
@@ -136,6 +142,8 @@ export declare class AIPromptComponent implements AfterContentChecked, AfterView
136
142
  * Fires when you click the Stop Generation button in the Output view.
137
143
  */
138
144
  promptRequestCancel: EventEmitter<void>;
145
+ ngOnInit(): void;
146
+ ngOnChanges(changes: SimpleChanges): void;
139
147
  ngAfterContentChecked(): void;
140
148
  ngAfterViewInit(): void;
141
149
  ngOnDestroy(): void;
@@ -44,6 +44,10 @@ export declare class Messages extends ComponentMessages {
44
44
  * Sets the title of the **Prompt suggestions** button.
45
45
  */
46
46
  promptSuggestions: string;
47
+ /**
48
+ * Sets the aria-label for the **Speech to Text** button.
49
+ */
50
+ speechToTextButton: string;
47
51
  static ɵfac: i0.ɵɵFactoryDeclaration<Messages, never>;
48
- static ɵdir: i0.ɵɵDirectiveDeclaration<Messages, never, never, { "promptView": { "alias": "promptView"; "required": false; }; "outputView": { "alias": "outputView"; "required": false; }; "generateOutput": { "alias": "generateOutput"; "required": false; }; "promptPlaceholder": { "alias": "promptPlaceholder"; "required": false; }; "copyOutput": { "alias": "copyOutput"; "required": false; }; "retryGeneration": { "alias": "retryGeneration"; "required": false; }; "outputTitle": { "alias": "outputTitle"; "required": false; }; "outputRetryTitle": { "alias": "outputRetryTitle"; "required": false; }; "promptSuggestions": { "alias": "promptSuggestions"; "required": false; }; }, {}, never, never, false, never>;
52
+ static ɵdir: i0.ɵɵDirectiveDeclaration<Messages, never, never, { "promptView": { "alias": "promptView"; "required": false; }; "outputView": { "alias": "outputView"; "required": false; }; "generateOutput": { "alias": "generateOutput"; "required": false; }; "promptPlaceholder": { "alias": "promptPlaceholder"; "required": false; }; "copyOutput": { "alias": "copyOutput"; "required": false; }; "retryGeneration": { "alias": "retryGeneration"; "required": false; }; "outputTitle": { "alias": "outputTitle"; "required": false; }; "outputRetryTitle": { "alias": "outputRetryTitle"; "required": false; }; "promptSuggestions": { "alias": "promptSuggestions"; "required": false; }; "speechToTextButton": { "alias": "speechToTextButton"; "required": false; }; }, {}, never, never, false, never>;
49
53
  }
@@ -51,6 +51,10 @@ export declare class PromptViewComponent extends BaseView {
51
51
  * @hidden
52
52
  */
53
53
  suggestionClick(suggestion: string): void;
54
+ /**
55
+ * @hidden
56
+ */
57
+ suggestionKeydown(event: KeyboardEvent, suggestion: string): void;
54
58
  /**
55
59
  * @hidden
56
60
  */
@@ -2,7 +2,7 @@
2
2
  * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { Component, ContentChild, ContentChildren, EventEmitter, HostBinding, Input, NgZone, Output, QueryList } from "@angular/core";
5
+ import { Component, ContentChild, ContentChildren, ElementRef, EventEmitter, HostBinding, Input, NgZone, Output, QueryList, Renderer2, ViewChild } from "@angular/core";
6
6
  import { NgFor, NgIf, NgTemplateOutlet } from "@angular/common";
7
7
  import { Subscription } from "rxjs";
8
8
  import { sparklesIcon, commentIcon, stopSmIcon } from "@progress/kendo-svg-icons";
@@ -18,6 +18,7 @@ import { AIPromptToolbarFocusableDirective } from "./common/toolbar-focusable.di
18
18
  import { LocalizedMessagesDirective } from "./localization/localized-messages.directive";
19
19
  import { AIPromptOutputTemplateDirective } from "./templates/aiprompt-output-template.directive";
20
20
  import { AIPromptOutputBodyTemplateDirective } from "./templates/aiprompt-output-body-template.directive";
21
+ import { take } from "rxjs/operators";
21
22
  import * as i0 from "@angular/core";
22
23
  import * as i1 from "@progress/kendo-angular-l10n";
23
24
  import * as i2 from "./common/aiprompt.service";
@@ -44,21 +45,29 @@ export class AIPromptComponent {
44
45
  service;
45
46
  navigationService;
46
47
  ngZone;
48
+ element;
49
+ renderer;
47
50
  hostClasses = true;
48
51
  get dirAttr() {
49
52
  return this.direction;
50
53
  }
51
- constructor(localization, service, navigationService, ngZone) {
54
+ constructor(localization, service, navigationService, ngZone, element, renderer) {
52
55
  this.localization = localization;
53
56
  this.service = service;
54
57
  this.navigationService = navigationService;
55
58
  this.ngZone = ngZone;
59
+ this.element = element;
60
+ this.renderer = renderer;
56
61
  validatePackage(packageMetadata);
57
62
  this.direction = localization.rtl ? 'rtl' : 'ltr';
58
63
  this.subs.add(localization.changes.subscribe(({ rtl }) => {
59
64
  this.direction = rtl ? 'rtl' : 'ltr';
60
65
  }));
61
66
  }
67
+ /**
68
+ * @hidden
69
+ */
70
+ fabButton;
62
71
  /**
63
72
  * @hidden
64
73
  */
@@ -179,6 +188,21 @@ export class AIPromptComponent {
179
188
  * Fires when you click the Stop Generation button in the Output view.
180
189
  */
181
190
  promptRequestCancel = new EventEmitter();
191
+ ngOnInit() {
192
+ const aiPromptElement = this.element.nativeElement;
193
+ this.subs.add(this.renderer.listen(aiPromptElement, 'keydown', (event) => {
194
+ if (event.key === 'Escape') {
195
+ this.promptRequestCancel.emit();
196
+ }
197
+ }));
198
+ }
199
+ ngOnChanges(changes) {
200
+ if (changes['streaming'] && changes['streaming'].currentValue === true) {
201
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
202
+ this.fabButton?.focus();
203
+ });
204
+ }
205
+ }
182
206
  ngAfterContentChecked() {
183
207
  if (this.outputTemplate !== this.service.outputTemplate) {
184
208
  this.service.outputTemplate = this.outputTemplate;
@@ -273,7 +297,7 @@ export class AIPromptComponent {
273
297
  };
274
298
  this.promptRequest.emit(eventArgs);
275
299
  }
276
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIPromptComponent, deps: [{ token: i1.LocalizationService }, { token: i2.AIPromptService }, { token: i3.ToolbarNavigationService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
300
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIPromptComponent, deps: [{ token: i1.LocalizationService }, { token: i2.AIPromptService }, { token: i3.ToolbarNavigationService }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
277
301
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", 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: [
278
302
  LocalizationService,
279
303
  AIPromptService,
@@ -282,7 +306,7 @@ export class AIPromptComponent {
282
306
  provide: L10N_PREFIX,
283
307
  useValue: 'kendo.aiprompt'
284
308
  }
285
- ], 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 }], exportAs: ["kendoAIPrompt"], ngImport: i0, template: `
309
+ ], 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: `
286
310
  <ng-container kendoAIPromptLocalizedMessages
287
311
  i18n-promptView="kendo.aiprompt.promptView|The Toolbar button text for the Prompt view."
288
312
  promptView="Ask AI"
@@ -301,7 +325,9 @@ export class AIPromptComponent {
301
325
  i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card."
302
326
  outputRetryTitle="Generated with AI"
303
327
  i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button."
304
- promptSuggestions="Prompt suggestions">
328
+ promptSuggestions="Prompt suggestions"
329
+ i18n-speechToTextButton="kendo.aiprompt.speechToTextButton|The aria-label for the Speech to Text button."
330
+ speechToTextButton="Voice input">
305
331
  </ng-container>
306
332
  <div class="k-prompt-header">
307
333
  <div class="k-toolbar-flat k-toolbar k-toolbar-md"
@@ -326,7 +352,7 @@ export class AIPromptComponent {
326
352
  </div>
327
353
  </div>
328
354
  <div class="k-prompt-content">
329
- <kendo-floatingactionbutton *ngIf="streaming && selectedView?.viewType === 'output'"
355
+ <kendo-floatingactionbutton #fabButton *ngIf="streaming && selectedView?.viewType === 'output'"
330
356
  class="k-prompt-stop-fab"
331
357
  buttonClass="k-generating k-active"
332
358
  [positionMode]="fabPositionMode"
@@ -349,6 +375,8 @@ export class AIPromptComponent {
349
375
  themeColor="primary"
350
376
  rounded="full"
351
377
  [attr.title]="messageFor('generateOutput')"
378
+ [attr.aria-label]="messageFor('generateOutput')"
379
+ [attr.aria-disabled]="disabledGenerateButton"
352
380
  [svgIcon]="generateButtonSVGIcon"
353
381
  [icon]="generateButtonIcon"
354
382
  [disabled]="disabledGenerateButton"
@@ -390,7 +418,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
390
418
  i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card."
391
419
  outputRetryTitle="Generated with AI"
392
420
  i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button."
393
- promptSuggestions="Prompt suggestions">
421
+ promptSuggestions="Prompt suggestions"
422
+ i18n-speechToTextButton="kendo.aiprompt.speechToTextButton|The aria-label for the Speech to Text button."
423
+ speechToTextButton="Voice input">
394
424
  </ng-container>
395
425
  <div class="k-prompt-header">
396
426
  <div class="k-toolbar-flat k-toolbar k-toolbar-md"
@@ -415,7 +445,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
415
445
  </div>
416
446
  </div>
417
447
  <div class="k-prompt-content">
418
- <kendo-floatingactionbutton *ngIf="streaming && selectedView?.viewType === 'output'"
448
+ <kendo-floatingactionbutton #fabButton *ngIf="streaming && selectedView?.viewType === 'output'"
419
449
  class="k-prompt-stop-fab"
420
450
  buttonClass="k-generating k-active"
421
451
  [positionMode]="fabPositionMode"
@@ -438,6 +468,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
438
468
  themeColor="primary"
439
469
  rounded="full"
440
470
  [attr.title]="messageFor('generateOutput')"
471
+ [attr.aria-label]="messageFor('generateOutput')"
472
+ [attr.aria-disabled]="disabledGenerateButton"
441
473
  [svgIcon]="generateButtonSVGIcon"
442
474
  [icon]="generateButtonIcon"
443
475
  [disabled]="disabledGenerateButton"
@@ -448,12 +480,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
448
480
  standalone: true,
449
481
  imports: [LocalizedMessagesDirective, NgFor, ButtonComponent, AIPromptToolbarFocusableDirective, NgIf, NgTemplateOutlet, FloatingActionButtonComponent]
450
482
  }]
451
- }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i2.AIPromptService }, { type: i3.ToolbarNavigationService }, { type: i0.NgZone }]; }, propDecorators: { hostClasses: [{
483
+ }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i2.AIPromptService }, { type: i3.ToolbarNavigationService }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { hostClasses: [{
452
484
  type: HostBinding,
453
485
  args: ['class.k-prompt']
454
486
  }], dirAttr: [{
455
487
  type: HostBinding,
456
488
  args: ['attr.dir']
489
+ }], fabButton: [{
490
+ type: ViewChild,
491
+ args: ['fabButton']
457
492
  }], views: [{
458
493
  type: ContentChildren,
459
494
  args: [BaseView]
@@ -45,8 +45,12 @@ export class Messages extends ComponentMessages {
45
45
  * Sets the title of the **Prompt suggestions** button.
46
46
  */
47
47
  promptSuggestions;
48
+ /**
49
+ * Sets the aria-label for the **Speech to Text** button.
50
+ */
51
+ speechToTextButton;
48
52
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, deps: null, target: i0.ɵɵFactoryTarget.Directive });
49
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Messages, inputs: { promptView: "promptView", outputView: "outputView", generateOutput: "generateOutput", promptPlaceholder: "promptPlaceholder", copyOutput: "copyOutput", retryGeneration: "retryGeneration", outputTitle: "outputTitle", outputRetryTitle: "outputRetryTitle", promptSuggestions: "promptSuggestions" }, usesInheritance: true, ngImport: i0 });
53
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Messages, inputs: { promptView: "promptView", outputView: "outputView", generateOutput: "generateOutput", promptPlaceholder: "promptPlaceholder", copyOutput: "copyOutput", retryGeneration: "retryGeneration", outputTitle: "outputTitle", outputRetryTitle: "outputRetryTitle", promptSuggestions: "promptSuggestions", speechToTextButton: "speechToTextButton" }, usesInheritance: true, ngImport: i0 });
50
54
  }
51
55
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, decorators: [{
52
56
  type: Directive
@@ -68,4 +72,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
68
72
  type: Input
69
73
  }], promptSuggestions: [{
70
74
  type: Input
75
+ }], speechToTextButton: [{
76
+ type: Input
71
77
  }] } });
@@ -68,6 +68,14 @@ export class PromptViewComponent extends BaseView {
68
68
  suggestionClick(suggestion) {
69
69
  this.textAreaValue = this.service.promptValue = suggestion;
70
70
  }
71
+ /**
72
+ * @hidden
73
+ */
74
+ suggestionKeydown(event, suggestion) {
75
+ if (event.key === 'Enter' || event.key === ' ') {
76
+ this.suggestionClick(suggestion);
77
+ }
78
+ }
71
79
  /**
72
80
  * @hidden
73
81
  */
@@ -124,7 +132,8 @@ export class PromptViewComponent extends BaseView {
124
132
  [(value)]="textAreaValue"
125
133
  >
126
134
  <kendo-textarea-suffix *ngIf="speechToTextButtonSettings">
127
- <button kendoSpeechToTextButton
135
+ <button kendoSpeechToTextButton
136
+ role="button"
128
137
  [continuous]="speechToTextButtonSettings?.continuous"
129
138
  [disabled]="speechToTextButtonSettings?.disabled"
130
139
  [fillMode]="speechToTextButtonSettings?.fillMode ?? 'flat'"
@@ -135,6 +144,9 @@ export class PromptViewComponent extends BaseView {
135
144
  [rounded]="speechToTextButtonSettings?.rounded"
136
145
  [size]="speechToTextButtonSettings?.size"
137
146
  [themeColor]="speechToTextButtonSettings?.themeColor"
147
+ [attr.aria-label]="messageFor('speechToTextButton')"
148
+ [attr.title]="messageFor('speechToTextButton')"
149
+ [attr.aria-disabled]="speechToTextButtonSettings?.disabled"
138
150
  (error)="onSpeechToTextError($event)"
139
151
  (result)="onSpeechToTextResult($event)"
140
152
  ></button>
@@ -156,11 +168,15 @@ export class PromptViewComponent extends BaseView {
156
168
  class="k-prompt-expander-content"
157
169
  role="list"
158
170
  [attr.id]="contentId">
159
- <div class="k-suggestion-group">
171
+ <div class="k-suggestion-group" role="group">
160
172
  <div *ngFor="let suggestion of promptSuggestions"
161
173
  class="k-suggestion"
162
- role="listitem"
163
- (click)="suggestionClick(suggestion)">
174
+ role="button"
175
+ [attr.tabindex]="0"
176
+ [attr.aria-label]="suggestion"
177
+ [attr.title]="suggestion"
178
+ (click)="suggestionClick(suggestion)"
179
+ (keydown)="suggestionKeydown($event, suggestion)">
164
180
  {{suggestion}}
165
181
  </div>
166
182
  </div>
@@ -201,7 +217,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
201
217
  [(value)]="textAreaValue"
202
218
  >
203
219
  <kendo-textarea-suffix *ngIf="speechToTextButtonSettings">
204
- <button kendoSpeechToTextButton
220
+ <button kendoSpeechToTextButton
221
+ role="button"
205
222
  [continuous]="speechToTextButtonSettings?.continuous"
206
223
  [disabled]="speechToTextButtonSettings?.disabled"
207
224
  [fillMode]="speechToTextButtonSettings?.fillMode ?? 'flat'"
@@ -212,6 +229,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
212
229
  [rounded]="speechToTextButtonSettings?.rounded"
213
230
  [size]="speechToTextButtonSettings?.size"
214
231
  [themeColor]="speechToTextButtonSettings?.themeColor"
232
+ [attr.aria-label]="messageFor('speechToTextButton')"
233
+ [attr.title]="messageFor('speechToTextButton')"
234
+ [attr.aria-disabled]="speechToTextButtonSettings?.disabled"
215
235
  (error)="onSpeechToTextError($event)"
216
236
  (result)="onSpeechToTextResult($event)"
217
237
  ></button>
@@ -233,11 +253,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
233
253
  class="k-prompt-expander-content"
234
254
  role="list"
235
255
  [attr.id]="contentId">
236
- <div class="k-suggestion-group">
256
+ <div class="k-suggestion-group" role="group">
237
257
  <div *ngFor="let suggestion of promptSuggestions"
238
258
  class="k-suggestion"
239
- role="listitem"
240
- (click)="suggestionClick(suggestion)">
259
+ role="button"
260
+ [attr.tabindex]="0"
261
+ [attr.aria-label]="suggestion"
262
+ [attr.title]="suggestion"
263
+ (click)="suggestionClick(suggestion)"
264
+ (keydown)="suggestionKeydown($event, suggestion)">
241
265
  {{suggestion}}
242
266
  </div>
243
267
  </div>
@@ -10,7 +10,7 @@ export const packageMetadata = {
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCode: 'KENDOUIANGULAR',
12
12
  productCodes: ['KENDOUIANGULAR'],
13
- publishDate: 1754395802,
14
- version: '19.3.0-develop.21',
13
+ publishDate: 1754484353,
14
+ version: '19.3.0-develop.23',
15
15
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
16
16
  };
@@ -14,7 +14,7 @@ import { ButtonComponent, FloatingActionButtonComponent, SpeechToTextButtonCompo
14
14
  import { TextBoxComponent, TextAreaComponent, InputSeparatorComponent, TextBoxSuffixTemplateDirective, TextAreaSuffixComponent } from '@progress/kendo-angular-inputs';
15
15
  import * as i1 from '@progress/kendo-angular-intl';
16
16
  import { fromEvent, Subscription, Subject } from 'rxjs';
17
- import { debounceTime } from 'rxjs/operators';
17
+ import { debounceTime, take } from 'rxjs/operators';
18
18
  import { IconsService } from '@progress/kendo-angular-icons';
19
19
  import { PopupService } from '@progress/kendo-angular-popup';
20
20
  import { DialogContainerService, DialogService, WindowService, WindowContainerService } from '@progress/kendo-angular-dialog';
@@ -136,8 +136,8 @@ const packageMetadata = {
136
136
  productName: 'Kendo UI for Angular',
137
137
  productCode: 'KENDOUIANGULAR',
138
138
  productCodes: ['KENDOUIANGULAR'],
139
- publishDate: 1754395802,
140
- version: '19.3.0-develop.21',
139
+ publishDate: 1754484353,
140
+ version: '19.3.0-develop.23',
141
141
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
142
142
  };
143
143
 
@@ -2258,8 +2258,12 @@ class Messages extends ComponentMessages {
2258
2258
  * Sets the title of the **Prompt suggestions** button.
2259
2259
  */
2260
2260
  promptSuggestions;
2261
+ /**
2262
+ * Sets the aria-label for the **Speech to Text** button.
2263
+ */
2264
+ speechToTextButton;
2261
2265
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, deps: null, target: i0.ɵɵFactoryTarget.Directive });
2262
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Messages, inputs: { promptView: "promptView", outputView: "outputView", generateOutput: "generateOutput", promptPlaceholder: "promptPlaceholder", copyOutput: "copyOutput", retryGeneration: "retryGeneration", outputTitle: "outputTitle", outputRetryTitle: "outputRetryTitle", promptSuggestions: "promptSuggestions" }, usesInheritance: true, ngImport: i0 });
2266
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Messages, inputs: { promptView: "promptView", outputView: "outputView", generateOutput: "generateOutput", promptPlaceholder: "promptPlaceholder", copyOutput: "copyOutput", retryGeneration: "retryGeneration", outputTitle: "outputTitle", outputRetryTitle: "outputRetryTitle", promptSuggestions: "promptSuggestions", speechToTextButton: "speechToTextButton" }, usesInheritance: true, ngImport: i0 });
2263
2267
  }
2264
2268
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, decorators: [{
2265
2269
  type: Directive
@@ -2281,6 +2285,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2281
2285
  type: Input
2282
2286
  }], promptSuggestions: [{
2283
2287
  type: Input
2288
+ }], speechToTextButton: [{
2289
+ type: Input
2284
2290
  }] } });
2285
2291
 
2286
2292
  /**
@@ -2392,21 +2398,29 @@ class AIPromptComponent {
2392
2398
  service;
2393
2399
  navigationService;
2394
2400
  ngZone;
2401
+ element;
2402
+ renderer;
2395
2403
  hostClasses = true;
2396
2404
  get dirAttr() {
2397
2405
  return this.direction;
2398
2406
  }
2399
- constructor(localization, service, navigationService, ngZone) {
2407
+ constructor(localization, service, navigationService, ngZone, element, renderer) {
2400
2408
  this.localization = localization;
2401
2409
  this.service = service;
2402
2410
  this.navigationService = navigationService;
2403
2411
  this.ngZone = ngZone;
2412
+ this.element = element;
2413
+ this.renderer = renderer;
2404
2414
  validatePackage(packageMetadata);
2405
2415
  this.direction = localization.rtl ? 'rtl' : 'ltr';
2406
2416
  this.subs.add(localization.changes.subscribe(({ rtl }) => {
2407
2417
  this.direction = rtl ? 'rtl' : 'ltr';
2408
2418
  }));
2409
2419
  }
2420
+ /**
2421
+ * @hidden
2422
+ */
2423
+ fabButton;
2410
2424
  /**
2411
2425
  * @hidden
2412
2426
  */
@@ -2527,6 +2541,21 @@ class AIPromptComponent {
2527
2541
  * Fires when you click the Stop Generation button in the Output view.
2528
2542
  */
2529
2543
  promptRequestCancel = new EventEmitter();
2544
+ ngOnInit() {
2545
+ const aiPromptElement = this.element.nativeElement;
2546
+ this.subs.add(this.renderer.listen(aiPromptElement, 'keydown', (event) => {
2547
+ if (event.key === 'Escape') {
2548
+ this.promptRequestCancel.emit();
2549
+ }
2550
+ }));
2551
+ }
2552
+ ngOnChanges(changes) {
2553
+ if (changes['streaming'] && changes['streaming'].currentValue === true) {
2554
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => {
2555
+ this.fabButton?.focus();
2556
+ });
2557
+ }
2558
+ }
2530
2559
  ngAfterContentChecked() {
2531
2560
  if (this.outputTemplate !== this.service.outputTemplate) {
2532
2561
  this.service.outputTemplate = this.outputTemplate;
@@ -2621,7 +2650,7 @@ class AIPromptComponent {
2621
2650
  };
2622
2651
  this.promptRequest.emit(eventArgs);
2623
2652
  }
2624
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIPromptComponent, deps: [{ token: i1$1.LocalizationService }, { token: AIPromptService }, { token: ToolbarNavigationService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
2653
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: AIPromptComponent, deps: [{ token: i1$1.LocalizationService }, { token: AIPromptService }, { token: ToolbarNavigationService }, { token: i0.NgZone }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
2625
2654
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", 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: [
2626
2655
  LocalizationService,
2627
2656
  AIPromptService,
@@ -2630,7 +2659,7 @@ class AIPromptComponent {
2630
2659
  provide: L10N_PREFIX,
2631
2660
  useValue: 'kendo.aiprompt'
2632
2661
  }
2633
- ], 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 }], exportAs: ["kendoAIPrompt"], ngImport: i0, template: `
2662
+ ], 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: `
2634
2663
  <ng-container kendoAIPromptLocalizedMessages
2635
2664
  i18n-promptView="kendo.aiprompt.promptView|The Toolbar button text for the Prompt view."
2636
2665
  promptView="Ask AI"
@@ -2649,7 +2678,9 @@ class AIPromptComponent {
2649
2678
  i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card."
2650
2679
  outputRetryTitle="Generated with AI"
2651
2680
  i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button."
2652
- promptSuggestions="Prompt suggestions">
2681
+ promptSuggestions="Prompt suggestions"
2682
+ i18n-speechToTextButton="kendo.aiprompt.speechToTextButton|The aria-label for the Speech to Text button."
2683
+ speechToTextButton="Voice input">
2653
2684
  </ng-container>
2654
2685
  <div class="k-prompt-header">
2655
2686
  <div class="k-toolbar-flat k-toolbar k-toolbar-md"
@@ -2674,7 +2705,7 @@ class AIPromptComponent {
2674
2705
  </div>
2675
2706
  </div>
2676
2707
  <div class="k-prompt-content">
2677
- <kendo-floatingactionbutton *ngIf="streaming && selectedView?.viewType === 'output'"
2708
+ <kendo-floatingactionbutton #fabButton *ngIf="streaming && selectedView?.viewType === 'output'"
2678
2709
  class="k-prompt-stop-fab"
2679
2710
  buttonClass="k-generating k-active"
2680
2711
  [positionMode]="fabPositionMode"
@@ -2697,6 +2728,8 @@ class AIPromptComponent {
2697
2728
  themeColor="primary"
2698
2729
  rounded="full"
2699
2730
  [attr.title]="messageFor('generateOutput')"
2731
+ [attr.aria-label]="messageFor('generateOutput')"
2732
+ [attr.aria-disabled]="disabledGenerateButton"
2700
2733
  [svgIcon]="generateButtonSVGIcon"
2701
2734
  [icon]="generateButtonIcon"
2702
2735
  [disabled]="disabledGenerateButton"
@@ -2738,7 +2771,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2738
2771
  i18n-outputRetryTitle="kendo.aiprompt.outputRetryTitle|The title of each Output view retry card."
2739
2772
  outputRetryTitle="Generated with AI"
2740
2773
  i18n-promptSuggestions="kendo.aiprompt.promptSuggestions|The title of the Prompt suggestions button."
2741
- promptSuggestions="Prompt suggestions">
2774
+ promptSuggestions="Prompt suggestions"
2775
+ i18n-speechToTextButton="kendo.aiprompt.speechToTextButton|The aria-label for the Speech to Text button."
2776
+ speechToTextButton="Voice input">
2742
2777
  </ng-container>
2743
2778
  <div class="k-prompt-header">
2744
2779
  <div class="k-toolbar-flat k-toolbar k-toolbar-md"
@@ -2763,7 +2798,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2763
2798
  </div>
2764
2799
  </div>
2765
2800
  <div class="k-prompt-content">
2766
- <kendo-floatingactionbutton *ngIf="streaming && selectedView?.viewType === 'output'"
2801
+ <kendo-floatingactionbutton #fabButton *ngIf="streaming && selectedView?.viewType === 'output'"
2767
2802
  class="k-prompt-stop-fab"
2768
2803
  buttonClass="k-generating k-active"
2769
2804
  [positionMode]="fabPositionMode"
@@ -2786,6 +2821,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2786
2821
  themeColor="primary"
2787
2822
  rounded="full"
2788
2823
  [attr.title]="messageFor('generateOutput')"
2824
+ [attr.aria-label]="messageFor('generateOutput')"
2825
+ [attr.aria-disabled]="disabledGenerateButton"
2789
2826
  [svgIcon]="generateButtonSVGIcon"
2790
2827
  [icon]="generateButtonIcon"
2791
2828
  [disabled]="disabledGenerateButton"
@@ -2796,12 +2833,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2796
2833
  standalone: true,
2797
2834
  imports: [LocalizedMessagesDirective, NgFor, ButtonComponent, AIPromptToolbarFocusableDirective, NgIf, NgTemplateOutlet, FloatingActionButtonComponent]
2798
2835
  }]
2799
- }], ctorParameters: function () { return [{ type: i1$1.LocalizationService }, { type: AIPromptService }, { type: ToolbarNavigationService }, { type: i0.NgZone }]; }, propDecorators: { hostClasses: [{
2836
+ }], ctorParameters: function () { return [{ type: i1$1.LocalizationService }, { type: AIPromptService }, { type: ToolbarNavigationService }, { type: i0.NgZone }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { hostClasses: [{
2800
2837
  type: HostBinding,
2801
2838
  args: ['class.k-prompt']
2802
2839
  }], dirAttr: [{
2803
2840
  type: HostBinding,
2804
2841
  args: ['attr.dir']
2842
+ }], fabButton: [{
2843
+ type: ViewChild,
2844
+ args: ['fabButton']
2805
2845
  }], views: [{
2806
2846
  type: ContentChildren,
2807
2847
  args: [BaseView]
@@ -3380,6 +3420,14 @@ class PromptViewComponent extends BaseView {
3380
3420
  suggestionClick(suggestion) {
3381
3421
  this.textAreaValue = this.service.promptValue = suggestion;
3382
3422
  }
3423
+ /**
3424
+ * @hidden
3425
+ */
3426
+ suggestionKeydown(event, suggestion) {
3427
+ if (event.key === 'Enter' || event.key === ' ') {
3428
+ this.suggestionClick(suggestion);
3429
+ }
3430
+ }
3383
3431
  /**
3384
3432
  * @hidden
3385
3433
  */
@@ -3436,7 +3484,8 @@ class PromptViewComponent extends BaseView {
3436
3484
  [(value)]="textAreaValue"
3437
3485
  >
3438
3486
  <kendo-textarea-suffix *ngIf="speechToTextButtonSettings">
3439
- <button kendoSpeechToTextButton
3487
+ <button kendoSpeechToTextButton
3488
+ role="button"
3440
3489
  [continuous]="speechToTextButtonSettings?.continuous"
3441
3490
  [disabled]="speechToTextButtonSettings?.disabled"
3442
3491
  [fillMode]="speechToTextButtonSettings?.fillMode ?? 'flat'"
@@ -3447,6 +3496,9 @@ class PromptViewComponent extends BaseView {
3447
3496
  [rounded]="speechToTextButtonSettings?.rounded"
3448
3497
  [size]="speechToTextButtonSettings?.size"
3449
3498
  [themeColor]="speechToTextButtonSettings?.themeColor"
3499
+ [attr.aria-label]="messageFor('speechToTextButton')"
3500
+ [attr.title]="messageFor('speechToTextButton')"
3501
+ [attr.aria-disabled]="speechToTextButtonSettings?.disabled"
3450
3502
  (error)="onSpeechToTextError($event)"
3451
3503
  (result)="onSpeechToTextResult($event)"
3452
3504
  ></button>
@@ -3468,11 +3520,15 @@ class PromptViewComponent extends BaseView {
3468
3520
  class="k-prompt-expander-content"
3469
3521
  role="list"
3470
3522
  [attr.id]="contentId">
3471
- <div class="k-suggestion-group">
3523
+ <div class="k-suggestion-group" role="group">
3472
3524
  <div *ngFor="let suggestion of promptSuggestions"
3473
3525
  class="k-suggestion"
3474
- role="listitem"
3475
- (click)="suggestionClick(suggestion)">
3526
+ role="button"
3527
+ [attr.tabindex]="0"
3528
+ [attr.aria-label]="suggestion"
3529
+ [attr.title]="suggestion"
3530
+ (click)="suggestionClick(suggestion)"
3531
+ (keydown)="suggestionKeydown($event, suggestion)">
3476
3532
  {{suggestion}}
3477
3533
  </div>
3478
3534
  </div>
@@ -3513,7 +3569,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3513
3569
  [(value)]="textAreaValue"
3514
3570
  >
3515
3571
  <kendo-textarea-suffix *ngIf="speechToTextButtonSettings">
3516
- <button kendoSpeechToTextButton
3572
+ <button kendoSpeechToTextButton
3573
+ role="button"
3517
3574
  [continuous]="speechToTextButtonSettings?.continuous"
3518
3575
  [disabled]="speechToTextButtonSettings?.disabled"
3519
3576
  [fillMode]="speechToTextButtonSettings?.fillMode ?? 'flat'"
@@ -3524,6 +3581,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3524
3581
  [rounded]="speechToTextButtonSettings?.rounded"
3525
3582
  [size]="speechToTextButtonSettings?.size"
3526
3583
  [themeColor]="speechToTextButtonSettings?.themeColor"
3584
+ [attr.aria-label]="messageFor('speechToTextButton')"
3585
+ [attr.title]="messageFor('speechToTextButton')"
3586
+ [attr.aria-disabled]="speechToTextButtonSettings?.disabled"
3527
3587
  (error)="onSpeechToTextError($event)"
3528
3588
  (result)="onSpeechToTextResult($event)"
3529
3589
  ></button>
@@ -3545,11 +3605,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3545
3605
  class="k-prompt-expander-content"
3546
3606
  role="list"
3547
3607
  [attr.id]="contentId">
3548
- <div class="k-suggestion-group">
3608
+ <div class="k-suggestion-group" role="group">
3549
3609
  <div *ngFor="let suggestion of promptSuggestions"
3550
3610
  class="k-suggestion"
3551
- role="listitem"
3552
- (click)="suggestionClick(suggestion)">
3611
+ role="button"
3612
+ [attr.tabindex]="0"
3613
+ [attr.aria-label]="suggestion"
3614
+ [attr.title]="suggestion"
3615
+ (click)="suggestionClick(suggestion)"
3616
+ (keydown)="suggestionKeydown($event, suggestion)">
3553
3617
  {{suggestion}}
3554
3618
  </div>
3555
3619
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-conversational-ui",
3
- "version": "19.3.0-develop.21",
3
+ "version": "19.3.0-develop.23",
4
4
  "description": "Kendo UI for Angular Conversational UI components",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -20,7 +20,7 @@
20
20
  "package": {
21
21
  "productName": "Kendo UI for Angular",
22
22
  "productCode": "KENDOUIANGULAR",
23
- "publishDate": 1754395802,
23
+ "publishDate": 1754484353,
24
24
  "licensingDocsUrl": "https://www.telerik.com/kendo-angular-ui/my-license/"
25
25
  }
26
26
  },
@@ -30,19 +30,19 @@
30
30
  "@angular/core": "16 - 20",
31
31
  "@angular/platform-browser": "16 - 20",
32
32
  "@progress/kendo-licensing": "^1.7.0",
33
- "@progress/kendo-angular-buttons": "19.3.0-develop.21",
34
- "@progress/kendo-angular-inputs": "19.3.0-develop.21",
35
- "@progress/kendo-angular-layout": "19.3.0-develop.21",
36
- "@progress/kendo-angular-icons": "19.3.0-develop.21",
37
- "@progress/kendo-angular-common": "19.3.0-develop.21",
38
- "@progress/kendo-angular-intl": "19.3.0-develop.21",
39
- "@progress/kendo-angular-l10n": "19.3.0-develop.21",
40
- "@progress/kendo-angular-popup": "19.3.0-develop.21",
33
+ "@progress/kendo-angular-buttons": "19.3.0-develop.23",
34
+ "@progress/kendo-angular-inputs": "19.3.0-develop.23",
35
+ "@progress/kendo-angular-layout": "19.3.0-develop.23",
36
+ "@progress/kendo-angular-icons": "19.3.0-develop.23",
37
+ "@progress/kendo-angular-common": "19.3.0-develop.23",
38
+ "@progress/kendo-angular-intl": "19.3.0-develop.23",
39
+ "@progress/kendo-angular-l10n": "19.3.0-develop.23",
40
+ "@progress/kendo-angular-popup": "19.3.0-develop.23",
41
41
  "rxjs": "^6.5.3 || ^7.0.0"
42
42
  },
43
43
  "dependencies": {
44
44
  "tslib": "^2.3.1",
45
- "@progress/kendo-angular-schematics": "19.3.0-develop.21"
45
+ "@progress/kendo-angular-schematics": "19.3.0-develop.23"
46
46
  },
47
47
  "schematics": "./schematics/collection.json",
48
48
  "module": "fesm2022/progress-kendo-angular-conversational-ui.mjs",