@progress/kendo-angular-dropdowns 11.0.0-develop.93 → 11.0.0-develop.94

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.
package/common/util.d.ts CHANGED
@@ -173,3 +173,18 @@ export declare const isSafari: (userAgent: any) => boolean;
173
173
  * Checks if input is Japanese IME
174
174
  */
175
175
  export declare const isJapanese: (input: any) => boolean;
176
+ /**
177
+ * @hidden
178
+ */
179
+ export declare const isLetter: (text: string) => boolean;
180
+ /**
181
+ * @hidden
182
+ */
183
+ export declare const getTextField: (field: string | string[], level: number) => string;
184
+ /**
185
+ * @hidden
186
+ */
187
+ export declare const getSearchableItems: (popupId: string, popupElement: HTMLElement) => {
188
+ text: string;
189
+ index: string;
190
+ }[];
@@ -399,7 +399,10 @@ export declare class DropDownTreeComponent implements OnInit, OnDestroy, OnChang
399
399
  private _size;
400
400
  private _rounded;
401
401
  private _fillMode;
402
- private subscriptions;
402
+ private _searchableNodes;
403
+ private _typedValue;
404
+ private printableCharacters;
405
+ private subs;
403
406
  private touchstartDisposeHandler;
404
407
  constructor(injector: Injector, wrapper: ElementRef<HTMLElement>, popupService: PopupService, navigationService: NavigationService, renderer: Renderer2, _zone: NgZone, cdr: ChangeDetectorRef, localization: LocalizationService, touchEnabled: boolean);
405
408
  ngOnInit(): void;
@@ -520,6 +523,10 @@ export declare class DropDownTreeComponent implements OnInit, OnDestroy, OnChang
520
523
  protected verifySettings(): void;
521
524
  private emitValueChange;
522
525
  private getText;
526
+ /**
527
+ * @hidden
528
+ */
529
+ onChildrenLoaded(): void;
523
530
  /**
524
531
  * @hidden
525
532
  *
@@ -446,7 +446,10 @@ export declare class MultiSelectTreeComponent implements OnInit, OnDestroy, OnCh
446
446
  private _size;
447
447
  private _rounded;
448
448
  private _fillMode;
449
- private subscriptions;
449
+ private _searchableNodes;
450
+ private _typedValue;
451
+ private printableCharacters;
452
+ private subs;
450
453
  private lastNodeOnFocus;
451
454
  private isContentInit;
452
455
  constructor(injector: Injector, wrapper: ElementRef, popupService: PopupService, renderer: Renderer2, navigationService: NavigationService, _zone: NgZone, localization: LocalizationService, cdr: ChangeDetectorRef, lookup: MultiSelectTreeLookupService, touchEnabled: boolean);
@@ -600,6 +603,10 @@ export declare class MultiSelectTreeComponent implements OnInit, OnDestroy, OnCh
600
603
  private setState;
601
604
  private setTags;
602
605
  private updateValue;
606
+ /**
607
+ * @hidden
608
+ */
609
+ onChildrenLoaded(): void;
603
610
  /**
604
611
  * @hidden
605
612
  *
@@ -346,3 +346,29 @@ export const isJapanese = (input) => {
346
346
  const japaneseRegex = /[\u3000-\u303F]|[\u3040-\u309F]|[\u30A0-\u30FF]|[\uFF00-\uFFEF]|[\u4E00-\u9FAF]|[\u2605-\u2606]|[\u2190-\u2195]|\u203B/g;
347
347
  return japaneseRegex.test(input);
348
348
  };
349
+ /**
350
+ * @hidden
351
+ */
352
+ export const isLetter = (text) => {
353
+ const isLetter = /[a-zA-Z]/;
354
+ return isLetter.test(text) && text?.length === 1;
355
+ };
356
+ /**
357
+ * @hidden
358
+ */
359
+ export const getTextField = (field, level) => {
360
+ if (isArray(field)) {
361
+ return field[level];
362
+ }
363
+ return field;
364
+ };
365
+ /**
366
+ * @hidden
367
+ */
368
+ export const getSearchableItems = (popupId, popupElement) => {
369
+ const nodeSeletor = `kendo-popup[id='${popupId}'] li.k-treeview-item`;
370
+ const liElements = Array.from(popupElement.querySelectorAll(nodeSeletor));
371
+ return liElements.map((liElement) => {
372
+ return { text: liElement.innerText, index: liElement.getAttribute('data-treeindex') };
373
+ });
374
+ };
@@ -14,10 +14,10 @@ import { NavigationService } from '../common/navigation/navigation.service';
14
14
  import { L10N_PREFIX, LocalizationService } from '@progress/kendo-angular-l10n';
15
15
  import { SelectionService } from '../common/selection/selection.service';
16
16
  import { PreventableEvent } from '../common/models/preventable-event';
17
- import { getFillModeClass, getRoundedClass, getSizeClass, inDropDown, isArray, isPresent, isUntouched, noop } from '../common/util';
17
+ import { getFillModeClass, getRoundedClass, getSearchableItems, getSizeClass, inDropDown, isArray, isLetter, isPresent, isUntouched, noop } from '../common/util';
18
18
  import { NoDataTemplateDirective } from '../common/templates/no-data-template.directive';
19
- import { of } from 'rxjs';
20
- import { tap } from 'rxjs/operators';
19
+ import { of, Subject, Subscription } from 'rxjs';
20
+ import { debounceTime, tap } from 'rxjs/operators';
21
21
  import { HeaderTemplateDirective } from '../common/templates/header-template.directive';
22
22
  import { FooterTemplateDirective } from '../common/templates/footer-template.directive';
23
23
  import { NodeTemplateDirective } from './templates/node-template.directive';
@@ -212,7 +212,10 @@ export class DropDownTreeComponent {
212
212
  this._size = 'medium';
213
213
  this._rounded = 'medium';
214
214
  this._fillMode = 'solid';
215
- this.subscriptions = [];
215
+ this._searchableNodes = [];
216
+ this._typedValue = '';
217
+ this.printableCharacters = new Subject();
218
+ this.subs = new Subscription();
216
219
  this.onTouchedCallback = noop;
217
220
  this.onChangeCallback = noop;
218
221
  this.direction = localization.rtl ? 'rtl' : 'ltr';
@@ -266,6 +269,9 @@ export class DropDownTreeComponent {
266
269
  if (this.disabled || this.readonly) {
267
270
  return;
268
271
  }
272
+ if (isLetter(event.key)) {
273
+ this.printableCharacters.next(event.key);
274
+ }
269
275
  const eventData = event;
270
276
  this.navigationService.process({
271
277
  originalEvent: eventData
@@ -515,9 +521,20 @@ export class DropDownTreeComponent {
515
521
  return ngControl?.control || null;
516
522
  }
517
523
  ngOnInit() {
524
+ this.subs.add(this.printableCharacters.pipe(tap((char) => {
525
+ this._typedValue += char;
526
+ const itemToFocus = this._searchableNodes.find((node) => {
527
+ return node.text.toLowerCase().indexOf(this._typedValue) === 0;
528
+ });
529
+ this.treeview.focus(itemToFocus?.index);
530
+ const htmlItem = document.querySelector(`kendo-popup[id='${this._popupId}'] li.k-treeview-item[data-treeindex='${itemToFocus?.index}']`);
531
+ htmlItem?.scrollIntoView();
532
+ }), debounceTime(1000)).subscribe(() => {
533
+ this._typedValue = '';
534
+ }));
518
535
  this.renderer.removeAttribute(this.wrapper.nativeElement, 'tabindex');
519
536
  this.assignAriaDescribedBy();
520
- this.subscriptions.push(this.localization
537
+ this.subs.add(this.localization
521
538
  .changes.subscribe(({ rtl }) => {
522
539
  this.direction = rtl ? 'rtl' : 'ltr';
523
540
  this.cdr.markForCheck();
@@ -816,6 +833,16 @@ export class DropDownTreeComponent {
816
833
  }
817
834
  return null;
818
835
  }
836
+ /**
837
+ * @hidden
838
+ */
839
+ onChildrenLoaded() {
840
+ setTimeout(() => {
841
+ if (this.popupRef) {
842
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
843
+ }
844
+ });
845
+ }
819
846
  /**
820
847
  * @hidden
821
848
  *
@@ -872,6 +899,7 @@ export class DropDownTreeComponent {
872
899
  this.popupRef.popupOpen.subscribe(() => {
873
900
  this.cdr.detectChanges();
874
901
  this.opened.emit();
902
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
875
903
  });
876
904
  this.popupRef.popupClose.subscribe(() => {
877
905
  this.closed.emit();
@@ -913,33 +941,41 @@ export class DropDownTreeComponent {
913
941
  this.selectedKeys = [];
914
942
  }
915
943
  subscribeEvents() {
916
- this.subscriptions.push(this.navigationService.open.subscribe((event) => {
917
- event.originalEvent.preventDefault();
918
- this.togglePopup(true);
919
- }), this.navigationService.close.subscribe((event) => {
920
- event.originalEvent.preventDefault();
921
- this.togglePopup(false);
922
- this.focus();
923
- }), this.navigationService.enter
924
- .pipe(tap((event) => event.originalEvent.preventDefault()))
925
- .subscribe(() => this.togglePopup(true)), this.navigationService.esc
926
- .subscribe(() => this.handleEscape()), this.navigationService.tab.subscribe(() => this.focus()), this.navigationService.down.subscribe((event) => {
927
- if (!this.treeview) {
928
- return;
929
- }
930
- event.originalEvent.preventDefault();
931
- if (!this.treeview.isActive) {
932
- this.treeview.focus();
933
- }
934
- }), this.navigationService.up.subscribe((event) => {
935
- if (!this.treeview) {
936
- return;
937
- }
938
- event.originalEvent.preventDefault();
939
- if (this.filterable && this.treeview['navigationService']['activeIndex'] === '0') {
940
- this.filterInput.nativeElement.focus();
941
- }
942
- }));
944
+ [
945
+ this.navigationService.open.subscribe((event) => {
946
+ event.originalEvent.preventDefault();
947
+ this.togglePopup(true);
948
+ }),
949
+ this.navigationService.close.subscribe((event) => {
950
+ event.originalEvent.preventDefault();
951
+ this.togglePopup(false);
952
+ this.focus();
953
+ }),
954
+ this.navigationService.enter
955
+ .pipe(tap((event) => event.originalEvent.preventDefault()))
956
+ .subscribe(() => this.togglePopup(true)),
957
+ this.navigationService.esc
958
+ .subscribe(() => this.handleEscape()),
959
+ this.navigationService.tab.subscribe(() => this.focus()),
960
+ this.navigationService.down.subscribe((event) => {
961
+ if (!this.treeview) {
962
+ return;
963
+ }
964
+ event.originalEvent.preventDefault();
965
+ if (!this.treeview.isActive) {
966
+ this.treeview.focus();
967
+ }
968
+ }),
969
+ this.navigationService.up.subscribe((event) => {
970
+ if (!this.treeview) {
971
+ return;
972
+ }
973
+ event.originalEvent.preventDefault();
974
+ if (this.filterable && this.treeview['navigationService']['activeIndex'] === '0') {
975
+ this.filterInput.nativeElement.focus();
976
+ }
977
+ })
978
+ ].forEach(sub => this.subs.add(sub));
943
979
  }
944
980
  subscribeTouchEvents() {
945
981
  if (!isDocumentAvailable() || !this.touchEnabled) {
@@ -978,7 +1014,7 @@ export class DropDownTreeComponent {
978
1014
  }
979
1015
  }
980
1016
  unsubscribeEvents() {
981
- this.subscriptions.forEach(sub => sub.unsubscribe());
1017
+ this.subs.unsubscribe();
982
1018
  this.unSubscribeFocusEvents();
983
1019
  if (this.touchstartDisposeHandler) {
984
1020
  this.touchstartDisposeHandler();
@@ -1163,6 +1199,7 @@ DropDownTreeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
1163
1199
  (selectionChange)="onSelectionChange($event)"
1164
1200
  (expand)="nodeExpand.emit($event)"
1165
1201
  (collapse)="nodeCollapse.emit($event)"
1202
+ (childrenLoaded)="onChildrenLoaded()"
1166
1203
  >
1167
1204
  </kendo-treeview>
1168
1205
  <!--footer template-->
@@ -1345,6 +1382,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1345
1382
  (selectionChange)="onSelectionChange($event)"
1346
1383
  (expand)="nodeExpand.emit($event)"
1347
1384
  (collapse)="nodeCollapse.emit($event)"
1385
+ (childrenLoaded)="onChildrenLoaded()"
1348
1386
  >
1349
1387
  </kendo-treeview>
1350
1388
  <!--footer template-->
@@ -16,7 +16,7 @@ import { PreventableEvent } from '../common/models/preventable-event';
16
16
  import { NavigationAction } from '../common/navigation/navigation-action';
17
17
  import { RemoveTagEvent } from '../common/models/remove-tag-event';
18
18
  import { MultiSelectTreeMessages } from '../common/constants/error-messages';
19
- import { fetchDescendentNodes, getFillModeClass, getRoundedClass, getSizeClass, hasProps, isArray, isObject, isObjectArray, isPresent, isUntouched, noop, parseNumber, valueFrom } from '../common/util';
19
+ import { fetchDescendentNodes, getFillModeClass, getRoundedClass, getSearchableItems, getSizeClass, hasProps, isArray, isLetter, isObject, isObjectArray, isPresent, isUntouched, noop, parseNumber, valueFrom } from '../common/util';
20
20
  import { HeaderTemplateDirective } from '../common/templates/header-template.directive';
21
21
  import { FooterTemplateDirective } from '../common/templates/footer-template.directive';
22
22
  import { NodeTemplateDirective } from './templates/node-template.directive';
@@ -24,8 +24,8 @@ import { NoDataTemplateDirective } from '../common/templates/no-data-template.di
24
24
  import { TagTemplateDirective } from '../common/templates/tag-template.directive';
25
25
  import { GroupTagTemplateDirective } from '../common/templates/group-tag-template.directive';
26
26
  import { TOUCH_ENABLED } from '../common/constants/touch-enabled';
27
- import { merge, of } from 'rxjs';
28
- import { filter, tap } from 'rxjs/operators';
27
+ import { merge, of, Subject, Subscription } from 'rxjs';
28
+ import { debounceTime, filter, tap } from 'rxjs/operators';
29
29
  import { buildTreeItem, MultiSelectTreeLookupService, nodeIndex } from './lookup/lookup.service';
30
30
  import { searchIcon, xIcon } from '@progress/kendo-svg-icons';
31
31
  import * as i0 from "@angular/core";
@@ -241,7 +241,10 @@ export class MultiSelectTreeComponent {
241
241
  this._size = 'medium';
242
242
  this._rounded = 'medium';
243
243
  this._fillMode = 'solid';
244
- this.subscriptions = [];
244
+ this._searchableNodes = [];
245
+ this._typedValue = '';
246
+ this.printableCharacters = new Subject();
247
+ this.subs = new Subscription();
245
248
  this.lastAction = 'check';
246
249
  this.onTouchedCallback = noop;
247
250
  this.onChangeCallback = noop;
@@ -310,6 +313,9 @@ export class MultiSelectTreeComponent {
310
313
  if (this.disabled || this.readonly) {
311
314
  return;
312
315
  }
316
+ if (isLetter(event.key)) {
317
+ this.printableCharacters.next(event.key);
318
+ }
313
319
  const eventData = event;
314
320
  const action = this.navigationService.process({
315
321
  originalEvent: eventData
@@ -640,9 +646,20 @@ export class MultiSelectTreeComponent {
640
646
  return this.checkAllInput && document.activeElement === this.checkAllInput.nativeElement;
641
647
  }
642
648
  ngOnInit() {
649
+ this.subs.add(this.printableCharacters.pipe(tap((char) => {
650
+ this._typedValue += char;
651
+ const itemToFocus = this._searchableNodes.find((node) => {
652
+ return node.text.toLowerCase().indexOf(this._typedValue) === 0;
653
+ });
654
+ this.treeview.focus(itemToFocus?.index);
655
+ const htmlItem = document.querySelector(`kendo-popup[id='${this._popupId}'] li.k-treeview-item[data-treeindex='${itemToFocus?.index}']`);
656
+ htmlItem?.scrollIntoView();
657
+ }), debounceTime(1000)).subscribe(() => {
658
+ this._typedValue = '';
659
+ }));
643
660
  this.renderer.removeAttribute(this.wrapper.nativeElement, 'tabindex');
644
661
  this.renderer.setAttribute(this.wrapper.nativeElement, 'aria-expanded', String(this.isOpen));
645
- this.subscriptions.push(this.localization
662
+ this.subs.add(this.localization
646
663
  .changes.subscribe(({ rtl }) => {
647
664
  this.direction = rtl ? 'rtl' : 'ltr';
648
665
  this.cdr.markForCheck();
@@ -1049,9 +1066,11 @@ export class MultiSelectTreeComponent {
1049
1066
  popupWrapper.style.height = this.height;
1050
1067
  this.renderer.setAttribute(popupWrapper, 'dir', this.direction);
1051
1068
  this.renderer.setAttribute(this.wrapper.nativeElement, 'aria-expanded', 'true');
1069
+ this.renderer.setAttribute(popupWrapper, 'id', this._popupId);
1052
1070
  this.popupRef.popupOpen.subscribe(() => {
1053
1071
  this.cdr.detectChanges();
1054
1072
  this.opened.emit();
1073
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
1055
1074
  });
1056
1075
  this.popupRef.popupClose.subscribe(() => {
1057
1076
  this.closed.emit();
@@ -1074,20 +1093,33 @@ export class MultiSelectTreeComponent {
1074
1093
  }
1075
1094
  }
1076
1095
  subscribeEvents() {
1077
- this.subscriptions.push(this.navigationService.open.subscribe((event) => {
1078
- event.originalEvent.preventDefault();
1079
- this.togglePopup(true);
1080
- }), this.navigationService.enter
1081
- .pipe(tap((event) => event.originalEvent.preventDefault()))
1082
- .subscribe(() => this.togglePopup(true)), merge(this.navigationService.close, this.navigationService.esc).subscribe((event) => {
1083
- event.originalEvent.preventDefault();
1084
- this.focus();
1085
- this.togglePopup(false);
1086
- }), this.navigationService.tab.subscribe(this.handleTabKey.bind(this)), this.navigationService.up.subscribe(this.handleUpKey.bind(this)), this.navigationService.down.subscribe(this.handleDownKey.bind(this)), this.navigationService.left
1087
- .pipe(filter(() => !this.isTreeViewActive))
1088
- .subscribe(this.direction === 'rtl' ? this.handleRightKey.bind(this) : this.handleLeftKey.bind(this)), this.navigationService.right
1089
- .pipe(filter(() => !this.isTreeViewActive))
1090
- .subscribe(this.direction === 'rtl' ? this.handleLeftKey.bind(this) : this.handleRightKey.bind(this)), this.navigationService.home.pipe(filter(() => !this.isOpen)).subscribe(this.handleHome.bind(this)), this.navigationService.end.pipe(filter(() => !this.isOpen)).subscribe(this.handleEnd.bind(this)), this.navigationService.backspace.pipe(filter(() => this.isTagFocused)).subscribe(this.handleBackspace.bind(this)), this.navigationService.delete.pipe(filter(() => this.isTagFocused)).subscribe(this.handleDelete.bind(this)));
1096
+ [
1097
+ this.navigationService.open.subscribe((event) => {
1098
+ event.originalEvent.preventDefault();
1099
+ this.togglePopup(true);
1100
+ }),
1101
+ this.navigationService.enter
1102
+ .pipe(tap((event) => event.originalEvent.preventDefault()))
1103
+ .subscribe(() => this.togglePopup(true)),
1104
+ merge(this.navigationService.close, this.navigationService.esc).subscribe((event) => {
1105
+ event.originalEvent.preventDefault();
1106
+ this.focus();
1107
+ this.togglePopup(false);
1108
+ }),
1109
+ this.navigationService.tab.subscribe(this.handleTabKey.bind(this)),
1110
+ this.navigationService.up.subscribe(this.handleUpKey.bind(this)),
1111
+ this.navigationService.down.subscribe(this.handleDownKey.bind(this)),
1112
+ this.navigationService.left
1113
+ .pipe(filter(() => !this.isTreeViewActive))
1114
+ .subscribe(this.direction === 'rtl' ? this.handleRightKey.bind(this) : this.handleLeftKey.bind(this)),
1115
+ this.navigationService.right
1116
+ .pipe(filter(() => !this.isTreeViewActive))
1117
+ .subscribe(this.direction === 'rtl' ? this.handleLeftKey.bind(this) : this.handleRightKey.bind(this)),
1118
+ this.navigationService.home.pipe(filter(() => !this.isOpen)).subscribe(this.handleHome.bind(this)),
1119
+ this.navigationService.end.pipe(filter(() => !this.isOpen)).subscribe(this.handleEnd.bind(this)),
1120
+ this.navigationService.backspace.pipe(filter(() => this.isTagFocused)).subscribe(this.handleBackspace.bind(this)),
1121
+ this.navigationService.delete.pipe(filter(() => this.isTagFocused)).subscribe(this.handleDelete.bind(this))
1122
+ ].forEach(sub => this.subs.add(sub));
1091
1123
  }
1092
1124
  subscribeFocusEvents() {
1093
1125
  if (isDocumentAvailable()) {
@@ -1218,7 +1250,7 @@ export class MultiSelectTreeComponent {
1218
1250
  }
1219
1251
  }
1220
1252
  unsubscribeEvents() {
1221
- this.subscriptions.forEach(sub => sub.unsubscribe());
1253
+ this.subs.unsubscribe();
1222
1254
  this.unSubscribeFocusEvents();
1223
1255
  }
1224
1256
  /**
@@ -1253,6 +1285,16 @@ export class MultiSelectTreeComponent {
1253
1285
  this.value = newValue;
1254
1286
  this.emitValueChange(this.value);
1255
1287
  }
1288
+ /**
1289
+ * @hidden
1290
+ */
1291
+ onChildrenLoaded() {
1292
+ setTimeout(() => {
1293
+ if (this.popupRef) {
1294
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
1295
+ }
1296
+ });
1297
+ }
1256
1298
  /**
1257
1299
  * @hidden
1258
1300
  *
@@ -1503,6 +1545,7 @@ MultiSelectTreeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0
1503
1545
  focusout: handleBlur
1504
1546
  }"
1505
1547
  [scope]="this"
1548
+ (childrenLoaded)="onChildrenLoaded()"
1506
1549
  >
1507
1550
  </kendo-treeview>
1508
1551
  <!--footer template-->
@@ -1718,6 +1761,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
1718
1761
  focusout: handleBlur
1719
1762
  }"
1720
1763
  [scope]="this"
1764
+ (childrenLoaded)="onChildrenLoaded()"
1721
1765
  >
1722
1766
  </kendo-treeview>
1723
1767
  <!--footer template-->
@@ -9,7 +9,7 @@ export const packageMetadata = {
9
9
  name: '@progress/kendo-angular-dropdowns',
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
12
- publishDate: 1673265672,
12
+ publishDate: 1673372510,
13
13
  version: '',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
15
15
  };
@@ -19,7 +19,7 @@ import { PopupModule } from '@progress/kendo-angular-popup';
19
19
  export { PopupComponent } from '@progress/kendo-angular-popup';
20
20
  import * as i8 from '@progress/kendo-angular-icons';
21
21
  import { IconsModule } from '@progress/kendo-angular-icons';
22
- import { map, switchMap, take, auditTime, tap, filter, partition, throttleTime, catchError, skipWhile, concatMap, takeUntil } from 'rxjs/operators';
22
+ import { map, switchMap, take, auditTime, tap, filter, partition, throttleTime, catchError, skipWhile, concatMap, takeUntil, debounceTime } from 'rxjs/operators';
23
23
  import * as i12 from '@angular/common';
24
24
  import { CommonModule } from '@angular/common';
25
25
  import * as i1$1 from '@progress/kendo-angular-treeview';
@@ -32,7 +32,7 @@ const packageMetadata = {
32
32
  name: '@progress/kendo-angular-dropdowns',
33
33
  productName: 'Kendo UI for Angular',
34
34
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
35
- publishDate: 1673265672,
35
+ publishDate: 1673372510,
36
36
  version: '',
37
37
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
38
38
  };
@@ -379,6 +379,32 @@ const isJapanese = (input) => {
379
379
  const japaneseRegex = /[\u3000-\u303F]|[\u3040-\u309F]|[\u30A0-\u30FF]|[\uFF00-\uFFEF]|[\u4E00-\u9FAF]|[\u2605-\u2606]|[\u2190-\u2195]|\u203B/g;
380
380
  return japaneseRegex.test(input);
381
381
  };
382
+ /**
383
+ * @hidden
384
+ */
385
+ const isLetter = (text) => {
386
+ const isLetter = /[a-zA-Z]/;
387
+ return isLetter.test(text) && (text === null || text === void 0 ? void 0 : text.length) === 1;
388
+ };
389
+ /**
390
+ * @hidden
391
+ */
392
+ const getTextField = (field, level) => {
393
+ if (isArray(field)) {
394
+ return field[level];
395
+ }
396
+ return field;
397
+ };
398
+ /**
399
+ * @hidden
400
+ */
401
+ const getSearchableItems = (popupId, popupElement) => {
402
+ const nodeSeletor = `kendo-popup[id='${popupId}'] li.k-treeview-item`;
403
+ const liElements = Array.from(popupElement.querySelectorAll(nodeSeletor));
404
+ return liElements.map((liElement) => {
405
+ return { text: liElement.innerText, index: liElement.getAttribute('data-treeindex') };
406
+ });
407
+ };
382
408
 
383
409
  /**
384
410
  * @hidden
@@ -10437,7 +10463,10 @@ class DropDownTreeComponent {
10437
10463
  this._size = 'medium';
10438
10464
  this._rounded = 'medium';
10439
10465
  this._fillMode = 'solid';
10440
- this.subscriptions = [];
10466
+ this._searchableNodes = [];
10467
+ this._typedValue = '';
10468
+ this.printableCharacters = new Subject();
10469
+ this.subs = new Subscription();
10441
10470
  this.onTouchedCallback = noop;
10442
10471
  this.onChangeCallback = noop;
10443
10472
  this.direction = localization.rtl ? 'rtl' : 'ltr';
@@ -10491,6 +10520,9 @@ class DropDownTreeComponent {
10491
10520
  if (this.disabled || this.readonly) {
10492
10521
  return;
10493
10522
  }
10523
+ if (isLetter(event.key)) {
10524
+ this.printableCharacters.next(event.key);
10525
+ }
10494
10526
  const eventData = event;
10495
10527
  this.navigationService.process({
10496
10528
  originalEvent: eventData
@@ -10740,9 +10772,20 @@ class DropDownTreeComponent {
10740
10772
  return (ngControl === null || ngControl === void 0 ? void 0 : ngControl.control) || null;
10741
10773
  }
10742
10774
  ngOnInit() {
10775
+ this.subs.add(this.printableCharacters.pipe(tap((char) => {
10776
+ this._typedValue += char;
10777
+ const itemToFocus = this._searchableNodes.find((node) => {
10778
+ return node.text.toLowerCase().indexOf(this._typedValue) === 0;
10779
+ });
10780
+ this.treeview.focus(itemToFocus === null || itemToFocus === void 0 ? void 0 : itemToFocus.index);
10781
+ const htmlItem = document.querySelector(`kendo-popup[id='${this._popupId}'] li.k-treeview-item[data-treeindex='${itemToFocus === null || itemToFocus === void 0 ? void 0 : itemToFocus.index}']`);
10782
+ htmlItem === null || htmlItem === void 0 ? void 0 : htmlItem.scrollIntoView();
10783
+ }), debounceTime(1000)).subscribe(() => {
10784
+ this._typedValue = '';
10785
+ }));
10743
10786
  this.renderer.removeAttribute(this.wrapper.nativeElement, 'tabindex');
10744
10787
  this.assignAriaDescribedBy();
10745
- this.subscriptions.push(this.localization
10788
+ this.subs.add(this.localization
10746
10789
  .changes.subscribe(({ rtl }) => {
10747
10790
  this.direction = rtl ? 'rtl' : 'ltr';
10748
10791
  this.cdr.markForCheck();
@@ -11041,6 +11084,16 @@ class DropDownTreeComponent {
11041
11084
  }
11042
11085
  return null;
11043
11086
  }
11087
+ /**
11088
+ * @hidden
11089
+ */
11090
+ onChildrenLoaded() {
11091
+ setTimeout(() => {
11092
+ if (this.popupRef) {
11093
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
11094
+ }
11095
+ });
11096
+ }
11044
11097
  /**
11045
11098
  * @hidden
11046
11099
  *
@@ -11097,6 +11150,7 @@ class DropDownTreeComponent {
11097
11150
  this.popupRef.popupOpen.subscribe(() => {
11098
11151
  this.cdr.detectChanges();
11099
11152
  this.opened.emit();
11153
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
11100
11154
  });
11101
11155
  this.popupRef.popupClose.subscribe(() => {
11102
11156
  this.closed.emit();
@@ -11138,33 +11192,41 @@ class DropDownTreeComponent {
11138
11192
  this.selectedKeys = [];
11139
11193
  }
11140
11194
  subscribeEvents() {
11141
- this.subscriptions.push(this.navigationService.open.subscribe((event) => {
11142
- event.originalEvent.preventDefault();
11143
- this.togglePopup(true);
11144
- }), this.navigationService.close.subscribe((event) => {
11145
- event.originalEvent.preventDefault();
11146
- this.togglePopup(false);
11147
- this.focus();
11148
- }), this.navigationService.enter
11149
- .pipe(tap((event) => event.originalEvent.preventDefault()))
11150
- .subscribe(() => this.togglePopup(true)), this.navigationService.esc
11151
- .subscribe(() => this.handleEscape()), this.navigationService.tab.subscribe(() => this.focus()), this.navigationService.down.subscribe((event) => {
11152
- if (!this.treeview) {
11153
- return;
11154
- }
11155
- event.originalEvent.preventDefault();
11156
- if (!this.treeview.isActive) {
11157
- this.treeview.focus();
11158
- }
11159
- }), this.navigationService.up.subscribe((event) => {
11160
- if (!this.treeview) {
11161
- return;
11162
- }
11163
- event.originalEvent.preventDefault();
11164
- if (this.filterable && this.treeview['navigationService']['activeIndex'] === '0') {
11165
- this.filterInput.nativeElement.focus();
11166
- }
11167
- }));
11195
+ [
11196
+ this.navigationService.open.subscribe((event) => {
11197
+ event.originalEvent.preventDefault();
11198
+ this.togglePopup(true);
11199
+ }),
11200
+ this.navigationService.close.subscribe((event) => {
11201
+ event.originalEvent.preventDefault();
11202
+ this.togglePopup(false);
11203
+ this.focus();
11204
+ }),
11205
+ this.navigationService.enter
11206
+ .pipe(tap((event) => event.originalEvent.preventDefault()))
11207
+ .subscribe(() => this.togglePopup(true)),
11208
+ this.navigationService.esc
11209
+ .subscribe(() => this.handleEscape()),
11210
+ this.navigationService.tab.subscribe(() => this.focus()),
11211
+ this.navigationService.down.subscribe((event) => {
11212
+ if (!this.treeview) {
11213
+ return;
11214
+ }
11215
+ event.originalEvent.preventDefault();
11216
+ if (!this.treeview.isActive) {
11217
+ this.treeview.focus();
11218
+ }
11219
+ }),
11220
+ this.navigationService.up.subscribe((event) => {
11221
+ if (!this.treeview) {
11222
+ return;
11223
+ }
11224
+ event.originalEvent.preventDefault();
11225
+ if (this.filterable && this.treeview['navigationService']['activeIndex'] === '0') {
11226
+ this.filterInput.nativeElement.focus();
11227
+ }
11228
+ })
11229
+ ].forEach(sub => this.subs.add(sub));
11168
11230
  }
11169
11231
  subscribeTouchEvents() {
11170
11232
  if (!isDocumentAvailable() || !this.touchEnabled) {
@@ -11203,7 +11265,7 @@ class DropDownTreeComponent {
11203
11265
  }
11204
11266
  }
11205
11267
  unsubscribeEvents() {
11206
- this.subscriptions.forEach(sub => sub.unsubscribe());
11268
+ this.subs.unsubscribe();
11207
11269
  this.unSubscribeFocusEvents();
11208
11270
  if (this.touchstartDisposeHandler) {
11209
11271
  this.touchstartDisposeHandler();
@@ -11388,6 +11450,7 @@ DropDownTreeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
11388
11450
  (selectionChange)="onSelectionChange($event)"
11389
11451
  (expand)="nodeExpand.emit($event)"
11390
11452
  (collapse)="nodeCollapse.emit($event)"
11453
+ (childrenLoaded)="onChildrenLoaded()"
11391
11454
  >
11392
11455
  </kendo-treeview>
11393
11456
  <!--footer template-->
@@ -11570,6 +11633,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
11570
11633
  (selectionChange)="onSelectionChange($event)"
11571
11634
  (expand)="nodeExpand.emit($event)"
11572
11635
  (collapse)="nodeCollapse.emit($event)"
11636
+ (childrenLoaded)="onChildrenLoaded()"
11573
11637
  >
11574
11638
  </kendo-treeview>
11575
11639
  <!--footer template-->
@@ -12386,7 +12450,10 @@ class MultiSelectTreeComponent {
12386
12450
  this._size = 'medium';
12387
12451
  this._rounded = 'medium';
12388
12452
  this._fillMode = 'solid';
12389
- this.subscriptions = [];
12453
+ this._searchableNodes = [];
12454
+ this._typedValue = '';
12455
+ this.printableCharacters = new Subject();
12456
+ this.subs = new Subscription();
12390
12457
  this.lastAction = 'check';
12391
12458
  this.onTouchedCallback = noop;
12392
12459
  this.onChangeCallback = noop;
@@ -12456,6 +12523,9 @@ class MultiSelectTreeComponent {
12456
12523
  if (this.disabled || this.readonly) {
12457
12524
  return;
12458
12525
  }
12526
+ if (isLetter(event.key)) {
12527
+ this.printableCharacters.next(event.key);
12528
+ }
12459
12529
  const eventData = event;
12460
12530
  const action = this.navigationService.process({
12461
12531
  originalEvent: eventData
@@ -12786,9 +12856,20 @@ class MultiSelectTreeComponent {
12786
12856
  return this.checkAllInput && document.activeElement === this.checkAllInput.nativeElement;
12787
12857
  }
12788
12858
  ngOnInit() {
12859
+ this.subs.add(this.printableCharacters.pipe(tap((char) => {
12860
+ this._typedValue += char;
12861
+ const itemToFocus = this._searchableNodes.find((node) => {
12862
+ return node.text.toLowerCase().indexOf(this._typedValue) === 0;
12863
+ });
12864
+ this.treeview.focus(itemToFocus === null || itemToFocus === void 0 ? void 0 : itemToFocus.index);
12865
+ const htmlItem = document.querySelector(`kendo-popup[id='${this._popupId}'] li.k-treeview-item[data-treeindex='${itemToFocus === null || itemToFocus === void 0 ? void 0 : itemToFocus.index}']`);
12866
+ htmlItem === null || htmlItem === void 0 ? void 0 : htmlItem.scrollIntoView();
12867
+ }), debounceTime(1000)).subscribe(() => {
12868
+ this._typedValue = '';
12869
+ }));
12789
12870
  this.renderer.removeAttribute(this.wrapper.nativeElement, 'tabindex');
12790
12871
  this.renderer.setAttribute(this.wrapper.nativeElement, 'aria-expanded', String(this.isOpen));
12791
- this.subscriptions.push(this.localization
12872
+ this.subs.add(this.localization
12792
12873
  .changes.subscribe(({ rtl }) => {
12793
12874
  this.direction = rtl ? 'rtl' : 'ltr';
12794
12875
  this.cdr.markForCheck();
@@ -13191,9 +13272,11 @@ class MultiSelectTreeComponent {
13191
13272
  popupWrapper.style.height = this.height;
13192
13273
  this.renderer.setAttribute(popupWrapper, 'dir', this.direction);
13193
13274
  this.renderer.setAttribute(this.wrapper.nativeElement, 'aria-expanded', 'true');
13275
+ this.renderer.setAttribute(popupWrapper, 'id', this._popupId);
13194
13276
  this.popupRef.popupOpen.subscribe(() => {
13195
13277
  this.cdr.detectChanges();
13196
13278
  this.opened.emit();
13279
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
13197
13280
  });
13198
13281
  this.popupRef.popupClose.subscribe(() => {
13199
13282
  this.closed.emit();
@@ -13216,20 +13299,33 @@ class MultiSelectTreeComponent {
13216
13299
  }
13217
13300
  }
13218
13301
  subscribeEvents() {
13219
- this.subscriptions.push(this.navigationService.open.subscribe((event) => {
13220
- event.originalEvent.preventDefault();
13221
- this.togglePopup(true);
13222
- }), this.navigationService.enter
13223
- .pipe(tap((event) => event.originalEvent.preventDefault()))
13224
- .subscribe(() => this.togglePopup(true)), merge(this.navigationService.close, this.navigationService.esc).subscribe((event) => {
13225
- event.originalEvent.preventDefault();
13226
- this.focus();
13227
- this.togglePopup(false);
13228
- }), this.navigationService.tab.subscribe(this.handleTabKey.bind(this)), this.navigationService.up.subscribe(this.handleUpKey.bind(this)), this.navigationService.down.subscribe(this.handleDownKey.bind(this)), this.navigationService.left
13229
- .pipe(filter(() => !this.isTreeViewActive))
13230
- .subscribe(this.direction === 'rtl' ? this.handleRightKey.bind(this) : this.handleLeftKey.bind(this)), this.navigationService.right
13231
- .pipe(filter(() => !this.isTreeViewActive))
13232
- .subscribe(this.direction === 'rtl' ? this.handleLeftKey.bind(this) : this.handleRightKey.bind(this)), this.navigationService.home.pipe(filter(() => !this.isOpen)).subscribe(this.handleHome.bind(this)), this.navigationService.end.pipe(filter(() => !this.isOpen)).subscribe(this.handleEnd.bind(this)), this.navigationService.backspace.pipe(filter(() => this.isTagFocused)).subscribe(this.handleBackspace.bind(this)), this.navigationService.delete.pipe(filter(() => this.isTagFocused)).subscribe(this.handleDelete.bind(this)));
13302
+ [
13303
+ this.navigationService.open.subscribe((event) => {
13304
+ event.originalEvent.preventDefault();
13305
+ this.togglePopup(true);
13306
+ }),
13307
+ this.navigationService.enter
13308
+ .pipe(tap((event) => event.originalEvent.preventDefault()))
13309
+ .subscribe(() => this.togglePopup(true)),
13310
+ merge(this.navigationService.close, this.navigationService.esc).subscribe((event) => {
13311
+ event.originalEvent.preventDefault();
13312
+ this.focus();
13313
+ this.togglePopup(false);
13314
+ }),
13315
+ this.navigationService.tab.subscribe(this.handleTabKey.bind(this)),
13316
+ this.navigationService.up.subscribe(this.handleUpKey.bind(this)),
13317
+ this.navigationService.down.subscribe(this.handleDownKey.bind(this)),
13318
+ this.navigationService.left
13319
+ .pipe(filter(() => !this.isTreeViewActive))
13320
+ .subscribe(this.direction === 'rtl' ? this.handleRightKey.bind(this) : this.handleLeftKey.bind(this)),
13321
+ this.navigationService.right
13322
+ .pipe(filter(() => !this.isTreeViewActive))
13323
+ .subscribe(this.direction === 'rtl' ? this.handleLeftKey.bind(this) : this.handleRightKey.bind(this)),
13324
+ this.navigationService.home.pipe(filter(() => !this.isOpen)).subscribe(this.handleHome.bind(this)),
13325
+ this.navigationService.end.pipe(filter(() => !this.isOpen)).subscribe(this.handleEnd.bind(this)),
13326
+ this.navigationService.backspace.pipe(filter(() => this.isTagFocused)).subscribe(this.handleBackspace.bind(this)),
13327
+ this.navigationService.delete.pipe(filter(() => this.isTagFocused)).subscribe(this.handleDelete.bind(this))
13328
+ ].forEach(sub => this.subs.add(sub));
13233
13329
  }
13234
13330
  subscribeFocusEvents() {
13235
13331
  if (isDocumentAvailable()) {
@@ -13360,7 +13456,7 @@ class MultiSelectTreeComponent {
13360
13456
  }
13361
13457
  }
13362
13458
  unsubscribeEvents() {
13363
- this.subscriptions.forEach(sub => sub.unsubscribe());
13459
+ this.subs.unsubscribe();
13364
13460
  this.unSubscribeFocusEvents();
13365
13461
  }
13366
13462
  /**
@@ -13395,6 +13491,16 @@ class MultiSelectTreeComponent {
13395
13491
  this.value = newValue;
13396
13492
  this.emitValueChange(this.value);
13397
13493
  }
13494
+ /**
13495
+ * @hidden
13496
+ */
13497
+ onChildrenLoaded() {
13498
+ setTimeout(() => {
13499
+ if (this.popupRef) {
13500
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
13501
+ }
13502
+ });
13503
+ }
13398
13504
  /**
13399
13505
  * @hidden
13400
13506
  *
@@ -13645,6 +13751,7 @@ MultiSelectTreeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0
13645
13751
  focusout: handleBlur
13646
13752
  }"
13647
13753
  [scope]="this"
13754
+ (childrenLoaded)="onChildrenLoaded()"
13648
13755
  >
13649
13756
  </kendo-treeview>
13650
13757
  <!--footer template-->
@@ -13860,6 +13967,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
13860
13967
  focusout: handleBlur
13861
13968
  }"
13862
13969
  [scope]="this"
13970
+ (childrenLoaded)="onChildrenLoaded()"
13863
13971
  >
13864
13972
  </kendo-treeview>
13865
13973
  <!--footer template-->
@@ -16,7 +16,7 @@ import { Subscription, merge, fromEvent, Subject, of, interval } from 'rxjs';
16
16
  import * as i2 from '@progress/kendo-angular-popup';
17
17
  import { PopupModule } from '@progress/kendo-angular-popup';
18
18
  export { PopupComponent } from '@progress/kendo-angular-popup';
19
- import { map, switchMap, take, auditTime, tap, filter, partition, throttleTime, catchError, skipWhile, concatMap, takeUntil } from 'rxjs/operators';
19
+ import { map, switchMap, take, auditTime, tap, filter, partition, throttleTime, catchError, skipWhile, concatMap, takeUntil, debounceTime } from 'rxjs/operators';
20
20
  import * as i12 from '@angular/common';
21
21
  import { CommonModule } from '@angular/common';
22
22
  import { xIcon, caretAltDownIcon, searchIcon, xCircleIcon, plusIcon } from '@progress/kendo-svg-icons';
@@ -32,7 +32,7 @@ const packageMetadata = {
32
32
  name: '@progress/kendo-angular-dropdowns',
33
33
  productName: 'Kendo UI for Angular',
34
34
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
35
- publishDate: 1673265672,
35
+ publishDate: 1673372510,
36
36
  version: '',
37
37
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
38
38
  };
@@ -379,6 +379,32 @@ const isJapanese = (input) => {
379
379
  const japaneseRegex = /[\u3000-\u303F]|[\u3040-\u309F]|[\u30A0-\u30FF]|[\uFF00-\uFFEF]|[\u4E00-\u9FAF]|[\u2605-\u2606]|[\u2190-\u2195]|\u203B/g;
380
380
  return japaneseRegex.test(input);
381
381
  };
382
+ /**
383
+ * @hidden
384
+ */
385
+ const isLetter = (text) => {
386
+ const isLetter = /[a-zA-Z]/;
387
+ return isLetter.test(text) && text?.length === 1;
388
+ };
389
+ /**
390
+ * @hidden
391
+ */
392
+ const getTextField = (field, level) => {
393
+ if (isArray(field)) {
394
+ return field[level];
395
+ }
396
+ return field;
397
+ };
398
+ /**
399
+ * @hidden
400
+ */
401
+ const getSearchableItems = (popupId, popupElement) => {
402
+ const nodeSeletor = `kendo-popup[id='${popupId}'] li.k-treeview-item`;
403
+ const liElements = Array.from(popupElement.querySelectorAll(nodeSeletor));
404
+ return liElements.map((liElement) => {
405
+ return { text: liElement.innerText, index: liElement.getAttribute('data-treeindex') };
406
+ });
407
+ };
382
408
 
383
409
  /**
384
410
  * @hidden
@@ -10426,7 +10452,10 @@ class DropDownTreeComponent {
10426
10452
  this._size = 'medium';
10427
10453
  this._rounded = 'medium';
10428
10454
  this._fillMode = 'solid';
10429
- this.subscriptions = [];
10455
+ this._searchableNodes = [];
10456
+ this._typedValue = '';
10457
+ this.printableCharacters = new Subject();
10458
+ this.subs = new Subscription();
10430
10459
  this.onTouchedCallback = noop;
10431
10460
  this.onChangeCallback = noop;
10432
10461
  this.direction = localization.rtl ? 'rtl' : 'ltr';
@@ -10480,6 +10509,9 @@ class DropDownTreeComponent {
10480
10509
  if (this.disabled || this.readonly) {
10481
10510
  return;
10482
10511
  }
10512
+ if (isLetter(event.key)) {
10513
+ this.printableCharacters.next(event.key);
10514
+ }
10483
10515
  const eventData = event;
10484
10516
  this.navigationService.process({
10485
10517
  originalEvent: eventData
@@ -10729,9 +10761,20 @@ class DropDownTreeComponent {
10729
10761
  return ngControl?.control || null;
10730
10762
  }
10731
10763
  ngOnInit() {
10764
+ this.subs.add(this.printableCharacters.pipe(tap((char) => {
10765
+ this._typedValue += char;
10766
+ const itemToFocus = this._searchableNodes.find((node) => {
10767
+ return node.text.toLowerCase().indexOf(this._typedValue) === 0;
10768
+ });
10769
+ this.treeview.focus(itemToFocus?.index);
10770
+ const htmlItem = document.querySelector(`kendo-popup[id='${this._popupId}'] li.k-treeview-item[data-treeindex='${itemToFocus?.index}']`);
10771
+ htmlItem?.scrollIntoView();
10772
+ }), debounceTime(1000)).subscribe(() => {
10773
+ this._typedValue = '';
10774
+ }));
10732
10775
  this.renderer.removeAttribute(this.wrapper.nativeElement, 'tabindex');
10733
10776
  this.assignAriaDescribedBy();
10734
- this.subscriptions.push(this.localization
10777
+ this.subs.add(this.localization
10735
10778
  .changes.subscribe(({ rtl }) => {
10736
10779
  this.direction = rtl ? 'rtl' : 'ltr';
10737
10780
  this.cdr.markForCheck();
@@ -11030,6 +11073,16 @@ class DropDownTreeComponent {
11030
11073
  }
11031
11074
  return null;
11032
11075
  }
11076
+ /**
11077
+ * @hidden
11078
+ */
11079
+ onChildrenLoaded() {
11080
+ setTimeout(() => {
11081
+ if (this.popupRef) {
11082
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
11083
+ }
11084
+ });
11085
+ }
11033
11086
  /**
11034
11087
  * @hidden
11035
11088
  *
@@ -11086,6 +11139,7 @@ class DropDownTreeComponent {
11086
11139
  this.popupRef.popupOpen.subscribe(() => {
11087
11140
  this.cdr.detectChanges();
11088
11141
  this.opened.emit();
11142
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
11089
11143
  });
11090
11144
  this.popupRef.popupClose.subscribe(() => {
11091
11145
  this.closed.emit();
@@ -11127,33 +11181,41 @@ class DropDownTreeComponent {
11127
11181
  this.selectedKeys = [];
11128
11182
  }
11129
11183
  subscribeEvents() {
11130
- this.subscriptions.push(this.navigationService.open.subscribe((event) => {
11131
- event.originalEvent.preventDefault();
11132
- this.togglePopup(true);
11133
- }), this.navigationService.close.subscribe((event) => {
11134
- event.originalEvent.preventDefault();
11135
- this.togglePopup(false);
11136
- this.focus();
11137
- }), this.navigationService.enter
11138
- .pipe(tap((event) => event.originalEvent.preventDefault()))
11139
- .subscribe(() => this.togglePopup(true)), this.navigationService.esc
11140
- .subscribe(() => this.handleEscape()), this.navigationService.tab.subscribe(() => this.focus()), this.navigationService.down.subscribe((event) => {
11141
- if (!this.treeview) {
11142
- return;
11143
- }
11144
- event.originalEvent.preventDefault();
11145
- if (!this.treeview.isActive) {
11146
- this.treeview.focus();
11147
- }
11148
- }), this.navigationService.up.subscribe((event) => {
11149
- if (!this.treeview) {
11150
- return;
11151
- }
11152
- event.originalEvent.preventDefault();
11153
- if (this.filterable && this.treeview['navigationService']['activeIndex'] === '0') {
11154
- this.filterInput.nativeElement.focus();
11155
- }
11156
- }));
11184
+ [
11185
+ this.navigationService.open.subscribe((event) => {
11186
+ event.originalEvent.preventDefault();
11187
+ this.togglePopup(true);
11188
+ }),
11189
+ this.navigationService.close.subscribe((event) => {
11190
+ event.originalEvent.preventDefault();
11191
+ this.togglePopup(false);
11192
+ this.focus();
11193
+ }),
11194
+ this.navigationService.enter
11195
+ .pipe(tap((event) => event.originalEvent.preventDefault()))
11196
+ .subscribe(() => this.togglePopup(true)),
11197
+ this.navigationService.esc
11198
+ .subscribe(() => this.handleEscape()),
11199
+ this.navigationService.tab.subscribe(() => this.focus()),
11200
+ this.navigationService.down.subscribe((event) => {
11201
+ if (!this.treeview) {
11202
+ return;
11203
+ }
11204
+ event.originalEvent.preventDefault();
11205
+ if (!this.treeview.isActive) {
11206
+ this.treeview.focus();
11207
+ }
11208
+ }),
11209
+ this.navigationService.up.subscribe((event) => {
11210
+ if (!this.treeview) {
11211
+ return;
11212
+ }
11213
+ event.originalEvent.preventDefault();
11214
+ if (this.filterable && this.treeview['navigationService']['activeIndex'] === '0') {
11215
+ this.filterInput.nativeElement.focus();
11216
+ }
11217
+ })
11218
+ ].forEach(sub => this.subs.add(sub));
11157
11219
  }
11158
11220
  subscribeTouchEvents() {
11159
11221
  if (!isDocumentAvailable() || !this.touchEnabled) {
@@ -11192,7 +11254,7 @@ class DropDownTreeComponent {
11192
11254
  }
11193
11255
  }
11194
11256
  unsubscribeEvents() {
11195
- this.subscriptions.forEach(sub => sub.unsubscribe());
11257
+ this.subs.unsubscribe();
11196
11258
  this.unSubscribeFocusEvents();
11197
11259
  if (this.touchstartDisposeHandler) {
11198
11260
  this.touchstartDisposeHandler();
@@ -11377,6 +11439,7 @@ DropDownTreeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0",
11377
11439
  (selectionChange)="onSelectionChange($event)"
11378
11440
  (expand)="nodeExpand.emit($event)"
11379
11441
  (collapse)="nodeCollapse.emit($event)"
11442
+ (childrenLoaded)="onChildrenLoaded()"
11380
11443
  >
11381
11444
  </kendo-treeview>
11382
11445
  <!--footer template-->
@@ -11559,6 +11622,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
11559
11622
  (selectionChange)="onSelectionChange($event)"
11560
11623
  (expand)="nodeExpand.emit($event)"
11561
11624
  (collapse)="nodeCollapse.emit($event)"
11625
+ (childrenLoaded)="onChildrenLoaded()"
11562
11626
  >
11563
11627
  </kendo-treeview>
11564
11628
  <!--footer template-->
@@ -12373,7 +12437,10 @@ class MultiSelectTreeComponent {
12373
12437
  this._size = 'medium';
12374
12438
  this._rounded = 'medium';
12375
12439
  this._fillMode = 'solid';
12376
- this.subscriptions = [];
12440
+ this._searchableNodes = [];
12441
+ this._typedValue = '';
12442
+ this.printableCharacters = new Subject();
12443
+ this.subs = new Subscription();
12377
12444
  this.lastAction = 'check';
12378
12445
  this.onTouchedCallback = noop;
12379
12446
  this.onChangeCallback = noop;
@@ -12442,6 +12509,9 @@ class MultiSelectTreeComponent {
12442
12509
  if (this.disabled || this.readonly) {
12443
12510
  return;
12444
12511
  }
12512
+ if (isLetter(event.key)) {
12513
+ this.printableCharacters.next(event.key);
12514
+ }
12445
12515
  const eventData = event;
12446
12516
  const action = this.navigationService.process({
12447
12517
  originalEvent: eventData
@@ -12772,9 +12842,20 @@ class MultiSelectTreeComponent {
12772
12842
  return this.checkAllInput && document.activeElement === this.checkAllInput.nativeElement;
12773
12843
  }
12774
12844
  ngOnInit() {
12845
+ this.subs.add(this.printableCharacters.pipe(tap((char) => {
12846
+ this._typedValue += char;
12847
+ const itemToFocus = this._searchableNodes.find((node) => {
12848
+ return node.text.toLowerCase().indexOf(this._typedValue) === 0;
12849
+ });
12850
+ this.treeview.focus(itemToFocus?.index);
12851
+ const htmlItem = document.querySelector(`kendo-popup[id='${this._popupId}'] li.k-treeview-item[data-treeindex='${itemToFocus?.index}']`);
12852
+ htmlItem?.scrollIntoView();
12853
+ }), debounceTime(1000)).subscribe(() => {
12854
+ this._typedValue = '';
12855
+ }));
12775
12856
  this.renderer.removeAttribute(this.wrapper.nativeElement, 'tabindex');
12776
12857
  this.renderer.setAttribute(this.wrapper.nativeElement, 'aria-expanded', String(this.isOpen));
12777
- this.subscriptions.push(this.localization
12858
+ this.subs.add(this.localization
12778
12859
  .changes.subscribe(({ rtl }) => {
12779
12860
  this.direction = rtl ? 'rtl' : 'ltr';
12780
12861
  this.cdr.markForCheck();
@@ -13181,9 +13262,11 @@ class MultiSelectTreeComponent {
13181
13262
  popupWrapper.style.height = this.height;
13182
13263
  this.renderer.setAttribute(popupWrapper, 'dir', this.direction);
13183
13264
  this.renderer.setAttribute(this.wrapper.nativeElement, 'aria-expanded', 'true');
13265
+ this.renderer.setAttribute(popupWrapper, 'id', this._popupId);
13184
13266
  this.popupRef.popupOpen.subscribe(() => {
13185
13267
  this.cdr.detectChanges();
13186
13268
  this.opened.emit();
13269
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
13187
13270
  });
13188
13271
  this.popupRef.popupClose.subscribe(() => {
13189
13272
  this.closed.emit();
@@ -13206,20 +13289,33 @@ class MultiSelectTreeComponent {
13206
13289
  }
13207
13290
  }
13208
13291
  subscribeEvents() {
13209
- this.subscriptions.push(this.navigationService.open.subscribe((event) => {
13210
- event.originalEvent.preventDefault();
13211
- this.togglePopup(true);
13212
- }), this.navigationService.enter
13213
- .pipe(tap((event) => event.originalEvent.preventDefault()))
13214
- .subscribe(() => this.togglePopup(true)), merge(this.navigationService.close, this.navigationService.esc).subscribe((event) => {
13215
- event.originalEvent.preventDefault();
13216
- this.focus();
13217
- this.togglePopup(false);
13218
- }), this.navigationService.tab.subscribe(this.handleTabKey.bind(this)), this.navigationService.up.subscribe(this.handleUpKey.bind(this)), this.navigationService.down.subscribe(this.handleDownKey.bind(this)), this.navigationService.left
13219
- .pipe(filter(() => !this.isTreeViewActive))
13220
- .subscribe(this.direction === 'rtl' ? this.handleRightKey.bind(this) : this.handleLeftKey.bind(this)), this.navigationService.right
13221
- .pipe(filter(() => !this.isTreeViewActive))
13222
- .subscribe(this.direction === 'rtl' ? this.handleLeftKey.bind(this) : this.handleRightKey.bind(this)), this.navigationService.home.pipe(filter(() => !this.isOpen)).subscribe(this.handleHome.bind(this)), this.navigationService.end.pipe(filter(() => !this.isOpen)).subscribe(this.handleEnd.bind(this)), this.navigationService.backspace.pipe(filter(() => this.isTagFocused)).subscribe(this.handleBackspace.bind(this)), this.navigationService.delete.pipe(filter(() => this.isTagFocused)).subscribe(this.handleDelete.bind(this)));
13292
+ [
13293
+ this.navigationService.open.subscribe((event) => {
13294
+ event.originalEvent.preventDefault();
13295
+ this.togglePopup(true);
13296
+ }),
13297
+ this.navigationService.enter
13298
+ .pipe(tap((event) => event.originalEvent.preventDefault()))
13299
+ .subscribe(() => this.togglePopup(true)),
13300
+ merge(this.navigationService.close, this.navigationService.esc).subscribe((event) => {
13301
+ event.originalEvent.preventDefault();
13302
+ this.focus();
13303
+ this.togglePopup(false);
13304
+ }),
13305
+ this.navigationService.tab.subscribe(this.handleTabKey.bind(this)),
13306
+ this.navigationService.up.subscribe(this.handleUpKey.bind(this)),
13307
+ this.navigationService.down.subscribe(this.handleDownKey.bind(this)),
13308
+ this.navigationService.left
13309
+ .pipe(filter(() => !this.isTreeViewActive))
13310
+ .subscribe(this.direction === 'rtl' ? this.handleRightKey.bind(this) : this.handleLeftKey.bind(this)),
13311
+ this.navigationService.right
13312
+ .pipe(filter(() => !this.isTreeViewActive))
13313
+ .subscribe(this.direction === 'rtl' ? this.handleLeftKey.bind(this) : this.handleRightKey.bind(this)),
13314
+ this.navigationService.home.pipe(filter(() => !this.isOpen)).subscribe(this.handleHome.bind(this)),
13315
+ this.navigationService.end.pipe(filter(() => !this.isOpen)).subscribe(this.handleEnd.bind(this)),
13316
+ this.navigationService.backspace.pipe(filter(() => this.isTagFocused)).subscribe(this.handleBackspace.bind(this)),
13317
+ this.navigationService.delete.pipe(filter(() => this.isTagFocused)).subscribe(this.handleDelete.bind(this))
13318
+ ].forEach(sub => this.subs.add(sub));
13223
13319
  }
13224
13320
  subscribeFocusEvents() {
13225
13321
  if (isDocumentAvailable()) {
@@ -13350,7 +13446,7 @@ class MultiSelectTreeComponent {
13350
13446
  }
13351
13447
  }
13352
13448
  unsubscribeEvents() {
13353
- this.subscriptions.forEach(sub => sub.unsubscribe());
13449
+ this.subs.unsubscribe();
13354
13450
  this.unSubscribeFocusEvents();
13355
13451
  }
13356
13452
  /**
@@ -13385,6 +13481,16 @@ class MultiSelectTreeComponent {
13385
13481
  this.value = newValue;
13386
13482
  this.emitValueChange(this.value);
13387
13483
  }
13484
+ /**
13485
+ * @hidden
13486
+ */
13487
+ onChildrenLoaded() {
13488
+ setTimeout(() => {
13489
+ if (this.popupRef) {
13490
+ this._searchableNodes = getSearchableItems(this._popupId, this.popupRef.popupElement);
13491
+ }
13492
+ });
13493
+ }
13388
13494
  /**
13389
13495
  * @hidden
13390
13496
  *
@@ -13635,6 +13741,7 @@ MultiSelectTreeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0
13635
13741
  focusout: handleBlur
13636
13742
  }"
13637
13743
  [scope]="this"
13744
+ (childrenLoaded)="onChildrenLoaded()"
13638
13745
  >
13639
13746
  </kendo-treeview>
13640
13747
  <!--footer template-->
@@ -13850,6 +13957,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImpo
13850
13957
  focusout: handleBlur
13851
13958
  }"
13852
13959
  [scope]="this"
13960
+ (childrenLoaded)="onChildrenLoaded()"
13853
13961
  >
13854
13962
  </kendo-treeview>
13855
13963
  <!--footer template-->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-dropdowns",
3
- "version": "11.0.0-develop.93",
3
+ "version": "11.0.0-develop.94",
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",
@@ -25,14 +25,14 @@
25
25
  "@angular/platform-browser": "13 - 15",
26
26
  "@progress/kendo-common": "^0.2.1",
27
27
  "@progress/kendo-licensing": "^1.0.2",
28
- "@progress/kendo-angular-common": "11.0.0-develop.93",
29
- "@progress/kendo-angular-l10n": "11.0.0-develop.93",
30
- "@progress/kendo-angular-popup": "11.0.0-develop.93",
31
- "@progress/kendo-angular-icons": "11.0.0-develop.93",
32
- "@progress/kendo-angular-schematics": "11.0.0-develop.93",
33
- "@progress/kendo-angular-treeview": "11.0.0-develop.93",
28
+ "@progress/kendo-angular-common": "11.0.0-develop.94",
29
+ "@progress/kendo-angular-l10n": "11.0.0-develop.94",
30
+ "@progress/kendo-angular-popup": "11.0.0-develop.94",
31
+ "@progress/kendo-angular-icons": "11.0.0-develop.94",
32
+ "@progress/kendo-angular-schematics": "11.0.0-develop.94",
33
+ "@progress/kendo-angular-treeview": "11.0.0-develop.94",
34
34
  "rxjs": "^6.5.3 || ^7.0.0",
35
- "@progress/kendo-angular-label": "11.0.0-develop.93"
35
+ "@progress/kendo-angular-label": "11.0.0-develop.94"
36
36
  },
37
37
  "dependencies": {
38
38
  "tslib": "^2.3.1"