@progress/kendo-angular-grid 19.3.0-develop.31 → 19.3.0-develop.33

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.
@@ -93,7 +93,7 @@ export class ColumnChooserComponent {
93
93
  const popupAriaElement = popupElement.querySelector('.k-popup');
94
94
  this.ngZone.runOutsideAngular(() => {
95
95
  this.escapeListener = this.renderer.listen(popupAriaElement, 'keydown', (e) => {
96
- if (e.keyCode === Keys.Escape) {
96
+ if (e.code === Keys.Escape) {
97
97
  this.close(true);
98
98
  }
99
99
  });
@@ -6,7 +6,7 @@ import { Component, HostBinding, Input, ElementRef, NgZone, Renderer2, Output, E
6
6
  import { ColumnMenuService } from './column-menu.service';
7
7
  import { ColumnListKeyboardNavigation } from './column-list-kb-nav.service';
8
8
  import { ColumnMenuChooserItemCheckedDirective } from './column-chooser-item-checked.directive';
9
- import { Keys } from '@progress/kendo-angular-common';
9
+ import { Keys, normalizeNumpadKeys } from '@progress/kendo-angular-common';
10
10
  import { Subscription } from 'rxjs';
11
11
  import { NgFor, NgIf, NgClass } from '@angular/common';
12
12
  import { CheckBoxComponent } from '@progress/kendo-angular-inputs';
@@ -157,13 +157,14 @@ export class ColumnListComponent {
157
157
  }
158
158
  }
159
159
  onKeydown = (e) => {
160
- if (e.keyCode !== Keys.Tab) {
160
+ const code = normalizeNumpadKeys(e);
161
+ if (code !== Keys.Tab) {
161
162
  e.preventDefault();
162
163
  }
163
- if (e.key === 'Tab' && !e.shiftKey && this.autoSync) {
164
+ if (code === 'Tab' && !e.shiftKey && this.autoSync) {
164
165
  e.preventDefault();
165
166
  }
166
- if (e.key === 'Tab' && e.shiftKey) {
167
+ if (code === 'Tab' && e.shiftKey) {
167
168
  this.ngZone.run(() => {
168
169
  if (e.target.matches('.k-column-list-item')) {
169
170
  e.preventDefault();
@@ -171,13 +172,13 @@ export class ColumnListComponent {
171
172
  }
172
173
  });
173
174
  }
174
- if (e.keyCode === Keys.ArrowDown) {
175
+ if (code === Keys.ArrowDown) {
175
176
  this.listNavigationService.next();
176
177
  }
177
- else if (e.keyCode === Keys.ArrowUp) {
178
+ else if (code === Keys.ArrowUp) {
178
179
  this.listNavigationService.prev();
179
180
  }
180
- else if (e.keyCode === Keys.Space && e.target.classList.contains('k-column-list-item')) {
181
+ else if (code === Keys.Space && e.target.classList.contains('k-column-list-item')) {
181
182
  this.listNavigationService.toggleCheckedState();
182
183
  }
183
184
  };
@@ -125,7 +125,7 @@ export class ColumnMenuItemDirective {
125
125
  }
126
126
  }
127
127
  onTab = (e) => {
128
- if (e.keyCode !== Keys.Tab) {
128
+ if (e.code !== Keys.Tab) {
129
129
  return;
130
130
  }
131
131
  if (this.isFirst && e.shiftKey && e.target === this.columnMenuItems[0]) {
@@ -74,7 +74,7 @@ export class InCellEditingDirective extends EditingDirectiveBase {
74
74
  args.preventDefault();
75
75
  }
76
76
  else if (formGroup.dirty) {
77
- if (args.originalEvent && args.originalEvent.keyCode === Keys.Escape) {
77
+ if (args.originalEvent && args.originalEvent.code === Keys.Escape) {
78
78
  return;
79
79
  }
80
80
  this.editService.assignValues(dataItem, formGroup.value);
@@ -114,7 +114,7 @@ export class FilterCellOperatorsComponent {
114
114
  * @hidden
115
115
  */
116
116
  clearKeydown(args) {
117
- if (args.keyCode === Keys.Enter || args.keyCode === Keys.Space) {
117
+ if (args.code === Keys.Enter || args.code === Keys.NumpadEnter || args.code === Keys.Space) {
118
118
  this.clear.emit();
119
119
  }
120
120
  }
@@ -125,7 +125,7 @@ export class FilterCellOperatorsComponent {
125
125
  if (args.defaultPrevented) {
126
126
  return;
127
127
  }
128
- if (args.keyCode === Keys.Enter && !this.dropdown.isOpen) {
128
+ if ((args.code === Keys.Enter || args.code === Keys.NumpadEnter) && !this.dropdown.isOpen) {
129
129
  this.dropdown.toggle(true);
130
130
  args.preventDefault();
131
131
  }
@@ -25,7 +25,7 @@ export class FilterMenuDropDownListDirective {
25
25
  this.host.wrapper.nativeElement.removeEventListener('keydown', this.keydownHandler);
26
26
  }
27
27
  keydownHandler = (e) => {
28
- if (e.keyCode === Keys.Escape && this.host.isOpen) {
28
+ if (e.code === Keys.Escape && this.host.isOpen) {
29
29
  e.stopPropagation();
30
30
  this.host.toggle(false);
31
31
  }
@@ -1546,6 +1546,7 @@ export class GridComponent {
1546
1546
  */
1547
1547
  closeRow(index) {
1548
1548
  this.editService.close(index);
1549
+ this.isStacked && (this.navigationService.stackedCellEntered = false);
1549
1550
  }
1550
1551
  /**
1551
1552
  * Creates a new row editor ([see example]({% slug inline_editing_grid %}#toc-adding-records-1)).
@@ -16,7 +16,7 @@ import { ContextService } from '../common/provider.service';
16
16
  import { PopupService } from '@progress/kendo-angular-popup';
17
17
  import { ChipComponent, ChipListComponent } from '@progress/kendo-angular-buttons';
18
18
  import { closest } from '../rendering/common/dom-queries';
19
- import { DraggableDirective, EventsOutsideAngularDirective, Keys } from '@progress/kendo-angular-common';
19
+ import { DraggableDirective, EventsOutsideAngularDirective, Keys, normalizeNumpadKeys } from '@progress/kendo-angular-common';
20
20
  import { IconWrapperComponent } from '@progress/kendo-angular-icons';
21
21
  import { DraggableColumnDirective } from '../dragdrop/draggable-column.directive';
22
22
  import { NgIf, NgFor } from '@angular/common';
@@ -176,18 +176,19 @@ export class GroupPanelComponent {
176
176
  });
177
177
  }
178
178
  handleKeyDown = (e) => {
179
- if (e.keyCode === Keys.ArrowDown || e.keyCode === Keys.ArrowUp) {
179
+ const code = normalizeNumpadKeys(e);
180
+ if (code === Keys.ArrowDown || code === Keys.ArrowUp) {
180
181
  e.preventDefault();
181
182
  const relatedItemType = e.target.matches(':first-child') ? 'next' : 'previous';
182
183
  this.activateMenuItem(e.target, relatedItemType);
183
184
  }
184
- else if (e.keyCode === Keys.Escape) {
185
+ else if (code === Keys.Escape) {
185
186
  this.destroyMenu(true);
186
187
  }
187
- else if (e.keyCode === Keys.Tab) {
188
+ else if (code === Keys.Tab) {
188
189
  this.destroyMenu(true);
189
190
  }
190
- else if (e.keyCode === Keys.Space || e.keyCode === Keys.Enter) {
191
+ else if (code === Keys.Space || code === Keys.Enter) {
191
192
  this.handleMenuClick(e);
192
193
  }
193
194
  };
@@ -15,7 +15,6 @@ const isNavigable = element => !element.disabled && (isButton(element) || isNavi
15
15
  */
16
16
  export class DefaultFocusableElement {
17
17
  renderer;
18
- ctx;
19
18
  get enabled() {
20
19
  return this.focusable && !this.focusable.disabled;
21
20
  }
@@ -24,9 +23,8 @@ export class DefaultFocusableElement {
24
23
  }
25
24
  element;
26
25
  focusable;
27
- constructor(host, renderer, ctx) {
26
+ constructor(host, renderer) {
28
27
  this.renderer = renderer;
29
- this.ctx = ctx;
30
28
  this.element = host.nativeElement;
31
29
  this.focusable = findFocusable(this.element, false) || this.element;
32
30
  }
@@ -34,17 +32,7 @@ export class DefaultFocusableElement {
34
32
  return this.canFocus() && isNavigable(this.element);
35
33
  }
36
34
  toggle(active) {
37
- if (this.ctx.grid?.isStacked) {
38
- if (active) {
39
- this.renderer.setAttribute(this.focusable, 'tabindex', '0');
40
- }
41
- else {
42
- this.renderer.removeAttribute(this.focusable, 'tabindex');
43
- }
44
- }
45
- else {
46
- this.renderer.setAttribute(this.focusable, 'tabindex', active ? '0' : '-1');
47
- }
35
+ this.renderer.setAttribute(this.focusable, 'tabIndex', active ? '0' : '-1');
48
36
  }
49
37
  focus() {
50
38
  if (this.focusable) {
@@ -70,7 +70,7 @@ export class FocusableDirective {
70
70
  }
71
71
  ngAfterViewInit() {
72
72
  if (!this.element && this.ctx.navigable) {
73
- this.element = new DefaultFocusableElement(this.hostElement, this.renderer, this.ctx);
73
+ this.element = new DefaultFocusableElement(this.hostElement, this.renderer);
74
74
  }
75
75
  if (this.group && this.element) {
76
76
  this.toggle(this.group.isActive);
@@ -11,7 +11,7 @@ import { GridFocusableElement } from './grid-focusable-element';
11
11
  import { NavigationCursor } from './navigation-cursor';
12
12
  import { NavigationModel } from './navigation-model';
13
13
  import { DomEventsService } from '../common/dom-events.service';
14
- import { hasClasses, isDocumentAvailable, isPresent, Keys } from '@progress/kendo-angular-common';
14
+ import { hasClasses, isDocumentAvailable, isPresent, Keys, normalizeNumpadKeys } from '@progress/kendo-angular-common';
15
15
  import { EditService } from '../editing/edit.service';
16
16
  import { GroupsService } from '../grouping/groups.service';
17
17
  import { PagerContextService } from '@progress/kendo-angular-pager';
@@ -226,10 +226,18 @@ export class NavigationService {
226
226
  .subscribe(() => {
227
227
  this.isShiftPressed = false;
228
228
  }));
229
- this.subs.add(this.domEvents.keydown.pipe(filter(args => args.keyCode === Keys.Tab && this.mode === 2 /* NavigationMode.Content */), switchMapTo(this.domEvents.focusOut.pipe(takeUntil(
229
+ this.subs.add(this.domEvents.keydown.pipe(filter(args => args.code === Keys.Tab && this.mode === 2 /* NavigationMode.Content */), switchMapTo(this.domEvents.focusOut.pipe(takeUntil(
230
230
  // Timeout if focusOut doesn't fire very soon
231
231
  interval(0).pipe(take(1))))))
232
232
  .subscribe(() => this.onTabout()));
233
+ this.subs.add(this.domEvents.cellClick
234
+ .subscribe(() => {
235
+ if (this.isStackedMode) {
236
+ const stackedCells = this.activeCell.focusGroup.focusableChildren;
237
+ const currFocusedIndex = stackedCells.findIndex(el => el.hasFocus() || el.hostElement?.nativeElement === document.activeElement);
238
+ currFocusedIndex > -1 && (this.stackedFocusedCellIndex = currFocusedIndex);
239
+ }
240
+ }));
233
241
  if (this.focusableParent) {
234
242
  const element = new GridFocusableElement(this);
235
243
  this.focusableParent.registerElement(element);
@@ -493,14 +501,16 @@ export class NavigationService {
493
501
  return;
494
502
  }
495
503
  const row = this.cursor.row;
496
- const dir = args.keyCode === Keys.ArrowDown ? 'Down' : 'Up';
497
- const right = args.keyCode === Keys.ArrowRight;
498
- const isArrowKey = args.code === 'ArrowDown' || args.code === 'ArrowUp' || args.code === 'ArrowLeft' || args.code === 'ArrowRight';
504
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
505
+ const code = normalizeNumpadKeys(args);
506
+ const dir = code === Keys.ArrowDown ? 'Down' : 'Up';
507
+ const right = code === Keys.ArrowRight;
508
+ const isArrowKey = code === Keys.ArrowDown || code === Keys.ArrowUp || code === Keys.ArrowLeft || code === Keys.ArrowRight;
499
509
  if (!this.isShiftPressed && args.shiftKey && isArrowKey) {
500
510
  startNewSelection = true;
501
511
  this.isShiftPressed = true;
502
512
  }
503
- switch (args.keyCode) {
513
+ switch (code) {
504
514
  case Keys.ArrowDown:
505
515
  case Keys.ArrowUp:
506
516
  if (rowspan > 1) {
@@ -615,7 +625,7 @@ export class NavigationService {
615
625
  case Keys.Enter:
616
626
  case Keys.F2: {
617
627
  if (this.stackedCellEntered) {
618
- if (args.keyCode === Keys.F2 && row.dataRowIndex > -1) {
628
+ if (code === Keys.F2 && row.dataRowIndex > -1) {
619
629
  this.zone.run(() => {
620
630
  this.editService.beginEdit(row.dataRowIndex);
621
631
  });
@@ -631,7 +641,7 @@ export class NavigationService {
631
641
  this.zone.run(() => this.detailsService.toggleRow(row.dataRowIndex, row.dataItem));
632
642
  }
633
643
  else {
634
- if (args.keyCode === Keys.F2 && row.dataRowIndex > -1) {
644
+ if (code === Keys.F2 && row.dataRowIndex > -1) {
635
645
  this.zone.run(() => {
636
646
  this.editService.beginEdit(row.dataRowIndex);
637
647
  });
@@ -675,9 +685,11 @@ export class NavigationService {
675
685
  if (!this.onCellKeydown(args)) {
676
686
  return;
677
687
  }
678
- const confirm = !args.defaultPrevented && args.keyCode === Keys.Enter && isTextInput(args.target);
679
- if (args.keyCode === Keys.Escape || args.keyCode === Keys.F2 || confirm) {
680
- if (this.tableCellEntered && args.keyCode === Keys.F2 && this.activeRow.dataRowIndex > -1) {
688
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
689
+ const code = normalizeNumpadKeys(args);
690
+ const confirm = !args.defaultPrevented && code === Keys.Enter && isTextInput(args.target);
691
+ if (code === Keys.Escape || code === Keys.F2 || confirm) {
692
+ if (this.tableCellEntered && code === Keys.F2 && this.activeRow.dataRowIndex > -1) {
681
693
  this.zone.run(() => {
682
694
  this.editService.beginEdit(this.activeRow.dataRowIndex);
683
695
  });
@@ -688,7 +700,7 @@ export class NavigationService {
688
700
  this.cursor.reset();
689
701
  args.stopPropagation();
690
702
  }
691
- else if (isNavigationKey(args.keyCode) && this.cursor.cell.focusGroup.isNavigable()) {
703
+ else if (isNavigationKey(code) && this.cursor.cell.focusGroup.isNavigable()) {
692
704
  this.onCursorKeydown(args);
693
705
  if (args.defaultPrevented) {
694
706
  this.leaveCell();
@@ -697,9 +709,11 @@ export class NavigationService {
697
709
  }
698
710
  onCellKeydown(args) {
699
711
  if (this.editService.isEditingCell()) {
700
- const confirm = args.keyCode === Keys.Enter;
701
- const cancel = args.keyCode === Keys.Escape;
702
- const navigate = isNavigationKey(args.keyCode);
712
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
713
+ const code = normalizeNumpadKeys(args);
714
+ const confirm = code === Keys.Enter;
715
+ const cancel = code === Keys.Escape;
716
+ const navigate = isNavigationKey(code);
703
717
  if (confirm) {
704
718
  this.editService.closeCell(args);
705
719
  }
@@ -854,13 +868,14 @@ export class NavigationService {
854
868
  const stackedCell = closest(target, (el) => hasClasses(el, 'k-grid-stack-cell'));
855
869
  const tableCell = closest(target, (el) => hasClasses(el, 'k-table-td'));
856
870
  const isInStackedCell = closest(target, (el) => hasClasses(el, 'k-grid-stack-content'));
871
+ const isInCommandCell = closest(target, (el) => hasClasses(el, 'k-command-cell'));
857
872
  if (!stackedCell || !tableCell) {
858
873
  return;
859
874
  }
860
- if (args.keyCode === Keys.Tab) {
875
+ if (args.code === Keys.Tab) {
861
876
  this.handleStackedTabNavigation(args);
862
877
  }
863
- else if (args.keyCode === Keys.Backspace || args.keyCode === Keys.Delete) {
878
+ else if (args.code === Keys.Backspace || args.code === Keys.Delete) {
864
879
  if (this.activeRow && this.activeRow.dataRowIndex >= 0 && this.activeRow.dataItem) {
865
880
  const row = this.cursor.row;
866
881
  if (!row.groupItem && !this.cursor.cell.detailExpandCell) {
@@ -871,11 +886,13 @@ export class NavigationService {
871
886
  }
872
887
  }
873
888
  }
874
- else if (isInStackedCell && (args.keyCode === Keys.Enter || args.keyCode === Keys.Escape)) {
889
+ else if (isInStackedCell && (args.code === Keys.Enter || args.code === Keys.NumpadEnter || args.code === Keys.Escape)) {
875
890
  this.editService.closeCell(args);
876
891
  this.activeCell.focusGroup.activate();
877
892
  this.activeCell.focusGroup.focusableChildren[this.stackedFocusedCellIndex]?.focus();
878
- args.preventDefault();
893
+ if (!isInCommandCell) {
894
+ args.preventDefault();
895
+ }
879
896
  }
880
897
  }
881
898
  stackedFocusedCellIndex = -1;
@@ -889,29 +906,24 @@ export class NavigationService {
889
906
  return;
890
907
  }
891
908
  const stackedCells = this.activeCell.focusGroup.focusableChildren;
892
- let nextIndex;
909
+ const currFocusedIndex = stackedCells.findIndex(el => el.hasFocus() || el.hostElement?.nativeElement === document.activeElement);
893
910
  if (args.shiftKey) {
894
- nextIndex = this.stackedFocusedCellIndex - 1;
895
- if (nextIndex < 0) {
896
- nextIndex = stackedCells.length - 1;
911
+ if (currFocusedIndex === 0) {
912
+ args.stopImmediatePropagation();
913
+ args.preventDefault();
914
+ }
915
+ else {
916
+ this.stackedFocusedCellIndex = currFocusedIndex - 1;
897
917
  }
898
918
  }
899
919
  else {
900
- nextIndex = this.stackedFocusedCellIndex + 1;
901
- if (nextIndex >= stackedCells.length) {
902
- nextIndex = 0;
920
+ if (currFocusedIndex === stackedCells.length - 1) {
921
+ args.stopImmediatePropagation();
922
+ args.preventDefault();
903
923
  }
904
- }
905
- let nextStackedCell = stackedCells[nextIndex];
906
- if (nextStackedCell) {
907
- if (nextStackedCell.hasFocus() || (isDocumentAvailable() && document.activeElement === nextStackedCell.hostElement.nativeElement)) {
908
- // next cell is already focused (as a focusable child of the previous one), skip to the next one
909
- nextIndex = args.shiftKey ? this.stackedFocusedCellIndex - 2 : this.stackedFocusedCellIndex + 2;
910
- nextStackedCell = stackedCells[nextIndex];
924
+ else {
925
+ this.stackedFocusedCellIndex = currFocusedIndex + 1;
911
926
  }
912
- nextStackedCell.focus();
913
- this.stackedFocusedCellIndex = nextIndex;
914
- args.preventDefault();
915
927
  }
916
928
  }
917
929
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, deps: [{ token: i0.NgZone }, { token: i1.DomEventsService }, { token: i2.PagerContextService }, { token: i3.ScrollRequestService }, { token: i4.GroupsService }, { token: i5.DetailsService }, { token: i6.FocusRoot }, { token: i7.EditService }, { token: i0.ChangeDetectorRef }, { token: i8.ContextService }, { token: i9.ColumnResizingService }, { token: i10.FocusableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
@@ -10,7 +10,7 @@ export const packageMetadata = {
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCode: 'KENDOUIANGULAR',
12
12
  productCodes: ['KENDOUIANGULAR'],
13
- publishDate: 1754576745,
14
- version: '19.3.0-develop.31',
13
+ publishDate: 1754589878,
14
+ version: '19.3.0-develop.33',
15
15
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
16
16
  };
@@ -223,7 +223,7 @@ export class CellComponent {
223
223
  [class.k-grid-stack-edit-cell]="isEdited(col)"
224
224
  [class.k-drag-cell]="isRowReorderColumn(col) && !isNew"
225
225
  [class.k-command-cell]="isCommand(col)"
226
- kendoGridFocusable>
226
+ [kendoGridFocusable]="!isCommand(col)">
227
227
  <div class="k-grid-stack-header">
228
228
  <ng-container *ngIf="!col.headerTemplateRef; else headerTemplate">
229
229
  {{col.displayTitle}}
@@ -431,7 +431,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
431
431
  [class.k-grid-stack-edit-cell]="isEdited(col)"
432
432
  [class.k-drag-cell]="isRowReorderColumn(col) && !isNew"
433
433
  [class.k-command-cell]="isCommand(col)"
434
- kendoGridFocusable>
434
+ [kendoGridFocusable]="!isCommand(col)">
435
435
  <div class="k-grid-stack-header">
436
436
  <ng-container *ngIf="!col.headerTemplateRef; else headerTemplate">
437
437
  {{col.displayTitle}}
@@ -16,7 +16,7 @@ import { columnsToRender, sortColumns, isInSpanColumn } from "../../columns/colu
16
16
  import { SinglePopupService } from '../../common/single-popup.service';
17
17
  import { hasFilterMenu, hasFilterRow } from '../../filtering/filterable';
18
18
  import { IdService } from '../../common/id.service';
19
- import { DraggableDirective, isDocumentAvailable, Keys, TemplateContextDirective } from '@progress/kendo-angular-common';
19
+ import { DraggableDirective, isDocumentAvailable, Keys, normalizeNumpadKeys, TemplateContextDirective } from '@progress/kendo-angular-common';
20
20
  import { DropTargetDirective } from '../../dragdrop/drop-target.directive';
21
21
  import { DraggableColumnDirective } from '../../dragdrop/draggable-column.directive';
22
22
  import { DragHintService } from '../../dragdrop/drag-hint.service';
@@ -168,14 +168,15 @@ export class HeaderComponent {
168
168
  this.sortColumn(toggledColumn);
169
169
  }
170
170
  onHeaderKeydown(column, args) {
171
- if (args.keyCode === Keys.ArrowDown && args.altKey && this.showFilterMenu) {
171
+ const code = normalizeNumpadKeys(args);
172
+ if (code === Keys.ArrowDown && args.altKey && this.showFilterMenu) {
172
173
  args.preventDefault();
173
174
  args.stopImmediatePropagation();
174
175
  const filterMenu = this.filterMenus.find(fm => fm.column === column);
175
176
  filterMenu.toggle(filterMenu.anchor.nativeElement, filterMenu.template);
176
177
  return;
177
178
  }
178
- if (args.keyCode === Keys.ArrowDown && args.altKey && this.showColumnMenu(column)) {
179
+ if (code === Keys.ArrowDown && args.altKey && this.showColumnMenu(column)) {
179
180
  args.preventDefault();
180
181
  args.stopImmediatePropagation();
181
182
  const columnMenu = this.columnMenus.find(cm => cm.column === column);
@@ -183,7 +184,7 @@ export class HeaderComponent {
183
184
  return;
184
185
  }
185
186
  const isCtrlOrMeta = args.ctrlKey || args.metaKey;
186
- const isGroupingKeyShortcut = (args.keyCode === Keys.Enter || args.keyCode === Keys.Space) && isCtrlOrMeta;
187
+ const isGroupingKeyShortcut = (code === Keys.Enter || code === Keys.Space) && isCtrlOrMeta;
187
188
  if (isGroupingKeyShortcut && this.isGroupable(column)) {
188
189
  args.preventDefault();
189
190
  args.stopImmediatePropagation();
@@ -199,12 +200,12 @@ export class HeaderComponent {
199
200
  this.contextService.grid.groupChange.emit(this.groups);
200
201
  return;
201
202
  }
202
- const isLeftOrRightArrow = args.keyCode === Keys.ArrowLeft || args.keyCode === Keys.ArrowRight;
203
+ const isLeftOrRightArrow = code === Keys.ArrowLeft || code === Keys.ArrowRight;
203
204
  const isReorderingKeyShortcut = isLeftOrRightArrow && isCtrlOrMeta;
204
205
  if (isReorderingKeyShortcut && this.isReorderable(column)) {
205
206
  args.preventDefault();
206
207
  const columnsCount = this.columnInfoService.leafNamedColumns.length;
207
- const reorderDirection = args.keyCode === Keys.ArrowLeft ? -1 : 1;
208
+ const reorderDirection = code === Keys.ArrowLeft ? -1 : 1;
208
209
  const rtlMultiplier = this.contextService.localization.rtl ? -1 : 1;
209
210
  const reorderDirectionOffset = reorderDirection * rtlMultiplier;
210
211
  const newIndex = column.leafIndex + reorderDirectionOffset;
@@ -221,7 +222,7 @@ export class HeaderComponent {
221
222
  if (!this.sortable || args.defaultPrevented || column.sortable === false) {
222
223
  return;
223
224
  }
224
- if (args.keyCode === Keys.Enter && isPresent(column.field)) {
225
+ if (code === Keys.Enter && isPresent(column.field)) {
225
226
  const modifier = this.matchModifier(args);
226
227
  this.sortService.sort(this.toggleSort(column, modifier));
227
228
  }
@@ -21,7 +21,7 @@ import { GroupsService } from "../grouping/groups.service";
21
21
  import { expandColumns, sumColumnWidths } from "../columns/column-common";
22
22
  import { ScrollSyncService } from "../scrolling/scroll-sync.service";
23
23
  import { ResizeService } from "../layout/resize.service";
24
- import { EventsOutsideAngularDirective, isDocumentAvailable, ResizeSensorComponent } from "@progress/kendo-angular-common";
24
+ import { EventsOutsideAngularDirective, isDocumentAvailable, normalizeNumpadKeys, ResizeSensorComponent } from "@progress/kendo-angular-common";
25
25
  import { BrowserSupportService } from "../layout/browser-support.service";
26
26
  import { EditService } from '../editing/edit.service';
27
27
  import { NavigationService } from '../navigation/navigation.service';
@@ -345,8 +345,10 @@ export class ListComponent {
345
345
  }
346
346
  }
347
347
  lockedKeydown(args) {
348
- if (args.keyCode === Keys.PageDown || args.keyCode === Keys.PageUp) {
349
- const dir = args.keyCode === Keys.PageDown ? 1 : -1;
348
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
349
+ const code = normalizeNumpadKeys(args);
350
+ if (code === Keys.PageDown || code === Keys.PageUp) {
351
+ const dir = code === Keys.PageDown ? 1 : -1;
350
352
  const element = this.container.nativeElement;
351
353
  element.scrollTop += element.offsetHeight * dir * 0.8;
352
354
  args.preventDefault();
@@ -314,7 +314,7 @@ export class TableBodyComponent {
314
314
  const element = this.element.nativeElement;
315
315
  const target = this.eventTarget(eventArg);
316
316
  const selectionEnabled = this.selectable && this.selectable.enabled !== false;
317
- if (eventArg.keyCode === Keys.Space) {
317
+ if (eventArg.code === Keys.Space) {
318
318
  if (!selectionEnabled) {
319
319
  return;
320
320
  }
@@ -403,7 +403,7 @@ export class TableBodyComponent {
403
403
  }));
404
404
  }
405
405
  cellKeydownHandler(args) {
406
- if (args.keyCode === Keys.Enter || args.keyCode === Keys.Space || (this.navigationService.tableCellEntered && args.keyCode === Keys.F2)) {
406
+ if (args.code === Keys.Enter || args.code === Keys.NumpadEnter || args.code === Keys.Space || (this.navigationService.tableCellEntered && args.code === Keys.F2)) {
407
407
  this.clickHandler(args);
408
408
  }
409
409
  }
@@ -8,7 +8,7 @@ import { IconWrapperComponent } from '@progress/kendo-angular-icons';
8
8
  import { chevronUpIcon, chevronDownIcon, xCircleIcon, plusCircleIcon, xIcon } from '@progress/kendo-svg-icons';
9
9
  import { KENDO_BUTTON } from '@progress/kendo-angular-buttons';
10
10
  import { take } from 'rxjs/operators';
11
- import { isPresent } from '@progress/kendo-angular-common';
11
+ import { isPresent, Keys, normalizeNumpadKeys } from '@progress/kendo-angular-common';
12
12
  import * as i0 from "@angular/core";
13
13
  import * as i1 from "@progress/kendo-angular-buttons";
14
14
  /**
@@ -172,30 +172,32 @@ export class GroupToolbarToolComponent {
172
172
  this.currentFocusedItemIndex = currentIndex;
173
173
  }
174
174
  handleGroupedKeydown(column, index, ev) {
175
- if (ev.code === 'Enter' || ev.code === 'Backspace' || ev.code === 'Delete') {
175
+ const code = normalizeNumpadKeys(ev);
176
+ if (code === Keys.Enter || code === Keys.Backspace || code === Keys.Delete) {
176
177
  this.removeGroup(column, ev);
177
178
  }
178
- else if (ev.code === 'ArrowUp' && ev.shiftKey) {
179
+ else if (code === Keys.ArrowUp && ev.shiftKey) {
179
180
  this.moveGroupUp(column, ev);
180
181
  }
181
- else if (ev.code === 'ArrowDown' && ev.shiftKey) {
182
+ else if (code === Keys.ArrowDown && ev.shiftKey) {
182
183
  this.moveGroupDown(column, ev);
183
184
  }
184
- else if (ev.code === 'ArrowUp') {
185
+ else if (code === Keys.ArrowUp) {
185
186
  this.navigateToPreviousItem();
186
187
  }
187
- else if (ev.code === 'ArrowDown') {
188
+ else if (code === Keys.ArrowDown) {
188
189
  this.navigateToNextItem();
189
190
  }
190
191
  }
191
192
  handleUngroupedKeydown(column, index, ev) {
192
- if (ev.code === 'Enter') {
193
+ const code = normalizeNumpadKeys(ev);
194
+ if (code === Keys.Enter) {
193
195
  this.addGroup(column, ev);
194
196
  }
195
- else if (ev.code === 'ArrowUp') {
197
+ else if (code === Keys.ArrowUp) {
196
198
  this.navigateToPreviousItem();
197
199
  }
198
- else if (ev.code === 'ArrowDown') {
200
+ else if (code === Keys.ArrowDown) {
199
201
  this.navigateToNextItem();
200
202
  }
201
203
  }
@@ -97,7 +97,7 @@ export class SelectionCheckboxDirective {
97
97
  }
98
98
  }
99
99
  onKeyDown(e) {
100
- if (e.keyCode === Keys.Enter) {
100
+ if (e.code === Keys.Enter || e.code === Keys.NumpadEnter) {
101
101
  this.onClick(e);
102
102
  }
103
103
  }
@@ -6,7 +6,7 @@ import * as i0 from '@angular/core';
6
6
  import { EventEmitter, Injectable, SecurityContext, InjectionToken, Optional, Inject, Directive, SkipSelf, Input, isDevMode, QueryList, Component, ContentChildren, ContentChild, forwardRef, Host, Output, HostBinding, Pipe, TemplateRef, ChangeDetectionStrategy, ViewChildren, ViewChild, Self, NgZone, HostListener, ElementRef, ViewContainerRef, ViewEncapsulation, inject, Injector, NgModule } from '@angular/core';
7
7
  import { merge, of, Subject, zip as zip$1, from, Subscription, interval, fromEvent, Observable, BehaviorSubject } from 'rxjs';
8
8
  import * as i1$3 from '@progress/kendo-angular-common';
9
- import { isDocumentAvailable, Keys, hasClasses as hasClasses$1, isPresent as isPresent$1, anyChanged, TemplateContextDirective, DraggableDirective, EventsOutsideAngularDirective, replaceMessagePlaceholder, isChanged as isChanged$1, KendoInput, guid, closest as closest$1, hasObservers, ResizeSensorComponent, closestInScope as closestInScope$1, isFocusable as isFocusable$1, PreventableEvent as PreventableEvent$1, getLicenseMessage, shouldShowValidationUI, WatermarkOverlayComponent, ResizeBatchService } from '@progress/kendo-angular-common';
9
+ import { isDocumentAvailable, Keys, hasClasses as hasClasses$1, normalizeNumpadKeys, isPresent as isPresent$1, anyChanged, TemplateContextDirective, DraggableDirective, EventsOutsideAngularDirective, replaceMessagePlaceholder, isChanged as isChanged$1, KendoInput, guid, closest as closest$1, hasObservers, ResizeSensorComponent, closestInScope as closestInScope$1, isFocusable as isFocusable$1, PreventableEvent as PreventableEvent$1, getLicenseMessage, shouldShowValidationUI, WatermarkOverlayComponent, ResizeBatchService } from '@progress/kendo-angular-common';
10
10
  import * as i1 from '@angular/platform-browser';
11
11
  import * as i1$1 from '@progress/kendo-angular-icons';
12
12
  import { IconWrapperComponent, IconsService, KENDO_ICONS } from '@progress/kendo-angular-icons';
@@ -758,7 +758,6 @@ const isNavigable = element => !element.disabled && (isButton(element) || isNavi
758
758
  */
759
759
  class DefaultFocusableElement {
760
760
  renderer;
761
- ctx;
762
761
  get enabled() {
763
762
  return this.focusable && !this.focusable.disabled;
764
763
  }
@@ -767,9 +766,8 @@ class DefaultFocusableElement {
767
766
  }
768
767
  element;
769
768
  focusable;
770
- constructor(host, renderer, ctx) {
769
+ constructor(host, renderer) {
771
770
  this.renderer = renderer;
772
- this.ctx = ctx;
773
771
  this.element = host.nativeElement;
774
772
  this.focusable = findFocusable(this.element, false) || this.element;
775
773
  }
@@ -777,17 +775,7 @@ class DefaultFocusableElement {
777
775
  return this.canFocus() && isNavigable(this.element);
778
776
  }
779
777
  toggle(active) {
780
- if (this.ctx.grid?.isStacked) {
781
- if (active) {
782
- this.renderer.setAttribute(this.focusable, 'tabindex', '0');
783
- }
784
- else {
785
- this.renderer.removeAttribute(this.focusable, 'tabindex');
786
- }
787
- }
788
- else {
789
- this.renderer.setAttribute(this.focusable, 'tabindex', active ? '0' : '-1');
790
- }
778
+ this.renderer.setAttribute(this.focusable, 'tabIndex', active ? '0' : '-1');
791
779
  }
792
780
  focus() {
793
781
  if (this.focusable) {
@@ -956,7 +944,7 @@ class FocusableDirective {
956
944
  }
957
945
  ngAfterViewInit() {
958
946
  if (!this.element && this.ctx.navigable) {
959
- this.element = new DefaultFocusableElement(this.hostElement, this.renderer, this.ctx);
947
+ this.element = new DefaultFocusableElement(this.hostElement, this.renderer);
960
948
  }
961
949
  if (this.group && this.element) {
962
950
  this.toggle(this.group.isActive);
@@ -3586,10 +3574,18 @@ class NavigationService {
3586
3574
  .subscribe(() => {
3587
3575
  this.isShiftPressed = false;
3588
3576
  }));
3589
- this.subs.add(this.domEvents.keydown.pipe(filter(args => args.keyCode === Keys.Tab && this.mode === 2 /* NavigationMode.Content */), switchMapTo(this.domEvents.focusOut.pipe(takeUntil(
3577
+ this.subs.add(this.domEvents.keydown.pipe(filter(args => args.code === Keys.Tab && this.mode === 2 /* NavigationMode.Content */), switchMapTo(this.domEvents.focusOut.pipe(takeUntil(
3590
3578
  // Timeout if focusOut doesn't fire very soon
3591
3579
  interval(0).pipe(take(1))))))
3592
3580
  .subscribe(() => this.onTabout()));
3581
+ this.subs.add(this.domEvents.cellClick
3582
+ .subscribe(() => {
3583
+ if (this.isStackedMode) {
3584
+ const stackedCells = this.activeCell.focusGroup.focusableChildren;
3585
+ const currFocusedIndex = stackedCells.findIndex(el => el.hasFocus() || el.hostElement?.nativeElement === document.activeElement);
3586
+ currFocusedIndex > -1 && (this.stackedFocusedCellIndex = currFocusedIndex);
3587
+ }
3588
+ }));
3593
3589
  if (this.focusableParent) {
3594
3590
  const element = new GridFocusableElement(this);
3595
3591
  this.focusableParent.registerElement(element);
@@ -3853,14 +3849,16 @@ class NavigationService {
3853
3849
  return;
3854
3850
  }
3855
3851
  const row = this.cursor.row;
3856
- const dir = args.keyCode === Keys.ArrowDown ? 'Down' : 'Up';
3857
- const right = args.keyCode === Keys.ArrowRight;
3858
- const isArrowKey = args.code === 'ArrowDown' || args.code === 'ArrowUp' || args.code === 'ArrowLeft' || args.code === 'ArrowRight';
3852
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
3853
+ const code = normalizeNumpadKeys(args);
3854
+ const dir = code === Keys.ArrowDown ? 'Down' : 'Up';
3855
+ const right = code === Keys.ArrowRight;
3856
+ const isArrowKey = code === Keys.ArrowDown || code === Keys.ArrowUp || code === Keys.ArrowLeft || code === Keys.ArrowRight;
3859
3857
  if (!this.isShiftPressed && args.shiftKey && isArrowKey) {
3860
3858
  startNewSelection = true;
3861
3859
  this.isShiftPressed = true;
3862
3860
  }
3863
- switch (args.keyCode) {
3861
+ switch (code) {
3864
3862
  case Keys.ArrowDown:
3865
3863
  case Keys.ArrowUp:
3866
3864
  if (rowspan > 1) {
@@ -3975,7 +3973,7 @@ class NavigationService {
3975
3973
  case Keys.Enter:
3976
3974
  case Keys.F2: {
3977
3975
  if (this.stackedCellEntered) {
3978
- if (args.keyCode === Keys.F2 && row.dataRowIndex > -1) {
3976
+ if (code === Keys.F2 && row.dataRowIndex > -1) {
3979
3977
  this.zone.run(() => {
3980
3978
  this.editService.beginEdit(row.dataRowIndex);
3981
3979
  });
@@ -3991,7 +3989,7 @@ class NavigationService {
3991
3989
  this.zone.run(() => this.detailsService.toggleRow(row.dataRowIndex, row.dataItem));
3992
3990
  }
3993
3991
  else {
3994
- if (args.keyCode === Keys.F2 && row.dataRowIndex > -1) {
3992
+ if (code === Keys.F2 && row.dataRowIndex > -1) {
3995
3993
  this.zone.run(() => {
3996
3994
  this.editService.beginEdit(row.dataRowIndex);
3997
3995
  });
@@ -4035,9 +4033,11 @@ class NavigationService {
4035
4033
  if (!this.onCellKeydown(args)) {
4036
4034
  return;
4037
4035
  }
4038
- const confirm = !args.defaultPrevented && args.keyCode === Keys.Enter && isTextInput(args.target);
4039
- if (args.keyCode === Keys.Escape || args.keyCode === Keys.F2 || confirm) {
4040
- if (this.tableCellEntered && args.keyCode === Keys.F2 && this.activeRow.dataRowIndex > -1) {
4036
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
4037
+ const code = normalizeNumpadKeys(args);
4038
+ const confirm = !args.defaultPrevented && code === Keys.Enter && isTextInput(args.target);
4039
+ if (code === Keys.Escape || code === Keys.F2 || confirm) {
4040
+ if (this.tableCellEntered && code === Keys.F2 && this.activeRow.dataRowIndex > -1) {
4041
4041
  this.zone.run(() => {
4042
4042
  this.editService.beginEdit(this.activeRow.dataRowIndex);
4043
4043
  });
@@ -4048,7 +4048,7 @@ class NavigationService {
4048
4048
  this.cursor.reset();
4049
4049
  args.stopPropagation();
4050
4050
  }
4051
- else if (isNavigationKey(args.keyCode) && this.cursor.cell.focusGroup.isNavigable()) {
4051
+ else if (isNavigationKey(code) && this.cursor.cell.focusGroup.isNavigable()) {
4052
4052
  this.onCursorKeydown(args);
4053
4053
  if (args.defaultPrevented) {
4054
4054
  this.leaveCell();
@@ -4057,9 +4057,11 @@ class NavigationService {
4057
4057
  }
4058
4058
  onCellKeydown(args) {
4059
4059
  if (this.editService.isEditingCell()) {
4060
- const confirm = args.keyCode === Keys.Enter;
4061
- const cancel = args.keyCode === Keys.Escape;
4062
- const navigate = isNavigationKey(args.keyCode);
4060
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
4061
+ const code = normalizeNumpadKeys(args);
4062
+ const confirm = code === Keys.Enter;
4063
+ const cancel = code === Keys.Escape;
4064
+ const navigate = isNavigationKey(code);
4063
4065
  if (confirm) {
4064
4066
  this.editService.closeCell(args);
4065
4067
  }
@@ -4214,13 +4216,14 @@ class NavigationService {
4214
4216
  const stackedCell = closest(target, (el) => hasClasses$1(el, 'k-grid-stack-cell'));
4215
4217
  const tableCell = closest(target, (el) => hasClasses$1(el, 'k-table-td'));
4216
4218
  const isInStackedCell = closest(target, (el) => hasClasses$1(el, 'k-grid-stack-content'));
4219
+ const isInCommandCell = closest(target, (el) => hasClasses$1(el, 'k-command-cell'));
4217
4220
  if (!stackedCell || !tableCell) {
4218
4221
  return;
4219
4222
  }
4220
- if (args.keyCode === Keys.Tab) {
4223
+ if (args.code === Keys.Tab) {
4221
4224
  this.handleStackedTabNavigation(args);
4222
4225
  }
4223
- else if (args.keyCode === Keys.Backspace || args.keyCode === Keys.Delete) {
4226
+ else if (args.code === Keys.Backspace || args.code === Keys.Delete) {
4224
4227
  if (this.activeRow && this.activeRow.dataRowIndex >= 0 && this.activeRow.dataItem) {
4225
4228
  const row = this.cursor.row;
4226
4229
  if (!row.groupItem && !this.cursor.cell.detailExpandCell) {
@@ -4231,11 +4234,13 @@ class NavigationService {
4231
4234
  }
4232
4235
  }
4233
4236
  }
4234
- else if (isInStackedCell && (args.keyCode === Keys.Enter || args.keyCode === Keys.Escape)) {
4237
+ else if (isInStackedCell && (args.code === Keys.Enter || args.code === Keys.NumpadEnter || args.code === Keys.Escape)) {
4235
4238
  this.editService.closeCell(args);
4236
4239
  this.activeCell.focusGroup.activate();
4237
4240
  this.activeCell.focusGroup.focusableChildren[this.stackedFocusedCellIndex]?.focus();
4238
- args.preventDefault();
4241
+ if (!isInCommandCell) {
4242
+ args.preventDefault();
4243
+ }
4239
4244
  }
4240
4245
  }
4241
4246
  stackedFocusedCellIndex = -1;
@@ -4249,29 +4254,24 @@ class NavigationService {
4249
4254
  return;
4250
4255
  }
4251
4256
  const stackedCells = this.activeCell.focusGroup.focusableChildren;
4252
- let nextIndex;
4257
+ const currFocusedIndex = stackedCells.findIndex(el => el.hasFocus() || el.hostElement?.nativeElement === document.activeElement);
4253
4258
  if (args.shiftKey) {
4254
- nextIndex = this.stackedFocusedCellIndex - 1;
4255
- if (nextIndex < 0) {
4256
- nextIndex = stackedCells.length - 1;
4259
+ if (currFocusedIndex === 0) {
4260
+ args.stopImmediatePropagation();
4261
+ args.preventDefault();
4262
+ }
4263
+ else {
4264
+ this.stackedFocusedCellIndex = currFocusedIndex - 1;
4257
4265
  }
4258
4266
  }
4259
4267
  else {
4260
- nextIndex = this.stackedFocusedCellIndex + 1;
4261
- if (nextIndex >= stackedCells.length) {
4262
- nextIndex = 0;
4268
+ if (currFocusedIndex === stackedCells.length - 1) {
4269
+ args.stopImmediatePropagation();
4270
+ args.preventDefault();
4263
4271
  }
4264
- }
4265
- let nextStackedCell = stackedCells[nextIndex];
4266
- if (nextStackedCell) {
4267
- if (nextStackedCell.hasFocus() || (isDocumentAvailable() && document.activeElement === nextStackedCell.hostElement.nativeElement)) {
4268
- // next cell is already focused (as a focusable child of the previous one), skip to the next one
4269
- nextIndex = args.shiftKey ? this.stackedFocusedCellIndex - 2 : this.stackedFocusedCellIndex + 2;
4270
- nextStackedCell = stackedCells[nextIndex];
4272
+ else {
4273
+ this.stackedFocusedCellIndex = currFocusedIndex + 1;
4271
4274
  }
4272
- nextStackedCell.focus();
4273
- this.stackedFocusedCellIndex = nextIndex;
4274
- args.preventDefault();
4275
4275
  }
4276
4276
  }
4277
4277
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NavigationService, deps: [{ token: i0.NgZone }, { token: DomEventsService }, { token: i53.PagerContextService }, { token: ScrollRequestService }, { token: GroupsService }, { token: DetailsService }, { token: FocusRoot }, { token: EditService }, { token: i0.ChangeDetectorRef }, { token: ContextService }, { token: ColumnResizingService }, { token: FocusableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
@@ -6121,18 +6121,19 @@ class GroupPanelComponent {
6121
6121
  });
6122
6122
  }
6123
6123
  handleKeyDown = (e) => {
6124
- if (e.keyCode === Keys.ArrowDown || e.keyCode === Keys.ArrowUp) {
6124
+ const code = normalizeNumpadKeys(e);
6125
+ if (code === Keys.ArrowDown || code === Keys.ArrowUp) {
6125
6126
  e.preventDefault();
6126
6127
  const relatedItemType = e.target.matches(':first-child') ? 'next' : 'previous';
6127
6128
  this.activateMenuItem(e.target, relatedItemType);
6128
6129
  }
6129
- else if (e.keyCode === Keys.Escape) {
6130
+ else if (code === Keys.Escape) {
6130
6131
  this.destroyMenu(true);
6131
6132
  }
6132
- else if (e.keyCode === Keys.Tab) {
6133
+ else if (code === Keys.Tab) {
6133
6134
  this.destroyMenu(true);
6134
6135
  }
6135
- else if (e.keyCode === Keys.Space || e.keyCode === Keys.Enter) {
6136
+ else if (code === Keys.Space || code === Keys.Enter) {
6136
6137
  this.handleMenuClick(e);
6137
6138
  }
6138
6139
  };
@@ -7842,7 +7843,7 @@ class FilterCellOperatorsComponent {
7842
7843
  * @hidden
7843
7844
  */
7844
7845
  clearKeydown(args) {
7845
- if (args.keyCode === Keys.Enter || args.keyCode === Keys.Space) {
7846
+ if (args.code === Keys.Enter || args.code === Keys.NumpadEnter || args.code === Keys.Space) {
7846
7847
  this.clear.emit();
7847
7848
  }
7848
7849
  }
@@ -7853,7 +7854,7 @@ class FilterCellOperatorsComponent {
7853
7854
  if (args.defaultPrevented) {
7854
7855
  return;
7855
7856
  }
7856
- if (args.keyCode === Keys.Enter && !this.dropdown.isOpen) {
7857
+ if ((args.code === Keys.Enter || args.code === Keys.NumpadEnter) && !this.dropdown.isOpen) {
7857
7858
  this.dropdown.toggle(true);
7858
7859
  args.preventDefault();
7859
7860
  }
@@ -8780,7 +8781,7 @@ class FilterMenuDropDownListDirective {
8780
8781
  this.host.wrapper.nativeElement.removeEventListener('keydown', this.keydownHandler);
8781
8782
  }
8782
8783
  keydownHandler = (e) => {
8783
- if (e.keyCode === Keys.Escape && this.host.isOpen) {
8784
+ if (e.code === Keys.Escape && this.host.isOpen) {
8784
8785
  e.stopPropagation();
8785
8786
  this.host.toggle(false);
8786
8787
  }
@@ -12247,13 +12248,14 @@ class ColumnListComponent {
12247
12248
  }
12248
12249
  }
12249
12250
  onKeydown = (e) => {
12250
- if (e.keyCode !== Keys.Tab) {
12251
+ const code = normalizeNumpadKeys(e);
12252
+ if (code !== Keys.Tab) {
12251
12253
  e.preventDefault();
12252
12254
  }
12253
- if (e.key === 'Tab' && !e.shiftKey && this.autoSync) {
12255
+ if (code === 'Tab' && !e.shiftKey && this.autoSync) {
12254
12256
  e.preventDefault();
12255
12257
  }
12256
- if (e.key === 'Tab' && e.shiftKey) {
12258
+ if (code === 'Tab' && e.shiftKey) {
12257
12259
  this.ngZone.run(() => {
12258
12260
  if (e.target.matches('.k-column-list-item')) {
12259
12261
  e.preventDefault();
@@ -12261,13 +12263,13 @@ class ColumnListComponent {
12261
12263
  }
12262
12264
  });
12263
12265
  }
12264
- if (e.keyCode === Keys.ArrowDown) {
12266
+ if (code === Keys.ArrowDown) {
12265
12267
  this.listNavigationService.next();
12266
12268
  }
12267
- else if (e.keyCode === Keys.ArrowUp) {
12269
+ else if (code === Keys.ArrowUp) {
12268
12270
  this.listNavigationService.prev();
12269
12271
  }
12270
- else if (e.keyCode === Keys.Space && e.target.classList.contains('k-column-list-item')) {
12272
+ else if (code === Keys.Space && e.target.classList.contains('k-column-list-item')) {
12271
12273
  this.listNavigationService.toggleCheckedState();
12272
12274
  }
12273
12275
  };
@@ -12592,7 +12594,7 @@ class ColumnChooserComponent {
12592
12594
  const popupAriaElement = popupElement.querySelector('.k-popup');
12593
12595
  this.ngZone.runOutsideAngular(() => {
12594
12596
  this.escapeListener = this.renderer.listen(popupAriaElement, 'keydown', (e) => {
12595
- if (e.keyCode === Keys.Escape) {
12597
+ if (e.code === Keys.Escape) {
12596
12598
  this.close(true);
12597
12599
  }
12598
12600
  });
@@ -14458,7 +14460,7 @@ class ColumnMenuItemDirective {
14458
14460
  }
14459
14461
  }
14460
14462
  onTab = (e) => {
14461
- if (e.keyCode !== Keys.Tab) {
14463
+ if (e.code !== Keys.Tab) {
14462
14464
  return;
14463
14465
  }
14464
14466
  if (this.isFirst && e.shiftKey && e.target === this.columnMenuItems[0]) {
@@ -18106,14 +18108,15 @@ class HeaderComponent {
18106
18108
  this.sortColumn(toggledColumn);
18107
18109
  }
18108
18110
  onHeaderKeydown(column, args) {
18109
- if (args.keyCode === Keys.ArrowDown && args.altKey && this.showFilterMenu) {
18111
+ const code = normalizeNumpadKeys(args);
18112
+ if (code === Keys.ArrowDown && args.altKey && this.showFilterMenu) {
18110
18113
  args.preventDefault();
18111
18114
  args.stopImmediatePropagation();
18112
18115
  const filterMenu = this.filterMenus.find(fm => fm.column === column);
18113
18116
  filterMenu.toggle(filterMenu.anchor.nativeElement, filterMenu.template);
18114
18117
  return;
18115
18118
  }
18116
- if (args.keyCode === Keys.ArrowDown && args.altKey && this.showColumnMenu(column)) {
18119
+ if (code === Keys.ArrowDown && args.altKey && this.showColumnMenu(column)) {
18117
18120
  args.preventDefault();
18118
18121
  args.stopImmediatePropagation();
18119
18122
  const columnMenu = this.columnMenus.find(cm => cm.column === column);
@@ -18121,7 +18124,7 @@ class HeaderComponent {
18121
18124
  return;
18122
18125
  }
18123
18126
  const isCtrlOrMeta = args.ctrlKey || args.metaKey;
18124
- const isGroupingKeyShortcut = (args.keyCode === Keys.Enter || args.keyCode === Keys.Space) && isCtrlOrMeta;
18127
+ const isGroupingKeyShortcut = (code === Keys.Enter || code === Keys.Space) && isCtrlOrMeta;
18125
18128
  if (isGroupingKeyShortcut && this.isGroupable(column)) {
18126
18129
  args.preventDefault();
18127
18130
  args.stopImmediatePropagation();
@@ -18137,12 +18140,12 @@ class HeaderComponent {
18137
18140
  this.contextService.grid.groupChange.emit(this.groups);
18138
18141
  return;
18139
18142
  }
18140
- const isLeftOrRightArrow = args.keyCode === Keys.ArrowLeft || args.keyCode === Keys.ArrowRight;
18143
+ const isLeftOrRightArrow = code === Keys.ArrowLeft || code === Keys.ArrowRight;
18141
18144
  const isReorderingKeyShortcut = isLeftOrRightArrow && isCtrlOrMeta;
18142
18145
  if (isReorderingKeyShortcut && this.isReorderable(column)) {
18143
18146
  args.preventDefault();
18144
18147
  const columnsCount = this.columnInfoService.leafNamedColumns.length;
18145
- const reorderDirection = args.keyCode === Keys.ArrowLeft ? -1 : 1;
18148
+ const reorderDirection = code === Keys.ArrowLeft ? -1 : 1;
18146
18149
  const rtlMultiplier = this.contextService.localization.rtl ? -1 : 1;
18147
18150
  const reorderDirectionOffset = reorderDirection * rtlMultiplier;
18148
18151
  const newIndex = column.leafIndex + reorderDirectionOffset;
@@ -18159,7 +18162,7 @@ class HeaderComponent {
18159
18162
  if (!this.sortable || args.defaultPrevented || column.sortable === false) {
18160
18163
  return;
18161
18164
  }
18162
- if (args.keyCode === Keys.Enter && isPresent(column.field)) {
18165
+ if (code === Keys.Enter && isPresent(column.field)) {
18163
18166
  const modifier = this.matchModifier(args);
18164
18167
  this.sortService.sort(this.toggleSort(column, modifier));
18165
18168
  }
@@ -19408,7 +19411,7 @@ class SelectionCheckboxDirective {
19408
19411
  }
19409
19412
  }
19410
19413
  onKeyDown(e) {
19411
- if (e.keyCode === Keys.Enter) {
19414
+ if (e.code === Keys.Enter || e.code === Keys.NumpadEnter) {
19412
19415
  this.onClick(e);
19413
19416
  }
19414
19417
  }
@@ -19716,7 +19719,7 @@ class CellComponent {
19716
19719
  [class.k-grid-stack-edit-cell]="isEdited(col)"
19717
19720
  [class.k-drag-cell]="isRowReorderColumn(col) && !isNew"
19718
19721
  [class.k-command-cell]="isCommand(col)"
19719
- kendoGridFocusable>
19722
+ [kendoGridFocusable]="!isCommand(col)">
19720
19723
  <div class="k-grid-stack-header">
19721
19724
  <ng-container *ngIf="!col.headerTemplateRef; else headerTemplate">
19722
19725
  {{col.displayTitle}}
@@ -19924,7 +19927,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
19924
19927
  [class.k-grid-stack-edit-cell]="isEdited(col)"
19925
19928
  [class.k-drag-cell]="isRowReorderColumn(col) && !isNew"
19926
19929
  [class.k-command-cell]="isCommand(col)"
19927
- kendoGridFocusable>
19930
+ [kendoGridFocusable]="!isCommand(col)">
19928
19931
  <div class="k-grid-stack-header">
19929
19932
  <ng-container *ngIf="!col.headerTemplateRef; else headerTemplate">
19930
19933
  {{col.displayTitle}}
@@ -20434,7 +20437,7 @@ class TableBodyComponent {
20434
20437
  const element = this.element.nativeElement;
20435
20438
  const target = this.eventTarget(eventArg);
20436
20439
  const selectionEnabled = this.selectable && this.selectable.enabled !== false;
20437
- if (eventArg.keyCode === Keys.Space) {
20440
+ if (eventArg.code === Keys.Space) {
20438
20441
  if (!selectionEnabled) {
20439
20442
  return;
20440
20443
  }
@@ -20523,7 +20526,7 @@ class TableBodyComponent {
20523
20526
  }));
20524
20527
  }
20525
20528
  cellKeydownHandler(args) {
20526
- if (args.keyCode === Keys.Enter || args.keyCode === Keys.Space || (this.navigationService.tableCellEntered && args.keyCode === Keys.F2)) {
20529
+ if (args.code === Keys.Enter || args.code === Keys.NumpadEnter || args.code === Keys.Space || (this.navigationService.tableCellEntered && args.code === Keys.F2)) {
20527
20530
  this.clickHandler(args);
20528
20531
  }
20529
20532
  }
@@ -21998,8 +22001,8 @@ const packageMetadata = {
21998
22001
  productName: 'Kendo UI for Angular',
21999
22002
  productCode: 'KENDOUIANGULAR',
22000
22003
  productCodes: ['KENDOUIANGULAR'],
22001
- publishDate: 1754576745,
22002
- version: '19.3.0-develop.31',
22004
+ publishDate: 1754589878,
22005
+ version: '19.3.0-develop.33',
22003
22006
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
22004
22007
  };
22005
22008
 
@@ -24546,8 +24549,10 @@ class ListComponent {
24546
24549
  }
24547
24550
  }
24548
24551
  lockedKeydown(args) {
24549
- if (args.keyCode === Keys.PageDown || args.keyCode === Keys.PageUp) {
24550
- const dir = args.keyCode === Keys.PageDown ? 1 : -1;
24552
+ // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
24553
+ const code = normalizeNumpadKeys(args);
24554
+ if (code === Keys.PageDown || code === Keys.PageUp) {
24555
+ const dir = code === Keys.PageDown ? 1 : -1;
24551
24556
  const element = this.container.nativeElement;
24552
24557
  element.scrollTop += element.offsetHeight * dir * 0.8;
24553
24558
  args.preventDefault();
@@ -27174,30 +27179,32 @@ class GroupToolbarToolComponent {
27174
27179
  this.currentFocusedItemIndex = currentIndex;
27175
27180
  }
27176
27181
  handleGroupedKeydown(column, index, ev) {
27177
- if (ev.code === 'Enter' || ev.code === 'Backspace' || ev.code === 'Delete') {
27182
+ const code = normalizeNumpadKeys(ev);
27183
+ if (code === Keys.Enter || code === Keys.Backspace || code === Keys.Delete) {
27178
27184
  this.removeGroup(column, ev);
27179
27185
  }
27180
- else if (ev.code === 'ArrowUp' && ev.shiftKey) {
27186
+ else if (code === Keys.ArrowUp && ev.shiftKey) {
27181
27187
  this.moveGroupUp(column, ev);
27182
27188
  }
27183
- else if (ev.code === 'ArrowDown' && ev.shiftKey) {
27189
+ else if (code === Keys.ArrowDown && ev.shiftKey) {
27184
27190
  this.moveGroupDown(column, ev);
27185
27191
  }
27186
- else if (ev.code === 'ArrowUp') {
27192
+ else if (code === Keys.ArrowUp) {
27187
27193
  this.navigateToPreviousItem();
27188
27194
  }
27189
- else if (ev.code === 'ArrowDown') {
27195
+ else if (code === Keys.ArrowDown) {
27190
27196
  this.navigateToNextItem();
27191
27197
  }
27192
27198
  }
27193
27199
  handleUngroupedKeydown(column, index, ev) {
27194
- if (ev.code === 'Enter') {
27200
+ const code = normalizeNumpadKeys(ev);
27201
+ if (code === Keys.Enter) {
27195
27202
  this.addGroup(column, ev);
27196
27203
  }
27197
- else if (ev.code === 'ArrowUp') {
27204
+ else if (code === Keys.ArrowUp) {
27198
27205
  this.navigateToPreviousItem();
27199
27206
  }
27200
- else if (ev.code === 'ArrowDown') {
27207
+ else if (code === Keys.ArrowDown) {
27201
27208
  this.navigateToNextItem();
27202
27209
  }
27203
27210
  }
@@ -30600,6 +30607,7 @@ class GridComponent {
30600
30607
  */
30601
30608
  closeRow(index) {
30602
30609
  this.editService.close(index);
30610
+ this.isStacked && (this.navigationService.stackedCellEntered = false);
30603
30611
  }
30604
30612
  /**
30605
30613
  * Creates a new row editor ([see example]({% slug inline_editing_grid %}#toc-adding-records-1)).
@@ -34159,7 +34167,7 @@ class InCellEditingDirective extends EditingDirectiveBase {
34159
34167
  args.preventDefault();
34160
34168
  }
34161
34169
  else if (formGroup.dirty) {
34162
- if (args.originalEvent && args.originalEvent.keyCode === Keys.Escape) {
34170
+ if (args.originalEvent && args.originalEvent.code === Keys.Escape) {
34163
34171
  return;
34164
34172
  }
34165
34173
  this.editService.assignValues(dataItem, formGroup.value);
@@ -60,7 +60,7 @@ export declare class GroupPanelComponent implements OnDestroy, DoCheck {
60
60
  insert(field: string, index: number): void;
61
61
  remove(group: GroupDescriptor): void;
62
62
  toggleMenu(chip: ChipComponent, first: boolean, last: boolean, field: string): void;
63
- handleKeyDown: (e: any) => void;
63
+ handleKeyDown: (e: KeyboardEvent) => void;
64
64
  handleClick: (e: any) => void;
65
65
  canDrop(draggable: DragAndDropContext, target: DragAndDropContext): boolean;
66
66
  private attachTargets;
@@ -4,18 +4,16 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { ElementRef, Renderer2 } from '@angular/core';
6
6
  import { FocusableElement } from './focusable-element.interface';
7
- import { ContextService } from '../common/provider.service';
8
7
  /**
9
8
  * @hidden
10
9
  */
11
10
  export declare class DefaultFocusableElement implements FocusableElement {
12
11
  private renderer;
13
- private ctx;
14
12
  private get enabled();
15
13
  private get visible();
16
14
  private element;
17
15
  private focusable;
18
- constructor(host: ElementRef, renderer: Renderer2, ctx: ContextService);
16
+ constructor(host: ElementRef, renderer: Renderer2);
19
17
  isNavigable(): boolean;
20
18
  toggle(active: boolean): void;
21
19
  focus(): void;
@@ -126,7 +126,7 @@ export declare class NavigationService implements OnDestroy {
126
126
  private calculateRowspanOffset;
127
127
  private get isStackedMode();
128
128
  private handleStackedKeydown;
129
- private stackedFocusedCellIndex;
129
+ stackedFocusedCellIndex: number;
130
130
  tableCellEntered: boolean;
131
131
  stackedCellEntered: boolean;
132
132
  private handleStackedTabNavigation;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-grid",
3
- "version": "19.3.0-develop.31",
3
+ "version": "19.3.0-develop.33",
4
4
  "description": "Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -26,7 +26,7 @@
26
26
  "package": {
27
27
  "productName": "Kendo UI for Angular",
28
28
  "productCode": "KENDOUIANGULAR",
29
- "publishDate": 1754576745,
29
+ "publishDate": 1754589878,
30
30
  "licensingDocsUrl": "https://www.telerik.com/kendo-angular-ui/my-license/"
31
31
  }
32
32
  },
@@ -39,29 +39,29 @@
39
39
  "@progress/kendo-data-query": "^1.0.0",
40
40
  "@progress/kendo-drawing": "^1.21.0",
41
41
  "@progress/kendo-licensing": "^1.7.0",
42
- "@progress/kendo-angular-buttons": "19.3.0-develop.31",
43
- "@progress/kendo-angular-common": "19.3.0-develop.31",
44
- "@progress/kendo-angular-dateinputs": "19.3.0-develop.31",
45
- "@progress/kendo-angular-layout": "19.3.0-develop.31",
46
- "@progress/kendo-angular-navigation": "19.3.0-develop.31",
47
- "@progress/kendo-angular-dropdowns": "19.3.0-develop.31",
48
- "@progress/kendo-angular-excel-export": "19.3.0-develop.31",
49
- "@progress/kendo-angular-icons": "19.3.0-develop.31",
50
- "@progress/kendo-angular-inputs": "19.3.0-develop.31",
51
- "@progress/kendo-angular-conversational-ui": "19.3.0-develop.31",
52
- "@progress/kendo-angular-intl": "19.3.0-develop.31",
53
- "@progress/kendo-angular-l10n": "19.3.0-develop.31",
54
- "@progress/kendo-angular-label": "19.3.0-develop.31",
55
- "@progress/kendo-angular-pager": "19.3.0-develop.31",
56
- "@progress/kendo-angular-pdf-export": "19.3.0-develop.31",
57
- "@progress/kendo-angular-popup": "19.3.0-develop.31",
58
- "@progress/kendo-angular-toolbar": "19.3.0-develop.31",
59
- "@progress/kendo-angular-utils": "19.3.0-develop.31",
42
+ "@progress/kendo-angular-buttons": "19.3.0-develop.33",
43
+ "@progress/kendo-angular-common": "19.3.0-develop.33",
44
+ "@progress/kendo-angular-dateinputs": "19.3.0-develop.33",
45
+ "@progress/kendo-angular-layout": "19.3.0-develop.33",
46
+ "@progress/kendo-angular-navigation": "19.3.0-develop.33",
47
+ "@progress/kendo-angular-dropdowns": "19.3.0-develop.33",
48
+ "@progress/kendo-angular-excel-export": "19.3.0-develop.33",
49
+ "@progress/kendo-angular-icons": "19.3.0-develop.33",
50
+ "@progress/kendo-angular-inputs": "19.3.0-develop.33",
51
+ "@progress/kendo-angular-conversational-ui": "19.3.0-develop.33",
52
+ "@progress/kendo-angular-intl": "19.3.0-develop.33",
53
+ "@progress/kendo-angular-l10n": "19.3.0-develop.33",
54
+ "@progress/kendo-angular-label": "19.3.0-develop.33",
55
+ "@progress/kendo-angular-pager": "19.3.0-develop.33",
56
+ "@progress/kendo-angular-pdf-export": "19.3.0-develop.33",
57
+ "@progress/kendo-angular-popup": "19.3.0-develop.33",
58
+ "@progress/kendo-angular-toolbar": "19.3.0-develop.33",
59
+ "@progress/kendo-angular-utils": "19.3.0-develop.33",
60
60
  "rxjs": "^6.5.3 || ^7.0.0"
61
61
  },
62
62
  "dependencies": {
63
63
  "tslib": "^2.3.1",
64
- "@progress/kendo-angular-schematics": "19.3.0-develop.31",
64
+ "@progress/kendo-angular-schematics": "19.3.0-develop.33",
65
65
  "@progress/kendo-common": "^1.0.1",
66
66
  "@progress/kendo-file-saver": "^1.0.0"
67
67
  },
@@ -4,14 +4,14 @@ const schematics_1 = require("@angular-devkit/schematics");
4
4
  function default_1(options) {
5
5
  const finalOptions = Object.assign(Object.assign({}, options), { mainNgModule: 'GridModule', package: 'grid', peerDependencies: {
6
6
  // peer deps of the dropdowns
7
- '@progress/kendo-angular-treeview': '19.3.0-develop.31',
8
- '@progress/kendo-angular-navigation': '19.3.0-develop.31',
7
+ '@progress/kendo-angular-treeview': '19.3.0-develop.33',
8
+ '@progress/kendo-angular-navigation': '19.3.0-develop.33',
9
9
  // peer dependency of kendo-angular-inputs
10
- '@progress/kendo-angular-dialog': '19.3.0-develop.31',
10
+ '@progress/kendo-angular-dialog': '19.3.0-develop.33',
11
11
  // peer dependency of kendo-angular-icons
12
12
  '@progress/kendo-svg-icons': '^4.0.0',
13
13
  // peer dependency of kendo-angular-layout
14
- '@progress/kendo-angular-progressbar': '19.3.0-develop.31'
14
+ '@progress/kendo-angular-progressbar': '19.3.0-develop.33'
15
15
  } });
16
16
  return (0, schematics_1.externalSchematic)('@progress/kendo-angular-schematics', 'ng-add', finalOptions);
17
17
  }