@progress/kendo-angular-treelist 21.0.0-develop.11 → 21.0.0-develop.12

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.
@@ -20,6 +20,8 @@ import { closest, contains, findFocusableChild, isVisible, matchesNodeName } fro
20
20
  import { ScrollRequestService } from '../scrolling/scroll-request.service';
21
21
  import { SelectionService } from '../selection/selection.service';
22
22
  import { PagerContextService } from '@progress/kendo-angular-pager';
23
+ import { ContextService } from '../common/provider.service';
24
+ import { hasClasses } from '@progress/kendo-angular-common';
23
25
  import * as i0 from "@angular/core";
24
26
  import * as i1 from "../common/dom-events.service";
25
27
  import * as i2 from "@progress/kendo-angular-pager";
@@ -29,7 +31,8 @@ import * as i5 from "../editing/edit.service";
29
31
  import * as i6 from "@progress/kendo-angular-l10n";
30
32
  import * as i7 from "../expand-state/expand-state.service";
31
33
  import * as i8 from "../selection/selection.service";
32
- import * as i9 from "./focusable.directive";
34
+ import * as i9 from "../common/provider.service";
35
+ import * as i10 from "./focusable.directive";
33
36
  const isInSameTreeList = (element, treelistElement) => closest(element, matchesNodeName('kendo-treelist')) === treelistElement;
34
37
  const matchHeaderCell = matchesNodeName('th');
35
38
  const matchDataCell = matchesNodeName('td');
@@ -96,6 +99,7 @@ export class NavigationService {
96
99
  expandState;
97
100
  selectionService;
98
101
  changeDetector;
102
+ ctx;
99
103
  focusableParent;
100
104
  changes;
101
105
  cellKeydown = new EventEmitter();
@@ -136,7 +140,7 @@ export class NavigationService {
136
140
  get activeDataRow() {
137
141
  return Math.max(0, this.activeRowIndex - this.meta.headerRows);
138
142
  }
139
- constructor(zone, domEvents, pagerContextService, scrollRequestService, focusRoot, editService, localization, expandState, selectionService, changeDetector, focusableParent) {
143
+ constructor(zone, domEvents, pagerContextService, scrollRequestService, focusRoot, editService, localization, expandState, selectionService, changeDetector, ctx, focusableParent) {
140
144
  this.zone = zone;
141
145
  this.domEvents = domEvents;
142
146
  this.pagerContextService = pagerContextService;
@@ -147,6 +151,7 @@ export class NavigationService {
147
151
  this.expandState = expandState;
148
152
  this.selectionService = selectionService;
149
153
  this.changeDetector = changeDetector;
154
+ this.ctx = ctx;
150
155
  this.focusableParent = focusableParent;
151
156
  this.changes = this.cursor.changes;
152
157
  }
@@ -400,6 +405,13 @@ export class NavigationService {
400
405
  }
401
406
  // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
402
407
  const code = normalizeNumpadKeys(args);
408
+ if ((args.ctrlKey || args.metaKey) && args.shiftKey && (code === Keys.ArrowUp || code === Keys.ArrowDown)) {
409
+ const row = this.cursor.row;
410
+ if (this.handleRowReorderKeyboard(args, code, row)) {
411
+ args.preventDefault();
412
+ return;
413
+ }
414
+ }
403
415
  const row = this.cursor.row;
404
416
  switch (code) {
405
417
  case Keys.Space:
@@ -414,13 +426,13 @@ export class NavigationService {
414
426
  break;
415
427
  case Keys.ArrowDown:
416
428
  preventDefault = this.cursor.moveDown(step);
417
- if (preventDefault && args.shiftKey) {
429
+ if (preventDefault && args.shiftKey && !modifier) {
418
430
  this.updateSelection(args);
419
431
  }
420
432
  break;
421
433
  case Keys.ArrowUp:
422
434
  preventDefault = this.cursor.moveUp(step);
423
- if (preventDefault && args.shiftKey) {
435
+ if (preventDefault && args.shiftKey && !modifier) {
424
436
  this.updateSelection(args);
425
437
  }
426
438
  break;
@@ -615,6 +627,45 @@ export class NavigationService {
615
627
  this.deactivateElements();
616
628
  this.cursor.announce();
617
629
  }
630
+ handleRowReorderKeyboard(args, code, row) {
631
+ if (!this.ctx.treelist?.rowReorderable || !this.activeCell) {
632
+ return false;
633
+ }
634
+ const cellElement = args.target;
635
+ if (!cellElement) {
636
+ return false;
637
+ }
638
+ const dragCell = closest(cellElement, (el) => hasClasses(el, 'k-drag-cell'));
639
+ if (!dragCell || row.dataRowIndex < 0 || !row.dataItem) {
640
+ return false;
641
+ }
642
+ const isUpArrow = code === Keys.ArrowUp;
643
+ const currentRowIndex = row.dataRowIndex;
644
+ const view = this.ctx.treelist.view;
645
+ if (!view || view.length === 0) {
646
+ return false;
647
+ }
648
+ const targetRowIndex = currentRowIndex + (isUpArrow ? -1 : 1);
649
+ if (targetRowIndex < 0 || targetRowIndex >= view.length) {
650
+ return false;
651
+ }
652
+ const dropPosition = isUpArrow ? 'before' : 'after';
653
+ this.zone.run(() => {
654
+ const rowReorderService = this.ctx.treelist.rowReorderService;
655
+ if (rowReorderService?.reorderViaKeyboard) {
656
+ // Convert ViewCollection to array for the reorder method
657
+ const viewArray = Array.from({ length: view.length }, (_, i) => view.at(i));
658
+ rowReorderService.reorderViaKeyboard(currentRowIndex, targetRowIndex, dropPosition, viewArray);
659
+ // Move focus to follow the reordered row
660
+ // After reordering, the row will be at the target position
661
+ this.zone.onStable.pipe(take(1)).subscribe(() => {
662
+ const newRowIndex = this.meta.headerRows + targetRowIndex;
663
+ this.cursor.reset(newRowIndex, this.activeCell.colIndex);
664
+ });
665
+ }
666
+ });
667
+ return true;
668
+ }
618
669
  onKeydown(args) {
619
670
  if (this.mode === 1 /* NavigationMode.Cursor */) {
620
671
  this.onCursorKeydown(args);
@@ -634,11 +685,11 @@ export class NavigationService {
634
685
  this.leaveCell();
635
686
  this.cursor.reset();
636
687
  }
637
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavigationService, deps: [{ token: i0.NgZone }, { token: i1.DomEventsService }, { token: i2.PagerContextService }, { token: i3.ScrollRequestService }, { token: i4.FocusRoot }, { token: i5.EditService }, { token: i6.LocalizationService }, { token: i7.ExpandStateService }, { token: i8.SelectionService }, { token: i0.ChangeDetectorRef }, { token: i9.FocusableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
688
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavigationService, deps: [{ token: i0.NgZone }, { token: i1.DomEventsService }, { token: i2.PagerContextService }, { token: i3.ScrollRequestService }, { token: i4.FocusRoot }, { token: i5.EditService }, { token: i6.LocalizationService }, { token: i7.ExpandStateService }, { token: i8.SelectionService }, { token: i0.ChangeDetectorRef }, { token: i9.ContextService }, { token: i10.FocusableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
638
689
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavigationService });
639
690
  }
640
691
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavigationService, decorators: [{
641
692
  type: Injectable
642
- }], ctorParameters: () => [{ type: i0.NgZone }, { type: i1.DomEventsService }, { type: i2.PagerContextService }, { type: i3.ScrollRequestService }, { type: i4.FocusRoot }, { type: i5.EditService }, { type: i6.LocalizationService }, { type: i7.ExpandStateService }, { type: i8.SelectionService }, { type: i0.ChangeDetectorRef }, { type: i9.FocusableDirective, decorators: [{
693
+ }], ctorParameters: () => [{ type: i0.NgZone }, { type: i1.DomEventsService }, { type: i2.PagerContextService }, { type: i3.ScrollRequestService }, { type: i4.FocusRoot }, { type: i5.EditService }, { type: i6.LocalizationService }, { type: i7.ExpandStateService }, { type: i8.SelectionService }, { type: i0.ChangeDetectorRef }, { type: i9.ContextService }, { type: i10.FocusableDirective, decorators: [{
643
694
  type: Optional
644
695
  }] }] });
@@ -10,7 +10,7 @@ export const packageMetadata = {
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCode: 'KENDOUIANGULAR',
12
12
  productCodes: ['KENDOUIANGULAR'],
13
- publishDate: 1761916649,
14
- version: '21.0.0-develop.11',
13
+ publishDate: 1761924258,
14
+ version: '21.0.0-develop.12',
15
15
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
16
16
  };
@@ -104,6 +104,34 @@ export class RowReorderService {
104
104
  }
105
105
  isOverChild(_item) { return false; }
106
106
  reorderRows(_ev, _collection, _field) { }
107
+ /**
108
+ * Triggers row reordering programmatically via keyboard shortcut.
109
+ * @param dragRowIndex - The index of the row to move
110
+ * @param dropRowIndex - The index of the target row
111
+ * @param dropPosition - The position relative to the target row ('before' or 'after')
112
+ * @param data - The data array (view)
113
+ */
114
+ reorderViaKeyboard(dragRowIndex, dropRowIndex, dropPosition, data) {
115
+ if (dropPosition === 'forbidden') {
116
+ return;
117
+ }
118
+ const dragRow = this.createVirtualRowElement(dragRowIndex);
119
+ const dropRow = this.createVirtualRowElement(dropRowIndex);
120
+ this.lastDropPosition = dropPosition;
121
+ const rowReorderArgs = this.rowReorderArgs(dragRow, dropRow, data);
122
+ this.rowReorder.emit(rowReorderArgs);
123
+ }
124
+ createVirtualRowElement(rowIndex) {
125
+ const virtualElement = {
126
+ getAttribute: (attr) => {
127
+ if (attr === rowIndexAttr) {
128
+ return String(rowIndex);
129
+ }
130
+ return null;
131
+ }
132
+ };
133
+ return virtualElement;
134
+ }
107
135
  get parentIdField() {
108
136
  return this.bindingDirective.parentIdField;
109
137
  }
@@ -49,8 +49,8 @@ const packageMetadata = {
49
49
  productName: 'Kendo UI for Angular',
50
50
  productCode: 'KENDOUIANGULAR',
51
51
  productCodes: ['KENDOUIANGULAR'],
52
- publishDate: 1761916649,
53
- version: '21.0.0-develop.11',
52
+ publishDate: 1761924258,
53
+ version: '21.0.0-develop.12',
54
54
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
55
55
  };
56
56
 
@@ -4509,6 +4509,80 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
4509
4509
  type: Injectable
4510
4510
  }] });
4511
4511
 
4512
+ /**
4513
+ * @hidden
4514
+ */
4515
+ class TreeListToolbarNavigationService {
4516
+ renderer;
4517
+ navigableElements = [];
4518
+ currentActiveIndex = 0;
4519
+ defaultFocusableSelector = `
4520
+ [kendoTreeListToolbarFocusable],
4521
+ [kendoTreeListAddCommand],
4522
+ [kendoTreeListCancelCommand],
4523
+ [kendoTreeListEditCommand],
4524
+ [kendoTreeListRemoveCommand],
4525
+ [kendoTreeListSaveCommand],
4526
+ [kendoTreeListExcelCommand],
4527
+ [kendoTreeListPDFCommand]
4528
+ `;
4529
+ constructor(renderer) {
4530
+ this.renderer = renderer;
4531
+ }
4532
+ notify() {
4533
+ // ensure focusable elements are in the same order as in the DOM
4534
+ this.navigableElements = (this.navigableElements.length && this.navigableElements[0]?.parentElement) ? Array.from(this.navigableElements[0]?.parentElement?.querySelectorAll(this.defaultFocusableSelector) || []) : [];
4535
+ this.currentActiveIndex = 0;
4536
+ this.updateFocus();
4537
+ }
4538
+ focus() {
4539
+ this.navigableElements[this.currentActiveIndex]?.focus();
4540
+ }
4541
+ updateFocus() {
4542
+ if (!this.navigableElements.length) {
4543
+ return;
4544
+ }
4545
+ this.navigableElements.forEach(el => {
4546
+ this.renderer.setAttribute(el, 'tabindex', '-1');
4547
+ });
4548
+ this.renderer.setAttribute(this.navigableElements[this.currentActiveIndex], 'tabindex', '0');
4549
+ if (isDocumentAvailable() && document.activeElement.closest('.k-toolbar')) {
4550
+ this.navigableElements[this.currentActiveIndex].focus();
4551
+ }
4552
+ }
4553
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TreeListToolbarNavigationService, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Injectable });
4554
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TreeListToolbarNavigationService });
4555
+ }
4556
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TreeListToolbarNavigationService, decorators: [{
4557
+ type: Injectable
4558
+ }], ctorParameters: () => [{ type: i0.Renderer2 }] });
4559
+
4560
+ /**
4561
+ * @hidden
4562
+ *
4563
+ * The Context service is used to provide common
4564
+ * services and DI tokens for a Grid instance.
4565
+ *
4566
+ * This keeps the constructor parameters stable
4567
+ * and a avoids dependency cycles between components.
4568
+ */
4569
+ class ContextService {
4570
+ localization;
4571
+ treelist;
4572
+ topToolbarNavigation;
4573
+ bottomToolbarNavigation;
4574
+ constructor(renderer, localization) {
4575
+ this.localization = localization;
4576
+ this.topToolbarNavigation = new TreeListToolbarNavigationService(renderer);
4577
+ this.bottomToolbarNavigation = new TreeListToolbarNavigationService(renderer);
4578
+ }
4579
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ContextService, deps: [{ token: i0.Renderer2 }, { token: i1$1.LocalizationService }], target: i0.ɵɵFactoryTarget.Injectable });
4580
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ContextService });
4581
+ }
4582
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ContextService, decorators: [{
4583
+ type: Injectable
4584
+ }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i1$1.LocalizationService }] });
4585
+
4512
4586
  const isInSameTreeList = (element, treelistElement) => closest(element, matchesNodeName('kendo-treelist')) === treelistElement;
4513
4587
  const matchHeaderCell = matchesNodeName('th');
4514
4588
  const matchDataCell = matchesNodeName('td');
@@ -4575,6 +4649,7 @@ class NavigationService {
4575
4649
  expandState;
4576
4650
  selectionService;
4577
4651
  changeDetector;
4652
+ ctx;
4578
4653
  focusableParent;
4579
4654
  changes;
4580
4655
  cellKeydown = new EventEmitter();
@@ -4615,7 +4690,7 @@ class NavigationService {
4615
4690
  get activeDataRow() {
4616
4691
  return Math.max(0, this.activeRowIndex - this.meta.headerRows);
4617
4692
  }
4618
- constructor(zone, domEvents, pagerContextService, scrollRequestService, focusRoot, editService, localization, expandState, selectionService, changeDetector, focusableParent) {
4693
+ constructor(zone, domEvents, pagerContextService, scrollRequestService, focusRoot, editService, localization, expandState, selectionService, changeDetector, ctx, focusableParent) {
4619
4694
  this.zone = zone;
4620
4695
  this.domEvents = domEvents;
4621
4696
  this.pagerContextService = pagerContextService;
@@ -4626,6 +4701,7 @@ class NavigationService {
4626
4701
  this.expandState = expandState;
4627
4702
  this.selectionService = selectionService;
4628
4703
  this.changeDetector = changeDetector;
4704
+ this.ctx = ctx;
4629
4705
  this.focusableParent = focusableParent;
4630
4706
  this.changes = this.cursor.changes;
4631
4707
  }
@@ -4879,6 +4955,13 @@ class NavigationService {
4879
4955
  }
4880
4956
  // on some keyboards arrow keys, PageUp/Down, and Home/End are mapped to Numpad keys
4881
4957
  const code = normalizeNumpadKeys(args);
4958
+ if ((args.ctrlKey || args.metaKey) && args.shiftKey && (code === Keys.ArrowUp || code === Keys.ArrowDown)) {
4959
+ const row = this.cursor.row;
4960
+ if (this.handleRowReorderKeyboard(args, code, row)) {
4961
+ args.preventDefault();
4962
+ return;
4963
+ }
4964
+ }
4882
4965
  const row = this.cursor.row;
4883
4966
  switch (code) {
4884
4967
  case Keys.Space:
@@ -4893,13 +4976,13 @@ class NavigationService {
4893
4976
  break;
4894
4977
  case Keys.ArrowDown:
4895
4978
  preventDefault = this.cursor.moveDown(step);
4896
- if (preventDefault && args.shiftKey) {
4979
+ if (preventDefault && args.shiftKey && !modifier) {
4897
4980
  this.updateSelection(args);
4898
4981
  }
4899
4982
  break;
4900
4983
  case Keys.ArrowUp:
4901
4984
  preventDefault = this.cursor.moveUp(step);
4902
- if (preventDefault && args.shiftKey) {
4985
+ if (preventDefault && args.shiftKey && !modifier) {
4903
4986
  this.updateSelection(args);
4904
4987
  }
4905
4988
  break;
@@ -5094,6 +5177,45 @@ class NavigationService {
5094
5177
  this.deactivateElements();
5095
5178
  this.cursor.announce();
5096
5179
  }
5180
+ handleRowReorderKeyboard(args, code, row) {
5181
+ if (!this.ctx.treelist?.rowReorderable || !this.activeCell) {
5182
+ return false;
5183
+ }
5184
+ const cellElement = args.target;
5185
+ if (!cellElement) {
5186
+ return false;
5187
+ }
5188
+ const dragCell = closest(cellElement, (el) => hasClasses$1(el, 'k-drag-cell'));
5189
+ if (!dragCell || row.dataRowIndex < 0 || !row.dataItem) {
5190
+ return false;
5191
+ }
5192
+ const isUpArrow = code === Keys.ArrowUp;
5193
+ const currentRowIndex = row.dataRowIndex;
5194
+ const view = this.ctx.treelist.view;
5195
+ if (!view || view.length === 0) {
5196
+ return false;
5197
+ }
5198
+ const targetRowIndex = currentRowIndex + (isUpArrow ? -1 : 1);
5199
+ if (targetRowIndex < 0 || targetRowIndex >= view.length) {
5200
+ return false;
5201
+ }
5202
+ const dropPosition = isUpArrow ? 'before' : 'after';
5203
+ this.zone.run(() => {
5204
+ const rowReorderService = this.ctx.treelist.rowReorderService;
5205
+ if (rowReorderService?.reorderViaKeyboard) {
5206
+ // Convert ViewCollection to array for the reorder method
5207
+ const viewArray = Array.from({ length: view.length }, (_, i) => view.at(i));
5208
+ rowReorderService.reorderViaKeyboard(currentRowIndex, targetRowIndex, dropPosition, viewArray);
5209
+ // Move focus to follow the reordered row
5210
+ // After reordering, the row will be at the target position
5211
+ this.zone.onStable.pipe(take(1)).subscribe(() => {
5212
+ const newRowIndex = this.meta.headerRows + targetRowIndex;
5213
+ this.cursor.reset(newRowIndex, this.activeCell.colIndex);
5214
+ });
5215
+ }
5216
+ });
5217
+ return true;
5218
+ }
5097
5219
  onKeydown(args) {
5098
5220
  if (this.mode === 1 /* NavigationMode.Cursor */) {
5099
5221
  this.onCursorKeydown(args);
@@ -5113,12 +5235,12 @@ class NavigationService {
5113
5235
  this.leaveCell();
5114
5236
  this.cursor.reset();
5115
5237
  }
5116
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavigationService, deps: [{ token: i0.NgZone }, { token: DomEventsService }, { token: i107.PagerContextService }, { token: ScrollRequestService }, { token: FocusRoot }, { token: EditService }, { token: i1$1.LocalizationService }, { token: ExpandStateService }, { token: SelectionService }, { token: i0.ChangeDetectorRef }, { token: FocusableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
5238
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavigationService, deps: [{ token: i0.NgZone }, { token: DomEventsService }, { token: i107.PagerContextService }, { token: ScrollRequestService }, { token: FocusRoot }, { token: EditService }, { token: i1$1.LocalizationService }, { token: ExpandStateService }, { token: SelectionService }, { token: i0.ChangeDetectorRef }, { token: ContextService }, { token: FocusableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
5117
5239
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavigationService });
5118
5240
  }
5119
5241
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NavigationService, decorators: [{
5120
5242
  type: Injectable
5121
- }], ctorParameters: () => [{ type: i0.NgZone }, { type: DomEventsService }, { type: i107.PagerContextService }, { type: ScrollRequestService }, { type: FocusRoot }, { type: EditService }, { type: i1$1.LocalizationService }, { type: ExpandStateService }, { type: SelectionService }, { type: i0.ChangeDetectorRef }, { type: FocusableDirective, decorators: [{
5243
+ }], ctorParameters: () => [{ type: i0.NgZone }, { type: DomEventsService }, { type: i107.PagerContextService }, { type: ScrollRequestService }, { type: FocusRoot }, { type: EditService }, { type: i1$1.LocalizationService }, { type: ExpandStateService }, { type: SelectionService }, { type: i0.ChangeDetectorRef }, { type: ContextService }, { type: FocusableDirective, decorators: [{
5122
5244
  type: Optional
5123
5245
  }] }] });
5124
5246
 
@@ -5329,80 +5451,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
5329
5451
  type: Injectable
5330
5452
  }] });
5331
5453
 
5332
- /**
5333
- * @hidden
5334
- */
5335
- class TreeListToolbarNavigationService {
5336
- renderer;
5337
- navigableElements = [];
5338
- currentActiveIndex = 0;
5339
- defaultFocusableSelector = `
5340
- [kendoTreeListToolbarFocusable],
5341
- [kendoTreeListAddCommand],
5342
- [kendoTreeListCancelCommand],
5343
- [kendoTreeListEditCommand],
5344
- [kendoTreeListRemoveCommand],
5345
- [kendoTreeListSaveCommand],
5346
- [kendoTreeListExcelCommand],
5347
- [kendoTreeListPDFCommand]
5348
- `;
5349
- constructor(renderer) {
5350
- this.renderer = renderer;
5351
- }
5352
- notify() {
5353
- // ensure focusable elements are in the same order as in the DOM
5354
- this.navigableElements = (this.navigableElements.length && this.navigableElements[0]?.parentElement) ? Array.from(this.navigableElements[0]?.parentElement?.querySelectorAll(this.defaultFocusableSelector) || []) : [];
5355
- this.currentActiveIndex = 0;
5356
- this.updateFocus();
5357
- }
5358
- focus() {
5359
- this.navigableElements[this.currentActiveIndex]?.focus();
5360
- }
5361
- updateFocus() {
5362
- if (!this.navigableElements.length) {
5363
- return;
5364
- }
5365
- this.navigableElements.forEach(el => {
5366
- this.renderer.setAttribute(el, 'tabindex', '-1');
5367
- });
5368
- this.renderer.setAttribute(this.navigableElements[this.currentActiveIndex], 'tabindex', '0');
5369
- if (isDocumentAvailable() && document.activeElement.closest('.k-toolbar')) {
5370
- this.navigableElements[this.currentActiveIndex].focus();
5371
- }
5372
- }
5373
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TreeListToolbarNavigationService, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Injectable });
5374
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TreeListToolbarNavigationService });
5375
- }
5376
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: TreeListToolbarNavigationService, decorators: [{
5377
- type: Injectable
5378
- }], ctorParameters: () => [{ type: i0.Renderer2 }] });
5379
-
5380
- /**
5381
- * @hidden
5382
- *
5383
- * The Context service is used to provide common
5384
- * services and DI tokens for a Grid instance.
5385
- *
5386
- * This keeps the constructor parameters stable
5387
- * and a avoids dependency cycles between components.
5388
- */
5389
- class ContextService {
5390
- localization;
5391
- treelist;
5392
- topToolbarNavigation;
5393
- bottomToolbarNavigation;
5394
- constructor(renderer, localization) {
5395
- this.localization = localization;
5396
- this.topToolbarNavigation = new TreeListToolbarNavigationService(renderer);
5397
- this.bottomToolbarNavigation = new TreeListToolbarNavigationService(renderer);
5398
- }
5399
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ContextService, deps: [{ token: i0.Renderer2 }, { token: i1$1.LocalizationService }], target: i0.ɵɵFactoryTarget.Injectable });
5400
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ContextService });
5401
- }
5402
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ContextService, decorators: [{
5403
- type: Injectable
5404
- }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i1$1.LocalizationService }] });
5405
-
5406
5454
  /**
5407
5455
  * @hidden
5408
5456
  */
@@ -5625,6 +5673,34 @@ class RowReorderService {
5625
5673
  }
5626
5674
  isOverChild(_item) { return false; }
5627
5675
  reorderRows(_ev, _collection, _field) { }
5676
+ /**
5677
+ * Triggers row reordering programmatically via keyboard shortcut.
5678
+ * @param dragRowIndex - The index of the row to move
5679
+ * @param dropRowIndex - The index of the target row
5680
+ * @param dropPosition - The position relative to the target row ('before' or 'after')
5681
+ * @param data - The data array (view)
5682
+ */
5683
+ reorderViaKeyboard(dragRowIndex, dropRowIndex, dropPosition, data) {
5684
+ if (dropPosition === 'forbidden') {
5685
+ return;
5686
+ }
5687
+ const dragRow = this.createVirtualRowElement(dragRowIndex);
5688
+ const dropRow = this.createVirtualRowElement(dropRowIndex);
5689
+ this.lastDropPosition = dropPosition;
5690
+ const rowReorderArgs = this.rowReorderArgs(dragRow, dropRow, data);
5691
+ this.rowReorder.emit(rowReorderArgs);
5692
+ }
5693
+ createVirtualRowElement(rowIndex) {
5694
+ const virtualElement = {
5695
+ getAttribute: (attr) => {
5696
+ if (attr === rowIndexAttr) {
5697
+ return String(rowIndex);
5698
+ }
5699
+ return null;
5700
+ }
5701
+ };
5702
+ return virtualElement;
5703
+ }
5628
5704
  get parentIdField() {
5629
5705
  return this.bindingDirective.parentIdField;
5630
5706
  }
@@ -19,6 +19,7 @@ import { ExpandStateService } from '../expand-state/expand-state.service';
19
19
  import { ScrollRequestService } from '../scrolling/scroll-request.service';
20
20
  import { SelectionService } from '../selection/selection.service';
21
21
  import { PagerContextService } from '@progress/kendo-angular-pager';
22
+ import { ContextService } from '../common/provider.service';
22
23
  import * as i0 from "@angular/core";
23
24
  /**
24
25
  * @hidden
@@ -44,6 +45,7 @@ export declare class NavigationService implements OnDestroy {
44
45
  private expandState;
45
46
  private selectionService;
46
47
  private changeDetector;
48
+ private ctx;
47
49
  private focusableParent;
48
50
  readonly changes: Subject<NavigationChange>;
49
51
  readonly cellKeydown: EventEmitter<any>;
@@ -65,7 +67,7 @@ export declare class NavigationService implements OnDestroy {
65
67
  private pendingRowIndex;
66
68
  private virtualCell;
67
69
  private get activeDataRow();
68
- constructor(zone: NgZone, domEvents: DomEventsService, pagerContextService: PagerContextService, scrollRequestService: ScrollRequestService, focusRoot: FocusRoot, editService: EditService, localization: LocalizationService, expandState: ExpandStateService, selectionService: SelectionService, changeDetector: ChangeDetectorRef, focusableParent: FocusableDirective);
70
+ constructor(zone: NgZone, domEvents: DomEventsService, pagerContextService: PagerContextService, scrollRequestService: ScrollRequestService, focusRoot: FocusRoot, editService: EditService, localization: LocalizationService, expandState: ExpandStateService, selectionService: SelectionService, changeDetector: ChangeDetectorRef, ctx: ContextService, focusableParent: FocusableDirective);
69
71
  init(meta: NavigationMetadata): void;
70
72
  ngOnDestroy(): void;
71
73
  registerCell(cell: LogicalCell): void;
@@ -102,8 +104,9 @@ export declare class NavigationService implements OnDestroy {
102
104
  private onCursorChanges;
103
105
  private onFocusOut;
104
106
  private onWindowBlur;
107
+ private handleRowReorderKeyboard;
105
108
  private onKeydown;
106
109
  private onTabout;
107
- static ɵfac: i0.ɵɵFactoryDeclaration<NavigationService, [null, null, null, null, null, null, null, null, null, null, { optional: true; }]>;
110
+ static ɵfac: i0.ɵɵFactoryDeclaration<NavigationService, [null, null, null, null, null, null, null, null, null, null, null, { optional: true; }]>;
108
111
  static ɵprov: i0.ɵɵInjectableDeclaration<NavigationService>;
109
112
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-treelist",
3
- "version": "21.0.0-develop.11",
3
+ "version": "21.0.0-develop.12",
4
4
  "description": "Kendo UI TreeList for Angular - Display hierarchical data in an Angular tree grid view that supports sorting, filtering, paging, and much more.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -24,7 +24,7 @@
24
24
  "package": {
25
25
  "productName": "Kendo UI for Angular",
26
26
  "productCode": "KENDOUIANGULAR",
27
- "publishDate": 1761916649,
27
+ "publishDate": 1761924258,
28
28
  "licensingDocsUrl": "https://www.telerik.com/kendo-angular-ui/my-license/"
29
29
  }
30
30
  },
@@ -37,26 +37,26 @@
37
37
  "@progress/kendo-data-query": "^1.0.0",
38
38
  "@progress/kendo-drawing": "^1.21.0",
39
39
  "@progress/kendo-licensing": "^1.7.0",
40
- "@progress/kendo-angular-buttons": "21.0.0-develop.11",
41
- "@progress/kendo-angular-common": "21.0.0-develop.11",
42
- "@progress/kendo-angular-dateinputs": "21.0.0-develop.11",
43
- "@progress/kendo-angular-dropdowns": "21.0.0-develop.11",
44
- "@progress/kendo-angular-excel-export": "21.0.0-develop.11",
45
- "@progress/kendo-angular-icons": "21.0.0-develop.11",
46
- "@progress/kendo-angular-inputs": "21.0.0-develop.11",
47
- "@progress/kendo-angular-intl": "21.0.0-develop.11",
48
- "@progress/kendo-angular-l10n": "21.0.0-develop.11",
49
- "@progress/kendo-angular-label": "21.0.0-develop.11",
50
- "@progress/kendo-angular-pager": "21.0.0-develop.11",
51
- "@progress/kendo-angular-pdf-export": "21.0.0-develop.11",
52
- "@progress/kendo-angular-popup": "21.0.0-develop.11",
53
- "@progress/kendo-angular-toolbar": "21.0.0-develop.11",
54
- "@progress/kendo-angular-utils": "21.0.0-develop.11",
40
+ "@progress/kendo-angular-buttons": "21.0.0-develop.12",
41
+ "@progress/kendo-angular-common": "21.0.0-develop.12",
42
+ "@progress/kendo-angular-dateinputs": "21.0.0-develop.12",
43
+ "@progress/kendo-angular-dropdowns": "21.0.0-develop.12",
44
+ "@progress/kendo-angular-excel-export": "21.0.0-develop.12",
45
+ "@progress/kendo-angular-icons": "21.0.0-develop.12",
46
+ "@progress/kendo-angular-inputs": "21.0.0-develop.12",
47
+ "@progress/kendo-angular-intl": "21.0.0-develop.12",
48
+ "@progress/kendo-angular-l10n": "21.0.0-develop.12",
49
+ "@progress/kendo-angular-label": "21.0.0-develop.12",
50
+ "@progress/kendo-angular-pager": "21.0.0-develop.12",
51
+ "@progress/kendo-angular-pdf-export": "21.0.0-develop.12",
52
+ "@progress/kendo-angular-popup": "21.0.0-develop.12",
53
+ "@progress/kendo-angular-toolbar": "21.0.0-develop.12",
54
+ "@progress/kendo-angular-utils": "21.0.0-develop.12",
55
55
  "rxjs": "^6.5.3 || ^7.0.0"
56
56
  },
57
57
  "dependencies": {
58
58
  "tslib": "^2.3.1",
59
- "@progress/kendo-angular-schematics": "21.0.0-develop.11",
59
+ "@progress/kendo-angular-schematics": "21.0.0-develop.12",
60
60
  "@progress/kendo-common": "^1.0.1",
61
61
  "@progress/kendo-file-saver": "^1.0.0"
62
62
  },
@@ -4,7 +4,7 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { DragTargetPressEvent, DragTargetDragEvent, DropTargetEvent } from '@progress/kendo-angular-utils';
6
6
  import { EventEmitter, Renderer2 } from '@angular/core';
7
- import { RowReorderEvent } from './types';
7
+ import { DropPosition, RowReorderEvent } from './types';
8
8
  import { SVGIcon } from '@progress/kendo-svg-icons';
9
9
  import { ColumnList } from '../columns/column-list';
10
10
  import * as i0 from "@angular/core";
@@ -42,6 +42,15 @@ export declare class RowReorderService {
42
42
  rowReorderArgs(dragRow: HTMLElement, dropRow: HTMLElement, data: Array<any>): RowReorderEvent;
43
43
  isOverChild(_item: any): boolean;
44
44
  reorderRows(_ev: RowReorderEvent, _collection: Array<any>, _field?: string): void;
45
+ /**
46
+ * Triggers row reordering programmatically via keyboard shortcut.
47
+ * @param dragRowIndex - The index of the row to move
48
+ * @param dropRowIndex - The index of the target row
49
+ * @param dropPosition - The position relative to the target row ('before' or 'after')
50
+ * @param data - The data array (view)
51
+ */
52
+ reorderViaKeyboard(dragRowIndex: number, dropRowIndex: number, dropPosition: DropPosition, data: Array<any>): void;
53
+ private createVirtualRowElement;
45
54
  get parentIdField(): string;
46
55
  get idField(): string;
47
56
  get childrenField(): string;
@@ -5,13 +5,13 @@ const schematics_1 = require("@angular-devkit/schematics");
5
5
  function default_1(options) {
6
6
  const finalOptions = Object.assign(Object.assign({}, options), { mainNgModule: 'TreeListModule', package: 'treelist', peerDependencies: {
7
7
  // peer dep of the dropdowns
8
- '@progress/kendo-angular-treeview': '21.0.0-develop.11',
8
+ '@progress/kendo-angular-treeview': '21.0.0-develop.12',
9
9
  // peer dependency of kendo-angular-inputs
10
- '@progress/kendo-angular-dialog': '21.0.0-develop.11',
10
+ '@progress/kendo-angular-dialog': '21.0.0-develop.12',
11
11
  // peer dependency of kendo-angular-icons
12
12
  '@progress/kendo-svg-icons': '^4.0.0',
13
13
  // peer dependency of kendo-angular-dateinputs
14
- '@progress/kendo-angular-navigation': '21.0.0-develop.11',
14
+ '@progress/kendo-angular-navigation': '21.0.0-develop.12',
15
15
  } });
16
16
  return (0, schematics_1.externalSchematic)('@progress/kendo-angular-schematics', 'ng-add', finalOptions);
17
17
  }