@progress/kendo-angular-grid 6.1.0-dev.202202251406 → 6.1.0

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.
@@ -39,7 +39,7 @@ export { GroupFooterItem } from './data/group-footer-item.interface';
39
39
  export { GridItem } from './data/grid-item.interface';
40
40
  export { ScrollMode } from './scrolling/scrollmode';
41
41
  export { SelectionEvent } from './selection/types';
42
- export { ColumnSortSettings, SortSettings } from './columns/sort-settings';
42
+ export { ColumnSortSettings, SingleSortSettings, MultipleSortSettings, SortSettings, ModifierKey } from './columns/sort-settings';
43
43
  export { ResizableContainerDirective } from './layout/resizable.directive';
44
44
  export { TemplateContextDirective } from './rendering/common/template-context.directive';
45
45
  export { GroupableSettings } from './grouping/group-settings';
@@ -9,7 +9,7 @@ export const packageMetadata = {
9
9
  name: '@progress/kendo-angular-grid',
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
12
- publishDate: 1645797443,
12
+ publishDate: 1646131378,
13
13
  version: '',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
15
15
  };
@@ -66,7 +66,7 @@ export declare class HeaderComponent implements AfterViewInit, OnInit, OnChanges
66
66
  private targetSubscription;
67
67
  private _leafColumns;
68
68
  constructor(popupService: SinglePopupService, hint: DragHintService, cue: DropCueService, reorderService: ColumnReorderService, idService: IdService, sortService: SortService, localization: LocalizationService, columnInfoService: ColumnInfoService, cd: ChangeDetectorRef);
69
- sortColumn(column: ColumnComponent): void;
69
+ sortColumn(descriptor: SortDescriptor[]): void;
70
70
  onSortClick(column: ColumnComponent, event: MouseEvent, link: Element): void;
71
71
  onHeaderKeydown(column: ColumnComponent, args: KeyboardEvent): void;
72
72
  showSortNumbering(column: ColumnComponent): boolean;
@@ -74,7 +74,19 @@ export declare class HeaderComponent implements AfterViewInit, OnInit, OnChanges
74
74
  sortIcon(field: string): any;
75
75
  sortState(column: ColumnComponent): string;
76
76
  sortStatus(column: ColumnComponent): string;
77
- toggleSort(column: ColumnComponent): Array<SortDescriptor>;
77
+ /**
78
+ *
79
+ * @param column
80
+ * @param modifier - Indicates whether the client-defined `multiSortKey` modifier is met. Defaults to `true`.
81
+ * @returns - SortDescriptor[]
82
+ */
83
+ toggleSort(column: ColumnComponent, modifier?: boolean): Array<SortDescriptor>;
84
+ /**
85
+ *
86
+ * Determines whether the modifier key (if any) passed
87
+ * with a click/keyboard event matches the user-defined multiSortKey.
88
+ */
89
+ matchModifier(event: MouseEvent | KeyboardEvent): boolean;
78
90
  ngAfterViewInit(): void;
79
91
  ngDoCheck(): void;
80
92
  ngOnChanges(changes: any): void;
@@ -60,6 +60,7 @@ const lockable = ({ draggable, target }) => draggable.context.column.lockable !=
60
60
  draggable.context.column.isLocked === target.context.column.isLocked;
61
61
  const ɵ10 = lockable;
62
62
  const rules = and(ofColumnType, reorderable, notInSpanColumn, notSameElement, sameParent, not(lastNonLocked), lockable);
63
+ const modifierKeys = ['alt', 'ctrl', 'shift', 'meta'];
63
64
  /**
64
65
  * @hidden
65
66
  */
@@ -98,8 +99,8 @@ let HeaderComponent = class HeaderComponent {
98
99
  get unlockedColumnsCount() {
99
100
  return this.totalColumnsCount - this.lockedColumnsCount - this.columns.length;
100
101
  }
101
- sortColumn(column) {
102
- this.sortService.sort(this.toggleSort(column));
102
+ sortColumn(descriptor) {
103
+ this.sortService.sort(descriptor);
103
104
  }
104
105
  onSortClick(column, event, link) {
105
106
  const target = event.target;
@@ -110,7 +111,9 @@ let HeaderComponent = class HeaderComponent {
110
111
  return;
111
112
  }
112
113
  }
113
- this.sortColumn(column);
114
+ const modifier = this.matchModifier(event);
115
+ const toggledColumn = this.toggleSort(column, modifier);
116
+ this.sortColumn(toggledColumn);
114
117
  }
115
118
  onHeaderKeydown(column, args) {
116
119
  if (args.keyCode === Keys.ArrowDown && args.altKey && this.showFilterMenu) {
@@ -129,7 +132,8 @@ let HeaderComponent = class HeaderComponent {
129
132
  return;
130
133
  }
131
134
  if (args.keyCode === Keys.Enter && isPresent(column.field)) {
132
- this.sortService.sort(this.toggleSort(column));
135
+ const modifier = this.matchModifier(args);
136
+ this.sortService.sort(this.toggleSort(column, modifier));
133
137
  }
134
138
  }
135
139
  showSortNumbering(column) {
@@ -179,14 +183,34 @@ let HeaderComponent = class HeaderComponent {
179
183
  }
180
184
  return this.localization.get(msg);
181
185
  }
182
- toggleSort(column) {
186
+ /**
187
+ *
188
+ * @param column
189
+ * @param modifier - Indicates whether the client-defined `multiSortKey` modifier is met. Defaults to `true`.
190
+ * @returns - SortDescriptor[]
191
+ */
192
+ toggleSort(column, modifier = true) {
183
193
  const { allowUnsort, mode, initialDirection } = normalize(this.sortable, column.sortable);
184
194
  const descriptor = this.toggleDirection(column.field, allowUnsort, initialDirection);
185
- if (mode === 'single') {
195
+ if (mode === 'single' || !modifier) {
186
196
  return [descriptor];
187
197
  }
188
198
  return [...this.sort.filter(desc => desc.field !== column.field), descriptor];
189
199
  }
200
+ /**
201
+ *
202
+ * Determines whether the modifier key (if any) passed
203
+ * with a click/keyboard event matches the user-defined multiSortKey.
204
+ */
205
+ matchModifier(event) {
206
+ const { multiSortKey } = normalize(this.sortable);
207
+ if (multiSortKey === 'none') {
208
+ return modifierKeys.every(key => !event[`${key}Key`]);
209
+ }
210
+ return multiSortKey === 'ctrl'
211
+ ? event.ctrlKey || event.metaKey
212
+ : event[`${multiSortKey}Key`];
213
+ }
190
214
  ngAfterViewInit() {
191
215
  this.subscription.add(observe(this.dropTargets)
192
216
  .subscribe(this.attachTargets.bind(this)));
@@ -708,7 +708,7 @@ ListComponent = tslib_1.__decorate([
708
708
  selector: 'kendo-grid-list',
709
709
  template: `
710
710
  <div #lockedContainer class="k-grid-content-locked" role="presentation"
711
- *ngIf="isLocked" [style.width.px]="lockedWidth"
711
+ *ngIf="isLocked" [style.width.px]="lockedWidth" tabindex="-1"
712
712
  [kendoEventsOutsideAngular]="{
713
713
  keydown: lockedKeydown,
714
714
  scroll: lockedScroll,
@@ -2831,7 +2831,7 @@ const packageMetadata = {
2831
2831
  name: '@progress/kendo-angular-grid',
2832
2832
  productName: 'Kendo UI for Angular',
2833
2833
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
2834
- publishDate: 1645797443,
2834
+ publishDate: 1646131378,
2835
2835
  version: '',
2836
2836
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
2837
2837
  };
@@ -10167,7 +10167,7 @@ ListComponent = __decorate([
10167
10167
  selector: 'kendo-grid-list',
10168
10168
  template: `
10169
10169
  <div #lockedContainer class="k-grid-content-locked" role="presentation"
10170
- *ngIf="isLocked" [style.width.px]="lockedWidth"
10170
+ *ngIf="isLocked" [style.width.px]="lockedWidth" tabindex="-1"
10171
10171
  [kendoEventsOutsideAngular]="{
10172
10172
  keydown: lockedKeydown,
10173
10173
  scroll: lockedScroll,
@@ -16055,7 +16055,8 @@ const DEFAULTS = {
16055
16055
  allowUnsort: true,
16056
16056
  mode: 'single',
16057
16057
  showIndexes: true,
16058
- initialDirection: 'asc'
16058
+ initialDirection: 'asc',
16059
+ multiSortKey: 'none'
16059
16060
  };
16060
16061
  /**
16061
16062
  * @hidden
@@ -16505,6 +16506,7 @@ const reorderable = ({ draggable }) => draggable.context.column.reorderable;
16505
16506
  const lockable = ({ draggable, target }) => draggable.context.column.lockable !== false ||
16506
16507
  draggable.context.column.isLocked === target.context.column.isLocked;
16507
16508
  const rules = and(ofColumnType, reorderable, notInSpanColumn, notSameElement, sameParent, not(lastNonLocked), lockable);
16509
+ const modifierKeys = ['alt', 'ctrl', 'shift', 'meta'];
16508
16510
  /**
16509
16511
  * @hidden
16510
16512
  */
@@ -16543,8 +16545,8 @@ let HeaderComponent = class HeaderComponent {
16543
16545
  get unlockedColumnsCount() {
16544
16546
  return this.totalColumnsCount - this.lockedColumnsCount - this.columns.length;
16545
16547
  }
16546
- sortColumn(column) {
16547
- this.sortService.sort(this.toggleSort(column));
16548
+ sortColumn(descriptor) {
16549
+ this.sortService.sort(descriptor);
16548
16550
  }
16549
16551
  onSortClick(column, event, link) {
16550
16552
  const target = event.target;
@@ -16555,7 +16557,9 @@ let HeaderComponent = class HeaderComponent {
16555
16557
  return;
16556
16558
  }
16557
16559
  }
16558
- this.sortColumn(column);
16560
+ const modifier = this.matchModifier(event);
16561
+ const toggledColumn = this.toggleSort(column, modifier);
16562
+ this.sortColumn(toggledColumn);
16559
16563
  }
16560
16564
  onHeaderKeydown(column, args) {
16561
16565
  if (args.keyCode === Keys.ArrowDown && args.altKey && this.showFilterMenu) {
@@ -16574,7 +16578,8 @@ let HeaderComponent = class HeaderComponent {
16574
16578
  return;
16575
16579
  }
16576
16580
  if (args.keyCode === Keys.Enter && isPresent(column.field)) {
16577
- this.sortService.sort(this.toggleSort(column));
16581
+ const modifier = this.matchModifier(args);
16582
+ this.sortService.sort(this.toggleSort(column, modifier));
16578
16583
  }
16579
16584
  }
16580
16585
  showSortNumbering(column) {
@@ -16624,14 +16629,34 @@ let HeaderComponent = class HeaderComponent {
16624
16629
  }
16625
16630
  return this.localization.get(msg);
16626
16631
  }
16627
- toggleSort(column) {
16632
+ /**
16633
+ *
16634
+ * @param column
16635
+ * @param modifier - Indicates whether the client-defined `multiSortKey` modifier is met. Defaults to `true`.
16636
+ * @returns - SortDescriptor[]
16637
+ */
16638
+ toggleSort(column, modifier = true) {
16628
16639
  const { allowUnsort, mode, initialDirection } = normalize$1(this.sortable, column.sortable);
16629
16640
  const descriptor = this.toggleDirection(column.field, allowUnsort, initialDirection);
16630
- if (mode === 'single') {
16641
+ if (mode === 'single' || !modifier) {
16631
16642
  return [descriptor];
16632
16643
  }
16633
16644
  return [...this.sort.filter(desc => desc.field !== column.field), descriptor];
16634
16645
  }
16646
+ /**
16647
+ *
16648
+ * Determines whether the modifier key (if any) passed
16649
+ * with a click/keyboard event matches the user-defined multiSortKey.
16650
+ */
16651
+ matchModifier(event) {
16652
+ const { multiSortKey } = normalize$1(this.sortable);
16653
+ if (multiSortKey === 'none') {
16654
+ return modifierKeys.every(key => !event[`${key}Key`]);
16655
+ }
16656
+ return multiSortKey === 'ctrl'
16657
+ ? event.ctrlKey || event.metaKey
16658
+ : event[`${multiSortKey}Key`];
16659
+ }
16635
16660
  ngAfterViewInit() {
16636
16661
  this.subscription.add(observe(this.dropTargets)
16637
16662
  .subscribe(this.attachTargets.bind(this)));
@@ -3044,7 +3044,7 @@ var packageMetadata = {
3044
3044
  name: '@progress/kendo-angular-grid',
3045
3045
  productName: 'Kendo UI for Angular',
3046
3046
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
3047
- publishDate: 1645797443,
3047
+ publishDate: 1646131378,
3048
3048
  version: '',
3049
3049
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
3050
3050
  };
@@ -10609,7 +10609,7 @@ var ListComponent = /** @class */ (function () {
10609
10609
  }
10610
10610
  ],
10611
10611
  selector: 'kendo-grid-list',
10612
- template: "\n <div #lockedContainer class=\"k-grid-content-locked\" role=\"presentation\"\n *ngIf=\"isLocked\" [style.width.px]=\"lockedWidth\"\n [kendoEventsOutsideAngular]=\"{\n keydown: lockedKeydown,\n scroll: lockedScroll,\n mousewheel: lockedMousewheel,\n DOMMouseScroll: lockedMousewheel\n }\"\n [scope]=\"this\"\n >\n <div role=\"presentation\" class=\"k-grid-table-wrap\">\n <table [locked]=\"true\" #lockedTable class=\"k-grid-table\" role=\"presentation\" [style.width.px]=\"lockedWidth\">\n <colgroup kendoGridColGroup\n role=\"presentation\"\n [groups]=\"groups\"\n [columns]=\"lockedLeafColumns\"\n [detailTemplate]=\"detailTemplate\">\n </colgroup>\n <tbody kendoGridTableBody\n role=\"presentation\"\n [groups]=\"groups\"\n [isLocked]=\"true\"\n [data]=\"data\"\n [noRecordsText]=\"''\"\n [columns]=\"lockedLeafColumns\"\n [totalColumnsCount]=\"leafColumns.length\"\n [detailTemplate]=\"detailTemplate\"\n [showGroupFooters]=\"showFooter\"\n [skip]=\"skip\"\n [selectable]=\"selectable\"\n [trackBy]=\"trackBy\"\n [filterable]=\"filterable\"\n [rowClass]=\"rowClass\"\n [isLoading]=\"loading\"\n [isVirtual]=\"isVirtual\"\n [cellLoadingTemplate]=\"cellLoadingTemplate\">\n </tbody>\n </table>\n <kendo-resize-sensor></kendo-resize-sensor>\n </div>\n <div class=\"k-height-container\" role=\"presentation\">\n <div [style.height.px]=\"totalHeight\"></div>\n </div>\n </div><div #container\n class=\"k-grid-content k-virtual-content\"\n role=\"presentation\" tabindex=\"-1\"\n [kendoGridResizableContainer]=\"lockedLeafColumns.length\"\n [lockedWidth]=\"lockedWidth + 1\">\n <div role=\"presentation\" class=\"k-grid-table-wrap\">\n <table [style.width.px]=\"nonLockedWidth\" #table [virtualColumns]=\"virtualColumns\"\n class=\"k-grid-table\" role=\"presentation\">\n <colgroup kendoGridColGroup\n role=\"presentation\"\n [groups]=\"isLocked ? [] : groups\"\n [columns]=\"nonLockedColumnsToRender\"\n [detailTemplate]=\"detailTemplate\">\n </colgroup>\n <tbody kendoGridTableBody\n role=\"presentation\"\n [skipGroupDecoration]=\"isLocked\"\n [data]=\"data\"\n [groups]=\"groups\"\n [showGroupFooters]=\"showFooter\"\n [columns]=\"nonLockedColumnsToRender\"\n [allColumns]=\"nonLockedLeafColumns\"\n [detailTemplate]=\"detailTemplate\"\n [noRecordsTemplate]=\"noRecordsTemplate\"\n [lockedColumnsCount]=\"lockedLeafColumns.length\"\n [totalColumnsCount]=\"leafColumns.length\"\n [skip]=\"skip\"\n [selectable]=\"selectable\"\n [trackBy]=\"trackBy\"\n [filterable]=\"filterable\"\n [rowClass]=\"rowClass\"\n [rowSticky]=\"rowSticky\"\n [virtualColumns]=\"virtualColumns\"\n [isLoading]=\"loading\"\n [isVirtual]=\"isVirtual\"\n [cellLoadingTemplate]=\"cellLoadingTemplate\">\n </tbody>\n </table>\n <kendo-resize-sensor *ngIf=\"isLocked\"></kendo-resize-sensor>\n </div>\n <kendo-resize-sensor *ngIf=\"isLocked || virtualColumns\"></kendo-resize-sensor>\n <div class=\"k-height-container\" role=\"presentation\">\n <div [style.height.px]=\"totalHeight\"></div>\n </div>\n <div *ngIf=\"virtualColumns\" class=\"k-width-container\" role=\"presentation\">\n <div [style.width.px]=\"totalWidth\"></div>\n </div>\n </div>\n <div [loadingTemplate]=\"loadingTemplate\" *ngIf=\"loading\" kendoGridLoading>\n </div>\n "
10612
+ template: "\n <div #lockedContainer class=\"k-grid-content-locked\" role=\"presentation\"\n *ngIf=\"isLocked\" [style.width.px]=\"lockedWidth\" tabindex=\"-1\"\n [kendoEventsOutsideAngular]=\"{\n keydown: lockedKeydown,\n scroll: lockedScroll,\n mousewheel: lockedMousewheel,\n DOMMouseScroll: lockedMousewheel\n }\"\n [scope]=\"this\"\n >\n <div role=\"presentation\" class=\"k-grid-table-wrap\">\n <table [locked]=\"true\" #lockedTable class=\"k-grid-table\" role=\"presentation\" [style.width.px]=\"lockedWidth\">\n <colgroup kendoGridColGroup\n role=\"presentation\"\n [groups]=\"groups\"\n [columns]=\"lockedLeafColumns\"\n [detailTemplate]=\"detailTemplate\">\n </colgroup>\n <tbody kendoGridTableBody\n role=\"presentation\"\n [groups]=\"groups\"\n [isLocked]=\"true\"\n [data]=\"data\"\n [noRecordsText]=\"''\"\n [columns]=\"lockedLeafColumns\"\n [totalColumnsCount]=\"leafColumns.length\"\n [detailTemplate]=\"detailTemplate\"\n [showGroupFooters]=\"showFooter\"\n [skip]=\"skip\"\n [selectable]=\"selectable\"\n [trackBy]=\"trackBy\"\n [filterable]=\"filterable\"\n [rowClass]=\"rowClass\"\n [isLoading]=\"loading\"\n [isVirtual]=\"isVirtual\"\n [cellLoadingTemplate]=\"cellLoadingTemplate\">\n </tbody>\n </table>\n <kendo-resize-sensor></kendo-resize-sensor>\n </div>\n <div class=\"k-height-container\" role=\"presentation\">\n <div [style.height.px]=\"totalHeight\"></div>\n </div>\n </div><div #container\n class=\"k-grid-content k-virtual-content\"\n role=\"presentation\" tabindex=\"-1\"\n [kendoGridResizableContainer]=\"lockedLeafColumns.length\"\n [lockedWidth]=\"lockedWidth + 1\">\n <div role=\"presentation\" class=\"k-grid-table-wrap\">\n <table [style.width.px]=\"nonLockedWidth\" #table [virtualColumns]=\"virtualColumns\"\n class=\"k-grid-table\" role=\"presentation\">\n <colgroup kendoGridColGroup\n role=\"presentation\"\n [groups]=\"isLocked ? [] : groups\"\n [columns]=\"nonLockedColumnsToRender\"\n [detailTemplate]=\"detailTemplate\">\n </colgroup>\n <tbody kendoGridTableBody\n role=\"presentation\"\n [skipGroupDecoration]=\"isLocked\"\n [data]=\"data\"\n [groups]=\"groups\"\n [showGroupFooters]=\"showFooter\"\n [columns]=\"nonLockedColumnsToRender\"\n [allColumns]=\"nonLockedLeafColumns\"\n [detailTemplate]=\"detailTemplate\"\n [noRecordsTemplate]=\"noRecordsTemplate\"\n [lockedColumnsCount]=\"lockedLeafColumns.length\"\n [totalColumnsCount]=\"leafColumns.length\"\n [skip]=\"skip\"\n [selectable]=\"selectable\"\n [trackBy]=\"trackBy\"\n [filterable]=\"filterable\"\n [rowClass]=\"rowClass\"\n [rowSticky]=\"rowSticky\"\n [virtualColumns]=\"virtualColumns\"\n [isLoading]=\"loading\"\n [isVirtual]=\"isVirtual\"\n [cellLoadingTemplate]=\"cellLoadingTemplate\">\n </tbody>\n </table>\n <kendo-resize-sensor *ngIf=\"isLocked\"></kendo-resize-sensor>\n </div>\n <kendo-resize-sensor *ngIf=\"isLocked || virtualColumns\"></kendo-resize-sensor>\n <div class=\"k-height-container\" role=\"presentation\">\n <div [style.height.px]=\"totalHeight\"></div>\n </div>\n <div *ngIf=\"virtualColumns\" class=\"k-width-container\" role=\"presentation\">\n <div [style.width.px]=\"totalWidth\"></div>\n </div>\n </div>\n <div [loadingTemplate]=\"loadingTemplate\" *ngIf=\"loading\" kendoGridLoading>\n </div>\n "
10613
10613
  }),
10614
10614
  __param(0, Inject(SCROLLER_FACTORY_TOKEN)),
10615
10615
  __metadata("design:paramtypes", [Object, DetailsService,
@@ -16571,7 +16571,8 @@ var DEFAULTS = {
16571
16571
  allowUnsort: true,
16572
16572
  mode: 'single',
16573
16573
  showIndexes: true,
16574
- initialDirection: 'asc'
16574
+ initialDirection: 'asc',
16575
+ multiSortKey: 'none'
16575
16576
  };
16576
16577
  /**
16577
16578
  * @hidden
@@ -17037,6 +17038,7 @@ var lockable = function (_a) {
17037
17038
  draggable.context.column.isLocked === target.context.column.isLocked;
17038
17039
  };
17039
17040
  var rules = and(ofColumnType, reorderable, notInSpanColumn, notSameElement, sameParent, not(lastNonLocked), lockable);
17041
+ var modifierKeys = ['alt', 'ctrl', 'shift', 'meta'];
17040
17042
  /**
17041
17043
  * @hidden
17042
17044
  */
@@ -17087,8 +17089,8 @@ var HeaderComponent = /** @class */ (function () {
17087
17089
  enumerable: true,
17088
17090
  configurable: true
17089
17091
  });
17090
- HeaderComponent.prototype.sortColumn = function (column) {
17091
- this.sortService.sort(this.toggleSort(column));
17092
+ HeaderComponent.prototype.sortColumn = function (descriptor) {
17093
+ this.sortService.sort(descriptor);
17092
17094
  };
17093
17095
  HeaderComponent.prototype.onSortClick = function (column, event, link) {
17094
17096
  var target = event.target;
@@ -17099,7 +17101,9 @@ var HeaderComponent = /** @class */ (function () {
17099
17101
  return;
17100
17102
  }
17101
17103
  }
17102
- this.sortColumn(column);
17104
+ var modifier = this.matchModifier(event);
17105
+ var toggledColumn = this.toggleSort(column, modifier);
17106
+ this.sortColumn(toggledColumn);
17103
17107
  };
17104
17108
  HeaderComponent.prototype.onHeaderKeydown = function (column, args) {
17105
17109
  if (args.keyCode === Keys.ArrowDown && args.altKey && this.showFilterMenu) {
@@ -17118,7 +17122,8 @@ var HeaderComponent = /** @class */ (function () {
17118
17122
  return;
17119
17123
  }
17120
17124
  if (args.keyCode === Keys.Enter && isPresent(column.field)) {
17121
- this.sortService.sort(this.toggleSort(column));
17125
+ var modifier = this.matchModifier(args);
17126
+ this.sortService.sort(this.toggleSort(column, modifier));
17122
17127
  }
17123
17128
  };
17124
17129
  HeaderComponent.prototype.showSortNumbering = function (column) {
@@ -17174,14 +17179,35 @@ var HeaderComponent = /** @class */ (function () {
17174
17179
  }
17175
17180
  return this.localization.get(msg);
17176
17181
  };
17177
- HeaderComponent.prototype.toggleSort = function (column) {
17182
+ /**
17183
+ *
17184
+ * @param column
17185
+ * @param modifier - Indicates whether the client-defined `multiSortKey` modifier is met. Defaults to `true`.
17186
+ * @returns - SortDescriptor[]
17187
+ */
17188
+ HeaderComponent.prototype.toggleSort = function (column, modifier) {
17189
+ if (modifier === void 0) { modifier = true; }
17178
17190
  var _a = normalize$1(this.sortable, column.sortable), allowUnsort = _a.allowUnsort, mode = _a.mode, initialDirection = _a.initialDirection;
17179
17191
  var descriptor = this.toggleDirection(column.field, allowUnsort, initialDirection);
17180
- if (mode === 'single') {
17192
+ if (mode === 'single' || !modifier) {
17181
17193
  return [descriptor];
17182
17194
  }
17183
17195
  return this.sort.filter(function (desc) { return desc.field !== column.field; }).concat([descriptor]);
17184
17196
  };
17197
+ /**
17198
+ *
17199
+ * Determines whether the modifier key (if any) passed
17200
+ * with a click/keyboard event matches the user-defined multiSortKey.
17201
+ */
17202
+ HeaderComponent.prototype.matchModifier = function (event) {
17203
+ var multiSortKey = normalize$1(this.sortable).multiSortKey;
17204
+ if (multiSortKey === 'none') {
17205
+ return modifierKeys.every(function (key) { return !event[key + "Key"]; });
17206
+ }
17207
+ return multiSortKey === 'ctrl'
17208
+ ? event.ctrlKey || event.metaKey
17209
+ : event[multiSortKey + "Key"];
17210
+ };
17185
17211
  HeaderComponent.prototype.ngAfterViewInit = function () {
17186
17212
  this.subscription.add(observe(this.dropTargets)
17187
17213
  .subscribe(this.attachTargets.bind(this)));
@@ -11,7 +11,8 @@ var DEFAULTS = {
11
11
  allowUnsort: true,
12
12
  mode: 'single',
13
13
  showIndexes: true,
14
- initialDirection: 'asc'
14
+ initialDirection: 'asc',
15
+ multiSortKey: 'none'
15
16
  };
16
17
  /**
17
18
  * @hidden
@@ -11,7 +11,7 @@ exports.packageMetadata = {
11
11
  name: '@progress/kendo-angular-grid',
12
12
  productName: 'Kendo UI for Angular',
13
13
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
14
- publishDate: 1645797443,
14
+ publishDate: 1646131378,
15
15
  version: '',
16
16
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
17
17
  };
@@ -103,6 +103,7 @@ var lockable = function (_a) {
103
103
  var ɵ10 = lockable;
104
104
  exports.ɵ10 = ɵ10;
105
105
  var rules = utils_1.and(ofColumnType, reorderable, notInSpanColumn, notSameElement, sameParent, utils_1.not(lastNonLocked), lockable);
106
+ var modifierKeys = ['alt', 'ctrl', 'shift', 'meta'];
106
107
  /**
107
108
  * @hidden
108
109
  */
@@ -153,8 +154,8 @@ var HeaderComponent = /** @class */ (function () {
153
154
  enumerable: true,
154
155
  configurable: true
155
156
  });
156
- HeaderComponent.prototype.sortColumn = function (column) {
157
- this.sortService.sort(this.toggleSort(column));
157
+ HeaderComponent.prototype.sortColumn = function (descriptor) {
158
+ this.sortService.sort(descriptor);
158
159
  };
159
160
  HeaderComponent.prototype.onSortClick = function (column, event, link) {
160
161
  var target = event.target;
@@ -165,7 +166,9 @@ var HeaderComponent = /** @class */ (function () {
165
166
  return;
166
167
  }
167
168
  }
168
- this.sortColumn(column);
169
+ var modifier = this.matchModifier(event);
170
+ var toggledColumn = this.toggleSort(column, modifier);
171
+ this.sortColumn(toggledColumn);
169
172
  };
170
173
  HeaderComponent.prototype.onHeaderKeydown = function (column, args) {
171
174
  if (args.keyCode === kendo_angular_common_1.Keys.ArrowDown && args.altKey && this.showFilterMenu) {
@@ -184,7 +187,8 @@ var HeaderComponent = /** @class */ (function () {
184
187
  return;
185
188
  }
186
189
  if (args.keyCode === kendo_angular_common_1.Keys.Enter && utils_1.isPresent(column.field)) {
187
- this.sortService.sort(this.toggleSort(column));
190
+ var modifier = this.matchModifier(args);
191
+ this.sortService.sort(this.toggleSort(column, modifier));
188
192
  }
189
193
  };
190
194
  HeaderComponent.prototype.showSortNumbering = function (column) {
@@ -240,14 +244,35 @@ var HeaderComponent = /** @class */ (function () {
240
244
  }
241
245
  return this.localization.get(msg);
242
246
  };
243
- HeaderComponent.prototype.toggleSort = function (column) {
247
+ /**
248
+ *
249
+ * @param column
250
+ * @param modifier - Indicates whether the client-defined `multiSortKey` modifier is met. Defaults to `true`.
251
+ * @returns - SortDescriptor[]
252
+ */
253
+ HeaderComponent.prototype.toggleSort = function (column, modifier) {
254
+ if (modifier === void 0) { modifier = true; }
244
255
  var _a = sort_settings_1.normalize(this.sortable, column.sortable), allowUnsort = _a.allowUnsort, mode = _a.mode, initialDirection = _a.initialDirection;
245
256
  var descriptor = this.toggleDirection(column.field, allowUnsort, initialDirection);
246
- if (mode === 'single') {
257
+ if (mode === 'single' || !modifier) {
247
258
  return [descriptor];
248
259
  }
249
260
  return this.sort.filter(function (desc) { return desc.field !== column.field; }).concat([descriptor]);
250
261
  };
262
+ /**
263
+ *
264
+ * Determines whether the modifier key (if any) passed
265
+ * with a click/keyboard event matches the user-defined multiSortKey.
266
+ */
267
+ HeaderComponent.prototype.matchModifier = function (event) {
268
+ var multiSortKey = sort_settings_1.normalize(this.sortable).multiSortKey;
269
+ if (multiSortKey === 'none') {
270
+ return modifierKeys.every(function (key) { return !event[key + "Key"]; });
271
+ }
272
+ return multiSortKey === 'ctrl'
273
+ ? event.ctrlKey || event.metaKey
274
+ : event[multiSortKey + "Key"];
275
+ };
251
276
  HeaderComponent.prototype.ngAfterViewInit = function () {
252
277
  this.subscription.add(utils_1.observe(this.dropTargets)
253
278
  .subscribe(this.attachTargets.bind(this)));
@@ -784,7 +784,7 @@ var ListComponent = /** @class */ (function () {
784
784
  }
785
785
  ],
786
786
  selector: 'kendo-grid-list',
787
- template: "\n <div #lockedContainer class=\"k-grid-content-locked\" role=\"presentation\"\n *ngIf=\"isLocked\" [style.width.px]=\"lockedWidth\"\n [kendoEventsOutsideAngular]=\"{\n keydown: lockedKeydown,\n scroll: lockedScroll,\n mousewheel: lockedMousewheel,\n DOMMouseScroll: lockedMousewheel\n }\"\n [scope]=\"this\"\n >\n <div role=\"presentation\" class=\"k-grid-table-wrap\">\n <table [locked]=\"true\" #lockedTable class=\"k-grid-table\" role=\"presentation\" [style.width.px]=\"lockedWidth\">\n <colgroup kendoGridColGroup\n role=\"presentation\"\n [groups]=\"groups\"\n [columns]=\"lockedLeafColumns\"\n [detailTemplate]=\"detailTemplate\">\n </colgroup>\n <tbody kendoGridTableBody\n role=\"presentation\"\n [groups]=\"groups\"\n [isLocked]=\"true\"\n [data]=\"data\"\n [noRecordsText]=\"''\"\n [columns]=\"lockedLeafColumns\"\n [totalColumnsCount]=\"leafColumns.length\"\n [detailTemplate]=\"detailTemplate\"\n [showGroupFooters]=\"showFooter\"\n [skip]=\"skip\"\n [selectable]=\"selectable\"\n [trackBy]=\"trackBy\"\n [filterable]=\"filterable\"\n [rowClass]=\"rowClass\"\n [isLoading]=\"loading\"\n [isVirtual]=\"isVirtual\"\n [cellLoadingTemplate]=\"cellLoadingTemplate\">\n </tbody>\n </table>\n <kendo-resize-sensor></kendo-resize-sensor>\n </div>\n <div class=\"k-height-container\" role=\"presentation\">\n <div [style.height.px]=\"totalHeight\"></div>\n </div>\n </div><div #container\n class=\"k-grid-content k-virtual-content\"\n role=\"presentation\" tabindex=\"-1\"\n [kendoGridResizableContainer]=\"lockedLeafColumns.length\"\n [lockedWidth]=\"lockedWidth + 1\">\n <div role=\"presentation\" class=\"k-grid-table-wrap\">\n <table [style.width.px]=\"nonLockedWidth\" #table [virtualColumns]=\"virtualColumns\"\n class=\"k-grid-table\" role=\"presentation\">\n <colgroup kendoGridColGroup\n role=\"presentation\"\n [groups]=\"isLocked ? [] : groups\"\n [columns]=\"nonLockedColumnsToRender\"\n [detailTemplate]=\"detailTemplate\">\n </colgroup>\n <tbody kendoGridTableBody\n role=\"presentation\"\n [skipGroupDecoration]=\"isLocked\"\n [data]=\"data\"\n [groups]=\"groups\"\n [showGroupFooters]=\"showFooter\"\n [columns]=\"nonLockedColumnsToRender\"\n [allColumns]=\"nonLockedLeafColumns\"\n [detailTemplate]=\"detailTemplate\"\n [noRecordsTemplate]=\"noRecordsTemplate\"\n [lockedColumnsCount]=\"lockedLeafColumns.length\"\n [totalColumnsCount]=\"leafColumns.length\"\n [skip]=\"skip\"\n [selectable]=\"selectable\"\n [trackBy]=\"trackBy\"\n [filterable]=\"filterable\"\n [rowClass]=\"rowClass\"\n [rowSticky]=\"rowSticky\"\n [virtualColumns]=\"virtualColumns\"\n [isLoading]=\"loading\"\n [isVirtual]=\"isVirtual\"\n [cellLoadingTemplate]=\"cellLoadingTemplate\">\n </tbody>\n </table>\n <kendo-resize-sensor *ngIf=\"isLocked\"></kendo-resize-sensor>\n </div>\n <kendo-resize-sensor *ngIf=\"isLocked || virtualColumns\"></kendo-resize-sensor>\n <div class=\"k-height-container\" role=\"presentation\">\n <div [style.height.px]=\"totalHeight\"></div>\n </div>\n <div *ngIf=\"virtualColumns\" class=\"k-width-container\" role=\"presentation\">\n <div [style.width.px]=\"totalWidth\"></div>\n </div>\n </div>\n <div [loadingTemplate]=\"loadingTemplate\" *ngIf=\"loading\" kendoGridLoading>\n </div>\n "
787
+ template: "\n <div #lockedContainer class=\"k-grid-content-locked\" role=\"presentation\"\n *ngIf=\"isLocked\" [style.width.px]=\"lockedWidth\" tabindex=\"-1\"\n [kendoEventsOutsideAngular]=\"{\n keydown: lockedKeydown,\n scroll: lockedScroll,\n mousewheel: lockedMousewheel,\n DOMMouseScroll: lockedMousewheel\n }\"\n [scope]=\"this\"\n >\n <div role=\"presentation\" class=\"k-grid-table-wrap\">\n <table [locked]=\"true\" #lockedTable class=\"k-grid-table\" role=\"presentation\" [style.width.px]=\"lockedWidth\">\n <colgroup kendoGridColGroup\n role=\"presentation\"\n [groups]=\"groups\"\n [columns]=\"lockedLeafColumns\"\n [detailTemplate]=\"detailTemplate\">\n </colgroup>\n <tbody kendoGridTableBody\n role=\"presentation\"\n [groups]=\"groups\"\n [isLocked]=\"true\"\n [data]=\"data\"\n [noRecordsText]=\"''\"\n [columns]=\"lockedLeafColumns\"\n [totalColumnsCount]=\"leafColumns.length\"\n [detailTemplate]=\"detailTemplate\"\n [showGroupFooters]=\"showFooter\"\n [skip]=\"skip\"\n [selectable]=\"selectable\"\n [trackBy]=\"trackBy\"\n [filterable]=\"filterable\"\n [rowClass]=\"rowClass\"\n [isLoading]=\"loading\"\n [isVirtual]=\"isVirtual\"\n [cellLoadingTemplate]=\"cellLoadingTemplate\">\n </tbody>\n </table>\n <kendo-resize-sensor></kendo-resize-sensor>\n </div>\n <div class=\"k-height-container\" role=\"presentation\">\n <div [style.height.px]=\"totalHeight\"></div>\n </div>\n </div><div #container\n class=\"k-grid-content k-virtual-content\"\n role=\"presentation\" tabindex=\"-1\"\n [kendoGridResizableContainer]=\"lockedLeafColumns.length\"\n [lockedWidth]=\"lockedWidth + 1\">\n <div role=\"presentation\" class=\"k-grid-table-wrap\">\n <table [style.width.px]=\"nonLockedWidth\" #table [virtualColumns]=\"virtualColumns\"\n class=\"k-grid-table\" role=\"presentation\">\n <colgroup kendoGridColGroup\n role=\"presentation\"\n [groups]=\"isLocked ? [] : groups\"\n [columns]=\"nonLockedColumnsToRender\"\n [detailTemplate]=\"detailTemplate\">\n </colgroup>\n <tbody kendoGridTableBody\n role=\"presentation\"\n [skipGroupDecoration]=\"isLocked\"\n [data]=\"data\"\n [groups]=\"groups\"\n [showGroupFooters]=\"showFooter\"\n [columns]=\"nonLockedColumnsToRender\"\n [allColumns]=\"nonLockedLeafColumns\"\n [detailTemplate]=\"detailTemplate\"\n [noRecordsTemplate]=\"noRecordsTemplate\"\n [lockedColumnsCount]=\"lockedLeafColumns.length\"\n [totalColumnsCount]=\"leafColumns.length\"\n [skip]=\"skip\"\n [selectable]=\"selectable\"\n [trackBy]=\"trackBy\"\n [filterable]=\"filterable\"\n [rowClass]=\"rowClass\"\n [rowSticky]=\"rowSticky\"\n [virtualColumns]=\"virtualColumns\"\n [isLoading]=\"loading\"\n [isVirtual]=\"isVirtual\"\n [cellLoadingTemplate]=\"cellLoadingTemplate\">\n </tbody>\n </table>\n <kendo-resize-sensor *ngIf=\"isLocked\"></kendo-resize-sensor>\n </div>\n <kendo-resize-sensor *ngIf=\"isLocked || virtualColumns\"></kendo-resize-sensor>\n <div class=\"k-height-container\" role=\"presentation\">\n <div [style.height.px]=\"totalHeight\"></div>\n </div>\n <div *ngIf=\"virtualColumns\" class=\"k-width-container\" role=\"presentation\">\n <div [style.width.px]=\"totalWidth\"></div>\n </div>\n </div>\n <div [loadingTemplate]=\"loadingTemplate\" *ngIf=\"loading\" kendoGridLoading>\n </div>\n "
788
788
  }),
789
789
  tslib_1.__param(0, core_1.Inject(exports.SCROLLER_FACTORY_TOKEN)),
790
790
  tslib_1.__metadata("design:paramtypes", [Object, details_service_1.DetailsService,