@progress/kendo-angular-grid 20.0.4-develop.2 → 20.1.0-develop.10

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 (65) hide show
  1. package/adaptiveness/adaptive-renderer.component.d.ts +2 -3
  2. package/column-menu/column-chooser-content.component.d.ts +60 -0
  3. package/column-menu/column-chooser.component.d.ts +15 -4
  4. package/column-menu/column-list-kb-nav.service.d.ts +2 -2
  5. package/column-menu/column-list.component.d.ts +28 -21
  6. package/column-menu/column-menu-chooser.component.d.ts +2 -7
  7. package/column-menu/column-menu.component.d.ts +0 -4
  8. package/columns/column-base.d.ts +8 -0
  9. package/columns/command-column.component.d.ts +1 -1
  10. package/columns/span-column.component.d.ts +1 -1
  11. package/directives.d.ts +1 -2
  12. package/editing/cancel-command.directive.d.ts +1 -1
  13. package/editing/edit-row-options.interface.d.ts +1 -1
  14. package/editing/edit-template.directive.d.ts +1 -1
  15. package/editing/remove-command.directive.d.ts +1 -1
  16. package/editing/save-command.directive.d.ts +1 -1
  17. package/editing-directives/edit-service.interface.d.ts +2 -2
  18. package/editing-directives/external-editing.directive.d.ts +1 -1
  19. package/editing-directives/in-cell-editing.directive.d.ts +1 -1
  20. package/editing-directives/reactive-editing.directive.d.ts +1 -1
  21. package/editing-directives/template-editing.directive.d.ts +1 -1
  22. package/esm2022/adaptiveness/adaptive-renderer.component.mjs +26 -46
  23. package/esm2022/column-menu/column-chooser-content.component.mjs +306 -0
  24. package/esm2022/column-menu/column-chooser.component.mjs +39 -31
  25. package/esm2022/column-menu/column-list-kb-nav.service.mjs +4 -4
  26. package/esm2022/column-menu/column-list.component.mjs +221 -176
  27. package/esm2022/column-menu/column-menu-chooser.component.mjs +17 -36
  28. package/esm2022/column-menu/column-menu-container.component.mjs +10 -1
  29. package/esm2022/column-menu/column-menu.component.mjs +19 -29
  30. package/esm2022/columns/column-base.mjs +8 -0
  31. package/esm2022/columns/command-column.component.mjs +1 -1
  32. package/esm2022/columns/span-column.component.mjs +1 -1
  33. package/esm2022/common/column-info.service.mjs +3 -0
  34. package/esm2022/directives.mjs +0 -2
  35. package/esm2022/editing/cancel-command.directive.mjs +1 -1
  36. package/esm2022/editing/edit-template.directive.mjs +1 -1
  37. package/esm2022/editing/remove-command.directive.mjs +1 -1
  38. package/esm2022/editing/save-command.directive.mjs +1 -1
  39. package/esm2022/editing-directives/external-editing.directive.mjs +1 -1
  40. package/esm2022/editing-directives/in-cell-editing.directive.mjs +1 -1
  41. package/esm2022/editing-directives/reactive-editing.directive.mjs +1 -1
  42. package/esm2022/editing-directives/template-editing.directive.mjs +1 -1
  43. package/esm2022/filtering/menu/filter-menu-input-wrapper.component.mjs +2 -2
  44. package/esm2022/filtering/menu/filter-menu.component.mjs +7 -1
  45. package/esm2022/grid.component.mjs +6 -0
  46. package/esm2022/grid.module.mjs +47 -48
  47. package/esm2022/localization/messages.mjs +12 -1
  48. package/esm2022/navigation/logical-cell.directive.mjs +8 -2
  49. package/esm2022/navigation/navigation.service.mjs +1 -0
  50. package/esm2022/package-metadata.mjs +2 -2
  51. package/esm2022/rendering/list.component.mjs +23 -1
  52. package/esm2022/rendering/toolbar/tools/column-chooser-tool.directive.mjs +39 -13
  53. package/esm2022/rendering/toolbar/tools/filter-toolbar-tool.component.mjs +1 -1
  54. package/esm2022/rendering/toolbar/tools/group-toolbar-tool.component.mjs +2 -2
  55. package/esm2022/rendering/toolbar/tools/sort-toolbar-tool.component.mjs +1 -1
  56. package/fesm2022/progress-kendo-angular-grid.mjs +739 -391
  57. package/grid.module.d.ts +46 -47
  58. package/localization/messages.d.ts +10 -1
  59. package/navigation/navigation.service.d.ts +1 -0
  60. package/package.json +21 -21
  61. package/rendering/list.component.d.ts +1 -0
  62. package/rendering/toolbar/tools/column-chooser-tool.directive.d.ts +13 -1
  63. package/schematics/ngAdd/index.js +4 -4
  64. package/column-menu/column-chooser-item-checked.directive.d.ts +0 -21
  65. package/esm2022/column-menu/column-chooser-item-checked.directive.mjs +0 -45
@@ -2,23 +2,22 @@
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, ViewChild, ViewChildren, QueryList, Optional } from '@angular/core';
5
+ import { Component, HostBinding, Input, ElementRef, NgZone, Renderer2, Output, EventEmitter, ViewChildren, QueryList, Optional, ChangeDetectorRef } from '@angular/core';
6
6
  import { ColumnMenuService } from './column-menu.service';
7
7
  import { ColumnListKeyboardNavigation } from './column-list-kb-nav.service';
8
- import { ColumnMenuChooserItemCheckedDirective } from './column-chooser-item-checked.directive';
9
8
  import { Keys, normalizeNumpadKeys } from '@progress/kendo-angular-common';
10
9
  import { Subscription } from 'rxjs';
11
- import { NgFor, NgIf, NgClass } from '@angular/common';
10
+ import { NgFor, NgIf } from '@angular/common';
12
11
  import { CheckBoxComponent } from '@progress/kendo-angular-inputs';
13
12
  import { take } from 'rxjs/operators';
14
- import { arrowRotateCcwIcon, checkIcon } from '@progress/kendo-svg-icons';
15
- import { ButtonComponent } from '@progress/kendo-angular-buttons';
16
13
  import { ContextService } from '../common/provider.service';
17
14
  import { AdaptiveGridService } from '../common/adaptiveness.service';
15
+ import { ColumnInfoService } from '../common/column-info.service';
18
16
  import * as i0 from "@angular/core";
19
17
  import * as i1 from "./column-list-kb-nav.service";
20
- import * as i2 from "../common/adaptiveness.service";
21
- import * as i3 from "../common/provider.service";
18
+ import * as i2 from "../common/column-info.service";
19
+ import * as i3 from "../common/adaptiveness.service";
20
+ import * as i4 from "../common/provider.service";
22
21
  /**
23
22
  * @hidden
24
23
  */
@@ -27,10 +26,10 @@ export class ColumnListComponent {
27
26
  ngZone;
28
27
  renderer;
29
28
  listNavigationService;
29
+ cdr;
30
+ columnInfoService;
30
31
  adaptiveGridService;
31
32
  ctx;
32
- checkIcon = checkIcon;
33
- arrowRotateCcwIcon = arrowRotateCcwIcon;
34
33
  className = true;
35
34
  get listSizeMd() {
36
35
  return !(this.ctx?.grid?.isActionSheetExpanded);
@@ -42,40 +41,59 @@ export class ColumnListComponent {
42
41
  apply = new EventEmitter();
43
42
  columnChange = new EventEmitter();
44
43
  set columns(value) {
44
+ this.listNavigationService.items = this.checkboxes?.toArray();
45
45
  this._columns = value.filter(column => column.includeInChooser !== false);
46
- this.allColumns = value;
47
- this.updateColumnState();
48
46
  }
49
47
  get columns() {
50
48
  return this._columns;
51
49
  }
52
- showActions = true;
50
+ get checkedCheckboxesLength() {
51
+ return this.columns?.filter(column => column.currentlyChecked).length;
52
+ }
53
+ filteredColumns = [];
53
54
  autoSync = true;
55
+ showSelectAll = false;
56
+ isFiltered = false;
54
57
  ariaLabel;
55
58
  allowHideAll = false;
56
59
  applyText;
57
60
  resetText;
58
- actionsClass = 'k-actions k-actions-stretched k-actions-horizontal';
59
61
  isLast;
60
62
  isExpanded;
61
63
  service;
64
+ filterable = false;
65
+ checkboxes;
66
+ get columnCheckboxes() {
67
+ if (this.showSelectAll) {
68
+ return this.checkboxes?.toArray().slice(1);
69
+ }
70
+ return this.checkboxes?.toArray();
71
+ }
72
+ get lockedColumnCheckboxes() {
73
+ return this.columnCheckboxes?.filter((checkbox, index) => this.filteredColumns[index]?.locked);
74
+ }
75
+ get unlockedColumnCheckboxes() {
76
+ return this.columnCheckboxes?.filter((checkbox, index) => !this.filteredColumns[index]?.locked);
77
+ }
78
+ get checkedCheckboxes() {
79
+ if (this.showSelectAll && !this.isFiltered) {
80
+ return this.checkboxes?.toArray().slice(1).filter(checkbox => checkbox.checkedState).length;
81
+ }
82
+ return this.checkboxes?.filter(checkbox => checkbox.checkedState).length;
83
+ }
62
84
  resetButton;
63
85
  applyButton;
64
- options;
65
- checkboxes;
66
- hasLocked;
67
- hasVisibleLocked;
68
- unlockedCount = 0;
69
- hasUnlockedFiltered;
70
- hasFiltered;
86
+ filterInput;
71
87
  _columns;
72
- allColumns;
73
88
  domSubscriptions = new Subscription();
74
- constructor(element, ngZone, renderer, listNavigationService, adaptiveGridService, ctx) {
89
+ lastDisabledCheckbox;
90
+ constructor(element, ngZone, renderer, listNavigationService, cdr, columnInfoService, adaptiveGridService, ctx) {
75
91
  this.element = element;
76
92
  this.ngZone = ngZone;
77
93
  this.renderer = renderer;
78
94
  this.listNavigationService = listNavigationService;
95
+ this.cdr = cdr;
96
+ this.columnInfoService = columnInfoService;
79
97
  this.adaptiveGridService = adaptiveGridService;
80
98
  this.ctx = ctx;
81
99
  }
@@ -85,17 +103,17 @@ export class ColumnListComponent {
85
103
  }
86
104
  this.ngZone.runOutsideAngular(() => {
87
105
  this.domSubscriptions.add(this.renderer.listen(this.element.nativeElement, 'click', (e) => {
88
- e.stopImmediatePropagation();
89
- this.ngZone.onStable.pipe(take(1)).subscribe(() => {
90
- this.handleCheckBoxClick(e);
91
- });
106
+ if (e.target.classList.contains('k-checkbox')) {
107
+ const label = e.target.closest('.k-column-list-item');
108
+ this.setTabindex(label);
109
+ }
92
110
  }));
93
111
  this.domSubscriptions.add(this.renderer.listen(this.element.nativeElement, 'keydown', this.onKeydown));
94
112
  });
95
113
  }
96
114
  ngAfterViewInit() {
97
115
  this.ngZone.onStable.pipe(take(1)).subscribe(() => {
98
- this.listNavigationService.items = this.options.toArray();
116
+ this.listNavigationService.items = this.checkboxes.toArray();
99
117
  if (this.adaptiveGridService?.viewType !== 'columnMenu') {
100
118
  this.listNavigationService.toggle(0, true);
101
119
  }
@@ -112,38 +130,88 @@ export class ColumnListComponent {
112
130
  return;
113
131
  }
114
132
  if (changes['isLast'] && this.isLast) {
115
- this.service.menuTabbingService.lastFocusable = this.applyButton.nativeElement;
133
+ this.service.menuTabbingService.lastFocusable = this.applyButton?.nativeElement;
116
134
  }
117
135
  if (changes['isExpanded'] && this.isExpanded && this.isLast && this.applyButton) {
118
136
  this.service.menuTabbingService.lastFocusable = this.applyButton.nativeElement;
119
137
  }
120
138
  }
139
+ onSelectAllCheckboxChange(checkedState) {
140
+ if (!checkedState && !this.allowHideAll) {
141
+ const columnsToKeep = [];
142
+ if (!columnsToKeep.length) {
143
+ const unlockedColumns = this.filteredColumns.filter(c => !c.locked);
144
+ if (unlockedColumns.length > 0) {
145
+ columnsToKeep.push(unlockedColumns[0]);
146
+ }
147
+ }
148
+ if (this.lockedColumnCheckboxes.length > 0) {
149
+ const lockedColumns = this.filteredColumns.filter(c => c.locked);
150
+ if (lockedColumns.length > 0) {
151
+ columnsToKeep.unshift(lockedColumns[0]);
152
+ }
153
+ }
154
+ this.filteredColumns.forEach(column => {
155
+ const isChecked = columnsToKeep.indexOf(column) >= 0;
156
+ column.currentlyChecked = isChecked;
157
+ });
158
+ }
159
+ else {
160
+ this.filteredColumns.forEach(column => {
161
+ column.currentlyChecked = checkedState;
162
+ });
163
+ }
164
+ if (this.autoSync) {
165
+ const changedColumns = this.filteredColumns.filter(column => column.initiallyChecked !== column.currentlyChecked);
166
+ if (changedColumns.length > 0) {
167
+ changedColumns.forEach(column => {
168
+ column.hidden = !column.currentlyChecked;
169
+ column.initiallyChecked = column.currentlyChecked;
170
+ });
171
+ this.ngZone.run(() => {
172
+ this.columnChange.emit(changedColumns);
173
+ });
174
+ }
175
+ }
176
+ this.filteredColumns = [...this.filteredColumns];
177
+ this.updateDisabled();
178
+ }
121
179
  ngOnDestroy() {
122
180
  this.domSubscriptions.unsubscribe();
123
181
  }
124
- isDisabled(column) {
125
- return !(this.allowHideAll || this.hasFiltered || column.hidden || this.columns.find(current => current !== column && !current.hidden)) ||
126
- (this.hasVisibleLocked && !this.hasUnlockedFiltered && this.unlockedCount === 1 && !column.locked && !column.hidden);
127
- }
128
182
  cancelChanges() {
129
- this.checkboxes.forEach((element, index) => {
130
- element.checkedState = !this.columns[index].hidden;
183
+ this.columns.forEach((column) => {
184
+ column.currentlyChecked = !column.hidden;
185
+ column.initiallyChecked = !column.hidden;
186
+ });
187
+ this.filteredColumns.forEach((column) => {
188
+ column.currentlyChecked = !column.hidden;
189
+ column.initiallyChecked = !column.hidden;
131
190
  });
132
191
  this.updateDisabled();
133
192
  this.reset.emit();
134
193
  }
135
194
  applyChanges() {
136
195
  const changed = [];
137
- this.checkboxes.forEach((item, index) => {
138
- const column = this.columns[index];
139
- const hidden = !item.checkedState;
140
- if (Boolean(column.hidden) !== hidden) {
141
- column.hidden = hidden;
196
+ this.columns.forEach(column => {
197
+ if (column.initiallyChecked !== column.currentlyChecked) {
198
+ column.hidden = !column.currentlyChecked;
142
199
  changed.push(column);
143
200
  }
144
201
  });
145
202
  this.updateDisabled();
146
203
  this.apply.emit(changed);
204
+ if (changed.length) {
205
+ this.cdr.markForCheck();
206
+ this.columnInfoService?.changeVisibility(changed);
207
+ }
208
+ }
209
+ focusActiveColumn(e) {
210
+ const keyboardEvent = e;
211
+ if (keyboardEvent.shiftKey) {
212
+ this.listNavigationService.toggle(this.listNavigationService.activeIndex, true);
213
+ e.preventDefault();
214
+ }
147
215
  }
148
216
  onTab(e) {
149
217
  if (this.isLast) {
@@ -151,6 +219,9 @@ export class ColumnListComponent {
151
219
  if (this.service) {
152
220
  this.service.menuTabbingService.firstFocusable.focus();
153
221
  }
222
+ else if (this.filterable) {
223
+ this.filterInput?.input.nativeElement.focus();
224
+ }
154
225
  else {
155
226
  this.listNavigationService.toggle(this.listNavigationService.activeIndex, true);
156
227
  }
@@ -161,10 +232,30 @@ export class ColumnListComponent {
161
232
  if (code !== Keys.Tab) {
162
233
  e.preventDefault();
163
234
  }
235
+ if (code === 'Tab' && e.shiftKey) {
236
+ this.resetButton?.nativeElement.focus();
237
+ e.preventDefault();
238
+ }
164
239
  if (code === 'Tab' && !e.shiftKey && this.autoSync) {
240
+ if (this.filterable) {
241
+ this.filterInput?.input.nativeElement.focus();
242
+ }
243
+ e.preventDefault();
244
+ }
245
+ if (code === 'Tab' && e.shiftKey && this.autoSync && this.filterable) {
246
+ this.filterInput?.input.nativeElement.focus();
247
+ e.preventDefault();
248
+ }
249
+ if (code === 'Tab' && !e.shiftKey && !this.autoSync) {
250
+ this.applyButton?.nativeElement.focus();
165
251
  e.preventDefault();
166
252
  }
167
253
  if (code === 'Tab' && e.shiftKey) {
254
+ if (!this.autoSync && this.filterable && e.target.matches('.k-column-list-item')) {
255
+ this.filterInput?.input.nativeElement.focus();
256
+ e.preventDefault();
257
+ return;
258
+ }
168
259
  this.ngZone.run(() => {
169
260
  if (e.target.matches('.k-column-list-item')) {
170
261
  e.preventDefault();
@@ -183,46 +274,33 @@ export class ColumnListComponent {
183
274
  }
184
275
  };
185
276
  updateDisabled() {
186
- if (this.allowHideAll && !this.hasLocked) {
277
+ const hasLockedColumns = this.columns.filter(c => c.locked).length > 0;
278
+ if (this.allowHideAll && !hasLockedColumns) {
187
279
  return;
188
280
  }
189
- // Cache visible columns to avoid repeated checks
190
- const visibleColumns = [];
191
- const columnMap = new Map();
192
- this.checkboxes.forEach((checkbox, index) => {
193
- // Reset all disabled states first
194
- this.setDisabledState(checkbox, false);
195
- if (checkbox.checkedState) {
196
- visibleColumns.push({ checkbox, index });
197
- columnMap.set(index, this.columns[index]);
198
- }
199
- });
200
- // Only apply disabled states where needed
201
- if (!this.allowHideAll && visibleColumns.length === 1 && !this.hasFiltered) {
202
- this.setDisabledState(visibleColumns[0].checkbox, true);
203
- }
204
- else if (this.hasLocked && !this.hasUnlockedFiltered) {
205
- const checkedUnlocked = visibleColumns.filter(item => !columnMap.get(item.index).locked);
206
- if (checkedUnlocked.length === 1) {
207
- this.setDisabledState(checkedUnlocked[0].checkbox, true);
208
- }
209
- }
210
- }
211
- updateColumnState() {
212
- this.hasLocked = this.allColumns.filter(column => column.locked && (!column.hidden || column.includeInChooser !== false)).length > 0;
213
- this.hasVisibleLocked = this.allColumns.filter(column => column.locked && !column.hidden).length > 0;
214
- this.unlockedCount = this.columns.filter(column => !column.locked && !column.hidden).length;
215
- const filteredColumns = this.allColumns.filter(column => column.includeInChooser === false && !column.hidden);
216
- if (filteredColumns.length) {
217
- this.hasFiltered = filteredColumns.length > 0;
218
- this.hasUnlockedFiltered = filteredColumns.filter(column => !column.locked).length > 0;
281
+ const currentlyCheckedUnlockedColumns = this.columns.filter(column => !column.locked && column.currentlyChecked).length;
282
+ const shouldEnforceMinimumColumns = hasLockedColumns || !this.allowHideAll;
283
+ if (shouldEnforceMinimumColumns && currentlyCheckedUnlockedColumns === 1) {
284
+ this.disableFirstUnlockedCheckedCheckbox();
219
285
  }
220
286
  else {
221
- this.hasFiltered = false;
222
- this.hasUnlockedFiltered = false;
287
+ this.enableLastDisabledColumn();
223
288
  }
224
289
  }
290
+ disableFirstUnlockedCheckedCheckbox() {
291
+ const index = this.filteredColumns.filter(c => !c.locked).findIndex(column => column.currentlyChecked);
292
+ const firstUnlockedCheckedCheckbox = this.unlockedColumnCheckboxes[index];
293
+ this.setDisabledState(firstUnlockedCheckedCheckbox, true);
294
+ this.lastDisabledCheckbox = firstUnlockedCheckedCheckbox;
295
+ }
296
+ enableLastDisabledColumn() {
297
+ this.setDisabledState(this.lastDisabledCheckbox, false);
298
+ this.lastDisabledCheckbox = null;
299
+ }
225
300
  setDisabledState(checkbox, disabled) {
301
+ if (!checkbox) {
302
+ return;
303
+ }
226
304
  if (checkbox.disabled !== disabled) {
227
305
  this.ngZone.runOutsideAngular(() => {
228
306
  checkbox.disabled = disabled;
@@ -239,85 +317,64 @@ export class ColumnListComponent {
239
317
  });
240
318
  }
241
319
  }
242
- handleCheckBoxClick = (e) => {
243
- const closestItem = e.target.closest('.k-column-list-item');
244
- if (closestItem) {
245
- const checkboxElement = closestItem.querySelector('.k-checkbox-wrap');
246
- const index = parseInt(checkboxElement.firstElementChild.getAttribute('data-index'), 10);
247
- const checkbox = this.checkboxes.toArray()[index];
248
- if (e.target === checkbox.input.nativeElement) {
249
- closestItem.focus();
250
- e.target.classList.remove('k-focus');
251
- }
252
- if (this.autoSync) {
253
- if (!this.columns[index]) {
254
- return;
255
- }
256
- const column = this.columns[index];
257
- const hidden = !checkbox.checkedState;
258
- if (Boolean(column.hidden) !== hidden) {
259
- this.ngZone.runOutsideAngular(() => {
260
- column.hidden = hidden;
261
- this.ngZone.run(() => {
262
- this.columnChange.emit([column]);
263
- });
264
- });
265
- }
266
- }
267
- else {
268
- this.ngZone.run(() => this.updateDisabled());
269
- }
270
- if (index !== this.listNavigationService.activeIndex) {
271
- this.listNavigationService.toggle(this.listNavigationService.activeIndex, false);
272
- this.listNavigationService.activeIndex = index;
273
- this.listNavigationService.toggle(index, true);
274
- }
320
+ onCheckboxChange(checkedState, column, _index) {
321
+ column.currentlyChecked = checkedState;
322
+ if (this.autoSync) {
323
+ column.hidden = !checkedState;
324
+ column.initiallyChecked = checkedState;
325
+ this.columnChange.emit([column]);
275
326
  }
276
- };
277
- 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 }, { token: i2.AdaptiveGridService, optional: true }, { token: i3.ContextService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
278
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnListComponent, isStandalone: true, selector: "kendo-grid-columnlist", inputs: { columns: "columns", showActions: "showActions", 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", "class.k-column-list-md": "this.listSizeMd", "class.k-column-list-lg": "this.listSizeLg" } }, 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: `
327
+ this.updateDisabled();
328
+ }
329
+ setTabindex(labelElement) {
330
+ if (!labelElement) {
331
+ return;
332
+ }
333
+ const allLabels = this.checkboxes.map(checkbox => checkbox.hostElement.nativeElement.parentElement);
334
+ allLabels.forEach((label) => {
335
+ const input = label.querySelector('input');
336
+ input.classList.remove('k-focus');
337
+ this.renderer.removeAttribute(label, 'tabindex');
338
+ });
339
+ this.renderer.setAttribute(labelElement, 'tabindex', '0');
340
+ labelElement.focus();
341
+ this.listNavigationService.activeIndex = allLabels.indexOf(labelElement);
342
+ }
343
+ 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 }, { token: i0.ChangeDetectorRef }, { token: i2.ColumnInfoService, optional: true }, { token: i3.AdaptiveGridService, optional: true }, { token: i4.ContextService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
344
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnListComponent, isStandalone: true, selector: "kendo-grid-columnlist", inputs: { columns: "columns", filteredColumns: "filteredColumns", autoSync: "autoSync", showSelectAll: "showSelectAll", isFiltered: "isFiltered", ariaLabel: "ariaLabel", allowHideAll: "allowHideAll", applyText: "applyText", resetText: "resetText", isLast: "isLast", isExpanded: "isExpanded", service: "service", filterable: "filterable" }, outputs: { reset: "reset", apply: "apply", columnChange: "columnChange" }, host: { properties: { "class.k-column-list-wrapper": "this.className", "class.k-column-list-md": "this.listSizeMd", "class.k-column-list-lg": "this.listSizeLg" } }, providers: [ColumnListKeyboardNavigation], viewQueries: [{ propertyName: "checkboxes", predicate: CheckBoxComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
279
345
  <div
280
346
  class="k-column-list"
281
347
  role="listbox"
282
348
  aria-multiselectable="true"
283
349
  [attr.aria-label]="ariaLabel">
284
350
  <label
285
- *ngFor="let column of columns; let index = index;"
351
+ *ngIf="showSelectAll"
286
352
  class='k-column-list-item'
287
- [kendoColumnMenuChooserItemChecked]="!column.hidden"
288
353
  role="option">
289
354
  <kendo-checkbox
355
+ #checkbox
356
+ [inputAttributes]="{'data-index': '0'}"
357
+ [tabindex]="-1"
358
+ [checkedState]="checkedCheckboxesLength === columns.length"
359
+ (checkedStateChange)="onSelectAllCheckboxChange($event)"
360
+ ></kendo-checkbox>
361
+ <span class="k-checkbox-label">{{ 'Select all' }}</span>
362
+ </label>
363
+ <label
364
+ *ngFor="let column of filteredColumns; let index = index;"
365
+ class='k-column-list-item'
366
+ role="option">
367
+ <kendo-checkbox
368
+ #checkbox
290
369
  [inputAttributes]="{'data-index': index.toString()}"
291
370
  [tabindex]="-1"
292
- [checkedState]="!column.hidden"
293
- [disabled]="isDisabled(column)"
371
+ [checkedState]="column.currentlyChecked"
372
+ (checkedStateChange)="onCheckboxChange($event, column, index)"
294
373
  ></kendo-checkbox>
295
374
  <span class="k-checkbox-label">{{ column.displayTitle }}</span>
296
375
  </label>
297
376
  </div>
298
- <div [ngClass]="actionsClass" *ngIf="!autoSync && showActions">
299
- <button
300
- #applyButton
301
- kendoButton
302
- type="button"
303
- icon="check"
304
- [svgIcon]="checkIcon"
305
- themeColor="primary"
306
- (click)="applyChanges()"
307
- (keydown.enter)="$event.preventDefault(); $event.stopPropagation(); applyChanges();"
308
- (keydown.space)="$event.preventDefault(); $event.stopPropagation(); applyChanges();">{{ applyText }}</button>
309
- <button
310
- #resetButton
311
- kendoButton
312
- type="button"
313
- icon="reset"
314
- [svgIcon]="arrowRotateCcwIcon"
315
- (keydown.tab)="onTab($event)"
316
- (click)="cancelChanges()"
317
- (keydown.enter)="$event.preventDefault(); $event.stopPropagation(); cancelChanges();"
318
- (keydown.space)="$event.preventDefault(); $event.stopPropagation(); cancelChanges();">{{ resetText }}</button>
319
- </div>
320
- `, 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"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
377
+ `, 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: "component", type: CheckBoxComponent, selector: "kendo-checkbox", inputs: ["checkedState", "rounded"], outputs: ["checkedStateChange"], exportAs: ["kendoCheckBox"] }] });
321
378
  }
322
379
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnListComponent, decorators: [{
323
380
  type: Component,
@@ -331,48 +388,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
331
388
  aria-multiselectable="true"
332
389
  [attr.aria-label]="ariaLabel">
333
390
  <label
334
- *ngFor="let column of columns; let index = index;"
391
+ *ngIf="showSelectAll"
392
+ class='k-column-list-item'
393
+ role="option">
394
+ <kendo-checkbox
395
+ #checkbox
396
+ [inputAttributes]="{'data-index': '0'}"
397
+ [tabindex]="-1"
398
+ [checkedState]="checkedCheckboxesLength === columns.length"
399
+ (checkedStateChange)="onSelectAllCheckboxChange($event)"
400
+ ></kendo-checkbox>
401
+ <span class="k-checkbox-label">{{ 'Select all' }}</span>
402
+ </label>
403
+ <label
404
+ *ngFor="let column of filteredColumns; let index = index;"
335
405
  class='k-column-list-item'
336
- [kendoColumnMenuChooserItemChecked]="!column.hidden"
337
406
  role="option">
338
407
  <kendo-checkbox
408
+ #checkbox
339
409
  [inputAttributes]="{'data-index': index.toString()}"
340
410
  [tabindex]="-1"
341
- [checkedState]="!column.hidden"
342
- [disabled]="isDisabled(column)"
411
+ [checkedState]="column.currentlyChecked"
412
+ (checkedStateChange)="onCheckboxChange($event, column, index)"
343
413
  ></kendo-checkbox>
344
414
  <span class="k-checkbox-label">{{ column.displayTitle }}</span>
345
415
  </label>
346
416
  </div>
347
- <div [ngClass]="actionsClass" *ngIf="!autoSync && showActions">
348
- <button
349
- #applyButton
350
- kendoButton
351
- type="button"
352
- icon="check"
353
- [svgIcon]="checkIcon"
354
- themeColor="primary"
355
- (click)="applyChanges()"
356
- (keydown.enter)="$event.preventDefault(); $event.stopPropagation(); applyChanges();"
357
- (keydown.space)="$event.preventDefault(); $event.stopPropagation(); applyChanges();">{{ applyText }}</button>
358
- <button
359
- #resetButton
360
- kendoButton
361
- type="button"
362
- icon="reset"
363
- [svgIcon]="arrowRotateCcwIcon"
364
- (keydown.tab)="onTab($event)"
365
- (click)="cancelChanges()"
366
- (keydown.enter)="$event.preventDefault(); $event.stopPropagation(); cancelChanges();"
367
- (keydown.space)="$event.preventDefault(); $event.stopPropagation(); cancelChanges();">{{ resetText }}</button>
368
- </div>
369
417
  `,
370
418
  standalone: true,
371
- imports: [NgFor, ColumnMenuChooserItemCheckedDirective, NgIf, NgClass, CheckBoxComponent, ButtonComponent]
419
+ imports: [NgFor, NgIf, CheckBoxComponent]
372
420
  }]
373
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i1.ColumnListKeyboardNavigation }, { type: i2.AdaptiveGridService, decorators: [{
421
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i1.ColumnListKeyboardNavigation }, { type: i0.ChangeDetectorRef }, { type: i2.ColumnInfoService, decorators: [{
422
+ type: Optional
423
+ }] }, { type: i3.AdaptiveGridService, decorators: [{
374
424
  type: Optional
375
- }] }, { type: i3.ContextService, decorators: [{
425
+ }] }, { type: i4.ContextService, decorators: [{
376
426
  type: Optional
377
427
  }] }]; }, propDecorators: { className: [{
378
428
  type: HostBinding,
@@ -391,10 +441,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
391
441
  type: Output
392
442
  }], columns: [{
393
443
  type: Input
394
- }], showActions: [{
444
+ }], filteredColumns: [{
395
445
  type: Input
396
446
  }], autoSync: [{
397
447
  type: Input
448
+ }], showSelectAll: [{
449
+ type: Input
450
+ }], isFiltered: [{
451
+ type: Input
398
452
  }], ariaLabel: [{
399
453
  type: Input
400
454
  }], allowHideAll: [{
@@ -403,23 +457,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
403
457
  type: Input
404
458
  }], resetText: [{
405
459
  type: Input
406
- }], actionsClass: [{
407
- type: Input
408
460
  }], isLast: [{
409
461
  type: Input
410
462
  }], isExpanded: [{
411
463
  type: Input
412
464
  }], service: [{
413
465
  type: Input
414
- }], resetButton: [{
415
- type: ViewChild,
416
- args: ['resetButton', { static: false }]
417
- }], applyButton: [{
418
- type: ViewChild,
419
- args: ['applyButton', { static: false }]
420
- }], options: [{
421
- type: ViewChildren,
422
- args: [ColumnMenuChooserItemCheckedDirective]
466
+ }], filterable: [{
467
+ type: Input
423
468
  }], checkboxes: [{
424
469
  type: ViewChildren,
425
470
  args: [CheckBoxComponent]