@progress/kendo-angular-treelist 18.2.1-develop.3 → 18.3.0-develop.1

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.
Files changed (109) hide show
  1. package/column-menu/column-chooser-item-checked.directive.d.ts +21 -0
  2. package/column-menu/column-chooser.component.d.ts +14 -3
  3. package/column-menu/column-list-kb-nav.service.d.ts +22 -0
  4. package/column-menu/column-list.component.d.ts +20 -5
  5. package/column-menu/column-menu-autosize-all.component.d.ts +39 -0
  6. package/column-menu/column-menu-autosize.component.d.ts +43 -0
  7. package/column-menu/column-menu-chooser.component.d.ts +16 -4
  8. package/column-menu/column-menu-container.component.d.ts +21 -0
  9. package/column-menu/column-menu-expandable-item.interface.d.ts +14 -0
  10. package/column-menu/column-menu-filter.component.d.ts +16 -3
  11. package/column-menu/column-menu-item.component.d.ts +11 -3
  12. package/column-menu/column-menu-item.directive.d.ts +45 -0
  13. package/column-menu/column-menu-settings.interface.d.ts +11 -2
  14. package/column-menu/column-menu.component.d.ts +40 -15
  15. package/column-menu/column-menu.service.d.ts +14 -0
  16. package/column-menu/utils.d.ts +13 -0
  17. package/columns/sort-settings.d.ts +12 -0
  18. package/common/error-messages.d.ts +8 -0
  19. package/common/id.service.d.ts +3 -0
  20. package/common/provider.service.d.ts +3 -1
  21. package/esm2022/column-menu/column-chooser-item-checked.directive.mjs +45 -0
  22. package/esm2022/column-menu/column-chooser.component.mjs +69 -14
  23. package/esm2022/column-menu/column-list-kb-nav.service.mjs +40 -0
  24. package/esm2022/column-menu/column-list.component.mjs +172 -50
  25. package/esm2022/column-menu/column-menu-autosize-all.component.mjs +79 -0
  26. package/esm2022/column-menu/column-menu-autosize.component.mjs +87 -0
  27. package/esm2022/column-menu/column-menu-chooser.component.mjs +44 -12
  28. package/esm2022/column-menu/column-menu-container.component.mjs +58 -0
  29. package/esm2022/column-menu/column-menu-expandable-item.interface.mjs +5 -0
  30. package/esm2022/column-menu/column-menu-filter.component.mjs +58 -25
  31. package/esm2022/column-menu/column-menu-item-base.mjs +2 -1
  32. package/esm2022/column-menu/column-menu-item.component.mjs +34 -5
  33. package/esm2022/column-menu/column-menu-item.directive.mjs +125 -0
  34. package/esm2022/column-menu/column-menu-lock.component.mjs +1 -1
  35. package/esm2022/column-menu/column-menu-sort.component.mjs +1 -1
  36. package/esm2022/column-menu/column-menu.component.mjs +264 -67
  37. package/esm2022/column-menu/column-menu.service.mjs +18 -2
  38. package/esm2022/column-menu/utils.mjs +21 -1
  39. package/esm2022/common/error-messages.mjs +15 -0
  40. package/esm2022/common/id.service.mjs +9 -0
  41. package/esm2022/common/provider.service.mjs +7 -3
  42. package/esm2022/filtering/cell/boolean-filter-cell.component.mjs +5 -2
  43. package/esm2022/filtering/cell/date-filter-cell.component.mjs +20 -3
  44. package/esm2022/filtering/cell/numeric-filter-cell.component.mjs +17 -3
  45. package/esm2022/filtering/filter-row.component.mjs +1 -1
  46. package/esm2022/filtering/filter.service.mjs +17 -3
  47. package/esm2022/filtering/menu/boolean-filter-menu.component.mjs +40 -14
  48. package/esm2022/filtering/menu/date-filter-menu-input.component.mjs +47 -17
  49. package/esm2022/filtering/menu/date-filter-menu.component.mjs +27 -7
  50. package/esm2022/filtering/menu/filter-menu-container.component.mjs +83 -31
  51. package/esm2022/filtering/menu/filter-menu-dropdownlist.directive.mjs +44 -0
  52. package/esm2022/filtering/menu/filter-menu-host.directive.mjs +6 -1
  53. package/esm2022/filtering/menu/filter-menu-input-wrapper.component.mjs +52 -9
  54. package/esm2022/filtering/menu/filter-menu.component.mjs +111 -16
  55. package/esm2022/filtering/menu/menu-tabbing.service.mjs +22 -0
  56. package/esm2022/filtering/menu/numeric-filter-menu-input.component.mjs +49 -35
  57. package/esm2022/filtering/menu/numeric-filter-menu.component.mjs +37 -7
  58. package/esm2022/filtering/menu/string-filter-menu-input.component.mjs +13 -4
  59. package/esm2022/filtering/menu/string-filter-menu.component.mjs +27 -8
  60. package/esm2022/filtering/operators/after-eq-filter-operator.component.mjs +2 -2
  61. package/esm2022/filtering/operators/after-filter-operator.component.mjs +2 -2
  62. package/esm2022/filtering/operators/before-eq-filter-operator.component.mjs +2 -2
  63. package/esm2022/filtering/operators/before-filter-operator.component.mjs +2 -2
  64. package/esm2022/filtering/operators/contains-filter-operator.component.mjs +1 -1
  65. package/esm2022/filtering/operators/ends-with-filter-operator.component.mjs +1 -1
  66. package/esm2022/filtering/operators/eq-filter-operator.component.mjs +1 -1
  67. package/esm2022/filtering/operators/filter-operator.base.mjs +18 -18
  68. package/esm2022/filtering/operators/gt-filter-operator.component.mjs +1 -1
  69. package/esm2022/filtering/operators/gte-filter-operator.component.mjs +1 -1
  70. package/esm2022/filtering/operators/is-empty-filter-operator.component.mjs +1 -1
  71. package/esm2022/filtering/operators/is-not-empty-filter-operator.component.mjs +1 -1
  72. package/esm2022/filtering/operators/is-not-null-filter-operator.component.mjs +1 -1
  73. package/esm2022/filtering/operators/isnull-filter-operator.component.mjs +1 -1
  74. package/esm2022/filtering/operators/lt-filter-operator.component.mjs +1 -1
  75. package/esm2022/filtering/operators/lte-filter-operator.component.mjs +1 -1
  76. package/esm2022/filtering/operators/neq-filter-operator.component.mjs +1 -1
  77. package/esm2022/filtering/operators/not-contains-filter-operator.component.mjs +1 -1
  78. package/esm2022/filtering/operators/starts-with-filter-operator.component.mjs +1 -1
  79. package/esm2022/localization/messages.mjs +97 -3
  80. package/esm2022/navigation/logical-cell.directive.mjs +4 -1
  81. package/esm2022/navigation/navigation.service.mjs +4 -4
  82. package/esm2022/package-metadata.mjs +2 -2
  83. package/esm2022/rendering/header/header.component.mjs +336 -178
  84. package/esm2022/rendering/table-body.component.mjs +1 -1
  85. package/esm2022/selection/selection.service.mjs +2 -2
  86. package/esm2022/treelist.component.mjs +73 -9
  87. package/fesm2022/progress-kendo-angular-treelist.mjs +2231 -628
  88. package/filtering/cell/date-filter-cell.component.d.ts +4 -0
  89. package/filtering/cell/numeric-filter-cell.component.d.ts +4 -0
  90. package/filtering/filter.service.d.ts +10 -1
  91. package/filtering/menu/boolean-filter-menu.component.d.ts +19 -7
  92. package/filtering/menu/date-filter-menu-input.component.d.ts +10 -3
  93. package/filtering/menu/date-filter-menu.component.d.ts +7 -1
  94. package/filtering/menu/filter-menu-container.component.d.ts +23 -6
  95. package/filtering/menu/filter-menu-dropdownlist.directive.d.ts +19 -0
  96. package/filtering/menu/filter-menu-host.directive.d.ts +3 -1
  97. package/filtering/menu/filter-menu-input-wrapper.component.d.ts +12 -2
  98. package/filtering/menu/filter-menu.component.d.ts +30 -7
  99. package/filtering/menu/menu-tabbing.service.d.ts +18 -0
  100. package/filtering/menu/numeric-filter-menu-input.component.d.ts +12 -26
  101. package/filtering/menu/numeric-filter-menu.component.d.ts +13 -1
  102. package/filtering/menu/string-filter-menu-input.component.d.ts +4 -1
  103. package/filtering/menu/string-filter-menu.component.d.ts +7 -1
  104. package/index.d.ts +1 -0
  105. package/localization/messages.d.ts +79 -3
  106. package/navigation/logical-cell.directive.d.ts +2 -1
  107. package/package.json +18 -18
  108. package/rendering/header/header.component.d.ts +43 -10
  109. package/schematics/ngAdd/index.js +3 -3
@@ -2,11 +2,17 @@
2
2
  * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { Component, HostBinding, Input, ElementRef, NgZone, Renderer2, Output, EventEmitter, QueryList, ViewChildren } from '@angular/core';
5
+ import { Component, HostBinding, Input, ElementRef, NgZone, Renderer2, Output, EventEmitter, QueryList, ViewChildren, ViewChild } from '@angular/core';
6
6
  import { NgFor, NgIf, NgClass } from '@angular/common';
7
7
  import { CheckBoxComponent } from '@progress/kendo-angular-inputs';
8
8
  import { take } from 'rxjs/operators';
9
+ import { ColumnMenuChooserItemCheckedDirective } from './column-chooser-item-checked.directive';
10
+ import { ColumnMenuService } from './column-menu.service';
11
+ import { ColumnListKeyboardNavigation } from './column-list-kb-nav.service';
12
+ import { Subscription } from 'rxjs';
13
+ import { Keys } from '@progress/kendo-angular-common';
9
14
  import * as i0 from "@angular/core";
15
+ import * as i1 from "./column-list-kb-nav.service";
10
16
  /**
11
17
  * @hidden
12
18
  */
@@ -14,9 +20,8 @@ export class ColumnListComponent {
14
20
  element;
15
21
  ngZone;
16
22
  renderer;
17
- get className() {
18
- return true;
19
- }
23
+ listNavigationService;
24
+ className = true;
20
25
  reset = new EventEmitter();
21
26
  apply = new EventEmitter();
22
27
  columnChange = new EventEmitter();
@@ -29,10 +34,17 @@ export class ColumnListComponent {
29
34
  return this._columns;
30
35
  }
31
36
  autoSync = true;
37
+ ariaLabel;
32
38
  allowHideAll = false;
33
39
  applyText;
34
40
  resetText;
35
- actionsClass = 'k-actions';
41
+ actionsClass = 'k-actions k-actions-stretched k-actions-horizontal';
42
+ isLast;
43
+ isExpanded;
44
+ service;
45
+ resetButton;
46
+ applyButton;
47
+ options;
36
48
  checkboxes;
37
49
  hasLocked;
38
50
  hasVisibleLocked;
@@ -41,36 +53,52 @@ export class ColumnListComponent {
41
53
  hasFiltered;
42
54
  _columns;
43
55
  allColumns;
44
- domSubscriptions;
45
- constructor(element, ngZone, renderer) {
56
+ domSubscriptions = new Subscription();
57
+ constructor(element, ngZone, renderer, listNavigationService) {
46
58
  this.element = element;
47
59
  this.ngZone = ngZone;
48
60
  this.renderer = renderer;
49
- }
50
- isDisabled(column) {
51
- return !(this.allowHideAll || this.hasFiltered || column.hidden || this.columns.find(current => current !== column && !current.hidden)) ||
52
- (this.hasVisibleLocked && !this.hasUnlockedFiltered && this.unlockedCount === 1 && !column.locked && !column.hidden);
61
+ this.listNavigationService = listNavigationService;
53
62
  }
54
63
  ngOnInit() {
55
64
  if (!this.element) {
56
65
  return;
57
66
  }
58
67
  this.ngZone.runOutsideAngular(() => {
59
- this.domSubscriptions = this.renderer.listen(this.element.nativeElement, 'click', (e) => {
68
+ this.domSubscriptions.add(this.renderer.listen(this.element.nativeElement, 'click', (e) => {
60
69
  this.ngZone.onStable.pipe(take(1)).subscribe(() => {
61
70
  this.handleCheckBoxClick(e);
62
71
  });
63
- });
72
+ }));
73
+ this.domSubscriptions.add(this.renderer.listen(this.element.nativeElement, 'keydown', this.onKeydown));
64
74
  });
65
75
  }
66
- ngOnDestroy() {
67
- if (this.domSubscriptions) {
68
- this.domSubscriptions();
76
+ ngAfterViewInit() {
77
+ this.listNavigationService.items = this.options.toArray();
78
+ this.listNavigationService.toggle(0, true);
79
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => this.updateDisabled());
80
+ }
81
+ ngOnChanges(changes) {
82
+ if (!this.service) {
83
+ return;
84
+ }
85
+ if (changes['isLast'] && this.isLast) {
86
+ this.service.menuTabbingService.lastFocusable = this.applyButton.nativeElement;
69
87
  }
88
+ if (changes['isExpanded'] && this.isExpanded && this.isLast && this.applyButton) {
89
+ this.service.menuTabbingService.lastFocusable = this.applyButton.nativeElement;
90
+ }
91
+ }
92
+ ngOnDestroy() {
93
+ this.domSubscriptions.unsubscribe();
94
+ }
95
+ isDisabled(column) {
96
+ return !(this.allowHideAll || this.hasFiltered || column.hidden || this.columns.find(current => current !== column && !current.hidden)) ||
97
+ (this.hasVisibleLocked && !this.hasUnlockedFiltered && this.unlockedCount === 1 && !column.locked && !column.hidden);
70
98
  }
71
99
  cancelChanges() {
72
- this.checkboxes.forEach((item, index) => {
73
- item.checkedState = !this.columns[index].hidden;
100
+ this.checkboxes.forEach((element, index) => {
101
+ element.checkedState = !this.columns[index].hidden;
74
102
  });
75
103
  this.updateDisabled();
76
104
  this.reset.emit();
@@ -88,6 +116,31 @@ export class ColumnListComponent {
88
116
  this.updateDisabled();
89
117
  this.apply.emit(changed);
90
118
  }
119
+ onTab(e) {
120
+ if (this.isLast) {
121
+ e.preventDefault();
122
+ if (this.service) {
123
+ this.service.menuTabbingService.firstFocusable.focus();
124
+ }
125
+ else {
126
+ this.listNavigationService.toggle(this.listNavigationService.activeIndex, true);
127
+ }
128
+ }
129
+ }
130
+ onKeydown = (e) => {
131
+ if (e.keyCode !== Keys.Tab) {
132
+ e.preventDefault();
133
+ }
134
+ if (e.keyCode === Keys.ArrowDown) {
135
+ this.listNavigationService.next();
136
+ }
137
+ else if (e.keyCode === Keys.ArrowUp) {
138
+ this.listNavigationService.prev();
139
+ }
140
+ else if (e.keyCode === Keys.Space && e.target.classList.contains('k-column-list-item')) {
141
+ this.listNavigationService.toggleCheckedState();
142
+ }
143
+ };
91
144
  updateDisabled() {
92
145
  if (this.allowHideAll && !this.hasLocked) {
93
146
  return;
@@ -97,16 +150,16 @@ export class ColumnListComponent {
97
150
  if (checkbox.checkedState) {
98
151
  checkedItems.push({ checkbox, index });
99
152
  }
100
- checkbox.disabled = false;
153
+ this.setDisabledState(checkbox, false);
101
154
  });
102
155
  if (!this.allowHideAll && checkedItems.length === 1 && !this.hasFiltered) {
103
- checkedItems[0].checkbox.disabled = true;
156
+ this.setDisabledState(checkedItems[0].checkbox, true);
104
157
  }
105
158
  else if (this.hasLocked && !this.hasUnlockedFiltered) {
106
159
  const columns = this.columns;
107
160
  const checkedUnlocked = checkedItems.filter(item => !columns[item.index].locked);
108
161
  if (checkedUnlocked.length === 1) {
109
- checkedUnlocked[0].checkbox.disabled = true;
162
+ this.setDisabledState(checkedUnlocked[0].checkbox, true);
110
163
  }
111
164
  }
112
165
  }
@@ -124,12 +177,39 @@ export class ColumnListComponent {
124
177
  this.hasUnlockedFiltered = false;
125
178
  }
126
179
  }
180
+ setDisabledState(checkbox, disabled) {
181
+ this.ngZone.run(() => checkbox.disabled = disabled);
182
+ const checkboxElement = checkbox.hostElement.nativeElement;
183
+ const parentElement = checkboxElement.parentElement;
184
+ const classCommand = disabled ? 'addClass' : 'removeClass';
185
+ const attributeCommand = disabled ? 'setAttribute' : 'removeAttribute';
186
+ this.renderer[classCommand](parentElement, 'k-disabled');
187
+ this.renderer[attributeCommand](parentElement, 'aria-disabled', disabled ? 'true' : undefined);
188
+ }
127
189
  handleCheckBoxClick = (e) => {
128
- const closestItem = e.target.closest('.k-checkbox-wrap');
190
+ const closestItem = e.target.closest('.k-column-list-item');
129
191
  if (closestItem) {
192
+ const checkboxElement = closestItem.querySelector('.k-checkbox-wrap');
193
+ const checkbox = this.checkboxes.find(checkBox => checkBox.hostElement.nativeElement === checkboxElement);
194
+ const index = parseInt(checkboxElement.firstElementChild.getAttribute('data-index'), 10);
195
+ if (index !== this.listNavigationService.activeIndex) {
196
+ this.listNavigationService.toggle(this.listNavigationService.activeIndex, false);
197
+ this.listNavigationService.activeIndex = index;
198
+ this.listNavigationService.toggle(index, true);
199
+ }
200
+ if (checkboxElement.contains(e.target)) {
201
+ const checkboxInputElement = checkboxElement.firstElementChild;
202
+ checkboxInputElement.blur();
203
+ checkboxInputElement.classList.remove('k-focus');
204
+ }
205
+ else {
206
+ this.listNavigationService.toggleCheckedState();
207
+ }
208
+ closestItem.focus();
130
209
  if (this.autoSync) {
131
- const checkbox = this.checkboxes.find(checkBox => checkBox.hostElement.nativeElement === closestItem);
132
- const index = parseInt(closestItem.firstElementChild.getAttribute('data-index'), 10);
210
+ if (!this.columns[index]) {
211
+ return;
212
+ }
133
213
  const column = this.columns[index];
134
214
  const hidden = !checkbox.checkedState;
135
215
  if (Boolean(column.hidden) !== hidden) {
@@ -140,72 +220,97 @@ export class ColumnListComponent {
140
220
  }
141
221
  }
142
222
  else {
143
- this.ngZone.run(() => this.updateDisabled());
223
+ this.updateDisabled();
144
224
  }
145
225
  }
146
226
  };
147
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnListComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
148
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnListComponent, isStandalone: true, selector: "kendo-treelist-columnlist", inputs: { columns: "columns", autoSync: "autoSync", allowHideAll: "allowHideAll", applyText: "applyText", resetText: "resetText", actionsClass: "actionsClass" }, outputs: { reset: "reset", apply: "apply", columnChange: "columnChange" }, host: { properties: { "class.k-column-list-wrapper": "this.className" } }, viewQueries: [{ propertyName: "checkboxes", predicate: CheckBoxComponent, descendants: true }], ngImport: i0, template: `
149
- <div class="k-column-list">
150
- <label *ngFor="let column of columns; let index = index;" class='k-column-list-item'>
227
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnListComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i1.ColumnListKeyboardNavigation }], target: i0.ɵɵFactoryTarget.Component });
228
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnListComponent, isStandalone: true, selector: "kendo-treelist-columnlist", inputs: { columns: "columns", autoSync: "autoSync", ariaLabel: "ariaLabel", allowHideAll: "allowHideAll", applyText: "applyText", resetText: "resetText", actionsClass: "actionsClass", isLast: "isLast", isExpanded: "isExpanded", service: "service" }, outputs: { reset: "reset", apply: "apply", columnChange: "columnChange" }, host: { properties: { "class.k-column-list-wrapper": "this.className" } }, providers: [ColumnListKeyboardNavigation], viewQueries: [{ propertyName: "resetButton", first: true, predicate: ["resetButton"], descendants: true }, { propertyName: "applyButton", first: true, predicate: ["applyButton"], descendants: true }, { propertyName: "options", predicate: ColumnMenuChooserItemCheckedDirective, descendants: true }, { propertyName: "checkboxes", predicate: CheckBoxComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
229
+ <div
230
+ class="k-column-list"
231
+ role="listbox"
232
+ aria-multiselectable="true"
233
+ [attr.aria-label]="ariaLabel">
234
+ <label
235
+ *ngFor="let column of columns; let index = index;"
236
+ class='k-column-list-item'
237
+ [kendoColumnMenuChooserItemChecked]="!column.hidden"
238
+ role="option">
151
239
  <kendo-checkbox
152
240
  [inputAttributes]="{'data-index': index.toString()}"
153
241
  [checkedState]="!column.hidden"
154
242
  [disabled]="isDisabled(column)"
243
+ [tabindex]="-1"
155
244
  ></kendo-checkbox>
156
245
  <span class="k-checkbox-label">{{ column.displayTitle }}</span>
157
246
  </label>
158
247
  </div>
159
248
  <div [ngClass]="actionsClass" *ngIf="!autoSync">
160
249
  <button
250
+ #applyButton
161
251
  type="button"
162
- class="k-button k-button-solid-base k-button-solid k-button-md k-rounded-md k-button-rectangle"
163
- (click)="cancelChanges()">
164
- {{ resetText }}
165
- </button>
252
+ class="k-button k-button-solid-primary k-button-solid k-button-md k-rounded-md k-button-rectangle"
253
+ (click)="applyChanges()"
254
+ (keydown.enter)="$event.preventDefault(); $event.stopPropagation(); applyChanges();"
255
+ (keydown.space)="$event.preventDefault(); $event.stopPropagation(); applyChanges();">{{ applyText }}</button>
166
256
  <button
257
+ #resetButton
167
258
  type="button"
168
- class="k-button k-button-solid-primary k-button-solid k-button-md k-rounded-md k-button-rectangle"
169
- (click)="applyChanges()">
170
- {{ applyText }}
171
- </button>
259
+ (keydown.tab)="onTab($event)"
260
+ class="k-button k-button-solid-base k-button-solid k-button-md k-rounded-md k-button-rectangle"
261
+ (click)="cancelChanges()"
262
+ (keydown.enter)="$event.preventDefault(); $event.stopPropagation(); cancelChanges();"
263
+ (keydown.space)="$event.preventDefault(); $event.stopPropagation(); cancelChanges();">{{ resetText }}</button>
172
264
  </div>
173
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }] });
265
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: ColumnMenuChooserItemCheckedDirective, selector: "[kendoColumnMenuChooserItemChecked]", inputs: ["kendoColumnMenuChooserItemChecked"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }] });
174
266
  }
175
267
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnListComponent, decorators: [{
176
268
  type: Component,
177
269
  args: [{
178
270
  selector: 'kendo-treelist-columnlist',
271
+ providers: [ColumnListKeyboardNavigation],
179
272
  template: `
180
- <div class="k-column-list">
181
- <label *ngFor="let column of columns; let index = index;" class='k-column-list-item'>
273
+ <div
274
+ class="k-column-list"
275
+ role="listbox"
276
+ aria-multiselectable="true"
277
+ [attr.aria-label]="ariaLabel">
278
+ <label
279
+ *ngFor="let column of columns; let index = index;"
280
+ class='k-column-list-item'
281
+ [kendoColumnMenuChooserItemChecked]="!column.hidden"
282
+ role="option">
182
283
  <kendo-checkbox
183
284
  [inputAttributes]="{'data-index': index.toString()}"
184
285
  [checkedState]="!column.hidden"
185
286
  [disabled]="isDisabled(column)"
287
+ [tabindex]="-1"
186
288
  ></kendo-checkbox>
187
289
  <span class="k-checkbox-label">{{ column.displayTitle }}</span>
188
290
  </label>
189
291
  </div>
190
292
  <div [ngClass]="actionsClass" *ngIf="!autoSync">
191
293
  <button
294
+ #applyButton
192
295
  type="button"
193
- class="k-button k-button-solid-base k-button-solid k-button-md k-rounded-md k-button-rectangle"
194
- (click)="cancelChanges()">
195
- {{ resetText }}
196
- </button>
296
+ class="k-button k-button-solid-primary k-button-solid k-button-md k-rounded-md k-button-rectangle"
297
+ (click)="applyChanges()"
298
+ (keydown.enter)="$event.preventDefault(); $event.stopPropagation(); applyChanges();"
299
+ (keydown.space)="$event.preventDefault(); $event.stopPropagation(); applyChanges();">{{ applyText }}</button>
197
300
  <button
301
+ #resetButton
198
302
  type="button"
199
- class="k-button k-button-solid-primary k-button-solid k-button-md k-rounded-md k-button-rectangle"
200
- (click)="applyChanges()">
201
- {{ applyText }}
202
- </button>
303
+ (keydown.tab)="onTab($event)"
304
+ class="k-button k-button-solid-base k-button-solid k-button-md k-rounded-md k-button-rectangle"
305
+ (click)="cancelChanges()"
306
+ (keydown.enter)="$event.preventDefault(); $event.stopPropagation(); cancelChanges();"
307
+ (keydown.space)="$event.preventDefault(); $event.stopPropagation(); cancelChanges();">{{ resetText }}</button>
203
308
  </div>
204
309
  `,
205
310
  standalone: true,
206
- imports: [NgFor, NgIf, NgClass, CheckBoxComponent]
311
+ imports: [NgFor, ColumnMenuChooserItemCheckedDirective, NgIf, NgClass, CheckBoxComponent]
207
312
  }]
208
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }]; }, propDecorators: { className: [{
313
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i1.ColumnListKeyboardNavigation }]; }, propDecorators: { className: [{
209
314
  type: HostBinding,
210
315
  args: ["class.k-column-list-wrapper"]
211
316
  }], reset: [{
@@ -218,6 +323,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
218
323
  type: Input
219
324
  }], autoSync: [{
220
325
  type: Input
326
+ }], ariaLabel: [{
327
+ type: Input
221
328
  }], allowHideAll: [{
222
329
  type: Input
223
330
  }], applyText: [{
@@ -226,6 +333,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
226
333
  type: Input
227
334
  }], actionsClass: [{
228
335
  type: Input
336
+ }], isLast: [{
337
+ type: Input
338
+ }], isExpanded: [{
339
+ type: Input
340
+ }], service: [{
341
+ type: Input
342
+ }], resetButton: [{
343
+ type: ViewChild,
344
+ args: ['resetButton', { static: false }]
345
+ }], applyButton: [{
346
+ type: ViewChild,
347
+ args: ['applyButton', { static: false }]
348
+ }], options: [{
349
+ type: ViewChildren,
350
+ args: [ColumnMenuChooserItemCheckedDirective]
229
351
  }], checkboxes: [{
230
352
  type: ViewChildren,
231
353
  args: [CheckBoxComponent]
@@ -0,0 +1,79 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ import { Component, isDevMode } from '@angular/core';
6
+ import { displayInlineFlexIcon } from '@progress/kendo-svg-icons';
7
+ import { ColumnMenuErrorMessages } from '../common/error-messages';
8
+ import { ContextService } from '../common/provider.service';
9
+ import { ColumnMenuItemBase } from './column-menu-item-base';
10
+ import { autoSizeColumn } from './utils';
11
+ import { ColumnMenuItemComponent } from './column-menu-item.component';
12
+ import { NgIf } from '@angular/common';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "../common/provider.service";
15
+ /**
16
+ * Represents the column-menu item for resizing all columns to the minimum possible width so that they fit the widest header or cell content without wrapping.
17
+ * [See example](slug:columnmenu_treelist#toc-autosize-all-columns-item).
18
+ *
19
+ * The component can be placed inside a [ColumnMenuTemplate]({% slug api_treelist_columnmenutemplatedirective %}) directive.
20
+ * To register the component as a known column menu item, set the [ColumnMenuService]({% slug api_treelist_columnmenuservice %}) that is passed by
21
+ * the template to the `service` input of the `kendo-treelist-columnmenu-autosize-all-columns` component. [See example](slug:columnmenu_treelist#toc-customizing-the-content).
22
+ *
23
+ * @example
24
+ * ```html
25
+ * <kendo-treelist [columnMenu]="true" ...>
26
+ * <ng-template kendoTreeListColumnMenuTemplate let-service="service">
27
+ * <kendo-treelist-columnmenu-autosize-all-columns [service]="service">
28
+ * </kendo-treelist-columnmenu-autosize-all-columns>
29
+ * </ng-template>
30
+ * </kendo-treelist>
31
+ * ```
32
+ */
33
+ export class ColumnMenuAutoSizeAllColumnsComponent extends ColumnMenuItemBase {
34
+ ctx;
35
+ displayInlineFlexIcon = displayInlineFlexIcon;
36
+ constructor(ctx) {
37
+ super();
38
+ this.ctx = ctx;
39
+ }
40
+ ngOnInit() {
41
+ const isVirtualColumns = this.ctx.treelist.columnMenuTemplate && this.ctx.treelist.virtualColumns;
42
+ if (isVirtualColumns && isDevMode()) {
43
+ console.warn(ColumnMenuErrorMessages.autoSizeAllColumns);
44
+ }
45
+ }
46
+ /**
47
+ * Resizes all columns to the minimum possible width so that they fit the widest header or cell content without wrapping.
48
+ */
49
+ autoSizeAllColumns() {
50
+ autoSizeColumn(this.ctx.treelist, this.service);
51
+ }
52
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuAutoSizeAllColumnsComponent, deps: [{ token: i1.ContextService }], target: i0.ɵɵFactoryTarget.Component });
53
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuAutoSizeAllColumnsComponent, isStandalone: true, selector: "kendo-treelist-columnmenu-autosize-all-columns", usesInheritance: true, ngImport: i0, template: `
54
+ <kendo-treelist-columnmenu-item
55
+ *ngIf="!this.ctx.treelist.virtualColumns"
56
+ [text]="ctx.localization.get('autosizeAllColumns')"
57
+ icon="display-inline-flex"
58
+ [svgIcon]="displayInlineFlexIcon"
59
+ (itemClick)="autoSizeAllColumns()"
60
+ ></kendo-treelist-columnmenu-item>
61
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded", "service"], outputs: ["itemClick", "expand", "collapse"] }] });
62
+ }
63
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuAutoSizeAllColumnsComponent, decorators: [{
64
+ type: Component,
65
+ args: [{
66
+ selector: 'kendo-treelist-columnmenu-autosize-all-columns',
67
+ template: `
68
+ <kendo-treelist-columnmenu-item
69
+ *ngIf="!this.ctx.treelist.virtualColumns"
70
+ [text]="ctx.localization.get('autosizeAllColumns')"
71
+ icon="display-inline-flex"
72
+ [svgIcon]="displayInlineFlexIcon"
73
+ (itemClick)="autoSizeAllColumns()"
74
+ ></kendo-treelist-columnmenu-item>
75
+ `,
76
+ standalone: true,
77
+ imports: [NgIf, ColumnMenuItemComponent]
78
+ }]
79
+ }], ctorParameters: function () { return [{ type: i1.ContextService }]; } });
@@ -0,0 +1,87 @@
1
+ /**-----------------------------------------------------------------------------------------
2
+ * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
+ * Licensed under commercial license. See LICENSE.md in the project root for more information
4
+ *-------------------------------------------------------------------------------------------*/
5
+ import { Component, Input, isDevMode } from '@angular/core';
6
+ import { maxWidthIcon } from '@progress/kendo-svg-icons';
7
+ import { ContextService } from '../common/provider.service';
8
+ import { ColumnMenuItemBase } from './column-menu-item-base';
9
+ import { autoSizeColumn } from './utils';
10
+ import { ColumnMenuItemComponent } from './column-menu-item.component';
11
+ import { NgIf } from '@angular/common';
12
+ import { ColumnMenuErrorMessages } from '../common/error-messages';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "../common/provider.service";
15
+ /**
16
+ * Represents the column-menu item for resizing the specified column to the minimum possible width so that it fits the header or cell content without wrapping.
17
+ * The component can be placed inside a [ColumnMenuTemplate]({% slug api_treelist_columnmenutemplatedirective %}) directive.
18
+ * [See example](slug:columnmenu_treelist#toc-customizing-the-content).
19
+ *
20
+ * You have to set the [ColumnMenuService]({% slug api_treelist_columnmenuservice %}) and `column` that are passed by
21
+ * the template to the `service` and `column` input of the `kendo-treelist-columnmenu-autosize-column` component.
22
+ *
23
+ * @example
24
+ * ```html
25
+ * <kendo-treelist [columnMenu]="true" ...>
26
+ * <ng-template kendoTreeListColumnMenuTemplate let-service="service" let-column="column">
27
+ * <kendo-treelist-columnmenu-autosize-column [column]="column" [service]="service">
28
+ * </kendo-treelist-columnmenu-autosize-column>
29
+ * </ng-template>
30
+ * </kendo-treelist>
31
+ * ```
32
+ */
33
+ export class ColumnMenuAutoSizeColumnComponent extends ColumnMenuItemBase {
34
+ ctx;
35
+ /**
36
+ * The TreeList column instance which will be resized through the auto size column option.
37
+ */
38
+ column;
39
+ maxWidthIcon = maxWidthIcon;
40
+ constructor(ctx) {
41
+ super();
42
+ this.ctx = ctx;
43
+ }
44
+ ngOnInit() {
45
+ const isVirtualColumns = this.ctx.treelist.columnMenuTemplate && this.ctx.treelist.virtualColumns;
46
+ if (isVirtualColumns && isDevMode()) {
47
+ console.warn(ColumnMenuErrorMessages.autoSizeColumn);
48
+ }
49
+ }
50
+ /**
51
+ * Resizes a specified column to the minimum possible width so that it fits the widest header or cell content without wrapping.
52
+ */
53
+ autoSizeColumn() {
54
+ autoSizeColumn(this.ctx.treelist, this.service, this.column);
55
+ }
56
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuAutoSizeColumnComponent, deps: [{ token: i1.ContextService }], target: i0.ɵɵFactoryTarget.Component });
57
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuAutoSizeColumnComponent, isStandalone: true, selector: "kendo-treelist-columnmenu-autosize-column", inputs: { column: "column" }, usesInheritance: true, ngImport: i0, template: `
58
+ <kendo-treelist-columnmenu-item
59
+ *ngIf="!this.ctx.treelist.virtualColumns"
60
+ class="k-grid-columnmenu-autosize-column"
61
+ [text]="ctx.localization.get('autosizeThisColumn')"
62
+ icon="max-width"
63
+ [svgIcon]="maxWidthIcon"
64
+ (itemClick)="autoSizeColumn()"
65
+ ></kendo-treelist-columnmenu-item>
66
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded", "service"], outputs: ["itemClick", "expand", "collapse"] }] });
67
+ }
68
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuAutoSizeColumnComponent, decorators: [{
69
+ type: Component,
70
+ args: [{
71
+ selector: 'kendo-treelist-columnmenu-autosize-column',
72
+ template: `
73
+ <kendo-treelist-columnmenu-item
74
+ *ngIf="!this.ctx.treelist.virtualColumns"
75
+ class="k-grid-columnmenu-autosize-column"
76
+ [text]="ctx.localization.get('autosizeThisColumn')"
77
+ icon="max-width"
78
+ [svgIcon]="maxWidthIcon"
79
+ (itemClick)="autoSizeColumn()"
80
+ ></kendo-treelist-columnmenu-item>
81
+ `,
82
+ standalone: true,
83
+ imports: [NgIf, ColumnMenuItemComponent]
84
+ }]
85
+ }], ctorParameters: function () { return [{ type: i1.ContextService }]; }, propDecorators: { column: [{
86
+ type: Input
87
+ }] } });