@progress/kendo-angular-filter 24.0.0-develop.3 → 24.0.0-develop.31

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.
package/directives.d.ts CHANGED
@@ -5,8 +5,10 @@
5
5
  import { FilterFieldComponent } from "./filter-field.component";
6
6
  import { FilterComponent } from "./filter.component";
7
7
  import { CustomMessagesComponent } from "./localization/custom-messages.component";
8
- import { FilterValueEditorTemplateDirective } from "./templates/value-editor.template";
8
+ import { FilterValueEditorTemplateDirective } from "./templates/value-editor-template.directive";
9
+ import { FilterOperatorTemplateDirective } from "./templates/operator-template.directive";
10
+ import { FilterFieldsTemplateDirective } from "./templates/field-template.directive";
9
11
  /**
10
12
  * Utility array that contains all `@progress/kendo-angular-filter` related components and directives
11
13
  */
12
- export declare const KENDO_FILTER: readonly [typeof FilterComponent, typeof FilterFieldComponent, typeof CustomMessagesComponent, typeof FilterValueEditorTemplateDirective];
14
+ export declare const KENDO_FILTER: readonly [typeof FilterComponent, typeof FilterFieldComponent, typeof CustomMessagesComponent, typeof FilterValueEditorTemplateDirective, typeof FilterOperatorTemplateDirective, typeof FilterFieldsTemplateDirective];
@@ -7,13 +7,13 @@ import { Injectable, Directive, ContentChild, Input, Component, EventEmitter, Ou
7
7
  import * as i1 from '@progress/kendo-angular-l10n';
8
8
  import { ComponentMessages, LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
9
9
  import { validatePackage } from '@progress/kendo-licensing';
10
- import { Keys, TemplateContextDirective, normalizeKeys, ResizeBatchService } from '@progress/kendo-angular-common';
10
+ import { Keys, normalizeKeys, ResizeBatchService } from '@progress/kendo-angular-common';
11
11
  import { xIcon, filterAddGroupIcon, filterAddExpressionIcon } from '@progress/kendo-svg-icons';
12
12
  import { ButtonComponent } from '@progress/kendo-angular-buttons';
13
13
  import { DatePickerComponent, DatePickerCustomMessagesComponent, CalendarDOMService, CenturyViewService, DecadeViewService, MonthViewService, YearViewService, TimePickerDOMService, HoursService, MinutesService, SecondsService, MillisecondsService, DayPeriodService } from '@progress/kendo-angular-dateinputs';
14
14
  import { DropDownListComponent, ValueTemplateDirective, ItemTemplateDirective } from '@progress/kendo-angular-dropdowns';
15
15
  import { NumericTextBoxComponent, NumericTextBoxCustomMessagesComponent, TextBoxComponent } from '@progress/kendo-angular-inputs';
16
- import { NgClass } from '@angular/common';
16
+ import { NgTemplateOutlet, NgClass } from '@angular/common';
17
17
  import { IconsService } from '@progress/kendo-angular-icons';
18
18
  import { PopupService } from '@progress/kendo-angular-popup';
19
19
  import { DialogContainerService, DialogService, WindowService, WindowContainerService, NavigationService as NavigationService$1 } from '@progress/kendo-angular-dialog';
@@ -24,6 +24,7 @@ import { DialogContainerService, DialogService, WindowService, WindowContainerSe
24
24
  class FilterService {
25
25
  normalizedValue = { logic: 'and', filters: [] };
26
26
  filters = [];
27
+ fieldTemplate = null;
27
28
  addFilterGroup(item) {
28
29
  const filterGroup = { logic: 'and', filters: [] };
29
30
  item.filters.push(filterGroup);
@@ -231,8 +232,8 @@ const packageMetadata = {
231
232
  productName: 'Kendo UI for Angular',
232
233
  productCode: 'KENDOUIANGULAR',
233
234
  productCodes: ['KENDOUIANGULAR'],
234
- publishDate: 1776940655,
235
- version: '24.0.0-develop.3',
235
+ publishDate: 1778841844,
236
+ version: '24.0.0-develop.31',
236
237
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
237
238
  };
238
239
 
@@ -263,6 +264,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
263
264
  }]
264
265
  }], ctorParameters: () => [{ type: i0.TemplateRef }] });
265
266
 
267
+ /**
268
+ * Replaces the default operator DropDownList in the Filter component with a custom template.
269
+ * Apply it to an `ng-template` inside a `kendo-filter-field` element.
270
+ *
271
+ * The template context provides the following field:
272
+ *
273
+ * - `let-filter`—The [filter descriptor](slug:api_kendo-data-query_filterdescriptor) for the current row. Set its `operator` property when the user selects a new operator.
274
+ *
275
+ * @example
276
+ * ```html
277
+ * <kendo-filter>
278
+ * <kendo-filter-field field="name" editor="string">
279
+ * <ng-template kendoFilterOperatorTemplate let-filter>
280
+ * <kendo-combobox
281
+ * [data]="customOperators"
282
+ * textField="text"
283
+ * valueField="value"
284
+ * [valuePrimitive]="true"
285
+ * [value]="filter.operator"
286
+ * (valueChange)="filter.operator = $event">
287
+ * </kendo-combobox>
288
+ * </ng-template>
289
+ * </kendo-filter-field>
290
+ * </kendo-filter>
291
+ * ```
292
+ */
293
+ class FilterOperatorTemplateDirective {
294
+ templateRef;
295
+ constructor(templateRef) {
296
+ this.templateRef = templateRef;
297
+ }
298
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterOperatorTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
299
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.20", type: FilterOperatorTemplateDirective, isStandalone: true, selector: "[kendoFilterOperatorTemplate]", ngImport: i0 });
300
+ }
301
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterOperatorTemplateDirective, decorators: [{
302
+ type: Directive,
303
+ args: [{
304
+ selector: '[kendoFilterOperatorTemplate]',
305
+ standalone: true
306
+ }]
307
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
308
+
266
309
  /**
267
310
  * Represents the [Kendo UI Filter Field component for Angular](https://www.telerik.com/kendo-angular-ui/components/filter/api/filterfieldcomponent).
268
311
  * Used to declare filter expressions for the Filter component.
@@ -340,8 +383,12 @@ class FilterFieldComponent {
340
383
  * @hidden
341
384
  */
342
385
  editorTemplate;
386
+ /**
387
+ * @hidden
388
+ */
389
+ operatorTemplate;
343
390
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
344
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: FilterFieldComponent, isStandalone: true, selector: "kendo-filter-field", inputs: { field: "field", title: "title", editor: "editor", operators: "operators", editorFormat: "editorFormat" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: FilterValueEditorTemplateDirective, descendants: true }], ngImport: i0, template: ``, isInline: true });
391
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: FilterFieldComponent, isStandalone: true, selector: "kendo-filter-field", inputs: { field: "field", title: "title", editor: "editor", operators: "operators", editorFormat: "editorFormat" }, queries: [{ propertyName: "editorTemplate", first: true, predicate: FilterValueEditorTemplateDirective, descendants: true }, { propertyName: "operatorTemplate", first: true, predicate: FilterOperatorTemplateDirective, descendants: true }], ngImport: i0, template: ``, isInline: true });
345
392
  }
346
393
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterFieldComponent, decorators: [{
347
394
  type: Component,
@@ -363,6 +410,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
363
410
  }], editorTemplate: [{
364
411
  type: ContentChild,
365
412
  args: [FilterValueEditorTemplateDirective]
413
+ }], operatorTemplate: [{
414
+ type: ContentChild,
415
+ args: [FilterOperatorTemplateDirective]
366
416
  }] } });
367
417
 
368
418
  /**
@@ -901,6 +951,7 @@ class FilterExpressionOperatorsComponent {
901
951
  editorType;
902
952
  valueChange = new EventEmitter();
903
953
  operators = [];
954
+ operatorTemplate;
904
955
  constructor(localization) {
905
956
  this.localization = localization;
906
957
  }
@@ -914,53 +965,67 @@ class FilterExpressionOperatorsComponent {
914
965
  this.valueChange.emit(value);
915
966
  }
916
967
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterExpressionOperatorsComponent, deps: [{ token: i1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
917
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.20", type: FilterExpressionOperatorsComponent, isStandalone: true, selector: "kendo-filter-expression-operators", inputs: { currentItem: "currentItem", editorType: "editorType", operators: "operators" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
918
- <kendo-dropdownlist
919
- [tabindex]="-1"
920
- [kendoAriaLabelValue]="messageFor('filterOperatorAriaLabel')"
921
- [data]="operators"
922
- [title]="messageFor('filterExpressionOperators')"
923
- [(value)]="currentItem.operator"
924
- (valueChange)="operatorValueChange($event)"
925
- [valuePrimitive]="true"
926
- textField="text"
927
- valueField="value"
928
- >
929
- <ng-template kendoDropDownListValueTemplate let-dataItem>
930
- <span>{{ getOperator(dataItem.value) }}</span>
931
- </ng-template>
932
- <ng-template kendoDropDownListItemTemplate let-dataItem>
933
- <span>{{ getOperator(dataItem.value) }}</span>
934
- </ng-template>
935
- </kendo-dropdownlist>
936
- `, isInline: true, dependencies: [{ kind: "component", type: DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "directive", type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { kind: "directive", type: ValueTemplateDirective, selector: "[kendoDropDownListValueTemplate],[kendoDropDownTreeValueTemplate]" }, { kind: "directive", type: ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }] });
968
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: FilterExpressionOperatorsComponent, isStandalone: true, selector: "kendo-filter-expression-operators", inputs: { currentItem: "currentItem", editorType: "editorType", operators: "operators", operatorTemplate: "operatorTemplate" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
969
+ @if (operatorTemplate) {
970
+ <ng-container
971
+ [ngTemplateOutlet]="operatorTemplate"
972
+ [ngTemplateOutletContext]="{$implicit: currentItem}">
973
+ </ng-container>
974
+ } @else {
975
+ <kendo-dropdownlist
976
+ [tabindex]="-1"
977
+ [kendoAriaLabelValue]="messageFor('filterOperatorAriaLabel')"
978
+ [data]="operators"
979
+ [title]="messageFor('filterExpressionOperators')"
980
+ [(value)]="currentItem.operator"
981
+ (valueChange)="operatorValueChange($event)"
982
+ [valuePrimitive]="true"
983
+ textField="text"
984
+ valueField="value"
985
+ >
986
+ <ng-template kendoDropDownListValueTemplate let-dataItem>
987
+ <span>{{ getOperator(dataItem.value) }}</span>
988
+ </ng-template>
989
+ <ng-template kendoDropDownListItemTemplate let-dataItem>
990
+ <span>{{ getOperator(dataItem.value) }}</span>
991
+ </ng-template>
992
+ </kendo-dropdownlist>
993
+ }
994
+ `, isInline: true, dependencies: [{ kind: "component", type: DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "directive", type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { kind: "directive", type: ValueTemplateDirective, selector: "[kendoDropDownListValueTemplate],[kendoDropDownTreeValueTemplate]" }, { kind: "directive", type: ItemTemplateDirective, selector: "[kendoDropDownListItemTemplate],[kendoComboBoxItemTemplate],[kendoAutoCompleteItemTemplate],[kendoMultiSelectItemTemplate]" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
937
995
  }
938
996
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterExpressionOperatorsComponent, decorators: [{
939
997
  type: Component,
940
998
  args: [{
941
999
  selector: "kendo-filter-expression-operators",
942
1000
  template: `
943
- <kendo-dropdownlist
944
- [tabindex]="-1"
945
- [kendoAriaLabelValue]="messageFor('filterOperatorAriaLabel')"
946
- [data]="operators"
947
- [title]="messageFor('filterExpressionOperators')"
948
- [(value)]="currentItem.operator"
949
- (valueChange)="operatorValueChange($event)"
950
- [valuePrimitive]="true"
951
- textField="text"
952
- valueField="value"
953
- >
954
- <ng-template kendoDropDownListValueTemplate let-dataItem>
955
- <span>{{ getOperator(dataItem.value) }}</span>
956
- </ng-template>
957
- <ng-template kendoDropDownListItemTemplate let-dataItem>
958
- <span>{{ getOperator(dataItem.value) }}</span>
959
- </ng-template>
960
- </kendo-dropdownlist>
1001
+ @if (operatorTemplate) {
1002
+ <ng-container
1003
+ [ngTemplateOutlet]="operatorTemplate"
1004
+ [ngTemplateOutletContext]="{$implicit: currentItem}">
1005
+ </ng-container>
1006
+ } @else {
1007
+ <kendo-dropdownlist
1008
+ [tabindex]="-1"
1009
+ [kendoAriaLabelValue]="messageFor('filterOperatorAriaLabel')"
1010
+ [data]="operators"
1011
+ [title]="messageFor('filterExpressionOperators')"
1012
+ [(value)]="currentItem.operator"
1013
+ (valueChange)="operatorValueChange($event)"
1014
+ [valuePrimitive]="true"
1015
+ textField="text"
1016
+ valueField="value"
1017
+ >
1018
+ <ng-template kendoDropDownListValueTemplate let-dataItem>
1019
+ <span>{{ getOperator(dataItem.value) }}</span>
1020
+ </ng-template>
1021
+ <ng-template kendoDropDownListItemTemplate let-dataItem>
1022
+ <span>{{ getOperator(dataItem.value) }}</span>
1023
+ </ng-template>
1024
+ </kendo-dropdownlist>
1025
+ }
961
1026
  `,
962
1027
  standalone: true,
963
- imports: [DropDownListComponent, AriaLabelValueDirective, ValueTemplateDirective, ItemTemplateDirective]
1028
+ imports: [DropDownListComponent, AriaLabelValueDirective, ValueTemplateDirective, ItemTemplateDirective, NgTemplateOutlet]
964
1029
  }]
965
1030
  }], ctorParameters: () => [{ type: i1.LocalizationService }], propDecorators: { currentItem: [{
966
1031
  type: Input
@@ -970,6 +1035,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
970
1035
  type: Output
971
1036
  }], operators: [{
972
1037
  type: Input
1038
+ }], operatorTemplate: [{
1039
+ type: Input
973
1040
  }] } });
974
1041
 
975
1042
  /**
@@ -988,7 +1055,15 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
988
1055
  editorType;
989
1056
  isEditorDisabled = false;
990
1057
  editorTemplate;
1058
+ operatorTemplate;
991
1059
  editorFormat;
1060
+ get availableFilters() {
1061
+ return this.filterService.filters || [];
1062
+ }
1063
+ _previousField;
1064
+ get fieldTemplate() {
1065
+ return this.filterService.fieldTemplate;
1066
+ }
992
1067
  get currentFilterExpression() {
993
1068
  return this.getFilterExpressionByField(this.currentItem.field);
994
1069
  }
@@ -1032,7 +1107,21 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
1032
1107
  super(element, navigationService, localization, renderer);
1033
1108
  this.filterService = filterService;
1034
1109
  }
1110
+ ngDoCheck() {
1111
+ if (this.fieldTemplate && this.currentItem.field !== this._previousField) {
1112
+ if (!this.currentItem.field) {
1113
+ this.currentItem.field = this._previousField;
1114
+ return;
1115
+ }
1116
+ const previousField = this._previousField;
1117
+ this._previousField = this.currentItem.field;
1118
+ if (previousField !== undefined) {
1119
+ this.filterValueChange(this.currentItem.field);
1120
+ }
1121
+ }
1122
+ }
1035
1123
  ngOnInit() {
1124
+ this._previousField = this.currentItem.field;
1036
1125
  this.isEditorDisabled = nullOperators.indexOf(this.currentItem.operator) >= 0;
1037
1126
  const foundFilter = this.getFilterExpressionByField(this.currentItem.field);
1038
1127
  if (this.currentItem.field) {
@@ -1049,7 +1138,7 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
1049
1138
  }
1050
1139
  this.setOperators(defaultFilter);
1051
1140
  }
1052
- this.setEditorTemplate();
1141
+ this.setTemplates();
1053
1142
  }
1054
1143
  normalizeOperators(filterEditor, operators) {
1055
1144
  const result = [];
@@ -1075,7 +1164,7 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
1075
1164
  this.navigationService.currentToolbarItemChildrenIndex = 0;
1076
1165
  this.currentItem.value = null;
1077
1166
  this.currentItem.field = value;
1078
- this.setEditorTemplate();
1167
+ this.setTemplates();
1079
1168
  const foundFilter = this.getFilterExpressionByField(this.currentItem.field);
1080
1169
  this.setOperators(foundFilter);
1081
1170
  this.editorFormat = foundFilter.editorFormat;
@@ -1097,9 +1186,6 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
1097
1186
  const filterExpression = this.filterService.filters.find((filterExpression) => filterExpression.field === this.currentItem.field);
1098
1187
  return filterExpression?.editor;
1099
1188
  }
1100
- getFilters() {
1101
- return this.filterService.filters || [];
1102
- }
1103
1189
  removeFilterExpression() {
1104
1190
  this.filterService.remove(this.currentItem, this.index);
1105
1191
  this.valueChange.emit(true);
@@ -1136,9 +1222,10 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
1136
1222
  this.isEditorDisabled = false;
1137
1223
  }
1138
1224
  }
1139
- setEditorTemplate() {
1225
+ setTemplates() {
1140
1226
  const filterExpression = this.filterService.filters.find((filter) => filter.field === this.currentItem.field);
1141
1227
  this.editorTemplate = filterExpression?.editorTemplate;
1228
+ this.operatorTemplate = filterExpression?.operatorTemplate;
1142
1229
  }
1143
1230
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterExpressionComponent, deps: [{ token: FilterService }, { token: i0.ElementRef }, { token: NavigationService }, { token: i1.LocalizationService }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
1144
1231
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.20", type: FilterExpressionComponent, isStandalone: true, selector: "kendo-filter-expression", inputs: { currentItem: "currentItem" }, providers: [{
@@ -1148,17 +1235,24 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
1148
1235
  <div class="k-filter-toolbar">
1149
1236
  <div class="k-toolbar k-toolbar-md k-toolbar-solid" role="toolbar" [attr.aria-label]="messageFor('filterToolbarAriaLabel')" (mousedown)="onMouseDown($event)">
1150
1237
  <div class="k-filter-field k-toolbar-item" >
1151
- <kendo-dropdownlist
1152
- [tabindex]="-1"
1153
- [kendoAriaLabelValue]="messageFor('filterFieldAriaLabel')"
1154
- [title]="messageFor('filterExpressionFilters')"
1155
- [data]="getFilters()"
1156
- textField="title"
1157
- valueField="field"
1158
- [value]="currentItem.field"
1159
- [valuePrimitive]="true"
1160
- (valueChange)="filterValueChange($event)">
1161
- </kendo-dropdownlist>
1238
+ @if (fieldTemplate) {
1239
+ <ng-container
1240
+ [ngTemplateOutlet]="fieldTemplate"
1241
+ [ngTemplateOutletContext]="{$implicit: currentItem, filters: availableFilters}">
1242
+ </ng-container>
1243
+ } @else {
1244
+ <kendo-dropdownlist
1245
+ [tabindex]="-1"
1246
+ [kendoAriaLabelValue]="messageFor('filterFieldAriaLabel')"
1247
+ [title]="messageFor('filterExpressionFilters')"
1248
+ [data]="availableFilters"
1249
+ textField="title"
1250
+ valueField="field"
1251
+ [value]="currentItem.field"
1252
+ [valuePrimitive]="true"
1253
+ (valueChange)="filterValueChange($event)">
1254
+ </kendo-dropdownlist>
1255
+ }
1162
1256
  </div>
1163
1257
  @if (!isBoolean) {
1164
1258
  <div class="k-filter-operator k-toolbar-item" >
@@ -1166,6 +1260,7 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
1166
1260
  [currentItem]="currentItem"
1167
1261
  [operators]="operators"
1168
1262
  [editorType]="getEditorType()"
1263
+ [operatorTemplate]="operatorTemplate"
1169
1264
  (valueChange)="onOperatorChange($event);">
1170
1265
  </kendo-filter-expression-operators>
1171
1266
  </div>
@@ -1189,9 +1284,10 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
1189
1284
  }
1190
1285
  }
1191
1286
  @if (editorTemplate) {
1192
- <ng-template
1193
- [templateContext]="{templateRef: editorTemplate, $implicit: currentItem}">
1194
- </ng-template>
1287
+ <ng-container
1288
+ [ngTemplateOutlet]="editorTemplate"
1289
+ [ngTemplateOutletContext]="{$implicit: currentItem}">
1290
+ </ng-container>
1195
1291
  }
1196
1292
  </div>
1197
1293
 
@@ -1207,7 +1303,7 @@ class FilterExpressionComponent extends BaseFilterRowComponent {
1207
1303
  </button>
1208
1304
  </div>
1209
1305
  </div>
1210
- `, isInline: true, dependencies: [{ kind: "component", type: DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "directive", type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { kind: "component", type: FilterExpressionOperatorsComponent, selector: "kendo-filter-expression-operators", inputs: ["currentItem", "editorType", "operators"], outputs: ["valueChange"] }, { kind: "component", type: FilterTextEditorComponent, selector: "kendo-filter-text-editor", inputs: ["currentItem", "isDisabled"], outputs: ["valueChange"] }, { kind: "component", type: FilterNumericEditorComponent, selector: "kendo-filter-numeric-editor", inputs: ["currentItem", "isDisabled", "format"], outputs: ["valueChange"] }, { kind: "component", type: FilterBooleanEditorComponent, selector: "kendo-filter-boolean-editor", inputs: ["currentItem"], outputs: ["valueChange"] }, { kind: "component", type: FilterDateEditorComponent, selector: "kendo-filter-date-editor", inputs: ["currentItem", "isDisabled", "format"], outputs: ["valueChange"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
1306
+ `, isInline: true, dependencies: [{ kind: "component", type: DropDownListComponent, selector: "kendo-dropdownlist", inputs: ["customIconClass", "showStickyHeader", "icon", "svgIcon", "loading", "data", "value", "textField", "valueField", "adaptiveMode", "adaptiveTitle", "adaptiveSubtitle", "popupSettings", "listHeight", "defaultItem", "disabled", "itemDisabled", "readonly", "filterable", "virtual", "ignoreCase", "delay", "valuePrimitive", "tabindex", "tabIndex", "size", "rounded", "fillMode", "leftRightArrowsNavigation", "id"], outputs: ["valueChange", "filterChange", "selectionChange", "open", "opened", "close", "closed", "focus", "blur"], exportAs: ["kendoDropDownList"] }, { kind: "directive", type: AriaLabelValueDirective, selector: "[kendoAriaLabelValue]", inputs: ["kendoAriaLabelValue"] }, { kind: "component", type: FilterExpressionOperatorsComponent, selector: "kendo-filter-expression-operators", inputs: ["currentItem", "editorType", "operators", "operatorTemplate"], outputs: ["valueChange"] }, { kind: "component", type: FilterTextEditorComponent, selector: "kendo-filter-text-editor", inputs: ["currentItem", "isDisabled"], outputs: ["valueChange"] }, { kind: "component", type: FilterNumericEditorComponent, selector: "kendo-filter-numeric-editor", inputs: ["currentItem", "isDisabled", "format"], outputs: ["valueChange"] }, { kind: "component", type: FilterBooleanEditorComponent, selector: "kendo-filter-boolean-editor", inputs: ["currentItem"], outputs: ["valueChange"] }, { kind: "component", type: FilterDateEditorComponent, selector: "kendo-filter-date-editor", inputs: ["currentItem", "isDisabled", "format"], outputs: ["valueChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
1211
1307
  }
1212
1308
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterExpressionComponent, decorators: [{
1213
1309
  type: Component,
@@ -1221,17 +1317,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
1221
1317
  <div class="k-filter-toolbar">
1222
1318
  <div class="k-toolbar k-toolbar-md k-toolbar-solid" role="toolbar" [attr.aria-label]="messageFor('filterToolbarAriaLabel')" (mousedown)="onMouseDown($event)">
1223
1319
  <div class="k-filter-field k-toolbar-item" >
1224
- <kendo-dropdownlist
1225
- [tabindex]="-1"
1226
- [kendoAriaLabelValue]="messageFor('filterFieldAriaLabel')"
1227
- [title]="messageFor('filterExpressionFilters')"
1228
- [data]="getFilters()"
1229
- textField="title"
1230
- valueField="field"
1231
- [value]="currentItem.field"
1232
- [valuePrimitive]="true"
1233
- (valueChange)="filterValueChange($event)">
1234
- </kendo-dropdownlist>
1320
+ @if (fieldTemplate) {
1321
+ <ng-container
1322
+ [ngTemplateOutlet]="fieldTemplate"
1323
+ [ngTemplateOutletContext]="{$implicit: currentItem, filters: availableFilters}">
1324
+ </ng-container>
1325
+ } @else {
1326
+ <kendo-dropdownlist
1327
+ [tabindex]="-1"
1328
+ [kendoAriaLabelValue]="messageFor('filterFieldAriaLabel')"
1329
+ [title]="messageFor('filterExpressionFilters')"
1330
+ [data]="availableFilters"
1331
+ textField="title"
1332
+ valueField="field"
1333
+ [value]="currentItem.field"
1334
+ [valuePrimitive]="true"
1335
+ (valueChange)="filterValueChange($event)">
1336
+ </kendo-dropdownlist>
1337
+ }
1235
1338
  </div>
1236
1339
  @if (!isBoolean) {
1237
1340
  <div class="k-filter-operator k-toolbar-item" >
@@ -1239,6 +1342,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
1239
1342
  [currentItem]="currentItem"
1240
1343
  [operators]="operators"
1241
1344
  [editorType]="getEditorType()"
1345
+ [operatorTemplate]="operatorTemplate"
1242
1346
  (valueChange)="onOperatorChange($event);">
1243
1347
  </kendo-filter-expression-operators>
1244
1348
  </div>
@@ -1262,9 +1366,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
1262
1366
  }
1263
1367
  }
1264
1368
  @if (editorTemplate) {
1265
- <ng-template
1266
- [templateContext]="{templateRef: editorTemplate, $implicit: currentItem}">
1267
- </ng-template>
1369
+ <ng-container
1370
+ [ngTemplateOutlet]="editorTemplate"
1371
+ [ngTemplateOutletContext]="{$implicit: currentItem}">
1372
+ </ng-container>
1268
1373
  }
1269
1374
  </div>
1270
1375
 
@@ -1282,7 +1387,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
1282
1387
  </div>
1283
1388
  `,
1284
1389
  standalone: true,
1285
- imports: [DropDownListComponent, AriaLabelValueDirective, FilterExpressionOperatorsComponent, FilterTextEditorComponent, FilterNumericEditorComponent, FilterBooleanEditorComponent, FilterDateEditorComponent, TemplateContextDirective, ButtonComponent]
1390
+ imports: [DropDownListComponent, AriaLabelValueDirective, FilterExpressionOperatorsComponent, FilterTextEditorComponent, FilterNumericEditorComponent, FilterBooleanEditorComponent, FilterDateEditorComponent, NgTemplateOutlet, ButtonComponent]
1286
1391
  }]
1287
1392
  }], ctorParameters: () => [{ type: FilterService }, { type: i0.ElementRef }, { type: NavigationService }, { type: i1.LocalizationService }, { type: i0.Renderer2 }], propDecorators: { currentItem: [{
1288
1393
  type: Input
@@ -1463,7 +1568,7 @@ class FilterGroupComponent extends BaseFilterRowComponent {
1463
1568
  }
1464
1569
  </ul>
1465
1570
  }
1466
- `, isInline: true, dependencies: [{ kind: "component", type: FilterGroupComponent, selector: "kendo-filter-group", inputs: ["currentItem"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: FilterExpressionComponent, selector: "kendo-filter-expression", inputs: ["currentItem"] }] });
1571
+ `, isInline: true, dependencies: [{ kind: "component", type: FilterGroupComponent, selector: "kendo-filter-group", inputs: ["currentItem"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconPosition", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: FilterExpressionComponent, selector: "kendo-filter-expression", inputs: ["currentItem"] }] });
1467
1572
  }
1468
1573
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterGroupComponent, decorators: [{
1469
1574
  type: Component,
@@ -1828,6 +1933,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
1828
1933
  }]
1829
1934
  }], ctorParameters: () => [{ type: i1.LocalizationService }] });
1830
1935
 
1936
+ /**
1937
+ * Replaces the default field selector DropDownList in the Filter component with a custom template.
1938
+ * Apply it to an `ng-template` that is a direct child of a `kendo-filter` element.
1939
+ *
1940
+ * The template context provides the following fields:
1941
+ *
1942
+ * - `let-currentItem`&mdash;The [filter descriptor](slug:api_kendo-data-query_filterdescriptor) for the current row. Set its `field` property to change the selected field. The component detects the change and updates the value, operator list, and editor type automatically.
1943
+ * - `let-filters="filters"`&mdash;The list of available [`FilterExpression`](slug:api_filter_filterexpression) items.
1944
+ *
1945
+ * @example
1946
+ * ```html
1947
+ * <kendo-filter>
1948
+ * <ng-template kendoFilterFieldsTemplate let-currentItem let-filters="filters">
1949
+ * <kendo-dropdownlist
1950
+ * [data]="filters"
1951
+ * textField="title"
1952
+ * valueField="field"
1953
+ * [valuePrimitive]="true"
1954
+ * [value]="currentItem.field"
1955
+ * (valueChange)="currentItem.field = $event">
1956
+ * </kendo-dropdownlist>
1957
+ * </ng-template>
1958
+ * <kendo-filter-field field="name" editor="string"></kendo-filter-field>
1959
+ * </kendo-filter>
1960
+ * ```
1961
+ */
1962
+ class FilterFieldsTemplateDirective {
1963
+ templateRef;
1964
+ constructor(templateRef) {
1965
+ this.templateRef = templateRef;
1966
+ }
1967
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterFieldsTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
1968
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.20", type: FilterFieldsTemplateDirective, isStandalone: true, selector: "[kendoFilterFieldsTemplate]", ngImport: i0 });
1969
+ }
1970
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterFieldsTemplateDirective, decorators: [{
1971
+ type: Directive,
1972
+ args: [{
1973
+ selector: '[kendoFilterFieldsTemplate]',
1974
+ standalone: true
1975
+ }]
1976
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
1977
+
1831
1978
  /**
1832
1979
  * Represents the [Kendo UI Filter component for Angular](https://www.telerik.com/kendo-angular-ui/components/filter).
1833
1980
  * The Filter component enables users to define and apply complex filter criteria.
@@ -1951,6 +2098,7 @@ class FilterComponent {
1951
2098
  filterFieldsSubscription;
1952
2099
  _value = { filters: [], logic: 'and' };
1953
2100
  filterFields;
2101
+ fieldTemplate;
1954
2102
  _filterItems;
1955
2103
  get filterItems() {
1956
2104
  return this._filterItems.toArray();
@@ -1974,6 +2122,9 @@ class FilterComponent {
1974
2122
  this.cdr.detectChanges();
1975
2123
  });
1976
2124
  }
2125
+ ngAfterContentInit() {
2126
+ this.filterService.fieldTemplate = this.fieldTemplate?.templateRef ?? null;
2127
+ }
1977
2128
  ngAfterViewInit() {
1978
2129
  this.filterFieldsChanged();
1979
2130
  this.filterFieldsSubscription = this.filterFields.changes.subscribe(this.filterFieldsChanged.bind(this));
@@ -1991,7 +2142,8 @@ class FilterComponent {
1991
2142
  this.filters = this.filterFields.map((filterField) => ({
1992
2143
  ...filterField,
1993
2144
  title: filterField.title,
1994
- editorTemplate: filterField.editorTemplate?.templateRef
2145
+ editorTemplate: filterField.editorTemplate?.templateRef,
2146
+ operatorTemplate: filterField.operatorTemplate?.templateRef
1995
2147
  }));
1996
2148
  }
1997
2149
  if (this.filters.length === 0) {
@@ -2123,7 +2275,7 @@ class FilterComponent {
2123
2275
  },
2124
2276
  FilterService,
2125
2277
  NavigationService
2126
- ], queries: [{ propertyName: "filterFields", predicate: FilterFieldComponent }], viewQueries: [{ propertyName: "_filterItems", predicate: FilterItem, descendants: true }], ngImport: i0, template: `
2278
+ ], queries: [{ propertyName: "fieldTemplate", first: true, predicate: FilterFieldsTemplateDirective, descendants: true }, { propertyName: "filterFields", predicate: FilterFieldComponent }], viewQueries: [{ propertyName: "_filterItems", predicate: FilterItem, descendants: true }], ngImport: i0, template: `
2127
2279
  <ng-container kendoFilterLocalizedMessages
2128
2280
  i18n-editorDateTodayText="kendo.filter.editorDateTodayText|The text of the Today button of the Date editor"
2129
2281
  editorDateTodayText="Today"
@@ -2413,6 +2565,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
2413
2565
  }], filterFields: [{
2414
2566
  type: ContentChildren,
2415
2567
  args: [FilterFieldComponent]
2568
+ }], fieldTemplate: [{
2569
+ type: ContentChild,
2570
+ args: [FilterFieldsTemplateDirective]
2416
2571
  }], _filterItems: [{
2417
2572
  type: ViewChildren,
2418
2573
  args: [FilterItem]
@@ -2461,7 +2616,9 @@ const KENDO_FILTER = [
2461
2616
  FilterComponent,
2462
2617
  FilterFieldComponent,
2463
2618
  CustomMessagesComponent,
2464
- FilterValueEditorTemplateDirective
2619
+ FilterValueEditorTemplateDirective,
2620
+ FilterOperatorTemplateDirective,
2621
+ FilterFieldsTemplateDirective
2465
2622
  ];
2466
2623
 
2467
2624
  // IMPORTANT: NgModule export kept for backwards compatibility
@@ -2498,7 +2655,7 @@ const KENDO_FILTER = [
2498
2655
  */
2499
2656
  class FilterModule {
2500
2657
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2501
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.20", ngImport: i0, type: FilterModule, imports: [FilterComponent, FilterFieldComponent, CustomMessagesComponent, FilterValueEditorTemplateDirective], exports: [FilterComponent, FilterFieldComponent, CustomMessagesComponent, FilterValueEditorTemplateDirective] });
2658
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.20", ngImport: i0, type: FilterModule, imports: [FilterComponent, FilterFieldComponent, CustomMessagesComponent, FilterValueEditorTemplateDirective, FilterOperatorTemplateDirective, FilterFieldsTemplateDirective], exports: [FilterComponent, FilterFieldComponent, CustomMessagesComponent, FilterValueEditorTemplateDirective, FilterOperatorTemplateDirective, FilterFieldsTemplateDirective] });
2502
2659
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.20", ngImport: i0, type: FilterModule, providers: [
2503
2660
  // InputsModule providers
2504
2661
  IconsService,
@@ -2558,5 +2715,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.20", ngImpo
2558
2715
  * Generated bundle index. Do not edit.
2559
2716
  */
2560
2717
 
2561
- export { AriaLabelValueDirective, CustomMessagesComponent, FilterBooleanEditorComponent, FilterComponent, FilterDateEditorComponent, FilterExpressionComponent, FilterExpressionOperatorsComponent, FilterFieldComponent, FilterGroupComponent, FilterModule, FilterNumericEditorComponent, FilterTextEditorComponent, FilterValueEditorTemplateDirective, KENDO_FILTER, LocalizedMessagesDirective };
2718
+ export { AriaLabelValueDirective, CustomMessagesComponent, FilterBooleanEditorComponent, FilterComponent, FilterDateEditorComponent, FilterExpressionComponent, FilterExpressionOperatorsComponent, FilterFieldComponent, FilterFieldsTemplateDirective, FilterGroupComponent, FilterModule, FilterNumericEditorComponent, FilterOperatorTemplateDirective, FilterTextEditorComponent, FilterValueEditorTemplateDirective, KENDO_FILTER, LocalizedMessagesDirective };
2562
2719
 
@@ -2,7 +2,7 @@
2
2
  * Copyright © 2026 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 { EventEmitter } from '@angular/core';
5
+ import { EventEmitter, TemplateRef } from '@angular/core';
6
6
  import { LocalizationService } from '@progress/kendo-angular-l10n';
7
7
  import { FilterDescriptor } from '@progress/kendo-data-query';
8
8
  import { FilterEditor, FilterOperator } from './model/filter-expression';
@@ -19,10 +19,11 @@ export declare class FilterExpressionOperatorsComponent {
19
19
  text: string;
20
20
  value: string;
21
21
  }[];
22
+ operatorTemplate: TemplateRef<any>;
22
23
  constructor(localization: LocalizationService);
23
24
  messageFor(key: string): string;
24
25
  getOperator(operatorValue: FilterOperator): string;
25
26
  operatorValueChange(value: FilterOperator): void;
26
27
  static ɵfac: i0.ɵɵFactoryDeclaration<FilterExpressionOperatorsComponent, never>;
27
- static ɵcmp: i0.ɵɵComponentDeclaration<FilterExpressionOperatorsComponent, "kendo-filter-expression-operators", never, { "currentItem": { "alias": "currentItem"; "required": false; }; "editorType": { "alias": "editorType"; "required": false; }; "operators": { "alias": "operators"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
28
+ static ɵcmp: i0.ɵɵComponentDeclaration<FilterExpressionOperatorsComponent, "kendo-filter-expression-operators", never, { "currentItem": { "alias": "currentItem"; "required": false; }; "editorType": { "alias": "editorType"; "required": false; }; "operators": { "alias": "operators"; "required": false; }; "operatorTemplate": { "alias": "operatorTemplate"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
28
29
  }