@progress/kendo-angular-grid 16.11.0-develop.1 → 16.11.0-develop.3

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.
@@ -6,6 +6,8 @@ import { TemplateRef } from '@angular/core';
6
6
  import { ColumnBase } from './column-base';
7
7
  import { CellTemplateDirective } from '../rendering/cell-template.directive';
8
8
  import { IdService } from '../common/id.service';
9
+ import { SelectionService } from '../selection/selection.service';
10
+ import { CellSelectionService } from '../selection/cell-selection.service';
9
11
  import * as i0 from "@angular/core";
10
12
  /**
11
13
  * Represents the checkbox column for selecting rows in the Grid. [See example](slug:grid_row_selection#toc-select-all-checkbox).
@@ -19,15 +21,25 @@ import * as i0 from "@angular/core";
19
21
  * ```
20
22
  */
21
23
  export declare class CheckboxColumnComponent extends ColumnBase {
24
+ private selectionService;
25
+ private cellSelectionService;
22
26
  parent?: ColumnBase;
23
27
  /**
24
28
  * Determines whether a select-all `kendoGridSelectAllCheckbox` checkbox will be displayed in the header.
25
29
  */
26
30
  showSelectAll: boolean;
31
+ /**
32
+ * Determines whether checkboxes will be rendered for rows which are marked as non-selectable. By default, such checkboxes are visible and disabled.
33
+ */
34
+ showDisabledCheckbox: boolean;
27
35
  readonly isCheckboxColumn: boolean;
28
36
  template: CellTemplateDirective;
29
- constructor(parent?: ColumnBase, idService?: IdService);
37
+ constructor(selectionService: SelectionService, cellSelectionService: CellSelectionService, parent?: ColumnBase, idService?: IdService);
30
38
  get templateRef(): TemplateRef<any>;
31
- static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxColumnComponent, [{ optional: true; host: true; skipSelf: true; }, { optional: true; }]>;
32
- static ɵcmp: i0.ɵɵComponentDeclaration<CheckboxColumnComponent, "kendo-grid-checkbox-column", never, { "showSelectAll": "showSelectAll"; }, {}, ["template"], never, true, never>;
39
+ /**
40
+ * @hidden
41
+ */
42
+ rowSelectable(rowIdx: number): boolean;
43
+ static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxColumnComponent, [null, null, { optional: true; host: true; skipSelf: true; }, { optional: true; }]>;
44
+ static ɵcmp: i0.ɵɵComponentDeclaration<CheckboxColumnComponent, "kendo-grid-checkbox-column", never, { "showSelectAll": "showSelectAll"; "showDisabledCheckbox": "showDisabledCheckbox"; }, {}, ["template"], never, true, never>;
33
45
  }
@@ -6,9 +6,13 @@ import { Component, forwardRef, ContentChild, SkipSelf, Host, Optional, Input }
6
6
  import { ColumnBase } from './column-base';
7
7
  import { CellTemplateDirective } from '../rendering/cell-template.directive';
8
8
  import { IdService } from '../common/id.service';
9
+ import { SelectionService } from '../selection/selection.service';
10
+ import { CellSelectionService } from '../selection/cell-selection.service';
9
11
  import * as i0 from "@angular/core";
10
- import * as i1 from "./column-base";
11
- import * as i2 from "../common/id.service";
12
+ import * as i1 from "../selection/selection.service";
13
+ import * as i2 from "../selection/cell-selection.service";
14
+ import * as i3 from "./column-base";
15
+ import * as i4 from "../common/id.service";
12
16
  /**
13
17
  * Represents the checkbox column for selecting rows in the Grid. [See example](slug:grid_row_selection#toc-select-all-checkbox).
14
18
  *
@@ -21,9 +25,15 @@ import * as i2 from "../common/id.service";
21
25
  * ```
22
26
  */
23
27
  export class CheckboxColumnComponent extends ColumnBase {
24
- constructor(parent, idService) {
28
+ constructor(selectionService, cellSelectionService, parent, idService) {
25
29
  super(parent, idService);
30
+ this.selectionService = selectionService;
31
+ this.cellSelectionService = cellSelectionService;
26
32
  this.parent = parent;
33
+ /**
34
+ * Determines whether checkboxes will be rendered for rows which are marked as non-selectable. By default, such checkboxes are visible and disabled.
35
+ */
36
+ this.showDisabledCheckbox = true;
27
37
  /*
28
38
  * @hidden
29
39
  */
@@ -32,9 +42,15 @@ export class CheckboxColumnComponent extends ColumnBase {
32
42
  get templateRef() {
33
43
  return this.template ? this.template.templateRef : undefined;
34
44
  }
45
+ /**
46
+ * @hidden
47
+ */
48
+ rowSelectable(rowIdx) {
49
+ return !this.selectionService.nonSelectableRows.has(rowIdx) && !this.cellSelectionService.nonSelectableRows.has(rowIdx);
50
+ }
35
51
  }
36
- CheckboxColumnComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CheckboxColumnComponent, deps: [{ token: i1.ColumnBase, host: true, optional: true, skipSelf: true }, { token: i2.IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
37
- CheckboxColumnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CheckboxColumnComponent, isStandalone: true, selector: "kendo-grid-checkbox-column", inputs: { showSelectAll: "showSelectAll" }, providers: [
52
+ CheckboxColumnComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CheckboxColumnComponent, deps: [{ token: i1.SelectionService }, { token: i2.CellSelectionService }, { token: i3.ColumnBase, host: true, optional: true, skipSelf: true }, { token: i4.IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
53
+ CheckboxColumnComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CheckboxColumnComponent, isStandalone: true, selector: "kendo-grid-checkbox-column", inputs: { showSelectAll: "showSelectAll", showDisabledCheckbox: "showDisabledCheckbox" }, providers: [
38
54
  {
39
55
  provide: ColumnBase,
40
56
  useExisting: forwardRef(() => CheckboxColumnComponent)
@@ -53,16 +69,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
53
69
  template: ``,
54
70
  standalone: true
55
71
  }]
56
- }], ctorParameters: function () { return [{ type: i1.ColumnBase, decorators: [{
72
+ }], ctorParameters: function () { return [{ type: i1.SelectionService }, { type: i2.CellSelectionService }, { type: i3.ColumnBase, decorators: [{
57
73
  type: SkipSelf
58
74
  }, {
59
75
  type: Host
60
76
  }, {
61
77
  type: Optional
62
- }] }, { type: i2.IdService, decorators: [{
78
+ }] }, { type: i4.IdService, decorators: [{
63
79
  type: Optional
64
80
  }] }]; }, propDecorators: { showSelectAll: [{
65
81
  type: Input
82
+ }], showDisabledCheckbox: [{
83
+ type: Input
66
84
  }], template: [{
67
85
  type: ContentChild,
68
86
  args: [CellTemplateDirective, { static: false }]
@@ -167,6 +167,7 @@ export class DataBindingDirective {
167
167
  }
168
168
  updateGridData() {
169
169
  this.grid.data = this.process(this.state);
170
+ this.grid.updateNavigationMetadata();
170
171
  this.dataChanged = false;
171
172
  }
172
173
  }
@@ -404,11 +404,16 @@ export class GridComponent {
404
404
  this._data = [];
405
405
  this.cachedWindowWidth = 0;
406
406
  this._rowSelected = null;
407
+ this._isRowSelectable = null;
407
408
  this._cellSelected = null;
408
409
  this._rowReorderable = false;
409
410
  this._navigable = [];
410
411
  this._size = 'medium';
411
412
  this._loading = false;
413
+ /**
414
+ * @hidden
415
+ */
416
+ this.blockArrowSelection = false;
412
417
  this.rtl = false;
413
418
  this._rowClass = () => null;
414
419
  const isValid = validatePackage(packageMetadata);
@@ -455,6 +460,9 @@ export class GridComponent {
455
460
  */
456
461
  set data(value) {
457
462
  this._data = value;
463
+ if (this.selectable && this.selectableSettings?.enabled && this.isVirtual) {
464
+ this.blockArrowSelection = false;
465
+ }
458
466
  if (this.notifyTimeout) {
459
467
  clearTimeout(this.notifyTimeout);
460
468
  this.notifyTimeout = null;
@@ -680,6 +688,19 @@ export class GridComponent {
680
688
  get rowSelected() {
681
689
  return this._rowSelected;
682
690
  }
691
+ /**
692
+ * Defines a Boolean function that is executed for each data row in the component.
693
+ * Determines whether the row will be selectable.
694
+ */
695
+ set isRowSelectable(fn) {
696
+ if (isDevMode() && typeof fn !== 'function') {
697
+ throw new Error(GridConfigurationErrorMessages.functionType('isRowSelectable', fn));
698
+ }
699
+ this._isRowSelectable = fn;
700
+ }
701
+ get isRowSelectable() {
702
+ return this._isRowSelectable;
703
+ }
683
704
  /**
684
705
  * Defines a function that determines the selected state of a data cell.
685
706
  * Returns an object with `selected` and `item` properties.
@@ -1482,6 +1503,12 @@ export class GridComponent {
1482
1503
  get flatData() {
1483
1504
  return isArray(this.data) ? this.data : this.data.data;
1484
1505
  }
1506
+ /**
1507
+ * @hidden
1508
+ */
1509
+ updateNavigationMetadata() {
1510
+ this.navigationService.metadata = this.navigationMetadata();
1511
+ }
1485
1512
  /**
1486
1513
  * @hidden
1487
1514
  */
@@ -1597,6 +1624,7 @@ export class GridComponent {
1597
1624
  activeService.init({
1598
1625
  cellSelected: cellSelectionMode ? this.cellSelected : undefined,
1599
1626
  rowSelected: cellSelectionMode ? undefined : this.rowSelected,
1627
+ isRowSelectable: this.isRowSelectable,
1600
1628
  selectable: this.selectable,
1601
1629
  view: this.view,
1602
1630
  columns: cellSelectionMode ? this.columnList.toArray() : undefined
@@ -1713,6 +1741,9 @@ export class GridComponent {
1713
1741
  .subscribe(x => {
1714
1742
  this.closeCell();
1715
1743
  this.cancelCell();
1744
+ if (this.selectable && this.selectableSettings?.enabled && this.isVirtual) {
1745
+ this.blockArrowSelection = true;
1746
+ }
1716
1747
  this.dataStateChange.emit(x);
1717
1748
  });
1718
1749
  }
@@ -1898,9 +1929,6 @@ export class GridComponent {
1898
1929
  const headerRows = this.totalColumnLevels + 1 + filterRowOffset + addRowOffset;
1899
1930
  return new NavigationMetadata(dataRows, headerRows, isVirtual, this.hasPager, isPresent(this.detailTemplate), this.wrapper, this.virtualColumns, this.columnsContainer);
1900
1931
  }
1901
- updateNavigationMetadata() {
1902
- this.navigationService.metadata = this.navigationMetadata();
1903
- }
1904
1932
  applyAutoSize() {
1905
1933
  const cols = this.columns.filter((c) => this.autoSize ? c.autoSize !== false : c.autoSize);
1906
1934
  if (cols.length > 0) {
@@ -2004,7 +2032,7 @@ export class GridComponent {
2004
2032
  }
2005
2033
  }
2006
2034
  GridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: GridComponent, deps: [{ token: i1.BrowserSupportService }, { token: i2.SelectionService }, { token: i3.CellSelectionService }, { token: i0.ElementRef }, { token: i4.GroupInfoService }, { token: i5.GroupsService }, { token: i6.ChangeNotificationService }, { token: i7.DetailsService }, { token: i8.EditService }, { token: i9.FilterService }, { token: i10.PDFService }, { token: i11.ResponsiveService }, { token: i0.Renderer2 }, { token: i12.ExcelService }, { token: i0.NgZone }, { token: i13.ScrollSyncService }, { token: i14.DomEventsService }, { token: i15.ColumnResizingService }, { token: i0.ChangeDetectorRef }, { token: i16.ColumnReorderService }, { token: i17.ColumnInfoService }, { token: i18.NavigationService }, { token: i19.SortService }, { token: i20.ScrollRequestService }, { token: i21.LocalizationService }, { token: i22.ContextService }, { token: i23.SizingOptionsService }, { token: i24.RowReorderService }], target: i0.ɵɵFactoryTarget.Component });
2007
- GridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: GridComponent, isStandalone: true, selector: "kendo-grid", inputs: { data: "data", pageSize: "pageSize", height: "height", rowHeight: "rowHeight", detailRowHeight: "detailRowHeight", skip: "skip", scrollable: "scrollable", selectable: "selectable", sort: "sort", size: "size", trackBy: "trackBy", filter: "filter", group: "group", virtualColumns: "virtualColumns", filterable: "filterable", sortable: "sortable", pageable: "pageable", groupable: "groupable", rowReorderable: "rowReorderable", navigable: "navigable", navigatable: "navigatable", autoSize: "autoSize", rowClass: "rowClass", rowSticky: "rowSticky", rowSelected: "rowSelected", cellSelected: "cellSelected", resizable: "resizable", reorderable: "reorderable", loading: "loading", columnMenu: "columnMenu", hideHeader: "hideHeader", isDetailExpanded: "isDetailExpanded", isGroupExpanded: "isGroupExpanded" }, outputs: { filterChange: "filterChange", pageChange: "pageChange", groupChange: "groupChange", sortChange: "sortChange", selectionChange: "selectionChange", rowReorder: "rowReorder", dataStateChange: "dataStateChange", groupExpand: "groupExpand", groupCollapse: "groupCollapse", detailExpand: "detailExpand", detailCollapse: "detailCollapse", edit: "edit", cancel: "cancel", save: "save", remove: "remove", add: "add", cellClose: "cellClose", cellClick: "cellClick", pdfExport: "pdfExport", excelExport: "excelExport", columnResize: "columnResize", columnReorder: "columnReorder", columnVisibilityChange: "columnVisibilityChange", columnLockedChange: "columnLockedChange", columnStickyChange: "columnStickyChange", scrollBottom: "scrollBottom", contentScroll: "contentScroll" }, host: { properties: { "attr.dir": "this.dir", "class.k-grid": "this.hostClass", "class.k-grid-sm": "this.sizeSmallClass", "class.k-grid-md": "this.sizeMediumClass", "class.k-grid-lockedcolumns": "this.lockedClasses", "class.k-grid-virtual": "this.virtualClasses", "class.k-grid-no-scrollbar": "this.noScrollbarClass" } }, providers: [
2035
+ GridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: GridComponent, isStandalone: true, selector: "kendo-grid", inputs: { data: "data", pageSize: "pageSize", height: "height", rowHeight: "rowHeight", detailRowHeight: "detailRowHeight", skip: "skip", scrollable: "scrollable", selectable: "selectable", sort: "sort", size: "size", trackBy: "trackBy", filter: "filter", group: "group", virtualColumns: "virtualColumns", filterable: "filterable", sortable: "sortable", pageable: "pageable", groupable: "groupable", rowReorderable: "rowReorderable", navigable: "navigable", navigatable: "navigatable", autoSize: "autoSize", rowClass: "rowClass", rowSticky: "rowSticky", rowSelected: "rowSelected", isRowSelectable: "isRowSelectable", cellSelected: "cellSelected", resizable: "resizable", reorderable: "reorderable", loading: "loading", columnMenu: "columnMenu", hideHeader: "hideHeader", isDetailExpanded: "isDetailExpanded", isGroupExpanded: "isGroupExpanded" }, outputs: { filterChange: "filterChange", pageChange: "pageChange", groupChange: "groupChange", sortChange: "sortChange", selectionChange: "selectionChange", rowReorder: "rowReorder", dataStateChange: "dataStateChange", groupExpand: "groupExpand", groupCollapse: "groupCollapse", detailExpand: "detailExpand", detailCollapse: "detailCollapse", edit: "edit", cancel: "cancel", save: "save", remove: "remove", add: "add", cellClose: "cellClose", cellClick: "cellClick", pdfExport: "pdfExport", excelExport: "excelExport", columnResize: "columnResize", columnReorder: "columnReorder", columnVisibilityChange: "columnVisibilityChange", columnLockedChange: "columnLockedChange", columnStickyChange: "columnStickyChange", scrollBottom: "scrollBottom", contentScroll: "contentScroll" }, host: { properties: { "attr.dir": "this.dir", "class.k-grid": "this.hostClass", "class.k-grid-sm": "this.sizeSmallClass", "class.k-grid-md": "this.sizeMediumClass", "class.k-grid-lockedcolumns": "this.lockedClasses", "class.k-grid-virtual": "this.virtualClasses", "class.k-grid-no-scrollbar": "this.noScrollbarClass" } }, providers: [
2008
2036
  BrowserSupportService,
2009
2037
  LocalizationService,
2010
2038
  ColumnInfoService,
@@ -3330,6 +3358,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
3330
3358
  type: Input
3331
3359
  }], rowSelected: [{
3332
3360
  type: Input
3361
+ }], isRowSelectable: [{
3362
+ type: Input
3333
3363
  }], cellSelected: [{
3334
3364
  type: Input
3335
3365
  }], resizable: [{
@@ -148,6 +148,10 @@ export class NavigationCursor {
148
148
  if (cell.colSpan > 1 && cell.colIndex <= virtualCol && virtualCol < cell.colIndex + cell.colSpan) {
149
149
  nextColIndex = offset > 0 ? Math.min(cell.colIndex + cell.colSpan, lastIndex) : Math.max(0, cell.colIndex + offset);
150
150
  const nextCell = this.model.findCell(nextColIndex, prevRow);
151
+ if (!nextCell) {
152
+ this.virtualCol = nextColIndex;
153
+ return this.activate(cell.rowIndex, nextColIndex);
154
+ }
151
155
  if (cell !== nextCell) {
152
156
  cell = nextCell;
153
157
  this.virtualCol = cell.colIndex;
@@ -155,7 +159,9 @@ export class NavigationCursor {
155
159
  else {
156
160
  this.virtualCol = virtualCol;
157
161
  }
162
+ return this.activate(cell.rowIndex, this.virtualCol);
158
163
  }
164
+ this.virtualCol = cell.colIndex;
159
165
  return this.activate(cell.rowIndex, cell.colIndex);
160
166
  }
161
167
  offsetRow(offset) {
@@ -182,6 +188,9 @@ export class NavigationCursor {
182
188
  }
183
189
  if (cell.rowIndex <= this.virtualRow && offset > 0 && cell.rowSpan > 1) {
184
190
  cell = this.model.findCell(this.virtualCol, this.model.findRow(cell.rowIndex + cell.rowSpan - 1 + offset));
191
+ if (!cell) {
192
+ return;
193
+ }
185
194
  }
186
195
  nextIndex = cell.rowIndex;
187
196
  nextColIndex = cell.colIndex;
@@ -11,7 +11,7 @@ import { GridFocusableElement } from './grid-focusable-element';
11
11
  import { NavigationCursor } from './navigation-cursor';
12
12
  import { NavigationModel } from './navigation-model';
13
13
  import { DomEventsService } from '../common/dom-events.service';
14
- import { isDocumentAvailable, Keys } from '@progress/kendo-angular-common';
14
+ import { isDocumentAvailable, isPresent, Keys } from '@progress/kendo-angular-common';
15
15
  import { EditService } from '../editing/edit.service';
16
16
  import { GroupsService } from '../grouping/groups.service';
17
17
  import { PagerContextService } from '../pager/pager-context.service';
@@ -135,7 +135,7 @@ export class NavigationService {
135
135
  get activeRow() {
136
136
  if (this.mode !== 0 /* NavigationMode.Standby */) {
137
137
  return Object.assign({}, this.cursor.row, {
138
- cells: this.cursor.row.cells.toArray()
138
+ cells: this.cursor.row?.cells.toArray()
139
139
  });
140
140
  }
141
141
  }
@@ -407,16 +407,56 @@ export class NavigationService {
407
407
  const row = this.cursor.row;
408
408
  switch (args.keyCode) {
409
409
  case Keys.ArrowDown:
410
- preventDefault = this.cursor.moveDown(step);
410
+ if (args.shiftKey) {
411
+ if (this.ctx.grid.blockArrowSelection) {
412
+ return;
413
+ }
414
+ preventDefault = this.cursor.moveDown(step);
415
+ if (this.activeRow?.dataItem) {
416
+ this.handleVerticalArrowSelection(step);
417
+ }
418
+ }
419
+ else {
420
+ preventDefault = this.cursor.moveDown(step);
421
+ }
411
422
  break;
412
423
  case Keys.ArrowUp:
413
- preventDefault = this.cursor.moveUp(step);
424
+ if (args.shiftKey) {
425
+ if (this.ctx.grid.blockArrowSelection) {
426
+ return;
427
+ }
428
+ preventDefault = this.cursor.moveUp(step);
429
+ if (this.activeRow?.dataItem) {
430
+ this.handleVerticalArrowSelection(-step);
431
+ }
432
+ }
433
+ else {
434
+ preventDefault = this.cursor.moveUp(step);
435
+ }
414
436
  break;
415
437
  case Keys.ArrowRight:
416
- preventDefault = this.moveCursorFwd();
438
+ if (args.shiftKey) {
439
+ if (this.ctx.grid.blockArrowSelection) {
440
+ return;
441
+ }
442
+ preventDefault = this.moveCursorFwd();
443
+ this.handleHorizontalArrowSelection(args);
444
+ }
445
+ else {
446
+ preventDefault = this.moveCursorFwd();
447
+ }
417
448
  break;
418
449
  case Keys.ArrowLeft:
419
- preventDefault = this.moveCursorBwd();
450
+ if (args.shiftKey) {
451
+ if (this.ctx.grid.blockArrowSelection) {
452
+ return;
453
+ }
454
+ preventDefault = this.moveCursorBwd();
455
+ this.handleHorizontalArrowSelection(args);
456
+ }
457
+ else {
458
+ preventDefault = this.moveCursorBwd();
459
+ }
420
460
  break;
421
461
  case Keys.PageDown:
422
462
  if (this.metadata.isVirtual && this.viewport) {
@@ -607,6 +647,58 @@ export class NavigationService {
607
647
  this.leaveCell();
608
648
  this.cursor.reset();
609
649
  }
650
+ handleVerticalArrowSelection(args) {
651
+ const cellSelectionEnabled = this.ctx.grid.cellSelectionService.active;
652
+ const rowSelectionEnabled = this.ctx.grid.selectionService.active && !this.ctx.grid.selectableSettings.checkboxOnly;
653
+ if (cellSelectionEnabled || rowSelectionEnabled) {
654
+ const selectionService = this.ctx.grid[cellSelectionEnabled ? 'cellSelectionService' : 'selectionService'];
655
+ const colIdx = this.cursor.cell ? this.cursor.cell.colIndex : 0;
656
+ const rowIdx = this.activeRow.dataRowIndex - this.ctx.grid.skip;
657
+ const dataItem = selectionService.settings.view.at(rowIdx);
658
+ const item = { index: this.activeRow.dataRowIndex, data: dataItem, column: this.ctx.grid.columnsContainer.leafColumnsToRender[colIdx] };
659
+ if (selectionService.options.mode === 'multiple') {
660
+ cellSelectionEnabled ? this.handleMultipleArrowCellSelection(item) : this.handleMultipleArrowRowSelection(item);
661
+ }
662
+ else {
663
+ selectionService.handleClick(item, args);
664
+ }
665
+ }
666
+ }
667
+ handleHorizontalArrowSelection(args) {
668
+ const cellSelectionEnabled = this.ctx.grid.cellSelectionService.active;
669
+ if (cellSelectionEnabled) {
670
+ const selectionService = this.ctx.grid[cellSelectionEnabled ? 'cellSelectionService' : 'selectionService'];
671
+ const row = this.activeRow;
672
+ const colIdx = this.cursor.cell ? this.cursor.cell.colIndex : 0;
673
+ const dataItem = selectionService.settings.view.at(row.dataRowIndex - this.ctx.grid.skip);
674
+ const item = { index: row.dataRowIndex, data: dataItem, column: this.ctx.grid.columnsContainer.leafColumnsToRender[colIdx] };
675
+ if (!isPresent(dataItem) || !isPresent(item.column)) {
676
+ return;
677
+ }
678
+ if (selectionService.options.mode === 'multiple') {
679
+ this.handleMultipleArrowCellSelection(item);
680
+ }
681
+ else {
682
+ selectionService.handleClick(item, args);
683
+ }
684
+ }
685
+ }
686
+ handleMultipleArrowCellSelection(item) {
687
+ const cellSelectionService = this.ctx.grid.cellSelectionService;
688
+ const startRowIndex = Math.min(cellSelectionService.lastSelectionItemRowIndex, item.index);
689
+ const startColIndex = Math.min(cellSelectionService.lastSelectionItemColIndex, item.column.leafIndex);
690
+ const endRowIndex = Math.max(cellSelectionService.lastSelectionItemRowIndex, item.index);
691
+ const endColIndex = Math.max(cellSelectionService.lastSelectionItemColIndex, item.column.leafIndex);
692
+ const ev = cellSelectionService.selectRange(startRowIndex, startColIndex, endRowIndex, endColIndex);
693
+ cellSelectionService.changes.emit(ev);
694
+ }
695
+ handleMultipleArrowRowSelection(item) {
696
+ const rowSelectionService = this.ctx.grid.selectionService;
697
+ const startRowIndex = Math.min(rowSelectionService.lastSelectionStartIndex, item.index);
698
+ const endRowIndex = Math.max(rowSelectionService.lastSelectionStartIndex, item.index);
699
+ const ev = rowSelectionService.selectRange(startRowIndex, endRowIndex);
700
+ rowSelectionService.changes.emit(ev);
701
+ }
610
702
  }
611
703
  NavigationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NavigationService, deps: [{ token: i0.NgZone }, { token: i1.DomEventsService }, { token: i2.PagerContextService }, { token: i3.ScrollRequestService }, { token: i4.GroupsService }, { token: i5.DetailsService }, { token: i6.FocusRoot }, { token: i7.EditService }, { token: i0.ChangeDetectorRef }, { token: i8.ContextService }, { token: i9.FocusableDirective, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
612
704
  NavigationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NavigationService });
@@ -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: 1727353679,
13
- version: '16.11.0-develop.1',
12
+ publishDate: 1727428394,
13
+ version: '16.11.0-develop.3',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
15
15
  };
@@ -110,6 +110,9 @@ export class CellComponent {
110
110
  get isRowReorderColumn() {
111
111
  return isRowReorderColumn(this.column) && !this.column.templateRef;
112
112
  }
113
+ get isRowSelectable() {
114
+ return this.column.rowSelectable(this._rowIndex);
115
+ }
113
116
  get isColumnEditable() {
114
117
  if (!this.column || this.isCommand(this.column)) {
115
118
  return false;
@@ -171,13 +174,25 @@ CellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version:
171
174
  </ng-container>
172
175
  <ng-container *ngIf="isBoundColumn">{{ dataItem | valueOf: column.field: column.format}}</ng-container>
173
176
  <ng-container *ngIf="isCheckboxColumn && !isNew">
174
- <span class="k-checkbox-wrap">
175
- <input
176
- class="k-checkbox k-checkbox-md k-rounded-md"
177
- [kendoGridSelectionCheckbox]="rowIndex"
178
- [attr.id]="selectionCheckboxId"
179
- [attr.aria-label]="selectionCheckboxLabel" />
180
- </span>
177
+ <ng-container *ngIf="isRowSelectable; else nonSelectableRow">
178
+ <span class="k-checkbox-wrap">
179
+ <input
180
+ class="k-checkbox k-checkbox-md k-rounded-md"
181
+ [kendoGridSelectionCheckbox]="rowIndex"
182
+ [attr.id]="selectionCheckboxId"
183
+ [attr.aria-label]="selectionCheckboxLabel" />
184
+ </span>
185
+ </ng-container>
186
+ <ng-template #nonSelectableRow>
187
+ <span class="k-checkbox-wrap" *ngIf="column.showDisabledCheckbox">
188
+ <input
189
+ class="k-checkbox k-checkbox-md k-rounded-md k-disabled"
190
+ [kendoGridSelectionCheckbox]="rowIndex"
191
+ [attr.id]="selectionCheckboxId"
192
+ [attr.aria-label]="selectionCheckboxLabel"
193
+ [disabled]="true" />
194
+ </span>
195
+ </ng-template>
181
196
  </ng-container>
182
197
  <ng-container *ngIf="isRowReorderColumn && !isNew">
183
198
  <kendo-icon-wrapper
@@ -256,13 +271,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
256
271
  </ng-container>
257
272
  <ng-container *ngIf="isBoundColumn">{{ dataItem | valueOf: column.field: column.format}}</ng-container>
258
273
  <ng-container *ngIf="isCheckboxColumn && !isNew">
259
- <span class="k-checkbox-wrap">
260
- <input
261
- class="k-checkbox k-checkbox-md k-rounded-md"
262
- [kendoGridSelectionCheckbox]="rowIndex"
263
- [attr.id]="selectionCheckboxId"
264
- [attr.aria-label]="selectionCheckboxLabel" />
265
- </span>
274
+ <ng-container *ngIf="isRowSelectable; else nonSelectableRow">
275
+ <span class="k-checkbox-wrap">
276
+ <input
277
+ class="k-checkbox k-checkbox-md k-rounded-md"
278
+ [kendoGridSelectionCheckbox]="rowIndex"
279
+ [attr.id]="selectionCheckboxId"
280
+ [attr.aria-label]="selectionCheckboxLabel" />
281
+ </span>
282
+ </ng-container>
283
+ <ng-template #nonSelectableRow>
284
+ <span class="k-checkbox-wrap" *ngIf="column.showDisabledCheckbox">
285
+ <input
286
+ class="k-checkbox k-checkbox-md k-rounded-md k-disabled"
287
+ [kendoGridSelectionCheckbox]="rowIndex"
288
+ [attr.id]="selectionCheckboxId"
289
+ [attr.aria-label]="selectionCheckboxLabel"
290
+ [disabled]="true" />
291
+ </span>
292
+ </ng-template>
266
293
  </ng-container>
267
294
  <ng-container *ngIf="isRowReorderColumn && !isNew">
268
295
  <kendo-icon-wrapper
@@ -155,12 +155,17 @@ export class TableBodyComponent {
155
155
  isOdd(item) {
156
156
  return item.index % 2 !== 0;
157
157
  }
158
- isSelectable() {
159
- return this.selectable && this.selectable.enabled !== false;
158
+ isSelectable(args) {
159
+ const rowSelectable = this.isRowSelectable(args);
160
+ const selectionEnabled = this.selectable && this.selectable.enabled !== false;
161
+ return selectionEnabled && rowSelectable;
160
162
  }
161
163
  isRowSelected(item) {
162
164
  return this.selectionService.isSelected(item.index);
163
165
  }
166
+ isRowSelectable(args) {
167
+ return this.selectionService.settings?.isRowSelectable(args) || this.cellSelectionService.settings?.isRowSelectable(args);
168
+ }
164
169
  trackByWrapper(index, item) {
165
170
  if (item.type === 'data') {
166
171
  item.isEditing = this.editService.hasEdited(item.index);
@@ -318,6 +323,10 @@ export class TableBodyComponent {
318
323
  if (!focusable && !matchesNodeName('label')(target) && !hasClasses(target, IGNORE_TARGET_CLASSSES) &&
319
324
  !closestInScope(target, matchesClasses(IGNORE_CONTAINER_CLASSES), cell)) {
320
325
  const args = this.cellClickArgs(cell, row, eventArg);
326
+ const selectionEnabled = this.selectable && this.selectable.enabled !== false;
327
+ if (selectionEnabled && !this.isRowSelectable({ index: args.rowIndex, dataItem: args.dataItem })) {
328
+ return;
329
+ }
321
330
  if (eventArg.type === 'mousedown' || eventArg.type === 'touchstart') {
322
331
  this.domEvents.cellMousedown.emit(args);
323
332
  }
@@ -490,9 +499,9 @@ TableBodyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", ver
490
499
  [ngClass]="rowClass({ dataItem: item.data, index: $any(item).index })"
491
500
  [class.k-master-row]="true"
492
501
  [class.k-grid-edit-row]="isEditingRow($any(item).index)"
493
- [attr.aria-selected]="lockedColumnsCount < 1 ? isSelectable() && isRowSelected(item) : undefined"
502
+ [attr.aria-selected]="lockedColumnsCount < 1 ? isSelectable({ dataItem: item.data, index: $any(item).index }) && isRowSelected(item) : undefined"
494
503
  [attr.data-kendo-grid-item-index]="$any(item).index"
495
- [class.k-selected]="isSelectable() && isRowSelected(item)">
504
+ [class.k-selected]="isSelectable({ dataItem: item.data, index: $any(item).index }) && isRowSelected(item)">
496
505
  <ng-container *ngIf="!skipGroupDecoration">
497
506
  <td class="k-group-cell k-table-td" *ngFor="let g of groups" role="presentation"></td>
498
507
  </ng-container>
@@ -535,10 +544,10 @@ TableBodyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", ver
535
544
  [colSpan]="column.colspan"
536
545
  [attr.role]="column.tableCellsRole"
537
546
  class="k-table-td"
538
- [attr.aria-selected]="lockedColumnsCount < 1 && isSelectable() ? isAriaSelected(item, column) : undefined"
547
+ [attr.aria-selected]="lockedColumnsCount < 1 && isSelectable({ dataItem: item.data, index: $any(item).index }) ? isAriaSelected(item, column) : undefined"
539
548
  [class.k-grid-content-sticky]="column.sticky"
540
- [class.k-touch-action-none]="isSelectable() && $any(selectable).drag"
541
- [class.k-touch-action-auto]="!(isSelectable() && $any(selectable).drag)"
549
+ [class.k-touch-action-none]="isSelectable({ dataItem: item.data, index: $any(item).index }) && $any(selectable).drag"
550
+ [class.k-touch-action-auto]="!(isSelectable({ dataItem: item.data, index: $any(item).index }) && $any(selectable).drag)"
542
551
  [ngClass]="column.cssClass"
543
552
  [class.k-grid-edit-cell]="isEditingCell($any(item).index, column)"
544
553
  [ngStyle]="column.sticky ? addStickyColumnStyles(column) : column.style"
@@ -719,9 +728,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
719
728
  [ngClass]="rowClass({ dataItem: item.data, index: $any(item).index })"
720
729
  [class.k-master-row]="true"
721
730
  [class.k-grid-edit-row]="isEditingRow($any(item).index)"
722
- [attr.aria-selected]="lockedColumnsCount < 1 ? isSelectable() && isRowSelected(item) : undefined"
731
+ [attr.aria-selected]="lockedColumnsCount < 1 ? isSelectable({ dataItem: item.data, index: $any(item).index }) && isRowSelected(item) : undefined"
723
732
  [attr.data-kendo-grid-item-index]="$any(item).index"
724
- [class.k-selected]="isSelectable() && isRowSelected(item)">
733
+ [class.k-selected]="isSelectable({ dataItem: item.data, index: $any(item).index }) && isRowSelected(item)">
725
734
  <ng-container *ngIf="!skipGroupDecoration">
726
735
  <td class="k-group-cell k-table-td" *ngFor="let g of groups" role="presentation"></td>
727
736
  </ng-container>
@@ -764,10 +773,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
764
773
  [colSpan]="column.colspan"
765
774
  [attr.role]="column.tableCellsRole"
766
775
  class="k-table-td"
767
- [attr.aria-selected]="lockedColumnsCount < 1 && isSelectable() ? isAriaSelected(item, column) : undefined"
776
+ [attr.aria-selected]="lockedColumnsCount < 1 && isSelectable({ dataItem: item.data, index: $any(item).index }) ? isAriaSelected(item, column) : undefined"
768
777
  [class.k-grid-content-sticky]="column.sticky"
769
- [class.k-touch-action-none]="isSelectable() && $any(selectable).drag"
770
- [class.k-touch-action-auto]="!(isSelectable() && $any(selectable).drag)"
778
+ [class.k-touch-action-none]="isSelectable({ dataItem: item.data, index: $any(item).index }) && $any(selectable).drag"
779
+ [class.k-touch-action-auto]="!(isSelectable({ dataItem: item.data, index: $any(item).index }) && $any(selectable).drag)"
771
780
  [ngClass]="column.cssClass"
772
781
  [class.k-grid-edit-cell]="isEditingCell($any(item).index, column)"
773
782
  [ngStyle]="column.sticky ? addStickyColumnStyles(column) : column.style"