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

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,7 +2,7 @@
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, Input, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
5
+ import { Component, Input, Output, EventEmitter, ChangeDetectorRef, ElementRef } from '@angular/core';
6
6
  import { ColumnInfoService } from '../common/column-info.service';
7
7
  import { LocalizationService } from "@progress/kendo-angular-l10n";
8
8
  import { ColumnMenuItemBase } from './column-menu-item-base';
@@ -20,12 +20,12 @@ import * as i2 from "../common/column-info.service";
20
20
  *
21
21
  * To register the component as a known column menu item, set the [`ColumnMenuService`]({% slug api_treelist_columnmenuservice %})
22
22
  * that is passed by the template to the service input of the `kendo-treelist-columnmenu-chooser` component.
23
- *
24
23
  */
25
24
  export class ColumnMenuChooserComponent extends ColumnMenuItemBase {
26
25
  localization;
27
26
  columnInfoService;
28
27
  changeDetector;
28
+ hostElement;
29
29
  /**
30
30
  * Fires when the content is expanded.
31
31
  */
@@ -42,16 +42,21 @@ export class ColumnMenuChooserComponent extends ColumnMenuItemBase {
42
42
  /**
43
43
  * @hidden
44
44
  */
45
- actionsClass = 'k-actions';
45
+ isLast = false;
46
+ /**
47
+ * @hidden
48
+ */
49
+ actionsClass = 'k-actions k-actions-stretched k-actions-horizontal';
46
50
  get columns() {
47
51
  return this.columnInfoService.leafNamedColumns;
48
52
  }
49
53
  columnsIcon = columnsIcon;
50
- constructor(localization, columnInfoService, changeDetector) {
54
+ constructor(localization, columnInfoService, changeDetector, hostElement) {
51
55
  super();
52
56
  this.localization = localization;
53
57
  this.columnInfoService = columnInfoService;
54
58
  this.changeDetector = changeDetector;
59
+ this.hostElement = hostElement;
55
60
  }
56
61
  /**
57
62
  * @hidden
@@ -63,28 +68,49 @@ export class ColumnMenuChooserComponent extends ColumnMenuItemBase {
63
68
  this.columnInfoService.changeVisibility(changed);
64
69
  }
65
70
  }
66
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuChooserComponent, deps: [{ token: i1.LocalizationService }, { token: i2.ColumnInfoService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
67
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuChooserComponent, isStandalone: true, selector: "kendo-treelist-columnmenu-chooser", inputs: { expanded: "expanded" }, outputs: { expand: "expand", collapse: "collapse" }, usesInheritance: true, ngImport: i0, template: `
71
+ /**
72
+ * @hidden
73
+ */
74
+ onCollapse() {
75
+ this.expanded = false;
76
+ if (this.isLast) {
77
+ this.service.menuTabbingService.lastFocusable = this.hostElement.nativeElement.querySelector('.k-columnmenu-item');
78
+ }
79
+ this.collapse.emit();
80
+ }
81
+ /**
82
+ * @hidden
83
+ */
84
+ onExpand() {
85
+ this.expanded = true;
86
+ this.expand.emit();
87
+ }
88
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuChooserComponent, deps: [{ token: i1.LocalizationService }, { token: i2.ColumnInfoService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
89
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuChooserComponent, isStandalone: true, selector: "kendo-treelist-columnmenu-chooser", inputs: { expanded: "expanded", isLast: "isLast" }, outputs: { expand: "expand", collapse: "collapse" }, usesInheritance: true, ngImport: i0, template: `
68
90
  <kendo-treelist-columnmenu-item
69
91
  [text]="localization.get('columns')"
70
92
  icon="columns"
71
93
  [svgIcon]="columnsIcon"
72
94
  [expanded]="expanded"
73
- (collapse)="collapse.emit()"
74
- (expand)="expand.emit()">
95
+ (collapse)="onCollapse()"
96
+ (expand)="onExpand()">
75
97
  <ng-template kendoTreeListColumnMenuItemContentTemplate>
76
98
  <kendo-treelist-columnlist
77
99
  [applyText]="localization.get('columnsApply')"
78
100
  [resetText]="localization.get('columnsReset')"
101
+ [ariaLabel]="localization.get('columns')"
79
102
  [columns]="columns"
80
103
  [autoSync]="false"
81
104
  [allowHideAll]="false"
82
105
  [actionsClass]="actionsClass"
106
+ [isLast]="isLast"
107
+ [isExpanded]="expanded"
108
+ [service]="service"
83
109
  (apply)="onApply($event)">
84
110
  </kendo-treelist-columnlist>
85
111
  </ng-template>
86
112
  </kendo-treelist-columnmenu-item>
87
- `, isInline: true, dependencies: [{ kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded"], outputs: ["itemClick", "expand", "collapse"] }, { kind: "directive", type: ColumnMenuItemContentTemplateDirective, selector: "[kendoTreeListColumnMenuItemContentTemplate]" }, { kind: "component", type: ColumnListComponent, selector: "kendo-treelist-columnlist", inputs: ["columns", "autoSync", "allowHideAll", "applyText", "resetText", "actionsClass"], outputs: ["reset", "apply", "columnChange"] }] });
113
+ `, isInline: true, dependencies: [{ kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded", "service"], outputs: ["itemClick", "expand", "collapse"] }, { kind: "directive", type: ColumnMenuItemContentTemplateDirective, selector: "[kendoTreeListColumnMenuItemContentTemplate]" }, { kind: "component", type: ColumnListComponent, selector: "kendo-treelist-columnlist", inputs: ["columns", "autoSync", "ariaLabel", "allowHideAll", "applyText", "resetText", "actionsClass", "isLast", "isExpanded", "service"], outputs: ["reset", "apply", "columnChange"] }] });
88
114
  }
89
115
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuChooserComponent, decorators: [{
90
116
  type: Component,
@@ -96,16 +122,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
96
122
  icon="columns"
97
123
  [svgIcon]="columnsIcon"
98
124
  [expanded]="expanded"
99
- (collapse)="collapse.emit()"
100
- (expand)="expand.emit()">
125
+ (collapse)="onCollapse()"
126
+ (expand)="onExpand()">
101
127
  <ng-template kendoTreeListColumnMenuItemContentTemplate>
102
128
  <kendo-treelist-columnlist
103
129
  [applyText]="localization.get('columnsApply')"
104
130
  [resetText]="localization.get('columnsReset')"
131
+ [ariaLabel]="localization.get('columns')"
105
132
  [columns]="columns"
106
133
  [autoSync]="false"
107
134
  [allowHideAll]="false"
108
135
  [actionsClass]="actionsClass"
136
+ [isLast]="isLast"
137
+ [isExpanded]="expanded"
138
+ [service]="service"
109
139
  (apply)="onApply($event)">
110
140
  </kendo-treelist-columnlist>
111
141
  </ng-template>
@@ -114,10 +144,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
114
144
  standalone: true,
115
145
  imports: [ColumnMenuItemComponent, ColumnMenuItemContentTemplateDirective, ColumnListComponent]
116
146
  }]
117
- }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i2.ColumnInfoService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { expand: [{
147
+ }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i2.ColumnInfoService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { expand: [{
118
148
  type: Output
119
149
  }], collapse: [{
120
150
  type: Output
121
151
  }], expanded: [{
122
152
  type: Input
153
+ }], isLast: [{
154
+ type: Input
123
155
  }] } });
@@ -0,0 +1,58 @@
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, ContentChildren, Inject, NgZone, QueryList } from '@angular/core';
6
+ import { take } from 'rxjs/operators';
7
+ import { ColumnMenuService } from './column-menu.service';
8
+ import { ColumnMenuItemDirective } from './column-menu-item.directive';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "./column-menu.service";
11
+ /**
12
+ * @hidden
13
+ */
14
+ export class ColumnMenuContainerComponent {
15
+ service;
16
+ ngZone;
17
+ columnMenuItems;
18
+ templateMenuItems = [];
19
+ constructor(service, ngZone) {
20
+ this.service = service;
21
+ this.ngZone = ngZone;
22
+ service.columnMenuContainer = this;
23
+ }
24
+ ngAfterViewInit() {
25
+ if (this.columnMenuItems.length) {
26
+ this.columnMenuItems.first.isFirst = true;
27
+ this.columnMenuItems.last.isLast = true;
28
+ }
29
+ else if (this.templateMenuItems.length) {
30
+ this.templateMenuItems[0].isFirst = true;
31
+ this.templateMenuItems[this.templateMenuItems.length - 1].isLast = true;
32
+ }
33
+ else {
34
+ return;
35
+ }
36
+ this.ngZone.onStable.pipe(take(1)).subscribe(() => this.service.menuTabbingService.firstFocusable.focus());
37
+ }
38
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuContainerComponent, deps: [{ token: i1.ColumnMenuService }, { token: NgZone }], target: i0.ɵɵFactoryTarget.Component });
39
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuContainerComponent, isStandalone: true, selector: "kendo-treelist-columnmenu-container", queries: [{ propertyName: "columnMenuItems", predicate: ColumnMenuItemDirective, descendants: true }], ngImport: i0, template: `
40
+ <ng-content></ng-content>
41
+ `, isInline: true });
42
+ }
43
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuContainerComponent, decorators: [{
44
+ type: Component,
45
+ args: [{
46
+ selector: 'kendo-treelist-columnmenu-container',
47
+ template: `
48
+ <ng-content></ng-content>
49
+ `,
50
+ standalone: true
51
+ }]
52
+ }], ctorParameters: function () { return [{ type: i1.ColumnMenuService }, { type: i0.NgZone, decorators: [{
53
+ type: Inject,
54
+ args: [NgZone]
55
+ }] }]; }, propDecorators: { columnMenuItems: [{
56
+ type: ContentChildren,
57
+ args: [ColumnMenuItemDirective, { descendants: true }]
58
+ }] } });
@@ -0,0 +1,5 @@
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
+ export {};
@@ -2,7 +2,7 @@
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, Input, Output, EventEmitter } from '@angular/core';
5
+ import { Component, Input, Output, EventEmitter, ElementRef } from '@angular/core';
6
6
  import { LocalizationService } from "@progress/kendo-angular-l10n";
7
7
  import { ColumnMenuItemBase } from './column-menu-item-base';
8
8
  import { filterIcon } from '@progress/kendo-svg-icons';
@@ -22,6 +22,7 @@ import * as i1 from "@progress/kendo-angular-l10n";
22
22
  */
23
23
  export class ColumnMenuFilterComponent extends ColumnMenuItemBase {
24
24
  localization;
25
+ hostElement;
25
26
  /**
26
27
  * Fires when the content is expanded.
27
28
  */
@@ -38,31 +39,57 @@ export class ColumnMenuFilterComponent extends ColumnMenuItemBase {
38
39
  /**
39
40
  * @hidden
40
41
  */
41
- actionsClass = 'k-actions';
42
+ isLast = false;
43
+ /**
44
+ * @hidden
45
+ */
46
+ actionsClass = 'k-actions k-actions-stretched k-actions-horizontal';
42
47
  filterIcon = filterIcon;
43
- constructor(localization) {
48
+ constructor(localization, hostElement) {
44
49
  super();
45
50
  this.localization = localization;
51
+ this.hostElement = hostElement;
52
+ }
53
+ /**
54
+ * @hidden
55
+ */
56
+ onCollapse() {
57
+ this.expanded = false;
58
+ if (this.isLast) {
59
+ this.service.menuTabbingService.lastFocusable = this.hostElement.nativeElement.querySelector('.k-columnmenu-item');
60
+ }
61
+ this.collapse.emit();
62
+ }
63
+ /**
64
+ * @hidden
65
+ */
66
+ onExpand() {
67
+ this.expanded = true;
68
+ this.expand.emit();
46
69
  }
47
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuFilterComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
48
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuFilterComponent, isStandalone: true, selector: "kendo-treelist-columnmenu-filter", inputs: { expanded: "expanded" }, outputs: { expand: "expand", collapse: "collapse" }, usesInheritance: true, ngImport: i0, template: `
70
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuFilterComponent, deps: [{ token: i1.LocalizationService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
71
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuFilterComponent, isStandalone: true, selector: "kendo-treelist-columnmenu-filter", inputs: { expanded: "expanded", isLast: "isLast" }, outputs: { expand: "expand", collapse: "collapse" }, usesInheritance: true, ngImport: i0, template: `
49
72
  <kendo-treelist-columnmenu-item
50
73
  [text]="localization.get('filter')"
51
74
  icon="filter"
52
75
  [svgIcon]="filterIcon"
53
76
  [expanded]="expanded"
54
- (collapse)="collapse.emit()"
55
- (expand)="expand.emit()">
77
+ (collapse)="onCollapse()"
78
+ (expand)="onExpand()">
56
79
  <ng-template kendoTreeListColumnMenuItemContentTemplate>
57
- <kendo-treelist-filter-menu-container
58
- [column]="service.column"
59
- [filter]="service.filter"
60
- [actionsClass]="actionsClass"
61
- (close)="close()">
62
- </kendo-treelist-filter-menu-container>
63
- </ng-template>
80
+ <kendo-treelist-filter-menu-container
81
+ [column]="service.column"
82
+ [menuTabbingService]="service.menuTabbingService"
83
+ [filter]="service.filter"
84
+ [actionsClass]="actionsClass"
85
+ [isLast]="isLast"
86
+ [isExpanded]="expanded"
87
+ (keydown.shift.tab)="$event.stopImmediatePropagation()"
88
+ (close)="close()">
89
+ </kendo-treelist-filter-menu-container>
90
+ </ng-template>
64
91
  </kendo-treelist-columnmenu-item>
65
- `, isInline: true, dependencies: [{ kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded"], outputs: ["itemClick", "expand", "collapse"] }, { kind: "directive", type: ColumnMenuItemContentTemplateDirective, selector: "[kendoTreeListColumnMenuItemContentTemplate]" }, { kind: "component", type: FilterMenuContainerComponent, selector: "kendo-treelist-filter-menu-container", inputs: ["column", "filter", "actionsClass"], outputs: ["close"] }] });
92
+ `, isInline: true, dependencies: [{ kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded", "service"], outputs: ["itemClick", "expand", "collapse"] }, { kind: "directive", type: ColumnMenuItemContentTemplateDirective, selector: "[kendoTreeListColumnMenuItemContentTemplate]" }, { kind: "component", type: FilterMenuContainerComponent, selector: "kendo-treelist-filter-menu-container", inputs: ["column", "isLast", "isExpanded", "menuTabbingService", "filter", "actionsClass"], outputs: ["close"] }] });
66
93
  }
67
94
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuFilterComponent, decorators: [{
68
95
  type: Component,
@@ -74,25 +101,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
74
101
  icon="filter"
75
102
  [svgIcon]="filterIcon"
76
103
  [expanded]="expanded"
77
- (collapse)="collapse.emit()"
78
- (expand)="expand.emit()">
104
+ (collapse)="onCollapse()"
105
+ (expand)="onExpand()">
79
106
  <ng-template kendoTreeListColumnMenuItemContentTemplate>
80
- <kendo-treelist-filter-menu-container
81
- [column]="service.column"
82
- [filter]="service.filter"
83
- [actionsClass]="actionsClass"
84
- (close)="close()">
85
- </kendo-treelist-filter-menu-container>
86
- </ng-template>
107
+ <kendo-treelist-filter-menu-container
108
+ [column]="service.column"
109
+ [menuTabbingService]="service.menuTabbingService"
110
+ [filter]="service.filter"
111
+ [actionsClass]="actionsClass"
112
+ [isLast]="isLast"
113
+ [isExpanded]="expanded"
114
+ (keydown.shift.tab)="$event.stopImmediatePropagation()"
115
+ (close)="close()">
116
+ </kendo-treelist-filter-menu-container>
117
+ </ng-template>
87
118
  </kendo-treelist-columnmenu-item>
88
119
  `,
89
120
  standalone: true,
90
121
  imports: [ColumnMenuItemComponent, ColumnMenuItemContentTemplateDirective, FilterMenuContainerComponent]
91
122
  }]
92
- }], ctorParameters: function () { return [{ type: i1.LocalizationService }]; }, propDecorators: { expand: [{
123
+ }], ctorParameters: function () { return [{ type: i1.LocalizationService }, { type: i0.ElementRef }]; }, propDecorators: { expand: [{
93
124
  type: Output
94
125
  }], collapse: [{
95
126
  type: Output
96
127
  }], expanded: [{
97
128
  type: Input
129
+ }], isLast: [{
130
+ type: Input
98
131
  }] } });
@@ -4,6 +4,7 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { Directive, HostBinding, Input, isDevMode } from '@angular/core';
6
6
  import { ColumnMenuService } from './column-menu.service';
7
+ import { ColumnMenuErrorMessages } from '../common/error-messages';
7
8
  import * as i0 from "@angular/core";
8
9
  /**
9
10
  * @hidden
@@ -17,7 +18,7 @@ export class ColumnMenuItemBase {
17
18
  hostClass = true;
18
19
  ngOnInit() {
19
20
  if (isDevMode() && !this.service) {
20
- throw new Error('The service input of the predefined column menu components is mandatory.');
21
+ throw new Error(ColumnMenuErrorMessages.serviceInput);
21
22
  }
22
23
  }
23
24
  /**
@@ -8,6 +8,8 @@ import { trigger, transition, style, animate, state } from '@angular/animations'
8
8
  import { chevronDownIcon, chevronUpIcon } from '@progress/kendo-svg-icons';
9
9
  import { IconWrapperComponent } from '@progress/kendo-angular-icons';
10
10
  import { ColumnMenuItemContentTemplateDirective } from './column-menu-item-content-template.directive';
11
+ import { ColumnMenuService } from './column-menu.service';
12
+ import { guid } from '@progress/kendo-angular-common';
11
13
  import * as i0 from "@angular/core";
12
14
  /**
13
15
  * Represents an item that can be placed inside a
@@ -61,8 +63,14 @@ export class ColumnMenuItemComponent {
61
63
  * Specifies if the item is expanded.
62
64
  */
63
65
  expanded;
66
+ /**
67
+ * Represents the [ColumnMenuService]({% slug api_treelist_columnmenuservice %}) class.
68
+ * Required to include the item in the column menu keyboard navigation sequence.
69
+ */
70
+ service;
64
71
  contentTemplate;
65
72
  contentState = 'collapsed';
73
+ contentId;
66
74
  chevronUpIcon = chevronUpIcon;
67
75
  chevronDownIcon = chevronDownIcon;
68
76
  get expandedIcon() {
@@ -71,6 +79,9 @@ export class ColumnMenuItemComponent {
71
79
  get expandedSvgIcon() {
72
80
  return this.expanded ? this.chevronUpIcon : this.chevronDownIcon;
73
81
  }
82
+ ngAfterViewInit() {
83
+ this.contentTemplate && (this.contentId = `k-${guid()}`);
84
+ }
74
85
  ngOnChanges(changes) {
75
86
  if (changes.expanded) {
76
87
  this.updateContentState();
@@ -96,13 +107,21 @@ export class ColumnMenuItemComponent {
96
107
  this.contentState = this.expanded ? 'expanded' : 'collapsed';
97
108
  }
98
109
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
99
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuItemComponent, isStandalone: true, selector: "kendo-treelist-columnmenu-item", inputs: { icon: "icon", svgIcon: "svgIcon", text: "text", selected: "selected", disabled: "disabled", expanded: "expanded" }, outputs: { itemClick: "itemClick", expand: "expand", collapse: "collapse" }, queries: [{ propertyName: "contentTemplate", first: true, predicate: ColumnMenuItemContentTemplateDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
110
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuItemComponent, isStandalone: true, selector: "kendo-treelist-columnmenu-item", inputs: { icon: "icon", svgIcon: "svgIcon", text: "text", selected: "selected", disabled: "disabled", expanded: "expanded", service: "service" }, outputs: { itemClick: "itemClick", expand: "expand", collapse: "collapse" }, queries: [{ propertyName: "contentTemplate", first: true, predicate: ColumnMenuItemContentTemplateDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: `
100
111
  <div *ngIf="contentTemplate; else content" class="k-expander">
101
112
  <ng-container [ngTemplateOutlet]="content"></ng-container>
102
113
  </div>
103
114
 
104
115
  <ng-template #content>
105
- <div class="k-columnmenu-item" (click)="onClick($event)" [class.k-selected]="selected" [class.k-disabled]="disabled">
116
+ <div
117
+ class="k-columnmenu-item"
118
+ (click)="onClick($event)"
119
+ (keydown.enter)="onClick($event)"
120
+ [class.k-selected]="selected"
121
+ [class.k-disabled]="disabled"
122
+ role="button"
123
+ [attr.aria-expanded]="expanded"
124
+ [attr.aria-controls]="expanded ? contentId : undefined">
106
125
  <kendo-icon-wrapper
107
126
  [name]="icon"
108
127
  [svgIcon]="svgIcon"></kendo-icon-wrapper>
@@ -115,7 +134,7 @@ export class ColumnMenuItemComponent {
115
134
  </kendo-icon-wrapper>
116
135
  </span>
117
136
  </div>
118
- <div *ngIf="contentTemplate" [@state]="contentState" [style.overflow]="'hidden'" class="k-columnmenu-item-content">
137
+ <div *ngIf="contentTemplate" [attr.id]="contentId" [@state]="contentState" [style.overflow]="'hidden'" class="k-columnmenu-item-content">
119
138
  <ng-container [ngTemplateOutlet]="contentTemplate.templateRef">
120
139
  </ng-container>
121
140
  </div>
@@ -177,7 +196,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
177
196
  </div>
178
197
 
179
198
  <ng-template #content>
180
- <div class="k-columnmenu-item" (click)="onClick($event)" [class.k-selected]="selected" [class.k-disabled]="disabled">
199
+ <div
200
+ class="k-columnmenu-item"
201
+ (click)="onClick($event)"
202
+ (keydown.enter)="onClick($event)"
203
+ [class.k-selected]="selected"
204
+ [class.k-disabled]="disabled"
205
+ role="button"
206
+ [attr.aria-expanded]="expanded"
207
+ [attr.aria-controls]="expanded ? contentId : undefined">
181
208
  <kendo-icon-wrapper
182
209
  [name]="icon"
183
210
  [svgIcon]="svgIcon"></kendo-icon-wrapper>
@@ -190,7 +217,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
190
217
  </kendo-icon-wrapper>
191
218
  </span>
192
219
  </div>
193
- <div *ngIf="contentTemplate" [@state]="contentState" [style.overflow]="'hidden'" class="k-columnmenu-item-content">
220
+ <div *ngIf="contentTemplate" [attr.id]="contentId" [@state]="contentState" [style.overflow]="'hidden'" class="k-columnmenu-item-content">
194
221
  <ng-container [ngTemplateOutlet]="contentTemplate.templateRef">
195
222
  </ng-container>
196
223
  </div>
@@ -217,6 +244,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
217
244
  type: Input
218
245
  }], expanded: [{
219
246
  type: Input
247
+ }], service: [{
248
+ type: Input
220
249
  }], contentTemplate: [{
221
250
  type: ContentChild,
222
251
  args: [ColumnMenuItemContentTemplateDirective]
@@ -0,0 +1,125 @@
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 { Directive, ElementRef, Input, NgZone, Renderer2 } from '@angular/core';
6
+ import { Subscription } from 'rxjs';
7
+ import { Keys } from '@progress/kendo-angular-common';
8
+ import { ColumnMenuChooserComponent } from './column-menu-chooser.component';
9
+ import { ColumnMenuFilterComponent } from './column-menu-filter.component';
10
+ import * as i0 from "@angular/core";
11
+ export class ColumnMenuItemDirective {
12
+ hostElement;
13
+ renderer;
14
+ ngZone;
15
+ /**
16
+ * The reference to the TreeList column menu item. Required to include the item in the built-in keyboard navigation.
17
+ */
18
+ menuItemComponent;
19
+ firstFocusableElement;
20
+ lastFocusableElement;
21
+ /**
22
+ * @hidden
23
+ */
24
+ set isFirst(value) {
25
+ if (value) {
26
+ const focusableElement = this.columnMenuItems[0];
27
+ this.menuItemComponent.service.menuTabbingService.firstFocusable = focusableElement;
28
+ this.ngZone.runOutsideAngular(() => {
29
+ const firstItemKeydownSub = this.renderer.listen(focusableElement, 'keydown', this.onTab);
30
+ this.subs.add(firstItemKeydownSub);
31
+ });
32
+ }
33
+ this._isFirst = value;
34
+ }
35
+ /**
36
+ * @hidden
37
+ */
38
+ get isFirst() {
39
+ return this._isFirst;
40
+ }
41
+ /**
42
+ * @hidden
43
+ */
44
+ set isLast(value) {
45
+ if (!this.columnMenuItems) {
46
+ return;
47
+ }
48
+ if (value) {
49
+ const lastFocusableElement = this.getLastColumnMenuItem();
50
+ this.menuItemComponent.service.menuTabbingService.lastFocusable = lastFocusableElement;
51
+ this.ngZone.runOutsideAngular(() => {
52
+ const lastItemKeydownSub = this.renderer.listen(lastFocusableElement, 'keydown', this.onTab);
53
+ this.subs.add(lastItemKeydownSub);
54
+ });
55
+ if (this.isExpandableItem()) {
56
+ this.menuItemComponent.isLast = true;
57
+ }
58
+ }
59
+ this._isLast = value;
60
+ }
61
+ /**
62
+ * @hidden
63
+ */
64
+ get isLast() {
65
+ return this._isLast;
66
+ }
67
+ _isFirst = false;
68
+ _isLast = false;
69
+ columnMenuItems;
70
+ subs = new Subscription();
71
+ constructor(hostElement, renderer, ngZone) {
72
+ this.hostElement = hostElement;
73
+ this.renderer = renderer;
74
+ this.ngZone = ngZone;
75
+ }
76
+ ngAfterViewInit() {
77
+ this.columnMenuItems = this.hostElement.nativeElement.querySelectorAll('.k-columnmenu-item');
78
+ [].slice.apply(this.columnMenuItems).forEach(el => this.renderer.setAttribute(el, 'tabindex', '0'));
79
+ if (this.menuItemComponent instanceof ColumnMenuFilterComponent) {
80
+ this.menuItemComponent.service.menuTabbingService.isColumnMenu = true;
81
+ }
82
+ this.menuItemComponent.service?.columnMenuContainer.templateMenuItems.push(this);
83
+ }
84
+ ngOnDestroy() {
85
+ if (this.subs) {
86
+ this.subs.unsubscribe();
87
+ }
88
+ }
89
+ onTab = (e) => {
90
+ if (e.keyCode !== Keys.Tab) {
91
+ return;
92
+ }
93
+ if (this.isFirst && e.shiftKey && e.target === this.columnMenuItems[0]) {
94
+ e.preventDefault();
95
+ this.menuItemComponent.service.menuTabbingService.lastFocusable.focus();
96
+ }
97
+ if (this.isLast && !e.shiftKey) {
98
+ const lastColumnMenuItem = this.getLastColumnMenuItem();
99
+ const isExpanded = this.menuItemComponent.expanded;
100
+ if (lastColumnMenuItem === e.target && !isExpanded) {
101
+ e.preventDefault();
102
+ this.menuItemComponent.service.menuTabbingService.firstFocusable.focus();
103
+ }
104
+ }
105
+ };
106
+ getLastColumnMenuItem() {
107
+ return (this.columnMenuItems.length === 1 ? this.columnMenuItems[0] : this.columnMenuItems[1]);
108
+ }
109
+ isExpandableItem() {
110
+ return this.menuItemComponent instanceof ColumnMenuFilterComponent ||
111
+ this.menuItemComponent instanceof ColumnMenuChooserComponent;
112
+ }
113
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuItemDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
114
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: ColumnMenuItemDirective, isStandalone: true, selector: "[kendoTreeListColumnMenuItem]", inputs: { menuItemComponent: ["kendoTreeListColumnMenuItem", "menuItemComponent"] }, ngImport: i0 });
115
+ }
116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuItemDirective, decorators: [{
117
+ type: Directive,
118
+ args: [{
119
+ selector: '[kendoTreeListColumnMenuItem]',
120
+ standalone: true
121
+ }]
122
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { menuItemComponent: [{
123
+ type: Input,
124
+ args: ['kendoTreeListColumnMenuItem']
125
+ }] } });
@@ -81,7 +81,7 @@ export class ColumnMenuLockComponent extends ColumnMenuItemBase {
81
81
  (itemClick)="toggleColumn()"
82
82
  [disabled]="disabled">
83
83
  </kendo-treelist-columnmenu-item>
84
- `, isInline: true, dependencies: [{ kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded"], outputs: ["itemClick", "expand", "collapse"] }] });
84
+ `, isInline: true, dependencies: [{ kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded", "service"], outputs: ["itemClick", "expand", "collapse"] }] });
85
85
  }
86
86
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuLockComponent, decorators: [{
87
87
  type: Component,
@@ -77,7 +77,7 @@ export class ColumnMenuSortComponent extends ColumnMenuItemBase {
77
77
  (itemClick)="toggleSort('desc')"
78
78
  [selected]="sortedDesc">
79
79
  </kendo-treelist-columnmenu-item>
80
- `, isInline: true, dependencies: [{ kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded"], outputs: ["itemClick", "expand", "collapse"] }] });
80
+ `, isInline: true, dependencies: [{ kind: "component", type: ColumnMenuItemComponent, selector: "kendo-treelist-columnmenu-item", inputs: ["icon", "svgIcon", "text", "selected", "disabled", "expanded", "service"], outputs: ["itemClick", "expand", "collapse"] }] });
81
81
  }
82
82
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnMenuSortComponent, decorators: [{
83
83
  type: Component,