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

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.
@@ -8,6 +8,7 @@ import { CellTemplateDirective } from '../rendering/cell-template.directive';
8
8
  import { IdService } from '../common/id.service';
9
9
  import { SelectionService } from '../selection/selection.service';
10
10
  import { CellSelectionService } from '../selection/cell-selection.service';
11
+ import { CellRowspanFn } from './cell-rowspan';
11
12
  import * as i0 from "@angular/core";
12
13
  /**
13
14
  * Represents the checkbox column for selecting rows in the Grid. [See example](slug:grid_row_selection#toc-select-all-checkbox).
@@ -40,6 +41,11 @@ export declare class CheckboxColumnComponent extends ColumnBase {
40
41
  * @hidden
41
42
  */
42
43
  rowSelectable(rowIdx: number): boolean;
44
+ /**
45
+ * Defines a function that is used to determine the rowspan of each column cell.
46
+ */
47
+ set cellRowspan(cellRowspan: CellRowspanFn);
48
+ get cellRowspan(): CellRowspanFn;
43
49
  static ɵfac: i0.ɵɵFactoryDeclaration<CheckboxColumnComponent, [null, null, { optional: true; host: true; skipSelf: true; }, { optional: true; }]>;
44
50
  static ɵcmp: i0.ɵɵComponentDeclaration<CheckboxColumnComponent, "kendo-grid-checkbox-column", never, { "showSelectAll": { "alias": "showSelectAll"; "required": false; }; "showDisabledCheckbox": { "alias": "showDisabledCheckbox"; "required": false; }; }, {}, ["template"], never, true, never>;
45
51
  }
@@ -2,7 +2,7 @@
2
2
  * Copyright © 2025 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { TemplateRef, QueryList, SimpleChanges } from '@angular/core';
5
+ import { TemplateRef, QueryList } from '@angular/core';
6
6
  import { HeaderTemplateDirective } from '../rendering/header/header-template.directive';
7
7
  import { FooterTemplateDirective } from '../rendering/footer/footer-template.directive';
8
8
  import { ColumnMenuTemplateDirective } from '../column-menu/column-menu-template.directive';
@@ -229,8 +229,11 @@ export declare class ColumnBase {
229
229
  };
230
230
  /**
231
231
  * Defines a function that is used to determine the rowspan of each column cell.
232
+ * If set to `true`, a default function is used that spans adjacent cells containing equal values.
233
+ * Cells have equal values when their data items' values for the respective field are equal.
232
234
  */
233
- cellRowspan: CellRowspanFn;
235
+ set cellRowspan(cellRowspan: CellRowspanFn | boolean);
236
+ get cellRowspan(): CellRowspanFn;
234
237
  /**
235
238
  * @hidden
236
239
  */
@@ -251,6 +254,10 @@ export declare class ColumnBase {
251
254
  * @hidden
252
255
  */
253
256
  idService: IdService;
257
+ /**
258
+ * @hidden
259
+ */
260
+ _cellRowspan: CellRowspanFn;
254
261
  /**
255
262
  * @hidden
256
263
  */
@@ -296,7 +303,6 @@ export declare class ColumnBase {
296
303
  * @hidden
297
304
  */
298
305
  constructor(parent?: ColumnBase, idService?: IdService);
299
- ngOnChanges(changes: SimpleChanges): void;
300
306
  static ɵfac: i0.ɵɵFactoryDeclaration<ColumnBase, never>;
301
307
  static ɵcmp: i0.ɵɵComponentDeclaration<ColumnBase, "kendo-grid-column-base", never, { "resizable": { "alias": "resizable"; "required": false; }; "reorderable": { "alias": "reorderable"; "required": false; }; "minResizableWidth": { "alias": "minResizableWidth"; "required": false; }; "maxResizableWidth": { "alias": "maxResizableWidth"; "required": false; }; "title": { "alias": "title"; "required": false; }; "width": { "alias": "width"; "required": false; }; "autoSize": { "alias": "autoSize"; "required": false; }; "locked": { "alias": "locked"; "required": false; }; "sticky": { "alias": "sticky"; "required": false; }; "hidden": { "alias": "hidden"; "required": false; }; "media": { "alias": "media"; "required": false; }; "lockable": { "alias": "lockable"; "required": false; }; "stickable": { "alias": "stickable"; "required": false; }; "columnMenu": { "alias": "columnMenu"; "required": false; }; "includeInChooser": { "alias": "includeInChooser"; "required": false; }; "tableCellsRole": { "alias": "tableCellsRole"; "required": false; }; "style": { "alias": "style"; "required": false; }; "headerStyle": { "alias": "headerStyle"; "required": false; }; "filterStyle": { "alias": "filterStyle"; "required": false; }; "footerStyle": { "alias": "footerStyle"; "required": false; }; "cssClass": { "alias": "class"; "required": false; }; "headerClass": { "alias": "headerClass"; "required": false; }; "filterClass": { "alias": "filterClass"; "required": false; }; "footerClass": { "alias": "footerClass"; "required": false; }; "cellRowspan": { "alias": "cellRowspan"; "required": false; }; }, {}, ["footerTemplate", "headerTemplates", "columnMenuTemplates"], never, false, never>;
302
308
  }
@@ -52,6 +52,12 @@ export declare class ColumnGroupComponent extends ColumnBase {
52
52
  * @hidden
53
53
  */
54
54
  rowspan(): number;
55
+ /**
56
+ * @hidden
57
+ *
58
+ * Used to hide the cellRowspan property from the public API.
59
+ */
60
+ set cellRowspan(cellRowSpan: any);
55
61
  /**
56
62
  * @hidden
57
63
  */
@@ -6,6 +6,7 @@ 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 { CellRowspanFn } from './cell-rowspan';
9
10
  import * as i0 from "@angular/core";
10
11
  /**
11
12
  * Represents the command columns of the Grid. You have to define the content of the
@@ -30,6 +31,11 @@ export declare class CommandColumnComponent extends ColumnBase {
30
31
  template: CellTemplateDirective;
31
32
  constructor(parent?: ColumnBase, idService?: IdService);
32
33
  get templateRef(): TemplateRef<any>;
34
+ /**
35
+ * Defines a function that is used to determine the rowspan of each column cell.
36
+ */
37
+ set cellRowspan(cellRowspan: CellRowspanFn);
38
+ get cellRowspan(): CellRowspanFn;
33
39
  static ɵfac: i0.ɵɵFactoryDeclaration<CommandColumnComponent, [{ optional: true; host: true; skipSelf: true; }, { optional: true; }]>;
34
40
  static ɵcmp: i0.ɵɵComponentDeclaration<CommandColumnComponent, "kendo-grid-command-column", never, {}, {}, ["template"], never, true, never>;
35
41
  }
@@ -8,6 +8,7 @@ import { IdService } from '../common/id.service';
8
8
  import { SVGIcon } from '@progress/kendo-svg-icons';
9
9
  import { RowDragHandleTemplateDirective } from '../row-reordering/drag-handle-template.directive';
10
10
  import { RowDragHintTemplateDirective } from '../row-reordering/drag-hint-template.directive';
11
+ import { CellRowspanFn } from './cell-rowspan';
11
12
  import * as i0 from "@angular/core";
12
13
  /**
13
14
  * Represents the drag handle for reordering rows in the Grid ([see example](slug:reordering_rows_grid))
@@ -45,6 +46,11 @@ export declare class RowReorderColumnComponent extends ColumnBase {
45
46
  */
46
47
  get rowDragHintTemplateRef(): TemplateRef<any>;
47
48
  constructor(parent?: ColumnBase, idService?: IdService);
49
+ /**
50
+ * Defines a function that is used to determine the rowspan of each column cell.
51
+ */
52
+ set cellRowspan(cellRowspan: CellRowspanFn);
53
+ get cellRowspan(): CellRowspanFn;
48
54
  static ɵfac: i0.ɵɵFactoryDeclaration<RowReorderColumnComponent, [{ optional: true; host: true; skipSelf: true; }, { optional: true; }]>;
49
55
  static ɵcmp: i0.ɵɵComponentDeclaration<RowReorderColumnComponent, "kendo-grid-rowreorder-column", never, { "dragHandleIcon": { "alias": "dragHandleIcon"; "required": false; }; "dragHandleSVGIcon": { "alias": "dragHandleSVGIcon"; "required": false; }; }, {}, ["dragHandleTemplate", "dragHintTemplate"], never, true, never>;
50
56
  }
@@ -111,6 +111,12 @@ export declare class SpanColumnComponent extends ColumnBase {
111
111
  get locked(): boolean;
112
112
  get childrenArray(): any[];
113
113
  get hasChildren(): boolean;
114
+ /**
115
+ * @hidden
116
+ *
117
+ * Used to hide the cellRowspan property from the public API.
118
+ */
119
+ set cellRowspan(cellRowSpan: any);
114
120
  static ɵfac: i0.ɵɵFactoryDeclaration<SpanColumnComponent, [{ optional: true; host: true; skipSelf: true; }, { optional: true; }]>;
115
121
  static ɵcmp: i0.ɵɵComponentDeclaration<SpanColumnComponent, "kendo-grid-span-column", never, { "editable": { "alias": "editable"; "required": false; }; "locked": { "alias": "locked"; "required": false; }; }, {}, ["template", "editTemplate", "childColumns"], never, true, never>;
116
122
  }
@@ -56,6 +56,15 @@ export class CheckboxColumnComponent extends ColumnBase {
56
56
  rowSelectable(rowIdx) {
57
57
  return !this.selectionService.nonSelectableRows.has(rowIdx) && !this.cellSelectionService.nonSelectableRows.has(rowIdx);
58
58
  }
59
+ /**
60
+ * Defines a function that is used to determine the rowspan of each column cell.
61
+ */
62
+ set cellRowspan(cellRowspan) {
63
+ super.cellRowspan = cellRowspan;
64
+ }
65
+ get cellRowspan() {
66
+ return super.cellRowspan;
67
+ }
59
68
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", 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 });
60
69
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CheckboxColumnComponent, isStandalone: true, selector: "kendo-grid-checkbox-column", inputs: { showSelectAll: "showSelectAll", showDisabledCheckbox: "showDisabledCheckbox" }, providers: [
61
70
  {
@@ -7,7 +7,8 @@ import { HeaderTemplateDirective } from '../rendering/header/header-template.dir
7
7
  import { FooterTemplateDirective } from '../rendering/footer/footer-template.directive';
8
8
  import { ColumnMenuTemplateDirective } from '../column-menu/column-menu-template.directive';
9
9
  import { IdService } from '../common/id.service';
10
- import { ColumnConfigurationErrorMessages, GridConfigurationErrorMessages } from '../common/error-messages';
10
+ import { ColumnConfigurationErrorMessages } from '../common/error-messages';
11
+ import { defaultCellRowSpan } from '../utils';
11
12
  import * as i0 from "@angular/core";
12
13
  import * as i1 from "../common/id.service";
13
14
  /**
@@ -233,8 +234,28 @@ export class ColumnBase {
233
234
  footerClass;
234
235
  /**
235
236
  * Defines a function that is used to determine the rowspan of each column cell.
237
+ * If set to `true`, a default function is used that spans adjacent cells containing equal values.
238
+ * Cells have equal values when their data items' values for the respective field are equal.
236
239
  */
237
- cellRowspan;
240
+ set cellRowspan(cellRowspan) {
241
+ if (isDevMode() && (this.isSpanColumn || this.isColumnGroup)) {
242
+ throw new Error(ColumnConfigurationErrorMessages.cellRowspanSpanGroupedColumns);
243
+ }
244
+ if (cellRowspan) {
245
+ const isFunction = typeof cellRowspan === 'function';
246
+ const isBoolean = typeof cellRowspan === 'boolean';
247
+ if (isDevMode() && !this.field && !isFunction) {
248
+ throw new Error(ColumnConfigurationErrorMessages.cellRowspanNonBoundColumns);
249
+ }
250
+ if (isDevMode() && !(isBoolean || isFunction)) {
251
+ throw new Error(ColumnConfigurationErrorMessages.cellRowspan);
252
+ }
253
+ this._cellRowspan = isBoolean ? defaultCellRowSpan : cellRowspan;
254
+ }
255
+ }
256
+ get cellRowspan() {
257
+ return this._cellRowspan;
258
+ }
238
259
  /**
239
260
  * @hidden
240
261
  */
@@ -255,6 +276,10 @@ export class ColumnBase {
255
276
  * @hidden
256
277
  */
257
278
  idService;
279
+ /**
280
+ * @hidden
281
+ */
282
+ _cellRowspan;
258
283
  /**
259
284
  * @hidden
260
285
  */
@@ -329,13 +354,8 @@ export class ColumnBase {
329
354
  throw new Error(ColumnConfigurationErrorMessages.columnNested);
330
355
  }
331
356
  }
332
- ngOnChanges(changes) {
333
- if (isDevMode() && changes['cellRowspan'] && typeof changes['cellRowspan'].currentValue !== 'function') {
334
- throw new Error(GridConfigurationErrorMessages.functionType('cellRowspan', changes['cellRowspan'].currentValue));
335
- }
336
- }
337
357
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnBase, deps: [{ token: ColumnBase }, { token: i1.IdService }], target: i0.ɵɵFactoryTarget.Component });
338
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnBase, selector: "kendo-grid-column-base", inputs: { resizable: "resizable", reorderable: "reorderable", minResizableWidth: "minResizableWidth", maxResizableWidth: "maxResizableWidth", title: "title", width: "width", autoSize: "autoSize", locked: "locked", sticky: "sticky", hidden: "hidden", media: "media", lockable: "lockable", stickable: "stickable", columnMenu: "columnMenu", includeInChooser: "includeInChooser", tableCellsRole: "tableCellsRole", style: "style", headerStyle: "headerStyle", filterStyle: "filterStyle", footerStyle: "footerStyle", cssClass: ["class", "cssClass"], headerClass: "headerClass", filterClass: "filterClass", footerClass: "footerClass", cellRowspan: "cellRowspan" }, queries: [{ propertyName: "footerTemplate", first: true, predicate: FooterTemplateDirective, descendants: true }, { propertyName: "headerTemplates", predicate: HeaderTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], usesOnChanges: true, ngImport: i0, template: ``, isInline: true });
358
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnBase, selector: "kendo-grid-column-base", inputs: { resizable: "resizable", reorderable: "reorderable", minResizableWidth: "minResizableWidth", maxResizableWidth: "maxResizableWidth", title: "title", width: "width", autoSize: "autoSize", locked: "locked", sticky: "sticky", hidden: "hidden", media: "media", lockable: "lockable", stickable: "stickable", columnMenu: "columnMenu", includeInChooser: "includeInChooser", tableCellsRole: "tableCellsRole", style: "style", headerStyle: "headerStyle", filterStyle: "filterStyle", footerStyle: "footerStyle", cssClass: ["class", "cssClass"], headerClass: "headerClass", filterClass: "filterClass", footerClass: "footerClass", cellRowspan: "cellRowspan" }, queries: [{ propertyName: "footerTemplate", first: true, predicate: FooterTemplateDirective, descendants: true }, { propertyName: "headerTemplates", predicate: HeaderTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], ngImport: i0, template: ``, isInline: true });
339
359
  }
340
360
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnBase, decorators: [{
341
361
  type: Component,
@@ -66,6 +66,14 @@ export class ColumnGroupComponent extends ColumnBase {
66
66
  rowspan() {
67
67
  return 1;
68
68
  }
69
+ /**
70
+ * @hidden
71
+ *
72
+ * Used to hide the cellRowspan property from the public API.
73
+ */
74
+ set cellRowspan(cellRowSpan) {
75
+ super.cellRowspan = cellRowSpan;
76
+ }
69
77
  /**
70
78
  * @hidden
71
79
  */
@@ -37,6 +37,15 @@ export class CommandColumnComponent extends ColumnBase {
37
37
  get templateRef() {
38
38
  return this.template ? this.template.templateRef : undefined;
39
39
  }
40
+ /**
41
+ * Defines a function that is used to determine the rowspan of each column cell.
42
+ */
43
+ set cellRowspan(cellRowspan) {
44
+ super.cellRowspan = cellRowspan;
45
+ }
46
+ get cellRowspan() {
47
+ return super.cellRowspan;
48
+ }
40
49
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CommandColumnComponent, deps: [{ token: i1.ColumnBase, host: true, optional: true, skipSelf: true }, { token: i2.IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
41
50
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CommandColumnComponent, isStandalone: true, selector: "kendo-grid-command-column", providers: [
42
51
  {
@@ -55,6 +55,15 @@ export class RowReorderColumnComponent extends ColumnBase {
55
55
  super(parent, idService);
56
56
  this.parent = parent;
57
57
  }
58
+ /**
59
+ * Defines a function that is used to determine the rowspan of each column cell.
60
+ */
61
+ set cellRowspan(cellRowspan) {
62
+ super.cellRowspan = cellRowspan;
63
+ }
64
+ get cellRowspan() {
65
+ return super.cellRowspan;
66
+ }
58
67
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RowReorderColumnComponent, deps: [{ token: i1.ColumnBase, host: true, optional: true, skipSelf: true }, { token: i2.IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
59
68
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: RowReorderColumnComponent, isStandalone: true, selector: "kendo-grid-rowreorder-column", inputs: { dragHandleIcon: "dragHandleIcon", dragHandleSVGIcon: "dragHandleSVGIcon" }, providers: [
60
69
  {
@@ -142,6 +142,14 @@ export class SpanColumnComponent extends ColumnBase {
142
142
  get hasChildren() {
143
143
  return this.childColumns.length > 0;
144
144
  }
145
+ /**
146
+ * @hidden
147
+ *
148
+ * Used to hide the cellRowspan property from the public API.
149
+ */
150
+ set cellRowspan(cellRowSpan) {
151
+ super.cellRowspan = cellRowSpan;
152
+ }
145
153
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpanColumnComponent, deps: [{ token: i1.ColumnBase, host: true, optional: true, skipSelf: true }, { token: i2.IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
146
154
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SpanColumnComponent, isStandalone: true, selector: "kendo-grid-span-column", inputs: { editable: "editable", locked: "locked" }, providers: [
147
155
  {
@@ -38,7 +38,10 @@ export const ColumnConfigurationErrorMessages = {
38
38
  groupColumnContent: 'ColumnGroupComponent should contain ColumnComponent or CommandColumnComponent.',
39
39
  lockedParent: 'Locked child columns require their parent columns to be locked.',
40
40
  columnNested: 'Columns can be nested only inside ColumnGroupComponent',
41
- nestedInside: (nestedColumnNameType, parentColumnType) => `${nestedColumnNameType} cannot be nested inside ${parentColumnType}.`
41
+ nestedInside: (nestedColumnNameType, parentColumnType) => `${nestedColumnNameType} cannot be nested inside ${parentColumnType}.`,
42
+ cellRowspanNonBoundColumns: 'cellRowspan must be a function for non-bound columns.',
43
+ cellRowspanSpanGroupedColumns: 'cellRowspan is not supported for SpanColumn and GroupColumn.',
44
+ cellRowspan: `cellRowspan must be a function or boolean.`
42
45
  };
43
46
  /**
44
47
  * @hidden
@@ -10,7 +10,7 @@ export const packageMetadata = {
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCode: 'KENDOUIANGULAR',
12
12
  productCodes: ['KENDOUIANGULAR'],
13
- publishDate: 1741597660,
14
- version: '18.1.2-develop.3',
13
+ publishDate: 1741947639,
14
+ version: '18.2.0-develop.1',
15
15
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
16
16
  };
package/esm2022/utils.mjs CHANGED
@@ -143,3 +143,50 @@ export const isGroupResult = (obj) => {
143
143
  * @hidden
144
144
  */
145
145
  export const roundDown = (value) => Math.floor(value * 100) / 100;
146
+ /**
147
+ * @hidden
148
+ */
149
+ export const defaultCellRowSpan = (row, column, data) => {
150
+ const field = column.field;
151
+ let rowspan = 1;
152
+ const rowIndex = row.index;
153
+ if (!data[0].items) {
154
+ //If no groups are present.
155
+ rowspan = findRowSpan(data, rowIndex, field);
156
+ }
157
+ else {
158
+ // If groups are present.
159
+ const group = row.dataItem.group;
160
+ if (field === group.data.field) {
161
+ // Set the rowspan to the number of data items in the same group if the column containing the current row matches the grouping field.
162
+ rowspan = group.data.items.length;
163
+ }
164
+ else {
165
+ //The index of the current row in the group.
166
+ const rowIndex = row.dataItem.group.data.items.indexOf(row.dataItem.data);
167
+ const groupItems = row.dataItem.group.data.items;
168
+ rowspan = findRowSpan(groupItems, rowIndex, field);
169
+ }
170
+ }
171
+ return rowspan;
172
+ };
173
+ /**
174
+ * @hidden
175
+ * Returns the rowspan number based on the provided data array, index of the item, and field that is checked.
176
+ */
177
+ const findRowSpan = (data, index, field) => {
178
+ let rowspan = 1;
179
+ if (typeof data[index][field]?.getTime === 'function') {
180
+ while (data[index][field].getTime() === data[index + 1]?.[field].getTime()) {
181
+ rowspan++;
182
+ index++;
183
+ }
184
+ }
185
+ else {
186
+ while (data[index][field] === data[index + 1]?.[field]) {
187
+ rowspan++;
188
+ index++;
189
+ }
190
+ }
191
+ return rowspan;
192
+ };
@@ -459,6 +459,53 @@ const isGroupResult = (obj) => {
459
459
  * @hidden
460
460
  */
461
461
  const roundDown = (value) => Math.floor(value * 100) / 100;
462
+ /**
463
+ * @hidden
464
+ */
465
+ const defaultCellRowSpan = (row, column, data) => {
466
+ const field = column.field;
467
+ let rowspan = 1;
468
+ const rowIndex = row.index;
469
+ if (!data[0].items) {
470
+ //If no groups are present.
471
+ rowspan = findRowSpan(data, rowIndex, field);
472
+ }
473
+ else {
474
+ // If groups are present.
475
+ const group = row.dataItem.group;
476
+ if (field === group.data.field) {
477
+ // Set the rowspan to the number of data items in the same group if the column containing the current row matches the grouping field.
478
+ rowspan = group.data.items.length;
479
+ }
480
+ else {
481
+ //The index of the current row in the group.
482
+ const rowIndex = row.dataItem.group.data.items.indexOf(row.dataItem.data);
483
+ const groupItems = row.dataItem.group.data.items;
484
+ rowspan = findRowSpan(groupItems, rowIndex, field);
485
+ }
486
+ }
487
+ return rowspan;
488
+ };
489
+ /**
490
+ * @hidden
491
+ * Returns the rowspan number based on the provided data array, index of the item, and field that is checked.
492
+ */
493
+ const findRowSpan = (data, index, field) => {
494
+ let rowspan = 1;
495
+ if (typeof data[index][field]?.getTime === 'function') {
496
+ while (data[index][field].getTime() === data[index + 1]?.[field].getTime()) {
497
+ rowspan++;
498
+ index++;
499
+ }
500
+ }
501
+ else {
502
+ while (data[index][field] === data[index + 1]?.[field]) {
503
+ rowspan++;
504
+ index++;
505
+ }
506
+ }
507
+ return rowspan;
508
+ };
462
509
 
463
510
  /**
464
511
  * @hidden
@@ -2046,7 +2093,10 @@ const ColumnConfigurationErrorMessages = {
2046
2093
  groupColumnContent: 'ColumnGroupComponent should contain ColumnComponent or CommandColumnComponent.',
2047
2094
  lockedParent: 'Locked child columns require their parent columns to be locked.',
2048
2095
  columnNested: 'Columns can be nested only inside ColumnGroupComponent',
2049
- nestedInside: (nestedColumnNameType, parentColumnType) => `${nestedColumnNameType} cannot be nested inside ${parentColumnType}.`
2096
+ nestedInside: (nestedColumnNameType, parentColumnType) => `${nestedColumnNameType} cannot be nested inside ${parentColumnType}.`,
2097
+ cellRowspanNonBoundColumns: 'cellRowspan must be a function for non-bound columns.',
2098
+ cellRowspanSpanGroupedColumns: 'cellRowspan is not supported for SpanColumn and GroupColumn.',
2099
+ cellRowspan: `cellRowspan must be a function or boolean.`
2050
2100
  };
2051
2101
  /**
2052
2102
  * @hidden
@@ -2297,8 +2347,28 @@ class ColumnBase {
2297
2347
  footerClass;
2298
2348
  /**
2299
2349
  * Defines a function that is used to determine the rowspan of each column cell.
2350
+ * If set to `true`, a default function is used that spans adjacent cells containing equal values.
2351
+ * Cells have equal values when their data items' values for the respective field are equal.
2300
2352
  */
2301
- cellRowspan;
2353
+ set cellRowspan(cellRowspan) {
2354
+ if (isDevMode() && (this.isSpanColumn || this.isColumnGroup)) {
2355
+ throw new Error(ColumnConfigurationErrorMessages.cellRowspanSpanGroupedColumns);
2356
+ }
2357
+ if (cellRowspan) {
2358
+ const isFunction = typeof cellRowspan === 'function';
2359
+ const isBoolean = typeof cellRowspan === 'boolean';
2360
+ if (isDevMode() && !this.field && !isFunction) {
2361
+ throw new Error(ColumnConfigurationErrorMessages.cellRowspanNonBoundColumns);
2362
+ }
2363
+ if (isDevMode() && !(isBoolean || isFunction)) {
2364
+ throw new Error(ColumnConfigurationErrorMessages.cellRowspan);
2365
+ }
2366
+ this._cellRowspan = isBoolean ? defaultCellRowSpan : cellRowspan;
2367
+ }
2368
+ }
2369
+ get cellRowspan() {
2370
+ return this._cellRowspan;
2371
+ }
2302
2372
  /**
2303
2373
  * @hidden
2304
2374
  */
@@ -2319,6 +2389,10 @@ class ColumnBase {
2319
2389
  * @hidden
2320
2390
  */
2321
2391
  idService;
2392
+ /**
2393
+ * @hidden
2394
+ */
2395
+ _cellRowspan;
2322
2396
  /**
2323
2397
  * @hidden
2324
2398
  */
@@ -2393,13 +2467,8 @@ class ColumnBase {
2393
2467
  throw new Error(ColumnConfigurationErrorMessages.columnNested);
2394
2468
  }
2395
2469
  }
2396
- ngOnChanges(changes) {
2397
- if (isDevMode() && changes['cellRowspan'] && typeof changes['cellRowspan'].currentValue !== 'function') {
2398
- throw new Error(GridConfigurationErrorMessages.functionType('cellRowspan', changes['cellRowspan'].currentValue));
2399
- }
2400
- }
2401
2470
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnBase, deps: [{ token: ColumnBase }, { token: IdService }], target: i0.ɵɵFactoryTarget.Component });
2402
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnBase, selector: "kendo-grid-column-base", inputs: { resizable: "resizable", reorderable: "reorderable", minResizableWidth: "minResizableWidth", maxResizableWidth: "maxResizableWidth", title: "title", width: "width", autoSize: "autoSize", locked: "locked", sticky: "sticky", hidden: "hidden", media: "media", lockable: "lockable", stickable: "stickable", columnMenu: "columnMenu", includeInChooser: "includeInChooser", tableCellsRole: "tableCellsRole", style: "style", headerStyle: "headerStyle", filterStyle: "filterStyle", footerStyle: "footerStyle", cssClass: ["class", "cssClass"], headerClass: "headerClass", filterClass: "filterClass", footerClass: "footerClass", cellRowspan: "cellRowspan" }, queries: [{ propertyName: "footerTemplate", first: true, predicate: FooterTemplateDirective, descendants: true }, { propertyName: "headerTemplates", predicate: HeaderTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], usesOnChanges: true, ngImport: i0, template: ``, isInline: true });
2471
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ColumnBase, selector: "kendo-grid-column-base", inputs: { resizable: "resizable", reorderable: "reorderable", minResizableWidth: "minResizableWidth", maxResizableWidth: "maxResizableWidth", title: "title", width: "width", autoSize: "autoSize", locked: "locked", sticky: "sticky", hidden: "hidden", media: "media", lockable: "lockable", stickable: "stickable", columnMenu: "columnMenu", includeInChooser: "includeInChooser", tableCellsRole: "tableCellsRole", style: "style", headerStyle: "headerStyle", filterStyle: "filterStyle", footerStyle: "footerStyle", cssClass: ["class", "cssClass"], headerClass: "headerClass", filterClass: "filterClass", footerClass: "footerClass", cellRowspan: "cellRowspan" }, queries: [{ propertyName: "footerTemplate", first: true, predicate: FooterTemplateDirective, descendants: true }, { propertyName: "headerTemplates", predicate: HeaderTemplateDirective }, { propertyName: "columnMenuTemplates", predicate: ColumnMenuTemplateDirective }], ngImport: i0, template: ``, isInline: true });
2403
2472
  }
2404
2473
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ColumnBase, decorators: [{
2405
2474
  type: Component,
@@ -2972,6 +3041,14 @@ class SpanColumnComponent extends ColumnBase {
2972
3041
  get hasChildren() {
2973
3042
  return this.childColumns.length > 0;
2974
3043
  }
3044
+ /**
3045
+ * @hidden
3046
+ *
3047
+ * Used to hide the cellRowspan property from the public API.
3048
+ */
3049
+ set cellRowspan(cellRowSpan) {
3050
+ super.cellRowspan = cellRowSpan;
3051
+ }
2975
3052
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SpanColumnComponent, deps: [{ token: ColumnBase, host: true, optional: true, skipSelf: true }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
2976
3053
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SpanColumnComponent, isStandalone: true, selector: "kendo-grid-span-column", inputs: { editable: "editable", locked: "locked" }, providers: [
2977
3054
  {
@@ -4202,6 +4279,14 @@ class ColumnGroupComponent extends ColumnBase {
4202
4279
  rowspan() {
4203
4280
  return 1;
4204
4281
  }
4282
+ /**
4283
+ * @hidden
4284
+ *
4285
+ * Used to hide the cellRowspan property from the public API.
4286
+ */
4287
+ set cellRowspan(cellRowSpan) {
4288
+ super.cellRowspan = cellRowSpan;
4289
+ }
4205
4290
  /**
4206
4291
  * @hidden
4207
4292
  */
@@ -17333,6 +17418,15 @@ class CommandColumnComponent extends ColumnBase {
17333
17418
  get templateRef() {
17334
17419
  return this.template ? this.template.templateRef : undefined;
17335
17420
  }
17421
+ /**
17422
+ * Defines a function that is used to determine the rowspan of each column cell.
17423
+ */
17424
+ set cellRowspan(cellRowspan) {
17425
+ super.cellRowspan = cellRowspan;
17426
+ }
17427
+ get cellRowspan() {
17428
+ return super.cellRowspan;
17429
+ }
17336
17430
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CommandColumnComponent, deps: [{ token: ColumnBase, host: true, optional: true, skipSelf: true }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
17337
17431
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CommandColumnComponent, isStandalone: true, selector: "kendo-grid-command-column", providers: [
17338
17432
  {
@@ -17410,6 +17504,15 @@ class CheckboxColumnComponent extends ColumnBase {
17410
17504
  rowSelectable(rowIdx) {
17411
17505
  return !this.selectionService.nonSelectableRows.has(rowIdx) && !this.cellSelectionService.nonSelectableRows.has(rowIdx);
17412
17506
  }
17507
+ /**
17508
+ * Defines a function that is used to determine the rowspan of each column cell.
17509
+ */
17510
+ set cellRowspan(cellRowspan) {
17511
+ super.cellRowspan = cellRowspan;
17512
+ }
17513
+ get cellRowspan() {
17514
+ return super.cellRowspan;
17515
+ }
17413
17516
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CheckboxColumnComponent, deps: [{ token: SelectionService }, { token: CellSelectionService }, { token: ColumnBase, host: true, optional: true, skipSelf: true }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
17414
17517
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: CheckboxColumnComponent, isStandalone: true, selector: "kendo-grid-checkbox-column", inputs: { showSelectAll: "showSelectAll", showDisabledCheckbox: "showDisabledCheckbox" }, providers: [
17415
17518
  {
@@ -19632,6 +19735,15 @@ class RowReorderColumnComponent extends ColumnBase {
19632
19735
  super(parent, idService);
19633
19736
  this.parent = parent;
19634
19737
  }
19738
+ /**
19739
+ * Defines a function that is used to determine the rowspan of each column cell.
19740
+ */
19741
+ set cellRowspan(cellRowspan) {
19742
+ super.cellRowspan = cellRowspan;
19743
+ }
19744
+ get cellRowspan() {
19745
+ return super.cellRowspan;
19746
+ }
19635
19747
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: RowReorderColumnComponent, deps: [{ token: ColumnBase, host: true, optional: true, skipSelf: true }, { token: IdService, optional: true }], target: i0.ɵɵFactoryTarget.Component });
19636
19748
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: RowReorderColumnComponent, isStandalone: true, selector: "kendo-grid-rowreorder-column", inputs: { dragHandleIcon: "dragHandleIcon", dragHandleSVGIcon: "dragHandleSVGIcon" }, providers: [
19637
19749
  {
@@ -19716,8 +19828,8 @@ const packageMetadata = {
19716
19828
  productName: 'Kendo UI for Angular',
19717
19829
  productCode: 'KENDOUIANGULAR',
19718
19830
  productCodes: ['KENDOUIANGULAR'],
19719
- publishDate: 1741597660,
19720
- version: '18.1.2-develop.3',
19831
+ publishDate: 1741947639,
19832
+ version: '18.2.0-develop.1',
19721
19833
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
19722
19834
  };
19723
19835
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-grid",
3
- "version": "18.1.2-develop.3",
3
+ "version": "18.2.0-develop.1",
4
4
  "description": "Kendo UI Grid for Angular - high performance data grid with paging, filtering, virtualization, CRUD, and more.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -26,7 +26,7 @@
26
26
  "package": {
27
27
  "productName": "Kendo UI for Angular",
28
28
  "productCode": "KENDOUIANGULAR",
29
- "publishDate": 1741597660,
29
+ "publishDate": 1741947639,
30
30
  "licensingDocsUrl": "https://www.telerik.com/kendo-angular-ui/my-license/"
31
31
  }
32
32
  },
@@ -39,27 +39,27 @@
39
39
  "@progress/kendo-data-query": "^1.0.0",
40
40
  "@progress/kendo-drawing": "^1.21.0",
41
41
  "@progress/kendo-licensing": "^1.5.0",
42
- "@progress/kendo-angular-buttons": "18.1.2-develop.3",
43
- "@progress/kendo-angular-common": "18.1.2-develop.3",
44
- "@progress/kendo-angular-dateinputs": "18.1.2-develop.3",
45
- "@progress/kendo-angular-layout": "18.1.2-develop.3",
46
- "@progress/kendo-angular-dropdowns": "18.1.2-develop.3",
47
- "@progress/kendo-angular-excel-export": "18.1.2-develop.3",
48
- "@progress/kendo-angular-icons": "18.1.2-develop.3",
49
- "@progress/kendo-angular-inputs": "18.1.2-develop.3",
50
- "@progress/kendo-angular-intl": "18.1.2-develop.3",
51
- "@progress/kendo-angular-l10n": "18.1.2-develop.3",
52
- "@progress/kendo-angular-label": "18.1.2-develop.3",
53
- "@progress/kendo-angular-pager": "18.1.2-develop.3",
54
- "@progress/kendo-angular-pdf-export": "18.1.2-develop.3",
55
- "@progress/kendo-angular-popup": "18.1.2-develop.3",
56
- "@progress/kendo-angular-toolbar": "18.1.2-develop.3",
57
- "@progress/kendo-angular-utils": "18.1.2-develop.3",
42
+ "@progress/kendo-angular-buttons": "18.2.0-develop.1",
43
+ "@progress/kendo-angular-common": "18.2.0-develop.1",
44
+ "@progress/kendo-angular-dateinputs": "18.2.0-develop.1",
45
+ "@progress/kendo-angular-layout": "18.2.0-develop.1",
46
+ "@progress/kendo-angular-dropdowns": "18.2.0-develop.1",
47
+ "@progress/kendo-angular-excel-export": "18.2.0-develop.1",
48
+ "@progress/kendo-angular-icons": "18.2.0-develop.1",
49
+ "@progress/kendo-angular-inputs": "18.2.0-develop.1",
50
+ "@progress/kendo-angular-intl": "18.2.0-develop.1",
51
+ "@progress/kendo-angular-l10n": "18.2.0-develop.1",
52
+ "@progress/kendo-angular-label": "18.2.0-develop.1",
53
+ "@progress/kendo-angular-pager": "18.2.0-develop.1",
54
+ "@progress/kendo-angular-pdf-export": "18.2.0-develop.1",
55
+ "@progress/kendo-angular-popup": "18.2.0-develop.1",
56
+ "@progress/kendo-angular-toolbar": "18.2.0-develop.1",
57
+ "@progress/kendo-angular-utils": "18.2.0-develop.1",
58
58
  "rxjs": "^6.5.3 || ^7.0.0"
59
59
  },
60
60
  "dependencies": {
61
61
  "tslib": "^2.3.1",
62
- "@progress/kendo-angular-schematics": "18.1.2-develop.3",
62
+ "@progress/kendo-angular-schematics": "18.2.0-develop.1",
63
63
  "@progress/kendo-common": "^1.0.1",
64
64
  "@progress/kendo-file-saver": "^1.0.0"
65
65
  },
@@ -4,14 +4,14 @@ const schematics_1 = require("@angular-devkit/schematics");
4
4
  function default_1(options) {
5
5
  const finalOptions = Object.assign(Object.assign({}, options), { mainNgModule: 'GridModule', package: 'grid', peerDependencies: {
6
6
  // peer deps of the dropdowns
7
- '@progress/kendo-angular-treeview': '18.1.2-develop.3',
8
- '@progress/kendo-angular-navigation': '18.1.2-develop.3',
7
+ '@progress/kendo-angular-treeview': '18.2.0-develop.1',
8
+ '@progress/kendo-angular-navigation': '18.2.0-develop.1',
9
9
  // peer dependency of kendo-angular-inputs
10
- '@progress/kendo-angular-dialog': '18.1.2-develop.3',
10
+ '@progress/kendo-angular-dialog': '18.2.0-develop.1',
11
11
  // peer dependency of kendo-angular-icons
12
12
  '@progress/kendo-svg-icons': '^4.0.0',
13
13
  // peer dependency of kendo-angular-layout
14
- '@progress/kendo-angular-progressbar': '18.1.2-develop.3'
14
+ '@progress/kendo-angular-progressbar': '18.2.0-develop.1'
15
15
  } });
16
16
  return (0, schematics_1.externalSchematic)('@progress/kendo-angular-schematics', 'ng-add', finalOptions);
17
17
  }
package/utils.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { QueryList, InjectionToken } from '@angular/core';
6
6
  import { Observable } from 'rxjs';
7
+ import { ColumnBase, RowArgs } from '.';
7
8
  export { isChanged, anyChanged, hasObservers } from '@progress/kendo-angular-common';
8
9
  /**
9
10
  * @hidden
@@ -100,3 +101,7 @@ export declare const isGroupResult: (obj: any) => boolean;
100
101
  * @hidden
101
102
  */
102
103
  export declare const roundDown: (value: number) => number;
104
+ /**
105
+ * @hidden
106
+ */
107
+ export declare const defaultCellRowSpan: (row: RowArgs, column: ColumnBase, data: any[]) => number;