@progress/kendo-angular-dropdowns 19.3.0-develop.4 → 19.3.0-develop.40

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.
@@ -4,6 +4,7 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { EventEmitter, QueryList, ElementRef, SimpleChange, ChangeDetectorRef, NgZone, Renderer2 } from '@angular/core';
6
6
  import { AfterViewInit, OnChanges, OnDestroy } from '@angular/core';
7
+ import { LocalizationService } from '@progress/kendo-angular-l10n';
7
8
  import { ListItemDirective } from './list-item.directive';
8
9
  import { ItemTemplateDirective } from './templates/item-template.directive';
9
10
  import { GroupTemplateDirective } from './templates/group-template.directive';
@@ -31,6 +32,7 @@ export declare class ListComponent implements OnChanges, OnDestroy, AfterViewIni
31
32
  private cdr;
32
33
  private zone;
33
34
  private renderer;
35
+ private localization;
34
36
  selected: any[];
35
37
  focused: number;
36
38
  textField: string;
@@ -88,11 +90,15 @@ export declare class ListComponent implements OnChanges, OnDestroy, AfterViewIni
88
90
  get pageSize(): number;
89
91
  get scrollHeight(): number;
90
92
  get overflowY(): string;
93
+ /**
94
+ * @hidden
95
+ */
96
+ get useCustomValueText(): string;
91
97
  /**
92
98
  * @hidden
93
99
  */
94
100
  get checkboxClasses(): any;
95
- constructor(dataService: DataService, wrapper: ElementRef<HTMLElement>, selectionService: SelectionService, disabledItemsService: DisabledItemsService, cdr: ChangeDetectorRef, zone: NgZone, renderer: Renderer2);
101
+ constructor(dataService: DataService, wrapper: ElementRef<HTMLElement>, selectionService: SelectionService, disabledItemsService: DisabledItemsService, cdr: ChangeDetectorRef, zone: NgZone, renderer: Renderer2, localization: LocalizationService);
96
102
  ngOnChanges(changes: {
97
103
  [propertyName: string]: SimpleChange;
98
104
  }): void;
@@ -40,6 +40,16 @@ export declare class Messages extends ComponentMessages {
40
40
  * The text for the input's placeholder when filtering is enabled.
41
41
  */
42
42
  filterInputPlaceholder: string;
43
+ /**
44
+ * The text displayed when the user types a custom value that is not in the list of options.
45
+ *
46
+ * The text includes a localizable string and the custom value.
47
+ * For example, when adding a custom value **Test**, the default text is **Use "Test"**.
48
+ *
49
+ * You can reorder the custom value and the localizable part by using a placeholder in `useCustomValueText`.
50
+ * Use `{customValue}` to insert the value, for example, **Add: {customValue}**.
51
+ */
52
+ useCustomValueText: string;
43
53
  static ɵfac: i0.ɵɵFactoryDeclaration<Messages, never>;
44
- static ɵdir: i0.ɵɵDirectiveDeclaration<Messages, never, never, { "noDataText": { "alias": "noDataText"; "required": false; }; "clearTitle": { "alias": "clearTitle"; "required": false; }; "checkAllText": { "alias": "checkAllText"; "required": false; }; "selectButtonText": { "alias": "selectButtonText"; "required": false; }; "filterInputLabel": { "alias": "filterInputLabel"; "required": false; }; "popupLabel": { "alias": "popupLabel"; "required": false; }; "adaptiveCloseButtonTitle": { "alias": "adaptiveCloseButtonTitle"; "required": false; }; "filterInputPlaceholder": { "alias": "filterInputPlaceholder"; "required": false; }; }, {}, never, never, false, never>;
54
+ static ɵdir: i0.ɵɵDirectiveDeclaration<Messages, never, never, { "noDataText": { "alias": "noDataText"; "required": false; }; "clearTitle": { "alias": "clearTitle"; "required": false; }; "checkAllText": { "alias": "checkAllText"; "required": false; }; "selectButtonText": { "alias": "selectButtonText"; "required": false; }; "filterInputLabel": { "alias": "filterInputLabel"; "required": false; }; "popupLabel": { "alias": "popupLabel"; "required": false; }; "adaptiveCloseButtonTitle": { "alias": "adaptiveCloseButtonTitle"; "required": false; }; "filterInputPlaceholder": { "alias": "filterInputPlaceholder"; "required": false; }; "useCustomValueText": { "alias": "useCustomValueText"; "required": false; }; }, {}, never, never, false, never>;
45
55
  }
@@ -85,7 +85,7 @@ export declare class SearchBarComponent implements OnChanges, OnInit, OnDestroy
85
85
  handleInput(event: any): void;
86
86
  handleFocus(event: any): void;
87
87
  handleBlur(event: any): void;
88
- handleKeydown(event: any): void;
88
+ handleKeydown(event: KeyboardEvent): void;
89
89
  focus(): void;
90
90
  blur(): void;
91
91
  setInputSize(): void;
@@ -3,7 +3,7 @@
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { Component, Renderer2, forwardRef, ElementRef, Input, Output, EventEmitter, ContentChild, ViewChild, ViewContainerRef, TemplateRef, HostBinding, isDevMode, ChangeDetectorRef, NgZone, Injector } from '@angular/core';
6
- import { isDocumentAvailable, KendoInput, hasObservers, SuffixTemplateDirective, PrefixTemplateDirective, isControlRequired, SeparatorComponent, ResizeSensorComponent, TemplateContextDirective, guid } from '@progress/kendo-angular-common';
6
+ import { isDocumentAvailable, KendoInput, hasObservers, SuffixTemplateDirective, PrefixTemplateDirective, isControlRequired, SeparatorComponent, ResizeSensorComponent, TemplateContextDirective, guid, normalizeNumpadKeys } from '@progress/kendo-angular-common';
7
7
  import { AdaptiveService } from '@progress/kendo-angular-utils';
8
8
  import { NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
9
9
  import { validatePackage } from '@progress/kendo-licensing';
@@ -967,8 +967,10 @@ export class AutoCompleteComponent {
967
967
  this.subs.add(this.valueChangeSubject
968
968
  .subscribe(value => {
969
969
  const hasChange = this.value !== value;
970
- const index = this.findIndex(value);
971
- this.selectionService.focused = index;
970
+ if (this.isOpen) {
971
+ const index = this.findIndex(value);
972
+ this.selectionService.focused = index;
973
+ }
972
974
  this.value = value;
973
975
  this.text = value;
974
976
  // emit change after assigning `this.value` => allows the user to modify the component value on `valueChange`
@@ -986,7 +988,8 @@ export class AutoCompleteComponent {
986
988
  this.subs.add(merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
987
989
  if (this.isOpen) {
988
990
  event.originalEvent.preventDefault();
989
- this.optionsList.scrollWithOnePage(NavigationAction[event.originalEvent.code]);
991
+ const code = normalizeNumpadKeys(event.originalEvent);
992
+ this.optionsList.scrollWithOnePage(NavigationAction[code]);
990
993
  }
991
994
  }));
992
995
  }
@@ -18,7 +18,7 @@ import { NavigationService } from '../common/navigation/navigation.service';
18
18
  import { DisabledItemsService } from '../common/disabled-items/disabled-items.service';
19
19
  import { merge, of, Subject, Subscription } from 'rxjs';
20
20
  import { catchError, filter, map, partition, tap, throttleTime } from 'rxjs/operators';
21
- import { isChanged, isDocumentAvailable, KendoInput, hasObservers, anyChanged, SuffixTemplateDirective, PrefixTemplateDirective, isControlRequired, MultiTabStop, SeparatorComponent, EventsOutsideAngularDirective, ResizeSensorComponent, Keys, TemplateContextDirective, guid } from '@progress/kendo-angular-common';
21
+ import { isChanged, isDocumentAvailable, KendoInput, hasObservers, anyChanged, SuffixTemplateDirective, PrefixTemplateDirective, isControlRequired, MultiTabStop, SeparatorComponent, EventsOutsideAngularDirective, ResizeSensorComponent, Keys, TemplateContextDirective, guid, normalizeNumpadKeys } from '@progress/kendo-angular-common';
22
22
  import { AdaptiveService } from '@progress/kendo-angular-utils';
23
23
  import { isPresent, getter, isEmptyString, isUntouched, inDropDown, getSizeClass, getRoundedClass, getFillModeClass, isTruthy, setListBoxAriaLabelledBy, setActionSheetTitle, animationDuration } from '../common/util';
24
24
  import { NavigationAction } from '../common/navigation/navigation-action';
@@ -798,7 +798,8 @@ export class ComboBoxComponent extends MultiTabStop {
798
798
  this.subs.add(merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
799
799
  if (this.isOpen) {
800
800
  event.originalEvent.preventDefault();
801
- this.optionsList.scrollWithOnePage(NavigationAction[event.originalEvent.code]);
801
+ const code = normalizeNumpadKeys(event.originalEvent);
802
+ this.optionsList.scrollWithOnePage(NavigationAction[code]);
802
803
  }
803
804
  }));
804
805
  this.subs.add(this.navigationService.esc.subscribe(this.handleEscape.bind(this)));
@@ -1147,14 +1148,18 @@ export class ComboBoxComponent extends MultiTabStop {
1147
1148
  if (this.disabled || this.readonly) {
1148
1149
  return;
1149
1150
  }
1150
- if (event.keyCode === Keys.Home || event.keyCode === Keys.End) {
1151
+ // on some keyboards, Home and End keys are mapped to Numpad keys
1152
+ const code = normalizeNumpadKeys(event);
1153
+ const isHomeKey = code === Keys.Home;
1154
+ const isEndKey = code === Keys.End;
1155
+ if (isHomeKey || isEndKey) {
1151
1156
  return;
1152
1157
  }
1153
1158
  if (!hasSelected) {
1154
- if (event.keyCode === Keys.ArrowDown) {
1159
+ if (code === Keys.ArrowDown) {
1155
1160
  offset = -1;
1156
1161
  }
1157
- else if (event.keyCode === Keys.ArrowUp) {
1162
+ else if (code === Keys.ArrowUp) {
1158
1163
  offset = 1;
1159
1164
  }
1160
1165
  }
@@ -3,7 +3,8 @@
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { Component, Input, Output, EventEmitter, ViewChildren, QueryList, ElementRef, ViewChild, ChangeDetectorRef, NgZone, Renderer2 } from '@angular/core';
6
- import { ResizeSensorComponent, TemplateContextDirective, isChanged } from '@progress/kendo-angular-common';
6
+ import { ResizeSensorComponent, TemplateContextDirective, isChanged, replaceMessagePlaceholder } from '@progress/kendo-angular-common';
7
+ import { LocalizationService } from '@progress/kendo-angular-l10n';
7
8
  import { ListItemDirective } from './list-item.directive';
8
9
  import { ItemTemplateDirective } from './templates/item-template.directive';
9
10
  import { GroupTemplateDirective } from './templates/group-template.directive';
@@ -22,6 +23,7 @@ import * as i0 from "@angular/core";
22
23
  import * as i1 from "./data.service";
23
24
  import * as i2 from "./selection/selection.service";
24
25
  import * as i3 from "./disabled-items/disabled-items.service";
26
+ import * as i4 from "@progress/kendo-angular-l10n";
25
27
  /**
26
28
  * @hidden
27
29
  */
@@ -33,6 +35,7 @@ export class ListComponent {
33
35
  cdr;
34
36
  zone;
35
37
  renderer;
38
+ localization;
36
39
  selected = [];
37
40
  focused = -1;
38
41
  textField;
@@ -117,6 +120,13 @@ export class ListComponent {
117
120
  return overflow;
118
121
  }
119
122
  }
123
+ /**
124
+ * @hidden
125
+ */
126
+ get useCustomValueText() {
127
+ const localizationMsg = this.localization.get('useCustomValueText');
128
+ return replaceMessagePlaceholder(localizationMsg, 'customValue', this.text);
129
+ }
120
130
  /**
121
131
  * @hidden
122
132
  */
@@ -124,7 +134,7 @@ export class ListComponent {
124
134
  return `${this.size ? getSizeClass('checkbox', this.size) : ''} ${this.rounded ? getRoundedClass(this.rounded) : ''}`;
125
135
  }
126
136
  /* tslint:disable:member-ordering */
127
- constructor(dataService, wrapper, selectionService, disabledItemsService, cdr, zone, renderer) {
137
+ constructor(dataService, wrapper, selectionService, disabledItemsService, cdr, zone, renderer, localization) {
128
138
  this.dataService = dataService;
129
139
  this.wrapper = wrapper;
130
140
  this.selectionService = selectionService;
@@ -132,6 +142,7 @@ export class ListComponent {
132
142
  this.cdr = cdr;
133
143
  this.zone = zone;
134
144
  this.renderer = renderer;
145
+ this.localization = localization;
135
146
  this.selectSubscription = merge(this.selectionService.onSelect.pipe(map((args) => args.indices[0])), this.selectionService.onFocus)
136
147
  .pipe(
137
148
  // handle only the very last onSelect/onFocus emission
@@ -453,7 +464,7 @@ export class ListComponent {
453
464
  this.renderer.addClass(this.wrapper.nativeElement, this.listVirtualClass);
454
465
  }
455
466
  }
456
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListComponent, deps: [{ token: i1.DataService }, { token: i0.ElementRef }, { token: i2.SelectionService }, { token: i3.DisabledItemsService }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
467
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListComponent, deps: [{ token: i1.DataService }, { token: i0.ElementRef }, { token: i2.SelectionService }, { token: i3.DisabledItemsService }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i4.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
457
468
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ListComponent, isStandalone: true, selector: "kendo-list", inputs: { selected: "selected", focused: "focused", textField: "textField", valueField: "valueField", height: "height", template: "template", groupTemplate: "groupTemplate", fixedGroupTemplate: "fixedGroupTemplate", show: "show", id: "id", optionPrefix: "optionPrefix", multipleSelection: "multipleSelection", virtual: "virtual", type: "type", checkboxes: "checkboxes", ariaLive: "ariaLive", isMultiselect: "isMultiselect", isActionSheetExpanded: "isActionSheetExpanded", showStickyHeader: "showStickyHeader", rowWidth: "rowWidth", customItemTemplate: "customItemTemplate", text: "text", allowCustom: "allowCustom", defaultItem: "defaultItem", data: "data", size: "size", rounded: "rounded" }, outputs: { onClick: "onClick", pageChange: "pageChange", listResize: "listResize", popupListScroll: "popupListScroll" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, static: true }, { propertyName: "virtualContainer", first: true, predicate: ["virtualContainer"], descendants: true }, { propertyName: "items", predicate: ListItemDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
458
469
  <div *ngIf="defaultItem && !template"
459
470
  class="k-list-optionlabel"
@@ -486,7 +497,7 @@ export class ListComponent {
486
497
  }">
487
498
  </ng-template>
488
499
  <ng-template #default_custom_item_template>
489
- Use "{{text}}"
500
+ {{useCustomValueText}}
490
501
  </ng-template>
491
502
  </div>
492
503
  <div *ngIf="dataService.grouped && showStickyHeader"
@@ -657,7 +668,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
657
668
  }">
658
669
  </ng-template>
659
670
  <ng-template #default_custom_item_template>
660
- Use "{{text}}"
671
+ {{useCustomValueText}}
661
672
  </ng-template>
662
673
  </div>
663
674
  <div *ngIf="dataService.grouped && showStickyHeader"
@@ -794,7 +805,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
794
805
  standalone: true,
795
806
  imports: [NgIf, NgStyle, TemplateContextDirective, NgFor, ListItemDirective, SelectableDirective, NgClass, ResizeSensorComponent]
796
807
  }]
797
- }], ctorParameters: function () { return [{ type: i1.DataService }, { type: i0.ElementRef }, { type: i2.SelectionService }, { type: i3.DisabledItemsService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.Renderer2 }]; }, propDecorators: { selected: [{
808
+ }], ctorParameters: function () { return [{ type: i1.DataService }, { type: i0.ElementRef }, { type: i2.SelectionService }, { type: i3.DisabledItemsService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i4.LocalizationService }]; }, propDecorators: { selected: [{
798
809
  type: Input
799
810
  }], focused: [{
800
811
  type: Input
@@ -41,8 +41,18 @@ export class Messages extends ComponentMessages {
41
41
  * The text for the input's placeholder when filtering is enabled.
42
42
  */
43
43
  filterInputPlaceholder;
44
+ /**
45
+ * The text displayed when the user types a custom value that is not in the list of options.
46
+ *
47
+ * The text includes a localizable string and the custom value.
48
+ * For example, when adding a custom value **Test**, the default text is **Use "Test"**.
49
+ *
50
+ * You can reorder the custom value and the localizable part by using a placeholder in `useCustomValueText`.
51
+ * Use `{customValue}` to insert the value, for example, **Add: {customValue}**.
52
+ */
53
+ useCustomValueText;
44
54
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, deps: null, target: i0.ɵɵFactoryTarget.Directive });
45
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Messages, inputs: { noDataText: "noDataText", clearTitle: "clearTitle", checkAllText: "checkAllText", selectButtonText: "selectButtonText", filterInputLabel: "filterInputLabel", popupLabel: "popupLabel", adaptiveCloseButtonTitle: "adaptiveCloseButtonTitle", filterInputPlaceholder: "filterInputPlaceholder" }, usesInheritance: true, ngImport: i0 });
55
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Messages, inputs: { noDataText: "noDataText", clearTitle: "clearTitle", checkAllText: "checkAllText", selectButtonText: "selectButtonText", filterInputLabel: "filterInputLabel", popupLabel: "popupLabel", adaptiveCloseButtonTitle: "adaptiveCloseButtonTitle", filterInputPlaceholder: "filterInputPlaceholder", useCustomValueText: "useCustomValueText" }, usesInheritance: true, ngImport: i0 });
46
56
  }
47
57
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, decorators: [{
48
58
  type: Directive
@@ -62,4 +72,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
62
72
  type: Input
63
73
  }], filterInputPlaceholder: [{
64
74
  type: Input
75
+ }], useCustomValueText: [{
76
+ type: Input
65
77
  }] } });
@@ -4,7 +4,7 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { Injectable, EventEmitter } from '@angular/core';
6
6
  import { isPresent } from '../util';
7
- import { Keys } from '@progress/kendo-angular-common';
7
+ import { Keys, normalizeNumpadKeys } from '@progress/kendo-angular-common';
8
8
  import { NavigationAction } from './navigation-action';
9
9
  import { DisabledItemsService } from '../disabled-items/disabled-items.service';
10
10
  import { SelectionService } from '../selection/selection.service';
@@ -57,7 +57,8 @@ export class NavigationService {
57
57
  this.selectionService = selectionService;
58
58
  }
59
59
  process(args) {
60
- const keyCode = args.originalEvent.keyCode;
60
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
61
+ const keyCode = normalizeNumpadKeys(args.originalEvent);
61
62
  const altKey = args.originalEvent.altKey;
62
63
  const shiftKey = args.originalEvent.shiftKey;
63
64
  const ctrlKey = args.originalEvent.ctrlKey || args.originalEvent.metaKey;
@@ -3,7 +3,7 @@
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { Component, Renderer2, Input, Output, EventEmitter, ElementRef, HostBinding, Injector, NgZone } from '@angular/core';
6
- import { isDocumentAvailable, isObjectPresent, isSafari, removeHTMLAttributes, setHTMLAttributes, Keys, parseAttributes } from '@progress/kendo-angular-common';
6
+ import { isDocumentAvailable, isObjectPresent, isSafari, removeHTMLAttributes, setHTMLAttributes, Keys, parseAttributes, normalizeNumpadKeys } from '@progress/kendo-angular-common';
7
7
  import { combineStr, isJapanese } from './util';
8
8
  import { LocalizationService } from '@progress/kendo-angular-l10n';
9
9
  import { Subscription } from 'rxjs';
@@ -269,7 +269,8 @@ export class SearchBarComponent {
269
269
  this.onBlur.emit(event);
270
270
  }
271
271
  handleKeydown(event) {
272
- const keyCode = event.keyCode;
272
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
273
+ const keyCode = normalizeNumpadKeys(event);
273
274
  const keys = [Keys.ArrowUp, Keys.ArrowDown, Keys.ArrowLeft, Keys.ArrowRight, Keys.Enter,
274
275
  Keys.Escape, Keys.Delete, Keys.Backspace, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp];
275
276
  if (keys.indexOf(keyCode) > -1) {
@@ -63,7 +63,7 @@ export class SharedDropDownEventsDirective {
63
63
  cursorInsideWrapper = false;
64
64
  }));
65
65
  this.subscriptions.add(this.renderer.listen(hostElement, 'keydown', (args) => {
66
- if (args.keyCode === Keys.Tab) {
66
+ if (args.code === Keys.Tab) {
67
67
  tabbing = true;
68
68
  }
69
69
  else {
@@ -8,7 +8,7 @@ import { validatePackage } from '@progress/kendo-licensing';
8
8
  import { packageMetadata } from '../package-metadata';
9
9
  import { merge, interval, Subscription } from 'rxjs';
10
10
  import { concatMap, filter, map, skipWhile, take, takeUntil, tap } from 'rxjs/operators';
11
- import { isDocumentAvailable, KendoInput, hasObservers, anyChanged, isChanged, EventsOutsideAngularDirective, ResizeSensorComponent, Keys, TemplateContextDirective, isSafari, guid } from '@progress/kendo-angular-common';
11
+ import { isDocumentAvailable, KendoInput, hasObservers, anyChanged, isChanged, EventsOutsideAngularDirective, ResizeSensorComponent, Keys, TemplateContextDirective, isSafari, guid, normalizeNumpadKeys } from '@progress/kendo-angular-common';
12
12
  import { AdaptiveService } from '@progress/kendo-angular-utils';
13
13
  import { isPresent, getter, shuffleData, sameCharsOnly, matchText, isUntouched, inDropDown, getSizeClass, getRoundedClass, getFillModeClass, isTruthy, setListBoxAriaLabelledBy, setActionSheetTitle, animationDuration } from '../common/util';
14
14
  import { SelectionService } from '../common/selection/selection.service';
@@ -598,7 +598,11 @@ export class DropDownListComponent {
598
598
  if (this.disabled || this.readonly) {
599
599
  return;
600
600
  }
601
- const isHomeEnd = event.keyCode === Keys.Home || event.keyCode === Keys.End;
601
+ // on some keyboards, Home and End keys are mapped to Numpad keys
602
+ const code = normalizeNumpadKeys(event);
603
+ const isHomeKey = code === Keys.Home;
604
+ const isEndKey = code === Keys.End;
605
+ const isHomeEnd = isHomeKey || isEndKey;
602
606
  const isFilterFocused = this.filterable && this.isFocused && this.isOpen;
603
607
  if (isFilterFocused && isHomeEnd) {
604
608
  return;
@@ -606,10 +610,10 @@ export class DropDownListComponent {
606
610
  const hasSelected = isPresent(this.selectionService.selected[0]);
607
611
  const focusedItemNotSelected = isPresent(this.selectionService.focused) && !this.selectionService.isSelected(this.selectionService.focused);
608
612
  if (!hasSelected || focusedItemNotSelected) {
609
- if (event.keyCode === Keys.ArrowDown || event.keyCode === Keys.ArrowRight && this.leftRightArrowsNavigation) {
613
+ if (code === Keys.ArrowDown || code === Keys.ArrowRight && this.leftRightArrowsNavigation) {
610
614
  offset = -1;
611
615
  }
612
- else if (event.keyCode === Keys.ArrowUp || event.keyCode === Keys.ArrowLeft && this.leftRightArrowsNavigation) {
616
+ else if (code === Keys.ArrowUp || code === Keys.ArrowLeft && this.leftRightArrowsNavigation) {
613
617
  offset = 1;
614
618
  }
615
619
  }
@@ -1061,7 +1065,8 @@ export class DropDownListComponent {
1061
1065
  this.subs.add(merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
1062
1066
  if (this.isOpen) {
1063
1067
  event.originalEvent.preventDefault();
1064
- this.optionsList.scrollWithOnePage(NavigationAction[event.originalEvent.code]);
1068
+ const code = normalizeNumpadKeys(event.originalEvent);
1069
+ this.optionsList.scrollWithOnePage(NavigationAction[code]);
1065
1070
  }
1066
1071
  }));
1067
1072
  this.subs.add(this.navigationService.open.subscribe(() => this.togglePopup(true)));
@@ -1256,10 +1261,10 @@ export class DropDownListComponent {
1256
1261
  }
1257
1262
  }
1258
1263
  onKeyPress(event) {
1259
- if (event.which === 0 || event.keyCode === Keys.Enter) {
1264
+ if (event.which === 0 || event.code === Keys.Enter || event.code === Keys.NumpadEnter || event.key.length > 1) {
1260
1265
  return;
1261
1266
  }
1262
- let character = String.fromCharCode(event.charCode || event.keyCode);
1267
+ let character = event.key;
1263
1268
  if (this.ignoreCase) {
1264
1269
  character = character.toLowerCase();
1265
1270
  }
@@ -804,7 +804,7 @@ export class DropDownTreeComponent {
804
804
  if (this.disabled || this.readonly) {
805
805
  return;
806
806
  }
807
- if (event.keyCode === Keys.Tab && this.isActionSheetExpanded) {
807
+ if (event.code === Keys.Tab && this.isActionSheetExpanded) {
808
808
  this.togglePopup(false);
809
809
  return;
810
810
  }
@@ -4,7 +4,7 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { ChangeDetectorRef, Component, ContentChild, ElementRef, EventEmitter, forwardRef, HostBinding, Injector, Input, isDevMode, NgZone, Output, Renderer2, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core';
6
6
  import { NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
7
- import { anyChanged, guid, hasObservers, Keys, KendoInput, isDocumentAvailable, EventsOutsideAngularDirective, ResizeSensorComponent, TemplateContextDirective } from '@progress/kendo-angular-common';
7
+ import { anyChanged, guid, hasObservers, Keys, KendoInput, isDocumentAvailable, EventsOutsideAngularDirective, ResizeSensorComponent, TemplateContextDirective, normalizeNumpadKeys } from '@progress/kendo-angular-common';
8
8
  import { AdaptiveService } from '@progress/kendo-angular-utils';
9
9
  import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
10
10
  import { NavigationService } from '../common/navigation/navigation.service';
@@ -201,14 +201,15 @@ export class MultiSelectTreeComponent {
201
201
  * @hidden
202
202
  */
203
203
  handleKeydown(event, input) {
204
+ const code = normalizeNumpadKeys(event);
204
205
  if (event.target === this.filterInput?.nativeElement &&
205
- (event.keyCode === Keys.ArrowLeft || event.keyCode === Keys.ArrowRight)) {
206
+ (code === Keys.ArrowLeft || code === Keys.ArrowRight)) {
206
207
  return;
207
208
  }
208
209
  if (input) {
209
210
  event.stopImmediatePropagation();
210
211
  }
211
- const deleteTag = this.isWrapperActive && event.keyCode === Keys.Backspace && this.tags.length > 0;
212
+ const deleteTag = this.isWrapperActive && code === Keys.Backspace && this.tags.length > 0;
212
213
  if (deleteTag) {
213
214
  this.handleBackspace();
214
215
  return;
@@ -6,7 +6,7 @@ import { isPresent, isArray, isObjectArray, resolveAllValues, selectedIndices, g
6
6
  import { SearchBarComponent } from '../common/searchbar.component';
7
7
  import { ViewChild, Renderer2, ViewContainerRef, Component, HostBinding, Input, ElementRef, TemplateRef, Output, EventEmitter, isDevMode, forwardRef, ContentChild, ChangeDetectorRef, KeyValueDiffers, NgZone, Injector } from '@angular/core';
8
8
  import { Subscription, Subject, of, merge } from 'rxjs';
9
- import { isChanged, isDocumentAvailable, KendoInput, hasObservers, anyChanged, SuffixTemplateDirective, PrefixTemplateDirective, isControlRequired, SeparatorComponent, ResizeSensorComponent, Keys, TemplateContextDirective, guid } from '@progress/kendo-angular-common';
9
+ import { isChanged, isDocumentAvailable, KendoInput, hasObservers, anyChanged, SuffixTemplateDirective, PrefixTemplateDirective, isControlRequired, SeparatorComponent, ResizeSensorComponent, Keys, TemplateContextDirective, guid, normalizeNumpadKeys } from '@progress/kendo-angular-common';
10
10
  import { AdaptiveService } from '@progress/kendo-angular-utils';
11
11
  import { catchError, filter, map, take, tap } from 'rxjs/operators';
12
12
  import { NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
@@ -956,10 +956,11 @@ export class MultiSelectComponent {
956
956
  * @hidden
957
957
  */
958
958
  handleNavigate(event) {
959
- const navigateInput = this.text && event.keyCode !== Keys.ArrowDown && event.keyCode !== Keys.ArrowUp;
960
- const selectValue = this.text && event.keyCode === Keys.Enter || event.keyCode === Keys.Escape;
961
- const deleteTag = !this.text && event.keyCode === Keys.Backspace && this.tags.length > 0;
962
- if (event.keyCode === Keys.Backspace && this.isActionSheetExpanded) {
959
+ const code = normalizeNumpadKeys(event);
960
+ const navigateInput = this.text && code !== Keys.ArrowDown && code !== Keys.ArrowUp;
961
+ const selectValue = this.text && code === Keys.Enter || code === Keys.Escape;
962
+ const deleteTag = !this.text && code === Keys.Backspace && this.tags.length > 0;
963
+ if (code === Keys.Backspace && this.isActionSheetExpanded) {
963
964
  return;
964
965
  }
965
966
  if (deleteTag) {
@@ -1217,7 +1218,8 @@ export class MultiSelectComponent {
1217
1218
  merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
1218
1219
  if (this.isOpen) {
1219
1220
  event.originalEvent.preventDefault();
1220
- this.optionsList.scrollWithOnePage(NavigationAction[event.originalEvent.code]);
1221
+ const code = normalizeNumpadKeys(event.originalEvent);
1222
+ this.optionsList.scrollWithOnePage(NavigationAction[code]);
1221
1223
  }
1222
1224
  })
1223
1225
  ].forEach(s => this.subs.add(s));
@@ -1408,7 +1410,7 @@ export class MultiSelectComponent {
1408
1410
  }
1409
1411
  }
1410
1412
  handleKeydown(event) {
1411
- if (this.isFocused && this.isOpen && (event.ctrlKey || event.metaKey) && event.keyCode === Keys.KeyA) {
1413
+ if (this.isFocused && this.isOpen && (event.ctrlKey || event.metaKey) && event.code === Keys.KeyA) {
1412
1414
  event.preventDefault();
1413
1415
  this.handleSelectAll();
1414
1416
  }
@@ -1812,6 +1814,9 @@ export class MultiSelectComponent {
1812
1814
 
1813
1815
  i18n-adaptiveCloseButtonTitle="kendo.multiselect.adaptiveCloseButtonTitle|The title of the Close button of the ActionSheet that is rendered instead of the Popup when using small screen devices in adaptive mode."
1814
1816
  adaptiveCloseButtonTitle="Close"
1817
+
1818
+ i18n-useCustomValueText="kendo.multiselect.useCustomValueText|The text displayed when the user types a custom value that is not in the list of options."
1819
+ useCustomValueText="{{ 'Use &quot;{customValue}&quot;' }}"
1815
1820
  >
1816
1821
  </ng-container>
1817
1822
 
@@ -2005,6 +2010,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2005
2010
 
2006
2011
  i18n-adaptiveCloseButtonTitle="kendo.multiselect.adaptiveCloseButtonTitle|The title of the Close button of the ActionSheet that is rendered instead of the Popup when using small screen devices in adaptive mode."
2007
2012
  adaptiveCloseButtonTitle="Close"
2013
+
2014
+ i18n-useCustomValueText="kendo.multiselect.useCustomValueText|The text displayed when the user types a custom value that is not in the list of options."
2015
+ useCustomValueText="{{ 'Use &quot;{customValue}&quot;' }}"
2008
2016
  >
2009
2017
  </ng-container>
2010
2018
 
@@ -10,7 +10,7 @@ export const packageMetadata = {
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCode: 'KENDOUIANGULAR',
12
12
  productCodes: ['KENDOUIANGULAR'],
13
- publishDate: 1752065402,
14
- version: '19.3.0-develop.4',
13
+ publishDate: 1754990723,
14
+ version: '19.3.0-develop.40',
15
15
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
16
16
  };
@@ -5,7 +5,7 @@
5
5
  import * as i0 from '@angular/core';
6
6
  import { EventEmitter, Component, Input, HostBinding, Output, Directive, Injectable, HostListener, ViewChildren, ViewChild, forwardRef, isDevMode, ViewContainerRef, ContentChild, ContentChildren, ChangeDetectionStrategy, NgModule } from '@angular/core';
7
7
  import * as i10 from '@progress/kendo-angular-common';
8
- import { isDocumentAvailable, isObjectPresent, removeHTMLAttributes, parseAttributes, isSafari, Keys, setHTMLAttributes, isChanged, TemplateContextDirective, ResizeSensorComponent, closest as closest$1, isControlRequired, guid, hasObservers, KendoInput, SuffixTemplateDirective, PrefixTemplateDirective, SeparatorComponent, MultiTabStop, anyChanged, EventsOutsideAngularDirective, ToggleButtonTabStopDirective, ResizeBatchService, KENDO_ADORNMENTS, KENDO_TOGGLEBUTTONTABSTOP } from '@progress/kendo-angular-common';
8
+ import { isDocumentAvailable, isObjectPresent, removeHTMLAttributes, parseAttributes, isSafari, normalizeNumpadKeys, Keys, setHTMLAttributes, replaceMessagePlaceholder, isChanged, TemplateContextDirective, ResizeSensorComponent, closest as closest$1, isControlRequired, guid, hasObservers, KendoInput, SuffixTemplateDirective, PrefixTemplateDirective, SeparatorComponent, MultiTabStop, anyChanged, EventsOutsideAngularDirective, ToggleButtonTabStopDirective, ResizeBatchService, KENDO_ADORNMENTS, KENDO_TOGGLEBUTTONTABSTOP } from '@progress/kendo-angular-common';
9
9
  export { PrefixTemplateDirective, SeparatorComponent, SuffixTemplateDirective, ToggleButtonTabStopDirective } from '@progress/kendo-angular-common';
10
10
  import * as i7 from '@progress/kendo-angular-utils';
11
11
  import { AdaptiveService } from '@progress/kendo-angular-utils';
@@ -37,8 +37,8 @@ const packageMetadata = {
37
37
  productName: 'Kendo UI for Angular',
38
38
  productCode: 'KENDOUIANGULAR',
39
39
  productCodes: ['KENDOUIANGULAR'],
40
- publishDate: 1752065402,
41
- version: '19.3.0-develop.4',
40
+ publishDate: 1754990723,
41
+ version: '19.3.0-develop.40',
42
42
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
43
43
  };
44
44
 
@@ -672,7 +672,8 @@ class SearchBarComponent {
672
672
  this.onBlur.emit(event);
673
673
  }
674
674
  handleKeydown(event) {
675
- const keyCode = event.keyCode;
675
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
676
+ const keyCode = normalizeNumpadKeys(event);
676
677
  const keys = [Keys.ArrowUp, Keys.ArrowDown, Keys.ArrowLeft, Keys.ArrowRight, Keys.Enter,
677
678
  Keys.Escape, Keys.Delete, Keys.Backspace, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp];
678
679
  if (keys.indexOf(keyCode) > -1) {
@@ -1532,7 +1533,8 @@ class NavigationService {
1532
1533
  this.selectionService = selectionService;
1533
1534
  }
1534
1535
  process(args) {
1535
- const keyCode = args.originalEvent.keyCode;
1536
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
1537
+ const keyCode = normalizeNumpadKeys(args.originalEvent);
1536
1538
  const altKey = args.originalEvent.altKey;
1537
1539
  const shiftKey = args.originalEvent.shiftKey;
1538
1540
  const ctrlKey = args.originalEvent.ctrlKey || args.originalEvent.metaKey;
@@ -1908,6 +1910,7 @@ class ListComponent {
1908
1910
  cdr;
1909
1911
  zone;
1910
1912
  renderer;
1913
+ localization;
1911
1914
  selected = [];
1912
1915
  focused = -1;
1913
1916
  textField;
@@ -1992,6 +1995,13 @@ class ListComponent {
1992
1995
  return overflow;
1993
1996
  }
1994
1997
  }
1998
+ /**
1999
+ * @hidden
2000
+ */
2001
+ get useCustomValueText() {
2002
+ const localizationMsg = this.localization.get('useCustomValueText');
2003
+ return replaceMessagePlaceholder(localizationMsg, 'customValue', this.text);
2004
+ }
1995
2005
  /**
1996
2006
  * @hidden
1997
2007
  */
@@ -1999,7 +2009,7 @@ class ListComponent {
1999
2009
  return `${this.size ? getSizeClass('checkbox', this.size) : ''} ${this.rounded ? getRoundedClass(this.rounded) : ''}`;
2000
2010
  }
2001
2011
  /* tslint:disable:member-ordering */
2002
- constructor(dataService, wrapper, selectionService, disabledItemsService, cdr, zone, renderer) {
2012
+ constructor(dataService, wrapper, selectionService, disabledItemsService, cdr, zone, renderer, localization) {
2003
2013
  this.dataService = dataService;
2004
2014
  this.wrapper = wrapper;
2005
2015
  this.selectionService = selectionService;
@@ -2007,6 +2017,7 @@ class ListComponent {
2007
2017
  this.cdr = cdr;
2008
2018
  this.zone = zone;
2009
2019
  this.renderer = renderer;
2020
+ this.localization = localization;
2010
2021
  this.selectSubscription = merge(this.selectionService.onSelect.pipe(map((args) => args.indices[0])), this.selectionService.onFocus)
2011
2022
  .pipe(
2012
2023
  // handle only the very last onSelect/onFocus emission
@@ -2328,7 +2339,7 @@ class ListComponent {
2328
2339
  this.renderer.addClass(this.wrapper.nativeElement, this.listVirtualClass);
2329
2340
  }
2330
2341
  }
2331
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListComponent, deps: [{ token: DataService }, { token: i0.ElementRef }, { token: SelectionService }, { token: DisabledItemsService }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
2342
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ListComponent, deps: [{ token: DataService }, { token: i0.ElementRef }, { token: SelectionService }, { token: DisabledItemsService }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
2332
2343
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ListComponent, isStandalone: true, selector: "kendo-list", inputs: { selected: "selected", focused: "focused", textField: "textField", valueField: "valueField", height: "height", template: "template", groupTemplate: "groupTemplate", fixedGroupTemplate: "fixedGroupTemplate", show: "show", id: "id", optionPrefix: "optionPrefix", multipleSelection: "multipleSelection", virtual: "virtual", type: "type", checkboxes: "checkboxes", ariaLive: "ariaLive", isMultiselect: "isMultiselect", isActionSheetExpanded: "isActionSheetExpanded", showStickyHeader: "showStickyHeader", rowWidth: "rowWidth", customItemTemplate: "customItemTemplate", text: "text", allowCustom: "allowCustom", defaultItem: "defaultItem", data: "data", size: "size", rounded: "rounded" }, outputs: { onClick: "onClick", pageChange: "pageChange", listResize: "listResize", popupListScroll: "popupListScroll" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, static: true }, { propertyName: "virtualContainer", first: true, predicate: ["virtualContainer"], descendants: true }, { propertyName: "items", predicate: ListItemDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
2333
2344
  <div *ngIf="defaultItem && !template"
2334
2345
  class="k-list-optionlabel"
@@ -2361,7 +2372,7 @@ class ListComponent {
2361
2372
  }">
2362
2373
  </ng-template>
2363
2374
  <ng-template #default_custom_item_template>
2364
- Use "{{text}}"
2375
+ {{useCustomValueText}}
2365
2376
  </ng-template>
2366
2377
  </div>
2367
2378
  <div *ngIf="dataService.grouped && showStickyHeader"
@@ -2532,7 +2543,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2532
2543
  }">
2533
2544
  </ng-template>
2534
2545
  <ng-template #default_custom_item_template>
2535
- Use "{{text}}"
2546
+ {{useCustomValueText}}
2536
2547
  </ng-template>
2537
2548
  </div>
2538
2549
  <div *ngIf="dataService.grouped && showStickyHeader"
@@ -2669,7 +2680,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
2669
2680
  standalone: true,
2670
2681
  imports: [NgIf, NgStyle, TemplateContextDirective, NgFor, ListItemDirective, SelectableDirective, NgClass, ResizeSensorComponent]
2671
2682
  }]
2672
- }], ctorParameters: function () { return [{ type: DataService }, { type: i0.ElementRef }, { type: SelectionService }, { type: DisabledItemsService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.Renderer2 }]; }, propDecorators: { selected: [{
2683
+ }], ctorParameters: function () { return [{ type: DataService }, { type: i0.ElementRef }, { type: SelectionService }, { type: DisabledItemsService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i1.LocalizationService }]; }, propDecorators: { selected: [{
2673
2684
  type: Input
2674
2685
  }], focused: [{
2675
2686
  type: Input
@@ -3046,7 +3057,7 @@ class SharedDropDownEventsDirective {
3046
3057
  cursorInsideWrapper = false;
3047
3058
  }));
3048
3059
  this.subscriptions.add(this.renderer.listen(hostElement, 'keydown', (args) => {
3049
- if (args.keyCode === Keys.Tab) {
3060
+ if (args.code === Keys.Tab) {
3050
3061
  tabbing = true;
3051
3062
  }
3052
3063
  else {
@@ -3117,8 +3128,18 @@ class Messages extends ComponentMessages {
3117
3128
  * The text for the input's placeholder when filtering is enabled.
3118
3129
  */
3119
3130
  filterInputPlaceholder;
3131
+ /**
3132
+ * The text displayed when the user types a custom value that is not in the list of options.
3133
+ *
3134
+ * The text includes a localizable string and the custom value.
3135
+ * For example, when adding a custom value **Test**, the default text is **Use "Test"**.
3136
+ *
3137
+ * You can reorder the custom value and the localizable part by using a placeholder in `useCustomValueText`.
3138
+ * Use `{customValue}` to insert the value, for example, **Add: {customValue}**.
3139
+ */
3140
+ useCustomValueText;
3120
3141
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, deps: null, target: i0.ɵɵFactoryTarget.Directive });
3121
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Messages, inputs: { noDataText: "noDataText", clearTitle: "clearTitle", checkAllText: "checkAllText", selectButtonText: "selectButtonText", filterInputLabel: "filterInputLabel", popupLabel: "popupLabel", adaptiveCloseButtonTitle: "adaptiveCloseButtonTitle", filterInputPlaceholder: "filterInputPlaceholder" }, usesInheritance: true, ngImport: i0 });
3142
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: Messages, inputs: { noDataText: "noDataText", clearTitle: "clearTitle", checkAllText: "checkAllText", selectButtonText: "selectButtonText", filterInputLabel: "filterInputLabel", popupLabel: "popupLabel", adaptiveCloseButtonTitle: "adaptiveCloseButtonTitle", filterInputPlaceholder: "filterInputPlaceholder", useCustomValueText: "useCustomValueText" }, usesInheritance: true, ngImport: i0 });
3122
3143
  }
3123
3144
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: Messages, decorators: [{
3124
3145
  type: Directive
@@ -3138,6 +3159,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
3138
3159
  type: Input
3139
3160
  }], filterInputPlaceholder: [{
3140
3161
  type: Input
3162
+ }], useCustomValueText: [{
3163
+ type: Input
3141
3164
  }] } });
3142
3165
 
3143
3166
  /**
@@ -4103,8 +4126,10 @@ class AutoCompleteComponent {
4103
4126
  this.subs.add(this.valueChangeSubject
4104
4127
  .subscribe(value => {
4105
4128
  const hasChange = this.value !== value;
4106
- const index = this.findIndex(value);
4107
- this.selectionService.focused = index;
4129
+ if (this.isOpen) {
4130
+ const index = this.findIndex(value);
4131
+ this.selectionService.focused = index;
4132
+ }
4108
4133
  this.value = value;
4109
4134
  this.text = value;
4110
4135
  // emit change after assigning `this.value` => allows the user to modify the component value on `valueChange`
@@ -4122,7 +4147,8 @@ class AutoCompleteComponent {
4122
4147
  this.subs.add(merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
4123
4148
  if (this.isOpen) {
4124
4149
  event.originalEvent.preventDefault();
4125
- this.optionsList.scrollWithOnePage(NavigationAction[event.originalEvent.code]);
4150
+ const code = normalizeNumpadKeys(event.originalEvent);
4151
+ this.optionsList.scrollWithOnePage(NavigationAction[code]);
4126
4152
  }
4127
4153
  }));
4128
4154
  }
@@ -5580,7 +5606,8 @@ class ComboBoxComponent extends MultiTabStop {
5580
5606
  this.subs.add(merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
5581
5607
  if (this.isOpen) {
5582
5608
  event.originalEvent.preventDefault();
5583
- this.optionsList.scrollWithOnePage(NavigationAction[event.originalEvent.code]);
5609
+ const code = normalizeNumpadKeys(event.originalEvent);
5610
+ this.optionsList.scrollWithOnePage(NavigationAction[code]);
5584
5611
  }
5585
5612
  }));
5586
5613
  this.subs.add(this.navigationService.esc.subscribe(this.handleEscape.bind(this)));
@@ -5929,14 +5956,18 @@ class ComboBoxComponent extends MultiTabStop {
5929
5956
  if (this.disabled || this.readonly) {
5930
5957
  return;
5931
5958
  }
5932
- if (event.keyCode === Keys.Home || event.keyCode === Keys.End) {
5959
+ // on some keyboards, Home and End keys are mapped to Numpad keys
5960
+ const code = normalizeNumpadKeys(event);
5961
+ const isHomeKey = code === Keys.Home;
5962
+ const isEndKey = code === Keys.End;
5963
+ if (isHomeKey || isEndKey) {
5933
5964
  return;
5934
5965
  }
5935
5966
  if (!hasSelected) {
5936
- if (event.keyCode === Keys.ArrowDown) {
5967
+ if (code === Keys.ArrowDown) {
5937
5968
  offset = -1;
5938
5969
  }
5939
- else if (event.keyCode === Keys.ArrowUp) {
5970
+ else if (code === Keys.ArrowUp) {
5940
5971
  offset = 1;
5941
5972
  }
5942
5973
  }
@@ -7509,7 +7540,11 @@ class DropDownListComponent {
7509
7540
  if (this.disabled || this.readonly) {
7510
7541
  return;
7511
7542
  }
7512
- const isHomeEnd = event.keyCode === Keys.Home || event.keyCode === Keys.End;
7543
+ // on some keyboards, Home and End keys are mapped to Numpad keys
7544
+ const code = normalizeNumpadKeys(event);
7545
+ const isHomeKey = code === Keys.Home;
7546
+ const isEndKey = code === Keys.End;
7547
+ const isHomeEnd = isHomeKey || isEndKey;
7513
7548
  const isFilterFocused = this.filterable && this.isFocused && this.isOpen;
7514
7549
  if (isFilterFocused && isHomeEnd) {
7515
7550
  return;
@@ -7517,10 +7552,10 @@ class DropDownListComponent {
7517
7552
  const hasSelected = isPresent(this.selectionService.selected[0]);
7518
7553
  const focusedItemNotSelected = isPresent(this.selectionService.focused) && !this.selectionService.isSelected(this.selectionService.focused);
7519
7554
  if (!hasSelected || focusedItemNotSelected) {
7520
- if (event.keyCode === Keys.ArrowDown || event.keyCode === Keys.ArrowRight && this.leftRightArrowsNavigation) {
7555
+ if (code === Keys.ArrowDown || code === Keys.ArrowRight && this.leftRightArrowsNavigation) {
7521
7556
  offset = -1;
7522
7557
  }
7523
- else if (event.keyCode === Keys.ArrowUp || event.keyCode === Keys.ArrowLeft && this.leftRightArrowsNavigation) {
7558
+ else if (code === Keys.ArrowUp || code === Keys.ArrowLeft && this.leftRightArrowsNavigation) {
7524
7559
  offset = 1;
7525
7560
  }
7526
7561
  }
@@ -7972,7 +8007,8 @@ class DropDownListComponent {
7972
8007
  this.subs.add(merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
7973
8008
  if (this.isOpen) {
7974
8009
  event.originalEvent.preventDefault();
7975
- this.optionsList.scrollWithOnePage(NavigationAction[event.originalEvent.code]);
8010
+ const code = normalizeNumpadKeys(event.originalEvent);
8011
+ this.optionsList.scrollWithOnePage(NavigationAction[code]);
7976
8012
  }
7977
8013
  }));
7978
8014
  this.subs.add(this.navigationService.open.subscribe(() => this.togglePopup(true)));
@@ -8167,10 +8203,10 @@ class DropDownListComponent {
8167
8203
  }
8168
8204
  }
8169
8205
  onKeyPress(event) {
8170
- if (event.which === 0 || event.keyCode === Keys.Enter) {
8206
+ if (event.which === 0 || event.code === Keys.Enter || event.code === Keys.NumpadEnter || event.key.length > 1) {
8171
8207
  return;
8172
8208
  }
8173
- let character = String.fromCharCode(event.charCode || event.keyCode);
8209
+ let character = event.key;
8174
8210
  if (this.ignoreCase) {
8175
8211
  character = character.toLowerCase();
8176
8212
  }
@@ -10160,10 +10196,11 @@ class MultiSelectComponent {
10160
10196
  * @hidden
10161
10197
  */
10162
10198
  handleNavigate(event) {
10163
- const navigateInput = this.text && event.keyCode !== Keys.ArrowDown && event.keyCode !== Keys.ArrowUp;
10164
- const selectValue = this.text && event.keyCode === Keys.Enter || event.keyCode === Keys.Escape;
10165
- const deleteTag = !this.text && event.keyCode === Keys.Backspace && this.tags.length > 0;
10166
- if (event.keyCode === Keys.Backspace && this.isActionSheetExpanded) {
10199
+ const code = normalizeNumpadKeys(event);
10200
+ const navigateInput = this.text && code !== Keys.ArrowDown && code !== Keys.ArrowUp;
10201
+ const selectValue = this.text && code === Keys.Enter || code === Keys.Escape;
10202
+ const deleteTag = !this.text && code === Keys.Backspace && this.tags.length > 0;
10203
+ if (code === Keys.Backspace && this.isActionSheetExpanded) {
10167
10204
  return;
10168
10205
  }
10169
10206
  if (deleteTag) {
@@ -10421,7 +10458,8 @@ class MultiSelectComponent {
10421
10458
  merge(this.navigationService.pagedown, this.navigationService.pageup).subscribe((event) => {
10422
10459
  if (this.isOpen) {
10423
10460
  event.originalEvent.preventDefault();
10424
- this.optionsList.scrollWithOnePage(NavigationAction[event.originalEvent.code]);
10461
+ const code = normalizeNumpadKeys(event.originalEvent);
10462
+ this.optionsList.scrollWithOnePage(NavigationAction[code]);
10425
10463
  }
10426
10464
  })
10427
10465
  ].forEach(s => this.subs.add(s));
@@ -10612,7 +10650,7 @@ class MultiSelectComponent {
10612
10650
  }
10613
10651
  }
10614
10652
  handleKeydown(event) {
10615
- if (this.isFocused && this.isOpen && (event.ctrlKey || event.metaKey) && event.keyCode === Keys.KeyA) {
10653
+ if (this.isFocused && this.isOpen && (event.ctrlKey || event.metaKey) && event.code === Keys.KeyA) {
10616
10654
  event.preventDefault();
10617
10655
  this.handleSelectAll();
10618
10656
  }
@@ -11016,6 +11054,9 @@ class MultiSelectComponent {
11016
11054
 
11017
11055
  i18n-adaptiveCloseButtonTitle="kendo.multiselect.adaptiveCloseButtonTitle|The title of the Close button of the ActionSheet that is rendered instead of the Popup when using small screen devices in adaptive mode."
11018
11056
  adaptiveCloseButtonTitle="Close"
11057
+
11058
+ i18n-useCustomValueText="kendo.multiselect.useCustomValueText|The text displayed when the user types a custom value that is not in the list of options."
11059
+ useCustomValueText="{{ 'Use &quot;{customValue}&quot;' }}"
11019
11060
  >
11020
11061
  </ng-container>
11021
11062
 
@@ -11209,6 +11250,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
11209
11250
 
11210
11251
  i18n-adaptiveCloseButtonTitle="kendo.multiselect.adaptiveCloseButtonTitle|The title of the Close button of the ActionSheet that is rendered instead of the Popup when using small screen devices in adaptive mode."
11211
11252
  adaptiveCloseButtonTitle="Close"
11253
+
11254
+ i18n-useCustomValueText="kendo.multiselect.useCustomValueText|The text displayed when the user types a custom value that is not in the list of options."
11255
+ useCustomValueText="{{ 'Use &quot;{customValue}&quot;' }}"
11212
11256
  >
11213
11257
  </ng-container>
11214
11258
 
@@ -13353,7 +13397,7 @@ class DropDownTreeComponent {
13353
13397
  if (this.disabled || this.readonly) {
13354
13398
  return;
13355
13399
  }
13356
- if (event.keyCode === Keys.Tab && this.isActionSheetExpanded) {
13400
+ if (event.code === Keys.Tab && this.isActionSheetExpanded) {
13357
13401
  this.togglePopup(false);
13358
13402
  return;
13359
13403
  }
@@ -15096,14 +15140,15 @@ class MultiSelectTreeComponent {
15096
15140
  * @hidden
15097
15141
  */
15098
15142
  handleKeydown(event, input) {
15143
+ const code = normalizeNumpadKeys(event);
15099
15144
  if (event.target === this.filterInput?.nativeElement &&
15100
- (event.keyCode === Keys.ArrowLeft || event.keyCode === Keys.ArrowRight)) {
15145
+ (code === Keys.ArrowLeft || code === Keys.ArrowRight)) {
15101
15146
  return;
15102
15147
  }
15103
15148
  if (input) {
15104
15149
  event.stopImmediatePropagation();
15105
15150
  }
15106
- const deleteTag = this.isWrapperActive && event.keyCode === Keys.Backspace && this.tags.length > 0;
15151
+ const deleteTag = this.isWrapperActive && code === Keys.Backspace && this.tags.length > 0;
15107
15152
  if (deleteTag) {
15108
15153
  this.handleBackspace();
15109
15154
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-dropdowns",
3
- "version": "19.3.0-develop.4",
3
+ "version": "19.3.0-develop.40",
4
4
  "description": "A wide variety of native Angular dropdown components including AutoComplete, ComboBox, DropDownList, DropDownTree, MultiColumnComboBox, MultiSelect, and MultiSelectTree ",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -100,7 +100,7 @@
100
100
  "package": {
101
101
  "productName": "Kendo UI for Angular",
102
102
  "productCode": "KENDOUIANGULAR",
103
- "publishDate": 1752065402,
103
+ "publishDate": 1754990723,
104
104
  "licensingDocsUrl": "https://www.telerik.com/kendo-angular-ui/my-license/"
105
105
  }
106
106
  },
@@ -110,19 +110,19 @@
110
110
  "@angular/core": "16 - 20",
111
111
  "@angular/forms": "16 - 20",
112
112
  "@angular/platform-browser": "16 - 20",
113
- "@progress/kendo-licensing": "^1.5.0",
114
- "@progress/kendo-angular-common": "19.3.0-develop.4",
115
- "@progress/kendo-angular-utils": "19.3.0-develop.4",
116
- "@progress/kendo-angular-l10n": "19.3.0-develop.4",
117
- "@progress/kendo-angular-navigation": "19.3.0-develop.4",
118
- "@progress/kendo-angular-popup": "19.3.0-develop.4",
119
- "@progress/kendo-angular-icons": "19.3.0-develop.4",
120
- "@progress/kendo-angular-treeview": "19.3.0-develop.4",
113
+ "@progress/kendo-licensing": "^1.7.0",
114
+ "@progress/kendo-angular-common": "19.3.0-develop.40",
115
+ "@progress/kendo-angular-utils": "19.3.0-develop.40",
116
+ "@progress/kendo-angular-l10n": "19.3.0-develop.40",
117
+ "@progress/kendo-angular-navigation": "19.3.0-develop.40",
118
+ "@progress/kendo-angular-popup": "19.3.0-develop.40",
119
+ "@progress/kendo-angular-icons": "19.3.0-develop.40",
120
+ "@progress/kendo-angular-treeview": "19.3.0-develop.40",
121
121
  "rxjs": "^6.5.3 || ^7.0.0"
122
122
  },
123
123
  "dependencies": {
124
124
  "tslib": "^2.3.1",
125
- "@progress/kendo-angular-schematics": "19.3.0-develop.4",
125
+ "@progress/kendo-angular-schematics": "19.3.0-develop.40",
126
126
  "@progress/kendo-common": "^1.0.1",
127
127
  "node-html-parser": "^7.0.1"
128
128
  },
@@ -4,9 +4,9 @@ const schematics_1 = require("@angular-devkit/schematics");
4
4
  function default_1(options) {
5
5
  const finalOptions = Object.assign(Object.assign({}, options), { mainNgModule: 'DropDownsModule', package: 'dropdowns', peerDependencies: {
6
6
  // peers of the treeview
7
- '@progress/kendo-angular-inputs': '19.3.0-develop.4',
7
+ '@progress/kendo-angular-inputs': '19.3.0-develop.40',
8
8
  // peers of inputs
9
- '@progress/kendo-angular-intl': '19.3.0-develop.4',
9
+ '@progress/kendo-angular-intl': '19.3.0-develop.40',
10
10
  '@progress/kendo-drawing': '^1.17.2',
11
11
  // Peer dependency of icons
12
12
  '@progress/kendo-svg-icons': '^4.0.0'