@progress/kendo-vue-dropdowns 3.10.2 → 3.11.0-dev.202305230751

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 (83) hide show
  1. package/dist/cdn/js/kendo-vue-dropdowns.js +1 -1
  2. package/dist/es/AutoComplete/AutoComplete.js +115 -15
  3. package/dist/es/AutoComplete/AutoCompleteProps.d.ts +12 -0
  4. package/dist/es/ComboBox/ComboBox.js +115 -16
  5. package/dist/es/ComboBox/ComboBoxProps.d.ts +12 -0
  6. package/dist/es/DropDownList/DropDownList.js +101 -14
  7. package/dist/es/DropDownList/DropDownListProps.d.ts +12 -0
  8. package/dist/es/DropDownTree/DropDownTree.d.ts +49 -1
  9. package/dist/es/DropDownTree/DropDownTree.js +863 -638
  10. package/dist/es/DropDownTree/DropDownTreeProps.d.ts +19 -8
  11. package/dist/es/MultiSelect/MultiSelect.js +122 -28
  12. package/dist/es/MultiSelect/MultiSelectProps.d.ts +12 -0
  13. package/dist/es/MultiSelectTree/MultiSelectTree.js +12 -12
  14. package/dist/es/common/DropDownBase.d.ts +2 -0
  15. package/dist/es/common/DropDownBase.js +20 -0
  16. package/dist/es/common/GroupStickyHeader.d.ts +29 -0
  17. package/dist/es/common/GroupStickyHeader.js +59 -0
  18. package/dist/es/common/List.d.ts +2 -0
  19. package/dist/es/common/List.js +53 -25
  20. package/dist/es/common/ListFilter.js +47 -25
  21. package/dist/es/common/ListGroupItem.d.ts +41 -0
  22. package/dist/es/common/ListGroupItem.js +71 -0
  23. package/dist/es/common/settings.d.ts +1 -0
  24. package/dist/es/main.d.ts +2 -1
  25. package/dist/es/main.js +2 -1
  26. package/dist/es/package-metadata.js +1 -1
  27. package/dist/esm/AutoComplete/AutoComplete.js +115 -15
  28. package/dist/esm/AutoComplete/AutoCompleteProps.d.ts +12 -0
  29. package/dist/esm/ComboBox/ComboBox.js +115 -16
  30. package/dist/esm/ComboBox/ComboBoxProps.d.ts +12 -0
  31. package/dist/esm/DropDownList/DropDownList.js +101 -14
  32. package/dist/esm/DropDownList/DropDownListProps.d.ts +12 -0
  33. package/dist/esm/DropDownTree/DropDownTree.d.ts +49 -1
  34. package/dist/esm/DropDownTree/DropDownTree.js +863 -638
  35. package/dist/esm/DropDownTree/DropDownTreeProps.d.ts +19 -8
  36. package/dist/esm/MultiSelect/MultiSelect.js +122 -28
  37. package/dist/esm/MultiSelect/MultiSelectProps.d.ts +12 -0
  38. package/dist/esm/MultiSelectTree/MultiSelectTree.js +12 -12
  39. package/dist/esm/common/DropDownBase.d.ts +2 -0
  40. package/dist/esm/common/DropDownBase.js +20 -0
  41. package/dist/esm/common/GroupStickyHeader.d.ts +29 -0
  42. package/dist/esm/common/GroupStickyHeader.js +59 -0
  43. package/dist/esm/common/List.d.ts +2 -0
  44. package/dist/esm/common/List.js +53 -25
  45. package/dist/esm/common/ListFilter.js +47 -25
  46. package/dist/esm/common/ListGroupItem.d.ts +41 -0
  47. package/dist/esm/common/ListGroupItem.js +71 -0
  48. package/dist/esm/common/settings.d.ts +1 -0
  49. package/dist/esm/main.d.ts +2 -1
  50. package/dist/esm/main.js +2 -1
  51. package/dist/esm/package-metadata.js +1 -1
  52. package/dist/npm/AutoComplete/AutoComplete.js +114 -14
  53. package/dist/npm/AutoComplete/AutoCompleteProps.d.ts +12 -0
  54. package/dist/npm/ComboBox/ComboBox.js +115 -16
  55. package/dist/npm/ComboBox/ComboBoxProps.d.ts +12 -0
  56. package/dist/npm/DropDownList/DropDownList.js +101 -14
  57. package/dist/npm/DropDownList/DropDownListProps.d.ts +12 -0
  58. package/dist/npm/DropDownTree/DropDownTree.d.ts +49 -1
  59. package/dist/npm/DropDownTree/DropDownTree.js +868 -639
  60. package/dist/npm/DropDownTree/DropDownTreeProps.d.ts +19 -8
  61. package/dist/npm/MultiSelect/MultiSelect.js +122 -28
  62. package/dist/npm/MultiSelect/MultiSelectProps.d.ts +12 -0
  63. package/dist/npm/MultiSelectTree/MultiSelectTree.js +12 -12
  64. package/dist/npm/common/DropDownBase.d.ts +2 -0
  65. package/dist/npm/common/DropDownBase.js +20 -0
  66. package/dist/npm/common/GroupStickyHeader.d.ts +29 -0
  67. package/dist/npm/common/GroupStickyHeader.js +66 -0
  68. package/dist/npm/common/List.d.ts +2 -0
  69. package/dist/npm/common/List.js +52 -24
  70. package/dist/npm/common/ListFilter.js +47 -25
  71. package/dist/npm/common/ListGroupItem.d.ts +41 -0
  72. package/dist/npm/common/ListGroupItem.js +78 -0
  73. package/dist/npm/common/settings.d.ts +1 -0
  74. package/dist/npm/main.d.ts +2 -1
  75. package/dist/npm/main.js +3 -1
  76. package/dist/npm/package-metadata.js +1 -1
  77. package/package.json +10 -8
  78. package/dist/es/DropDownTree/useDropdownWidth.d.ts +0 -4
  79. package/dist/es/DropDownTree/useDropdownWidth.js +0 -10
  80. package/dist/esm/DropDownTree/useDropdownWidth.d.ts +0 -4
  81. package/dist/esm/DropDownTree/useDropdownWidth.js +0 -10
  82. package/dist/npm/DropDownTree/useDropdownWidth.d.ts +0 -4
  83. package/dist/npm/DropDownTree/useDropdownWidth.js +0 -17
@@ -20,9 +20,10 @@ import { SearchBar } from './../common/SearchBar';
20
20
  import { ListContainer } from './../common/ListContainer';
21
21
  import { List } from './../common/List';
22
22
  import DropDownBase from '../common/DropDownBase';
23
+ import { GroupStickyHeader } from '../common/GroupStickyHeader';
23
24
  import { ClearButton } from '../common/ClearButton';
24
25
  import { itemIndexStartsWith, getItemValue, areSame, getFocusedItem } from '../common/utils';
25
- import { guid, Keys, classNames, templateRendering, getListeners, getTemplate, kendoThemeMaps, setRef, getRef } from '@progress/kendo-vue-common';
26
+ import { guid, Keys, classNames, templateRendering, getListeners, getTemplate, kendoThemeMaps, setRef, getRef, Icon } from '@progress/kendo-vue-common';
26
27
  var sizeMap = kendoThemeMaps.sizeMap,
27
28
  roundedMap = kendoThemeMaps.roundedMap;
28
29
  var VALIDATION_MESSAGE = 'Please enter a valid value!';
@@ -97,6 +98,8 @@ var AutoCompleteVue2 = {
97
98
  }
98
99
  },
99
100
  itemRender: [String, Function, Object],
101
+ groupHeaderItemRender: [String, Function, Object],
102
+ groupStickyHeaderItemRender: [String, Function, Object],
100
103
  listNoDataRender: [String, Function, Object],
101
104
  focusedItemIndex: Function,
102
105
  header: [String, Function, Object],
@@ -127,6 +130,9 @@ var AutoCompleteVue2 = {
127
130
  validator: function validator(value) {
128
131
  return ['small', 'medium', 'large'].includes(value);
129
132
  }
133
+ },
134
+ groupField: {
135
+ type: String
130
136
  }
131
137
  },
132
138
  data: function data() {
@@ -142,7 +148,10 @@ var AutoCompleteVue2 = {
142
148
  last: ''
143
149
  },
144
150
  valueDuringOnChange: {},
145
- suggested: ''
151
+ suggested: '',
152
+ group: undefined,
153
+ isScrolling: false,
154
+ itemHeight: 0
146
155
  };
147
156
  },
148
157
  created: function created() {
@@ -190,8 +199,12 @@ var AutoCompleteVue2 = {
190
199
  }
191
200
  },
192
201
  updated: function updated() {
193
- var _a = this.$props.dataItems,
194
- dataItems = _a === void 0 ? [] : _a;
202
+ var _a;
203
+ var _b = this.$props,
204
+ _c = _b.groupField,
205
+ groupField = _c === void 0 ? '' : _c,
206
+ _d = _b.dataItems,
207
+ dataItems = _d === void 0 ? [] : _d;
195
208
  var focusedIndex = this.focusedIndex();
196
209
  var focusedItem = dataItems[focusedIndex];
197
210
  var dataChanged = this.prevData !== dataItems;
@@ -206,8 +219,22 @@ var AutoCompleteVue2 = {
206
219
  // @ts-ignore
207
220
  this.base.list = list.list;
208
221
  }
209
- if (dataItems.length && (opened && (focusedItemChanged || dataChanged) || opening)) {
210
- this.base.scrollToItem(focusedIndex);
222
+ if (groupField === '') {
223
+ if (opened && (focusedItemChanged || dataChanged) || opening) {
224
+ this.base.scrollToItem(focusedIndex);
225
+ }
226
+ } else if (!this.isScrolling) {
227
+ var focusedItemIndex = (_a = this.base.getGroupedDataModernMode(dataItems, groupField)) === null || _a === void 0 ? void 0 : _a.indexOf(focusedItem);
228
+ if (opening) {
229
+ // Resets the sticky header group value for scenarios with open/close of component's popup
230
+ if (dataItems && dataItems.length !== 0) {
231
+ this.base.resetGroupStickyHeader(dataItems[0][groupField], this);
232
+ }
233
+ this.base.scrollToItem(focusedItemIndex);
234
+ }
235
+ if (opened && prevOpened && focusedItemChanged) {
236
+ this.base.scrollToItem(focusedItemIndex);
237
+ }
211
238
  }
212
239
  this.setValidity();
213
240
  },
@@ -377,6 +404,10 @@ var AutoCompleteVue2 = {
377
404
  this.togglePopup(state);
378
405
  }
379
406
  state.data.focusedItem = undefined;
407
+ // Resets the value of the StickyHeader when filtering the data or just entering symbols in the input
408
+ if (this.prevData && this.prevData.length !== this.$props.dataItems) {
409
+ state.data.group = undefined;
410
+ }
380
411
  this.applyState(state);
381
412
  },
382
413
  clearButtonClick: function clearButtonClick(event) {
@@ -396,6 +427,9 @@ var AutoCompleteVue2 = {
396
427
  this.applyState(state);
397
428
  },
398
429
  onInputKeyDown: function onInputKeyDown(event) {
430
+ if (this.isScrolling) {
431
+ this.isScrolling = false;
432
+ }
399
433
  var keyCode = event.keyCode;
400
434
  var opened = this.$props.opened !== undefined ? this.$props.opened : this.currentOpened;
401
435
  var state = this.base.initState();
@@ -481,6 +515,39 @@ var AutoCompleteVue2 = {
481
515
  },
482
516
  repositionPopup: function repositionPopup() {
483
517
  this.base.repositionPopup();
518
+ },
519
+ onScroll: function onScroll(event) {
520
+ this.isScrolling = true;
521
+ var state = this.base.initState();
522
+ var list = this.base.list;
523
+ var groupField = this.$props.groupField;
524
+ var _a = this.$props.dataItems,
525
+ dataItems = _a === void 0 ? [] : _a;
526
+ if (!groupField || !dataItems.length) {
527
+ return;
528
+ }
529
+ var itemHeight = this.itemHeight || (list.children ? list.children[0].offsetHeight : 0);
530
+ var target = event.target;
531
+ var scrollTop = target.scrollTop;
532
+ if (groupField) {
533
+ dataItems = this.base.getGroupedDataModernMode(dataItems, groupField);
534
+ }
535
+ var group = dataItems[0][groupField];
536
+ if (itemHeight === 0) {
537
+ itemHeight = 28;
538
+ }
539
+ for (var i = 1; i < dataItems.length; i++) {
540
+ if (itemHeight * i > scrollTop) {
541
+ break;
542
+ }
543
+ if (dataItems[i] && dataItems[i][groupField]) {
544
+ group = dataItems[i][groupField];
545
+ }
546
+ }
547
+ if (group !== this.group) {
548
+ state.data.group = group;
549
+ this.applyState(state);
550
+ }
484
551
  }
485
552
  },
486
553
  render: function render(createElement) {
@@ -572,11 +639,15 @@ var AutoCompleteVue2 = {
572
639
  var renderList = function renderList() {
573
640
  var _a = this.$props,
574
641
  textField = _a.textField,
575
- _b = _a.dataItems,
576
- dataItems = _b === void 0 ? [] : _b;
642
+ groupField = _a.groupField;
643
+ var dataItems = this.$props.dataItems || [];
577
644
  var itemRender = templateRendering.call(this, this.$props.itemRender, getListeners.call(this));
645
+ var groupHeaderItemRender = templateRendering.call(this, this.$props.groupHeaderItemRender, getListeners.call(this));
578
646
  var listNoDataRender = templateRendering.call(this, this.$props.listNoDataRender, getListeners.call(this));
579
647
  var opened = this.$props.opened !== undefined ? this.$props.opened : this.currentOpened;
648
+ if (groupField) {
649
+ dataItems = this.base.getGroupedDataModernMode(dataItems, groupField);
650
+ }
580
651
  return (
581
652
  // @ts-ignore
582
653
  h(List, {
@@ -596,7 +667,9 @@ var AutoCompleteVue2 = {
596
667
  },
597
668
  wrapperCssClass: "k-list-content",
598
669
  itemRender: itemRender,
599
- noDataRender: listNoDataRender
670
+ groupHeaderItemRender: groupHeaderItemRender,
671
+ noDataRender: listNoDataRender,
672
+ groupField: groupField
600
673
  },
601
674
  show: opened,
602
675
  dataItems: dataItems.slice(),
@@ -613,10 +686,14 @@ var AutoCompleteVue2 = {
613
686
  wrapperCssClass: "k-list-content",
614
687
  onListclick: this.handleItemClick,
615
688
  on: this.v3 ? undefined : {
616
- "listclick": this.handleItemClick
689
+ "listclick": this.handleItemClick,
690
+ "scroll": this.onScroll
617
691
  },
618
692
  itemRender: itemRender,
619
- noDataRender: listNoDataRender
693
+ groupHeaderItemRender: groupHeaderItemRender,
694
+ noDataRender: listNoDataRender,
695
+ groupField: groupField,
696
+ onScroll: this.onScroll
620
697
  })
621
698
  );
622
699
  };
@@ -625,6 +702,7 @@ var AutoCompleteVue2 = {
625
702
  var _a;
626
703
  var headerTemplate = templateRendering.call(this, this.$props.header, getListeners.call(this));
627
704
  var footerTemplate = templateRendering.call(this, this.$props.footer, getListeners.call(this));
705
+ var groupStickyHeaderTemplate = templateRendering.call(this, this.$props.groupStickyHeaderItemRender, getListeners.call(this));
628
706
  var header = getTemplate.call(this, {
629
707
  h: h,
630
708
  template: headerTemplate
@@ -635,6 +713,10 @@ var AutoCompleteVue2 = {
635
713
  });
636
714
  var opened = this.$props.opened !== undefined ? this.$props.opened : this.currentOpened;
637
715
  var popupWidth = popupSettings.width !== undefined ? popupSettings.width : base.popupWidth;
716
+ var dataItems = this.$props.dataItems || [];
717
+ if (this.group === undefined && this.$props.groupField !== undefined) {
718
+ this.group = getItemValue(dataItems[0], this.$props.groupField);
719
+ }
638
720
  return (
639
721
  // @ts-ignore function children
640
722
  h(ListContainer, {
@@ -668,12 +750,26 @@ var AutoCompleteVue2 = {
668
750
  }, this.v3 ? function () {
669
751
  return [header && h("div", {
670
752
  "class": "k-list-header"
671
- }, [header]), renderList.call(_this2), footer && h("div", {
753
+ }, [header]), _this2.group && dataItems.length !== 0 && h(GroupStickyHeader, {
754
+ group: _this2.group,
755
+ attrs: _this2.v3 ? undefined : {
756
+ group: _this2.group,
757
+ render: groupStickyHeaderTemplate
758
+ },
759
+ render: groupStickyHeaderTemplate
760
+ }), renderList.call(_this2), footer && h("div", {
672
761
  "class": "k-list-footer"
673
762
  }, [footer])];
674
763
  } : [header && h("div", {
675
764
  "class": "k-list-header"
676
- }, [header]), renderList.call(_this2), footer && h("div", {
765
+ }, [header]), _this2.group && dataItems.length !== 0 && h(GroupStickyHeader, {
766
+ group: _this2.group,
767
+ attrs: _this2.v3 ? undefined : {
768
+ group: _this2.group,
769
+ render: groupStickyHeaderTemplate
770
+ },
771
+ render: groupStickyHeaderTemplate
772
+ }), renderList.call(_this2), footer && h("div", {
677
773
  "class": "k-list-footer"
678
774
  }, [footer])])
679
775
  );
@@ -695,8 +791,12 @@ var AutoCompleteVue2 = {
695
791
  on: this.v3 ? undefined : {
696
792
  "clearclick": this.clearButtonClick
697
793
  }
698
- }), h("span", {
699
- "class": loading ? 'k-input-loading-icon k-icon k-i-loading' : undefined
794
+ }), h(Icon, {
795
+ name: loading ? 'loading' : '',
796
+ attrs: this.v3 ? undefined : {
797
+ name: loading ? 'loading' : ''
798
+ },
799
+ "class": 'k-input-loading-icon'
700
800
  }), renderListContainer.call(this)]);
701
801
  return label ? h("span", {
702
802
  "class": this.spanClassNames,
@@ -215,4 +215,16 @@ export interface AutoCompleteProps extends FormComponentProps {
215
215
  * @default `solid`
216
216
  */
217
217
  fillMode?: null | 'solid' | 'outline' | 'flat' | string;
218
+ /**
219
+ * Sets the data item field that represents the start of a group. Applicable to objects data.
220
+ */
221
+ groupField?: string;
222
+ /**
223
+ * Fires when a AutoComplete group header item is about to be rendered. Used to override the default appearance of the group's headers.
224
+ */
225
+ groupHeaderItemRender?: any;
226
+ /**
227
+ * Fires when a AutoComplete sticky group header item is about to be rendered. Used to override the default appearance of the sticky group header of the component.
228
+ */
229
+ groupStickyHeaderItemRender?: any;
218
230
  }
@@ -18,6 +18,7 @@ var isV3 = allVue.version && allVue.version[0] === '3';
18
18
  var ref = allVue.ref;
19
19
  var inject = allVue.inject;
20
20
  import DropDownBase from '../common/DropDownBase';
21
+ import { GroupStickyHeader } from '../common/GroupStickyHeader';
21
22
  import { guid, classNames, Keys, templateRendering, getListeners, getTemplate, kendoThemeMaps, getRef, setRef, Icon } from '@progress/kendo-vue-common';
22
23
  import { Button as KButton } from '@progress/kendo-vue-buttons';
23
24
  var sizeMap = kendoThemeMaps.sizeMap,
@@ -119,6 +120,8 @@ var ComboBoxVue2 = {
119
120
  }
120
121
  },
121
122
  itemRender: [String, Function, Object],
123
+ groupHeaderItemRender: [String, Function, Object],
124
+ groupStickyHeaderItemRender: [String, Function, Object],
122
125
  listNoDataRender: [String, Function, Object],
123
126
  focusedItemIndex: Function,
124
127
  header: [String, Function, Object],
@@ -168,6 +171,9 @@ var ComboBoxVue2 = {
168
171
  validator: function validator(value) {
169
172
  return ['small', 'medium', 'large'].includes(value);
170
173
  }
174
+ },
175
+ groupField: {
176
+ type: String
171
177
  }
172
178
  },
173
179
  inject: {
@@ -189,7 +195,10 @@ var ComboBoxVue2 = {
189
195
  _skipFocusEvent: false,
190
196
  valueDuringOnChange: {},
191
197
  _navigated: false,
192
- suggested: ''
198
+ suggested: '',
199
+ group: undefined,
200
+ isScrolling: false,
201
+ itemHeight: 0
193
202
  };
194
203
  },
195
204
  created: function created() {
@@ -228,11 +237,14 @@ var ComboBoxVue2 = {
228
237
  this.setValidity();
229
238
  },
230
239
  updated: function updated() {
231
- var _a = this.$props,
232
- _b = _a.dataItems,
233
- dataItems = _b === void 0 ? [] : _b,
234
- dataItemKey = _a.dataItemKey,
235
- virtual = _a.virtual;
240
+ var _a;
241
+ var _b = this.$props,
242
+ _c = _b.dataItems,
243
+ dataItems = _c === void 0 ? [] : _c,
244
+ dataItemKey = _b.dataItemKey,
245
+ virtual = _b.virtual,
246
+ groupField = _b.groupField,
247
+ textField = _b.textField;
236
248
  var opened = this.$props.opened !== undefined ? this.$props.opened : this.currentOpened;
237
249
  var prevOpened = this.prevOpened !== undefined ? this.prevOpened : this.prevCurrentOpened;
238
250
  var opening = !prevOpened && opened;
@@ -264,17 +276,37 @@ var ComboBoxVue2 = {
264
276
  var selectedItemIndex = dataItems.findIndex(function (i) {
265
277
  return areSame(i, selectedItem, dataItemKey);
266
278
  });
279
+ // Needed to calculate the proper item index when in grouping mode
280
+ if (groupField) {
281
+ selectedItemIndex = (_a = this.base.getGroupedDataModernMode(dataItems, groupField)) === null || _a === void 0 ? void 0 : _a.indexOf(selectedItem);
282
+ }
267
283
  var selectedItemChanged = !areSame(prevSelectedItem, selectedItem, dataItemKey);
268
284
  if (opening && virtual) {
269
285
  this.base.scrollToVirtualItem(virtual, selectedItemIndex);
270
286
  this.prevCurrentOpened = true;
271
287
  } else if (opening && !virtual) {
272
- this.base.scrollToItem(selectedItem ? selectedItemIndex : this.getFocusedIndex());
288
+ // Resets the sticky header group value for scenarios with open/close of component's popup
289
+ if (dataItems && dataItems.length !== 0) {
290
+ this.base.resetGroupStickyHeader(dataItems[0][groupField], this);
291
+ }
292
+ this.base.scrollToItem(selectedItemIndex);
273
293
  this.prevCurrentOpened = true;
274
294
  } else if (opened && prevOpened && selectedItem && selectedItemChanged) {
275
295
  this.base.scrollToItem(selectedItemIndex);
276
- } else if (opened && !selectedItem) {
277
- this.base.scrollToItem(this.getFocusedIndex());
296
+ } else if (opened && !selectedItem && !this.isScrolling) {
297
+ var groupHeadersBeforeFocus = 0;
298
+ // Handle the items' focusing when working with grouped data
299
+ if (groupField && this.getFocusedIndex() !== -1 && dataItems.length > 0) {
300
+ var focusedElemBeforeGrouping_1 = dataItems[this.getFocusedIndex()][textField];
301
+ var gropedDataItems = this.base.getGroupedDataModernMode(dataItems, groupField);
302
+ var groupedDataIdex = gropedDataItems.findIndex(function (el) {
303
+ return el[textField] === focusedElemBeforeGrouping_1;
304
+ });
305
+ groupHeadersBeforeFocus = gropedDataItems.slice(0, groupedDataIdex).filter(function (el) {
306
+ return Object.keys(el).length === 1;
307
+ }).length;
308
+ }
309
+ this.base.scrollToItem(this.getFocusedIndex() + groupHeadersBeforeFocus);
278
310
  }
279
311
  }
280
312
  if (opening && this.input) {
@@ -536,6 +568,9 @@ var ComboBoxVue2 = {
536
568
  },
537
569
  onInputKeyDown: function onInputKeyDown(event) {
538
570
  var _this = this;
571
+ if (this.isScrolling) {
572
+ this.isScrolling = false;
573
+ }
539
574
  var keyCode = event.keyCode;
540
575
  var opened = this.$props.opened !== undefined ? this.$props.opened : this.currentOpened;
541
576
  var state = this.base.initState();
@@ -600,6 +635,10 @@ var ComboBoxVue2 = {
600
635
  this.base.togglePopup(state);
601
636
  }
602
637
  this.base.filterChanged(value, state);
638
+ // Resets the value of the StickyHeader when filtering the data or just entering symbols in the input
639
+ if (this.$props.filterable) {
640
+ state.data.group = undefined;
641
+ }
603
642
  this.applyState(state);
604
643
  },
605
644
  clearButtonClick: function clearButtonClick(event) {
@@ -673,6 +712,39 @@ var ComboBoxVue2 = {
673
712
  },
674
713
  repositionPopup: function repositionPopup() {
675
714
  this.base.repositionPopup();
715
+ },
716
+ onScroll: function onScroll(event) {
717
+ this.isScrolling = true;
718
+ var _a = this.base,
719
+ vs = _a.vs,
720
+ list = _a.list;
721
+ vs.scrollHandler(event);
722
+ var state = this.base.initState();
723
+ var groupField = this.$props.groupField;
724
+ var _b = this.$props.dataItems,
725
+ dataItems = _b === void 0 ? [] : _b;
726
+ if (!groupField || !dataItems.length) {
727
+ return;
728
+ }
729
+ var itemHeight = this.itemHeight = this.itemHeight || (vs.enabled ? vs.itemHeight : list ? list.children[0].offsetHeight : 0);
730
+ var target = event.target;
731
+ var scrollTop = target.scrollTop - vs.skip * itemHeight;
732
+ if (groupField) {
733
+ dataItems = this.base.getGroupedDataModernMode(dataItems, groupField);
734
+ }
735
+ var group = dataItems[0][groupField];
736
+ for (var i = 1; i < dataItems.length; i++) {
737
+ if (itemHeight * i > scrollTop) {
738
+ break;
739
+ }
740
+ if (dataItems[i] && dataItems[i][groupField]) {
741
+ group = dataItems[i][groupField];
742
+ }
743
+ }
744
+ if (group !== this.group) {
745
+ state.data.group = group;
746
+ this.applyState(state);
747
+ }
676
748
  }
677
749
  },
678
750
  render: function render(createElement) {
@@ -719,9 +791,10 @@ var ComboBoxVue2 = {
719
791
  var _a;
720
792
  var _b = this.$props,
721
793
  dataItemKey = _b.dataItemKey,
722
- _c = _b.dataItems,
723
- dataItems = _c === void 0 ? [] : _c;
794
+ groupField = _b.groupField;
795
+ var dataItems = this.$props.dataItems || [];
724
796
  var itemRender = templateRendering.call(this, this.$props.itemRender, getListeners.call(this));
797
+ var groupHeaderItemRender = templateRendering.call(this, this.$props.groupHeaderItemRender, getListeners.call(this));
725
798
  var listNoDataRender = templateRendering.call(this, this.$props.listNoDataRender, getListeners.call(this));
726
799
  if (!virtual) {
727
800
  virtual = {
@@ -733,6 +806,9 @@ var ComboBoxVue2 = {
733
806
  var translate = "translateY(".concat(vs.translate, "px)");
734
807
  var focusedIndex = opened ? this.getFocusedIndex() : undefined;
735
808
  var value = isPresent(text) && text !== selectedItemText ? null : this.computedValue();
809
+ if (groupField) {
810
+ dataItems = this.base.getGroupedDataModernMode(dataItems, groupField);
811
+ }
736
812
  return (
737
813
  // @ts-ignore function children
738
814
  h(List, {
@@ -755,7 +831,9 @@ var ComboBoxVue2 = {
755
831
  } : undefined,
756
832
  skip: skip,
757
833
  itemRender: itemRender,
758
- noDataRender: listNoDataRender
834
+ groupHeaderItemRender: groupHeaderItemRender,
835
+ noDataRender: listNoDataRender,
836
+ groupField: groupField
759
837
  },
760
838
  show: opened,
761
839
  dataItems: dataItems,
@@ -777,11 +855,13 @@ var ComboBoxVue2 = {
777
855
  onListclick: this.handleItemClick,
778
856
  on: this.v3 ? undefined : {
779
857
  "listclick": this.handleItemClick,
780
- "scroll": vs.scrollHandler
858
+ "scroll": this.onScroll
781
859
  },
782
860
  itemRender: itemRender,
861
+ groupHeaderItemRender: groupHeaderItemRender,
783
862
  noDataRender: listNoDataRender,
784
- onScroll: vs.scrollHandler
863
+ groupField: groupField,
864
+ onScroll: this.onScroll
785
865
  }, this.v3 ? function () {
786
866
  return [renderScrollElement.call(_this2)];
787
867
  } : [renderScrollElement.call(_this2)])
@@ -798,6 +878,7 @@ var ComboBoxVue2 = {
798
878
  var _a;
799
879
  var headerTemplate = templateRendering.call(this, this.$props.header, getListeners.call(this));
800
880
  var footerTemplate = templateRendering.call(this, this.$props.footer, getListeners.call(this));
881
+ var groupStickyHeaderTemplate = templateRendering.call(this, this.$props.groupStickyHeaderItemRender, getListeners.call(this));
801
882
  var header = getTemplate.call(this, {
802
883
  h: h,
803
884
  template: headerTemplate
@@ -808,6 +889,10 @@ var ComboBoxVue2 = {
808
889
  });
809
890
  var opened = this.$props.opened !== undefined ? this.$props.opened : this.currentOpened;
810
891
  var popupWidth = popupSettings.width !== undefined ? popupSettings.width : base.popupWidth;
892
+ var dataItems = this.$props.dataItems || [];
893
+ if (this.group === undefined && this.$props.groupField !== undefined) {
894
+ this.group = getItemValue(dataItems[0], this.$props.groupField);
895
+ }
811
896
  return (
812
897
  // @ts-ignore function children
813
898
  h(ListContainer, {
@@ -841,12 +926,26 @@ var ComboBoxVue2 = {
841
926
  }, this.v3 ? function () {
842
927
  return [header && h("div", {
843
928
  "class": "k-list-header"
844
- }, [header]), renderList.call(_this3), footer && h("div", {
929
+ }, [header]), _this3.group && dataItems.length !== 0 && h(GroupStickyHeader, {
930
+ group: _this3.group,
931
+ attrs: _this3.v3 ? undefined : {
932
+ group: _this3.group,
933
+ render: groupStickyHeaderTemplate
934
+ },
935
+ render: groupStickyHeaderTemplate
936
+ }), renderList.call(_this3), footer && h("div", {
845
937
  "class": "k-list-footer"
846
938
  }, [footer])];
847
939
  } : [header && h("div", {
848
940
  "class": "k-list-header"
849
- }, [header]), renderList.call(_this3), footer && h("div", {
941
+ }, [header]), _this3.group && dataItems.length !== 0 && h(GroupStickyHeader, {
942
+ group: _this3.group,
943
+ attrs: _this3.v3 ? undefined : {
944
+ group: _this3.group,
945
+ render: groupStickyHeaderTemplate
946
+ },
947
+ render: groupStickyHeaderTemplate
948
+ }), renderList.call(_this3), footer && h("div", {
850
949
  "class": "k-list-footer"
851
950
  }, [footer])])
852
951
  );
@@ -250,4 +250,16 @@ export interface ComboBoxProps extends FormComponentProps {
250
250
  * @default `solid`
251
251
  */
252
252
  fillMode?: null | 'solid' | 'outline' | 'flat' | string;
253
+ /**
254
+ * Sets the data item field that represents the start of a group. Applicable to objects data.
255
+ */
256
+ groupField?: string;
257
+ /**
258
+ * Fires when a ComboBox group header item is about to be rendered. Used to override the default appearance of the group's headers.
259
+ */
260
+ groupHeaderItemRender?: any;
261
+ /**
262
+ * Fires when a ComboBox sticky group header item is about to be rendered. Used to override the default appearance of the sticky group header of the component.
263
+ */
264
+ groupStickyHeaderItemRender?: any;
253
265
  }