@reforgium/data-grid 2.5.4 → 3.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.
@@ -1,7 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { input, inject, TemplateRef, Directive, booleanAttribute, contentChild, Component, numberAttribute, InjectionToken, makeEnvironmentProviders, signal, computed, effect, Injectable, ChangeDetectionStrategy, output, untracked, DestroyRef, afterRenderEffect, viewChild, NgZone, contentChildren, afterNextRender } from '@angular/core';
3
3
  import { NgTemplateOutlet, DatePipe, DecimalPipe } from '@angular/common';
4
- import { Subject, debounceTime, fromEvent, Subscription } from 'rxjs';
5
4
 
6
5
  /**
7
6
  * Directive for defining type-specific cell templates in a data grid.
@@ -38,10 +37,10 @@ class DataGridTypeCellTemplateDirective {
38
37
  * receiving `RenderTemplateData` as its context with cell-specific information.
39
38
  */
40
39
  tpl = inject((TemplateRef));
41
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridTypeCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
42
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: DataGridTypeCellTemplateDirective, isStandalone: true, selector: "ng-template[reDataGridTypeCell]", inputs: { type: { classPropertyName: "type", publicName: "reDataGridTypeCell", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
40
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridTypeCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
41
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: DataGridTypeCellTemplateDirective, isStandalone: true, selector: "ng-template[reDataGridTypeCell]", inputs: { type: { classPropertyName: "type", publicName: "reDataGridTypeCell", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
43
42
  }
44
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridTypeCellTemplateDirective, decorators: [{
43
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridTypeCellTemplateDirective, decorators: [{
45
44
  type: Directive,
46
45
  args: [{ selector: 'ng-template[reDataGridTypeCell]' }]
47
46
  }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "reDataGridTypeCell", required: false }] }] } });
@@ -53,10 +52,10 @@ class DataGridCellTemplateDirective {
53
52
  * The template context is of the type `DataGridCellTemplateDirective`.
54
53
  */
55
54
  tpl = inject((TemplateRef));
56
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
57
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: DataGridCellTemplateDirective, isStandalone: true, selector: "ng-template[reDataGridCell]", inputs: { key: { classPropertyName: "key", publicName: "reDataGridCell", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
55
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
56
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: DataGridCellTemplateDirective, isStandalone: true, selector: "ng-template[reDataGridCell]", inputs: { key: { classPropertyName: "key", publicName: "reDataGridCell", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
58
57
  }
59
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellTemplateDirective, decorators: [{
58
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridCellTemplateDirective, decorators: [{
60
59
  type: Directive,
61
60
  args: [{ selector: 'ng-template[reDataGridCell]' }]
62
61
  }], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "reDataGridCell", required: false }] }] } });
@@ -87,10 +86,10 @@ class DataGridHeaderTemplateDirective {
87
86
  * The template context is of the type `HeaderTemplateData`.
88
87
  */
89
88
  tpl = inject((TemplateRef));
90
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridHeaderTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
91
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: DataGridHeaderTemplateDirective, isStandalone: true, selector: "ng-template[reDataGridHeader]", inputs: { key: { classPropertyName: "key", publicName: "reDataGridHeader", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
89
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridHeaderTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
90
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: DataGridHeaderTemplateDirective, isStandalone: true, selector: "ng-template[reDataGridHeader]", inputs: { key: { classPropertyName: "key", publicName: "reDataGridHeader", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
92
91
  }
93
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridHeaderTemplateDirective, decorators: [{
92
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridHeaderTemplateDirective, decorators: [{
94
93
  type: Directive,
95
94
  args: [{ selector: 'ng-template[reDataGridHeader]' }]
96
95
  }], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "reDataGridHeader", required: false }] }] } });
@@ -117,29 +116,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
117
116
  */
118
117
  class DataGridRowDirective {
119
118
  tpl = inject((TemplateRef));
120
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridRowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
121
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridRowDirective, isStandalone: true, selector: "ng-template[reDataGridRow]", ngImport: i0 });
119
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridRowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
120
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: DataGridRowDirective, isStandalone: true, selector: "ng-template[reDataGridRow]", ngImport: i0 });
122
121
  }
123
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridRowDirective, decorators: [{
122
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridRowDirective, decorators: [{
124
123
  type: Directive,
125
124
  args: [{ selector: 'ng-template[reDataGridRow]' }]
126
125
  }] });
127
126
 
128
127
  class DataGridDeclarativeHeaderDirective {
129
128
  tpl = inject((TemplateRef));
130
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridDeclarativeHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
131
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridDeclarativeHeaderDirective, isStandalone: true, selector: "ng-template[reHeader]", ngImport: i0 });
129
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridDeclarativeHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
130
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: DataGridDeclarativeHeaderDirective, isStandalone: true, selector: "ng-template[reHeader]", ngImport: i0 });
132
131
  }
133
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridDeclarativeHeaderDirective, decorators: [{
132
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridDeclarativeHeaderDirective, decorators: [{
134
133
  type: Directive,
135
134
  args: [{ selector: 'ng-template[reHeader]' }]
136
135
  }] });
137
136
  class DataGridDeclarativeCellDirective {
138
137
  tpl = inject((TemplateRef));
139
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridDeclarativeCellDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
140
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridDeclarativeCellDirective, isStandalone: true, selector: "ng-template[reCell]", ngImport: i0 });
138
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridDeclarativeCellDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
139
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: DataGridDeclarativeCellDirective, isStandalone: true, selector: "ng-template[reCell]", ngImport: i0 });
141
140
  }
142
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridDeclarativeCellDirective, decorators: [{
141
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridDeclarativeCellDirective, decorators: [{
143
142
  type: Directive,
144
143
  args: [{ selector: 'ng-template[reCell]' }]
145
144
  }] });
@@ -193,10 +192,10 @@ class DataGridDeclarativeColumn {
193
192
  tooltip: this.tooltip(),
194
193
  };
195
194
  }
196
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridDeclarativeColumn, deps: [], target: i0.ɵɵFactoryTarget.Component });
197
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.1.1", type: DataGridDeclarativeColumn, isStandalone: true, selector: "re-dg-column", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, sortKey: { classPropertyName: "sortKey", publicName: "sortKey", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, expandBy: { classPropertyName: "expandBy", publicName: "expandBy", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, flex: { classPropertyName: "flex", publicName: "flex", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, typeParams: { classPropertyName: "typeParams", publicName: "typeParams", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, transformer: { classPropertyName: "transformer", publicName: "transformer", isSignal: true, isRequired: false, transformFunction: null }, track: { classPropertyName: "track", publicName: "track", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "headerTplRef", first: true, predicate: DataGridDeclarativeHeaderDirective, descendants: true, isSignal: true }, { propertyName: "cellTplRef", first: true, predicate: DataGridDeclarativeCellDirective, descendants: true, isSignal: true }], ngImport: i0, template: '<ng-content />', isInline: true });
195
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridDeclarativeColumn, deps: [], target: i0.ɵɵFactoryTarget.Component });
196
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.4", type: DataGridDeclarativeColumn, isStandalone: true, selector: "re-dg-column", inputs: { key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: true, transformFunction: null }, header: { classPropertyName: "header", publicName: "header", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, sortKey: { classPropertyName: "sortKey", publicName: "sortKey", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, expandBy: { classPropertyName: "expandBy", publicName: "expandBy", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, flex: { classPropertyName: "flex", publicName: "flex", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, typeParams: { classPropertyName: "typeParams", publicName: "typeParams", isSignal: true, isRequired: false, transformFunction: null }, defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, transformer: { classPropertyName: "transformer", publicName: "transformer", isSignal: true, isRequired: false, transformFunction: null }, track: { classPropertyName: "track", publicName: "track", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "headerTplRef", first: true, predicate: DataGridDeclarativeHeaderDirective, descendants: true, isSignal: true }, { propertyName: "cellTplRef", first: true, predicate: DataGridDeclarativeCellDirective, descendants: true, isSignal: true }], ngImport: i0, template: '<ng-content />', isInline: true });
198
197
  }
199
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridDeclarativeColumn, decorators: [{
198
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridDeclarativeColumn, decorators: [{
200
199
  type: Component,
201
200
  args: [{
202
201
  selector: 're-dg-column',
@@ -235,10 +234,10 @@ function toOptionalBoolean(value) {
235
234
  */
236
235
  class DataGridCellEmptyDirective {
237
236
  tpl = inject((TemplateRef));
238
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellEmptyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
239
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridCellEmptyDirective, isStandalone: true, selector: "ng-template[reDataGridEmpty]", ngImport: i0 });
237
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridCellEmptyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
238
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: DataGridCellEmptyDirective, isStandalone: true, selector: "ng-template[reDataGridEmpty]", ngImport: i0 });
240
239
  }
241
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellEmptyDirective, decorators: [{
240
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridCellEmptyDirective, decorators: [{
242
241
  type: Directive,
243
242
  args: [{ selector: 'ng-template[reDataGridEmpty]' }]
244
243
  }] });
@@ -260,10 +259,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
260
259
  */
261
260
  class DataGridCellLoadingDirective {
262
261
  tpl = inject((TemplateRef));
263
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellLoadingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
264
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridCellLoadingDirective, isStandalone: true, selector: "ng-template[reDataGridLoading]", ngImport: i0 });
262
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridCellLoadingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
263
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: DataGridCellLoadingDirective, isStandalone: true, selector: "ng-template[reDataGridLoading]", ngImport: i0 });
265
264
  }
266
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellLoadingDirective, decorators: [{
265
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridCellLoadingDirective, decorators: [{
267
266
  type: Directive,
268
267
  args: [{ selector: 'ng-template[reDataGridLoading]' }]
269
268
  }] });
@@ -287,29 +286,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
287
286
  */
288
287
  class DataGridStickyRowDirective {
289
288
  tpl = inject((TemplateRef));
290
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridStickyRowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
291
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridStickyRowDirective, isStandalone: true, selector: "ng-template[reDataGridStickyRow]", ngImport: i0 });
289
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridStickyRowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
290
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: DataGridStickyRowDirective, isStandalone: true, selector: "ng-template[reDataGridStickyRow]", ngImport: i0 });
292
291
  }
293
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridStickyRowDirective, decorators: [{
292
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridStickyRowDirective, decorators: [{
294
293
  type: Directive,
295
294
  args: [{ selector: 'ng-template[reDataGridStickyRow]' }]
296
295
  }] });
297
296
 
298
297
  class DataGridSortIconDirective {
299
298
  tpl = inject((TemplateRef));
300
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridSortIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
301
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridSortIconDirective, isStandalone: true, selector: "ng-template[reDataGridSortIcon]", ngImport: i0 });
299
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridSortIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
300
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: DataGridSortIconDirective, isStandalone: true, selector: "ng-template[reDataGridSortIcon]", ngImport: i0 });
302
301
  }
303
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridSortIconDirective, decorators: [{
302
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridSortIconDirective, decorators: [{
304
303
  type: Directive,
305
304
  args: [{ selector: 'ng-template[reDataGridSortIcon]' }]
306
305
  }] });
307
306
  class DataGridExpanderIconDirective {
308
307
  tpl = inject((TemplateRef));
309
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridExpanderIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
310
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridExpanderIconDirective, isStandalone: true, selector: "ng-template[reDataGridExpanderIcon]", ngImport: i0 });
308
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridExpanderIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
309
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: DataGridExpanderIconDirective, isStandalone: true, selector: "ng-template[reDataGridExpanderIcon]", ngImport: i0 });
311
310
  }
312
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridExpanderIconDirective, decorators: [{
311
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridExpanderIconDirective, decorators: [{
313
312
  type: Directive,
314
313
  args: [{ selector: 'ng-template[reDataGridExpanderIcon]' }]
315
314
  }] });
@@ -357,6 +356,10 @@ const DATA_GRID_TYPE_RENDERERS = new InjectionToken('RE_DATA_GRID_TYPE_RENDERERS
357
356
  providedIn: 'root',
358
357
  factory: () => ({}),
359
358
  });
359
+ const DATA_GRID_HEADER_TEXT_RESOLVER = new InjectionToken('RE_DATA_GRID_HEADER_TEXT_RESOLVER', {
360
+ providedIn: 'root',
361
+ factory: () => (text) => text,
362
+ });
360
363
  /**
361
364
  * Provides a default configuration for Data Grid, overriding base settings.
362
365
  *
@@ -419,6 +422,37 @@ function provideDataGridTypeRenderers(renderers) {
419
422
  },
420
423
  ]);
421
424
  }
425
+ /**
426
+ * Provides a global header text resolver for all `re-data-grid` instances in the current injector scope.
427
+ *
428
+ * Useful for integrating i18n layers without coupling the grid package to a specific translation library.
429
+ * The factory runs in Angular DI context, so it may use `inject(...)` to access consumer-side services.
430
+ */
431
+ function provideDataGridHeaderTextResolver(factory) {
432
+ return makeEnvironmentProviders([
433
+ {
434
+ provide: DATA_GRID_HEADER_TEXT_RESOLVER,
435
+ useFactory: factory,
436
+ },
437
+ ]);
438
+ }
439
+ /**
440
+ * Advanced variant of `provideDataGridHeaderTextResolver(...)` that composes with the parent injector resolver.
441
+ *
442
+ * Use this only when the current scope should extend or wrap an existing header resolver
443
+ * instead of replacing it completely.
444
+ */
445
+ function provideDataGridHeaderTextResolverWithParent(factory) {
446
+ return makeEnvironmentProviders([
447
+ {
448
+ provide: DATA_GRID_HEADER_TEXT_RESOLVER,
449
+ useFactory: () => {
450
+ const parent = inject(DATA_GRID_HEADER_TEXT_RESOLVER, { optional: true, skipSelf: true }) ?? ((text) => text);
451
+ return factory(parent);
452
+ },
453
+ },
454
+ ]);
455
+ }
422
456
 
423
457
  const GRID_INDEX_COLUMN = {
424
458
  key: '_index',
@@ -666,6 +700,14 @@ function roundAndFix(cols, widths, fixedIdx, autoIdx, containerWidth) {
666
700
  need--;
667
701
  }
668
702
  }
703
+ // If all auto-columns are at maxWidth, the loop above exits without
704
+ // distributing remaining rounding pixels, causing a visual gap.
705
+ // Distribute the remainder ignoring maxWidth — these are sub-pixel
706
+ // corrections (typically 1–2px) that don't affect layout meaningfully.
707
+ for (let k = autoIdx.length - 1; k >= 0 && need > 0; k--) {
708
+ widths[autoIdx[k]] += 1;
709
+ need--;
710
+ }
669
711
  }
670
712
  /**
671
713
  * Clamps a numeric value between optional minimum and maximum bounds.
@@ -1223,10 +1265,10 @@ class DataGridVm {
1223
1265
  const right = rightCols.map((col) => `${col.key}:${this.widthByKey(col.key)}`).join(',');
1224
1266
  return `l:${left}|r:${right}`;
1225
1267
  }
1226
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridVm, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1227
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridVm });
1268
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridVm, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1269
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridVm });
1228
1270
  }
1229
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridVm, decorators: [{
1271
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridVm, decorators: [{
1230
1272
  type: Injectable
1231
1273
  }], ctorParameters: () => [] });
1232
1274
 
@@ -1358,7 +1400,6 @@ class DataGridCellComponent {
1358
1400
  }
1359
1401
  return displayValue;
1360
1402
  }, ...(ngDevMode ? [{ debugName: "value" }] : []));
1361
- resolvedAlign = computed(() => this.column().align ?? 'left', ...(ngDevMode ? [{ debugName: "resolvedAlign" }] : []));
1362
1403
  resolveTypeTemplate(type) {
1363
1404
  if (!type) {
1364
1405
  return undefined;
@@ -1366,46 +1407,47 @@ class DataGridCellComponent {
1366
1407
  return (this.vm.globalTypeCellTpls.get(type) ??
1367
1408
  this.typeRenderers[type]);
1368
1409
  }
1369
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1370
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DataGridCellComponent, isStandalone: true, selector: "re-data-grid-cell", inputs: { index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: true, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, isPinned: { classPropertyName: "isPinned", publicName: "isPinned", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
1410
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1411
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: DataGridCellComponent, isStandalone: true, selector: "re-data-grid-cell", inputs: { index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: true, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null }, isPinned: { classPropertyName: "isPinned", publicName: "isPinned", isSignal: true, isRequired: false, transformFunction: null }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
1371
1412
  @let row = item();
1372
1413
  @let col = $any(column());
1373
1414
  @let val = $any(value());
1374
1415
  @let pinned = isPinned();
1416
+ @let align = col.align ?? 'left';
1375
1417
 
1376
- @switch (type()) {
1377
- @case ('tpl') {
1378
- <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1379
- <ng-container
1380
- [ngTemplateOutlet]="col.renderTemplate"
1381
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1382
- />
1383
- </div>
1384
- }
1385
- @case ('globalTypeTpl') {
1386
- <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1387
- <ng-container
1388
- [ngTemplateOutlet]="resolveTypeTemplate(col.type)"
1389
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1390
- />
1391
- </div>
1392
- }
1393
- @case ('globalDataTpl') {
1394
- <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1395
- <ng-container
1396
- [ngTemplateOutlet]="vm.globalDataCellTpls.get(col.key)"
1397
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1398
- />
1399
- </div>
1400
- }
1401
- @case ('globalRowTpl') {
1402
- <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1403
- <ng-container
1404
- [ngTemplateOutlet]="vm.globalRowCellTpls.get(col.key)"
1405
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1406
- />
1407
- </div>
1408
- }
1418
+ @switch (type()) {
1419
+ @case ('tpl') {
1420
+ <div class="re-dg-cell-template" [style.justify-content]="align" [style.text-align]="align">
1421
+ <ng-container
1422
+ [ngTemplateOutlet]="col.renderTemplate"
1423
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1424
+ />
1425
+ </div>
1426
+ }
1427
+ @case ('globalTypeTpl') {
1428
+ <div class="re-dg-cell-template" [style.justify-content]="align" [style.text-align]="align">
1429
+ <ng-container
1430
+ [ngTemplateOutlet]="resolveTypeTemplate(col.type)"
1431
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1432
+ />
1433
+ </div>
1434
+ }
1435
+ @case ('globalDataTpl') {
1436
+ <div class="re-dg-cell-template" [style.justify-content]="align" [style.text-align]="align">
1437
+ <ng-container
1438
+ [ngTemplateOutlet]="vm.globalDataCellTpls.get(col.key)"
1439
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1440
+ />
1441
+ </div>
1442
+ }
1443
+ @case ('globalRowTpl') {
1444
+ <div class="re-dg-cell-template" [style.justify-content]="align" [style.text-align]="align">
1445
+ <ng-container
1446
+ [ngTemplateOutlet]="vm.globalRowCellTpls.get(col.key)"
1447
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1448
+ />
1449
+ </div>
1450
+ }
1409
1451
  @case ('date') {
1410
1452
  <span class="re-dg-cell-text">{{ val | date: col?.typeParams }}</span>
1411
1453
  }
@@ -1419,49 +1461,50 @@ class DataGridCellComponent {
1419
1461
  <span class="re-dg-cell-text">{{ val }}</span>
1420
1462
  }
1421
1463
  }
1422
- `, isInline: true, styles: [":host{display:block;width:100%;min-width:0;text-align:inherit}.re-dg-cell-text{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:var(--re-data-grid-cell-line-height, 1.2);-webkit-box-orient:vertical;-webkit-line-clamp:var(--re-data-grid-cell-max-lines, 2)}.re-dg-cell-template{display:flex;width:100%;min-width:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: DecimalPipe, name: "number" }] });
1464
+ `, isInline: true, styles: [":host{display:block;width:100%;min-width:0;text-align:inherit}.re-dg-cell-text{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:var(--re-data-grid-cell-line-height, 1.2);-webkit-box-orient:vertical;-webkit-line-clamp:var(--re-data-grid-cell-max-lines, 2)}.re-dg-cell-template{display:flex;width:100%;min-width:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1423
1465
  }
1424
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellComponent, decorators: [{
1466
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGridCellComponent, decorators: [{
1425
1467
  type: Component,
1426
1468
  args: [{ selector: 're-data-grid-cell', template: `
1427
1469
  @let row = item();
1428
1470
  @let col = $any(column());
1429
1471
  @let val = $any(value());
1430
1472
  @let pinned = isPinned();
1473
+ @let align = col.align ?? 'left';
1431
1474
 
1432
- @switch (type()) {
1433
- @case ('tpl') {
1434
- <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1435
- <ng-container
1436
- [ngTemplateOutlet]="col.renderTemplate"
1437
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1438
- />
1439
- </div>
1440
- }
1441
- @case ('globalTypeTpl') {
1442
- <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1443
- <ng-container
1444
- [ngTemplateOutlet]="resolveTypeTemplate(col.type)"
1445
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1446
- />
1447
- </div>
1448
- }
1449
- @case ('globalDataTpl') {
1450
- <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1451
- <ng-container
1452
- [ngTemplateOutlet]="vm.globalDataCellTpls.get(col.key)"
1453
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1454
- />
1455
- </div>
1456
- }
1457
- @case ('globalRowTpl') {
1458
- <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1459
- <ng-container
1460
- [ngTemplateOutlet]="vm.globalRowCellTpls.get(col.key)"
1461
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1462
- />
1463
- </div>
1464
- }
1475
+ @switch (type()) {
1476
+ @case ('tpl') {
1477
+ <div class="re-dg-cell-template" [style.justify-content]="align" [style.text-align]="align">
1478
+ <ng-container
1479
+ [ngTemplateOutlet]="col.renderTemplate"
1480
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1481
+ />
1482
+ </div>
1483
+ }
1484
+ @case ('globalTypeTpl') {
1485
+ <div class="re-dg-cell-template" [style.justify-content]="align" [style.text-align]="align">
1486
+ <ng-container
1487
+ [ngTemplateOutlet]="resolveTypeTemplate(col.type)"
1488
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1489
+ />
1490
+ </div>
1491
+ }
1492
+ @case ('globalDataTpl') {
1493
+ <div class="re-dg-cell-template" [style.justify-content]="align" [style.text-align]="align">
1494
+ <ng-container
1495
+ [ngTemplateOutlet]="vm.globalDataCellTpls.get(col.key)"
1496
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1497
+ />
1498
+ </div>
1499
+ }
1500
+ @case ('globalRowTpl') {
1501
+ <div class="re-dg-cell-template" [style.justify-content]="align" [style.text-align]="align">
1502
+ <ng-container
1503
+ [ngTemplateOutlet]="vm.globalRowCellTpls.get(col.key)"
1504
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1505
+ />
1506
+ </div>
1507
+ }
1465
1508
  @case ('date') {
1466
1509
  <span class="re-dg-cell-text">{{ val | date: col?.typeParams }}</span>
1467
1510
  }
@@ -1475,7 +1518,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
1475
1518
  <span class="re-dg-cell-text">{{ val }}</span>
1476
1519
  }
1477
1520
  }
1478
- `, imports: [NgTemplateOutlet, DatePipe, DecimalPipe], styles: [":host{display:block;width:100%;min-width:0;text-align:inherit}.re-dg-cell-text{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:var(--re-data-grid-cell-line-height, 1.2);-webkit-box-orient:vertical;-webkit-line-clamp:var(--re-data-grid-cell-max-lines, 2)}.re-dg-cell-template{display:flex;width:100%;min-width:0}\n"] }]
1521
+ `, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgTemplateOutlet, DatePipe, DecimalPipe], styles: [":host{display:block;width:100%;min-width:0;text-align:inherit}.re-dg-cell-text{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:var(--re-data-grid-cell-line-height, 1.2);-webkit-box-orient:vertical;-webkit-line-clamp:var(--re-data-grid-cell-max-lines, 2)}.re-dg-cell-template{display:flex;width:100%;min-width:0}\n"] }]
1479
1522
  }], propDecorators: { index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: true }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], isPinned: [{ type: i0.Input, args: [{ isSignal: true, alias: "isPinned", required: false }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }] } });
1480
1523
 
1481
1524
  // noinspection ES6PreferShortImport
@@ -1568,7 +1611,11 @@ function createGridColumnResizeFeature(ctx) {
1568
1611
  applyWidth(startWidth + delta);
1569
1612
  };
1570
1613
  onUpRef = () => {
1614
+ const resizedKey = activeKey;
1571
1615
  stopResize();
1616
+ if (resizedKey !== null) {
1617
+ ctx.emitResizeEnd?.(resizedKey, ctx.resolveWidth(resizedKey));
1618
+ }
1572
1619
  };
1573
1620
  const targetWindow = ctx.getWindow();
1574
1621
  targetWindow.addEventListener('mousemove', onMoveRef);
@@ -1625,6 +1672,56 @@ function createGridExpanderFeature(ctx) {
1625
1672
  };
1626
1673
  }
1627
1674
 
1675
+ function createGridGapLoaderFeature(ctx) {
1676
+ const topGap = () => {
1677
+ if (!ctx.hasSource() || ctx.getMode() !== 'infinity' || ctx.getRenderCount() <= 0) {
1678
+ return null;
1679
+ }
1680
+ let count = 0;
1681
+ const start = ctx.getStartIndex();
1682
+ const renderCount = ctx.getRenderCount();
1683
+ for (let offset = 0; offset < renderCount; offset++) {
1684
+ const index = start + offset;
1685
+ if (ctx.isStickyRowIndex(index) || ctx.hasRowAt(index)) {
1686
+ break;
1687
+ }
1688
+ count++;
1689
+ }
1690
+ return count ? { start, count } : null;
1691
+ };
1692
+ const bottomGap = () => {
1693
+ if (!ctx.hasSource() || ctx.getMode() !== 'infinity' || ctx.getRenderCount() <= 0) {
1694
+ return null;
1695
+ }
1696
+ let count = 0;
1697
+ const start = ctx.getStartIndex();
1698
+ const renderCount = ctx.getRenderCount();
1699
+ for (let offset = renderCount - 1; offset >= 0; offset--) {
1700
+ const index = start + offset;
1701
+ if (ctx.isStickyRowIndex(index) || ctx.hasRowAt(index)) {
1702
+ break;
1703
+ }
1704
+ count++;
1705
+ }
1706
+ return count ? { start: start + renderCount - count, count } : null;
1707
+ };
1708
+ const includesIndex = (index, gap) => !!gap && index >= gap.start && index < gap.start + gap.count;
1709
+ const shouldRenderPlaceholder = (index) => ctx.hasSource() && ctx.getMode() === 'infinity' && index >= 0 && index < ctx.getTotalCount();
1710
+ const shouldRenderInnerSkeleton = (index, top, bottom) => {
1711
+ if (!shouldRenderPlaceholder(index) || ctx.isStickyRowIndex(index)) {
1712
+ return false;
1713
+ }
1714
+ return !includesIndex(index, top) && !includesIndex(index, bottom);
1715
+ };
1716
+ return {
1717
+ bottomGap,
1718
+ includesIndex,
1719
+ shouldRenderInnerSkeleton,
1720
+ shouldRenderPlaceholder,
1721
+ topGap,
1722
+ };
1723
+ }
1724
+
1628
1725
  // noinspection ES6PreferShortImport
1629
1726
  function createGridHeaderGroupsFeature(ctx) {
1630
1727
  const sortOrderFor = (col) => {
@@ -1744,31 +1841,45 @@ function createGridResizeObserverFeature(ctx) {
1744
1841
  let observer;
1745
1842
  let lastResizeWidth = -1;
1746
1843
  let lastResizeHeight = -1;
1747
- const resizeSubject = new Subject();
1844
+ let debounceId = null;
1845
+ const processEntries = (entries) => {
1846
+ const rect = entries[0].contentRect;
1847
+ const width = rect.width;
1848
+ const height = rect.height;
1849
+ const widthChanged = width !== lastResizeWidth;
1850
+ const heightChanged = height !== lastResizeHeight;
1851
+ if (!widthChanged && !heightChanged) {
1852
+ return;
1853
+ }
1854
+ lastResizeWidth = width;
1855
+ lastResizeHeight = height;
1856
+ if (widthChanged) {
1857
+ ctx.onWidthChanged(width);
1858
+ }
1859
+ if (heightChanged) {
1860
+ ctx.onHeightChanged(height);
1861
+ }
1862
+ };
1748
1863
  const initObserver = () => {
1749
1864
  const root = ctx.getRootElement();
1750
1865
  if (!root) {
1751
1866
  return;
1752
1867
  }
1753
- ctx.addSubscription(resizeSubject.pipe(debounceTime(ctx.getResizeDebounceMs())).subscribe((entries) => {
1754
- const rect = entries[0].contentRect;
1755
- const width = rect.width;
1756
- const height = rect.height;
1757
- const widthChanged = width !== lastResizeWidth;
1758
- const heightChanged = height !== lastResizeHeight;
1759
- if (!widthChanged && !heightChanged) {
1760
- return;
1761
- }
1762
- lastResizeWidth = width;
1763
- lastResizeHeight = height;
1764
- if (widthChanged) {
1765
- ctx.onWidthChanged(width);
1868
+ ctx.addCleanup(() => {
1869
+ if (debounceId !== null) {
1870
+ clearTimeout(debounceId);
1871
+ debounceId = null;
1766
1872
  }
1767
- if (heightChanged) {
1768
- ctx.onHeightChanged(height);
1873
+ });
1874
+ observer = new ResizeObserver((entries) => {
1875
+ if (debounceId !== null) {
1876
+ clearTimeout(debounceId);
1769
1877
  }
1770
- }));
1771
- observer = new ResizeObserver((entries) => resizeSubject.next(entries));
1878
+ debounceId = setTimeout(() => {
1879
+ debounceId = null;
1880
+ processEntries(entries);
1881
+ }, ctx.getResizeDebounceMs());
1882
+ });
1772
1883
  observer.observe(root);
1773
1884
  };
1774
1885
  const disconnect = () => {
@@ -1854,8 +1965,12 @@ function createGridScrollLoopFeature(ctx) {
1854
1965
  if (scrollEl) {
1855
1966
  const scrollDetector = new ScrollDirectionDetector(scrollEl);
1856
1967
  ctx.runOutsideAngular(() => {
1857
- ctx.addSubscription(fromEvent(scrollEl, 'scroll').subscribe(() => scheduleScrollTick(scrollDetector)));
1858
- ctx.addSubscription(fromEvent(scrollEl, 'scroll').subscribe(() => ctx.onStickySchedule()));
1968
+ const onScrollTick = () => scheduleScrollTick(scrollDetector);
1969
+ const onScrollSticky = () => ctx.onStickySchedule();
1970
+ scrollEl.addEventListener('scroll', onScrollTick, { passive: true });
1971
+ scrollEl.addEventListener('scroll', onScrollSticky, { passive: true });
1972
+ ctx.addCleanup(() => scrollEl.removeEventListener('scroll', onScrollTick));
1973
+ ctx.addCleanup(() => scrollEl.removeEventListener('scroll', onScrollSticky));
1859
1974
  });
1860
1975
  }
1861
1976
  queueMicrotask(() => ctx.onInitialVerticalScroll());
@@ -1897,10 +2012,13 @@ function createGridSelectionReconcileFeature(ctx) {
1897
2012
  }
1898
2013
  lastSelectionKeyField = keyField;
1899
2014
  lastValidSelectionKeys = new Set(keySet);
1900
- const nextSelected = ctx
1901
- .getSelectedKeys()
1902
- .filter((selectedKey) => selectedKey !== null && selectedKey !== undefined && keySet.has(selectedKey));
2015
+ const currentSelected = ctx.getSelectedKeys();
2016
+ const nextSelected = currentSelected.filter((selectedKey) => selectedKey !== null && selectedKey !== undefined && keySet.has(selectedKey));
2017
+ if (nextSelected.length === currentSelected.length) {
2018
+ return;
2019
+ }
1903
2020
  ctx.setSelectedKeys(nextSelected);
2021
+ ctx.emitSelectChange(nextSelected);
1904
2022
  };
1905
2023
  return { reconcile };
1906
2024
  }
@@ -1929,35 +2047,50 @@ function createGridSlotsFeature(ctx) {
1929
2047
 
1930
2048
  // noinspection ES6PreferShortImport
1931
2049
  function createGridSortFeature(ctx) {
2050
+ const getSortKey = (sort) => {
2051
+ return sort?.sort;
2052
+ };
2053
+ const normalizeSortItem = (sort) => {
2054
+ const sortKey = getSortKey(sort);
2055
+ if (!sortKey || !sort.order) {
2056
+ return null;
2057
+ }
2058
+ return { sort: sortKey, order: sort.order };
2059
+ };
2060
+ const emitSortChange = (sortKey, order) => {
2061
+ ctx.emitSortChange({ sort: sortKey, order });
2062
+ };
1932
2063
  const resetSort = () => {
1933
2064
  const prevKey = (ctx.getSortField() ?? '');
1934
2065
  ctx.setSortField(undefined);
1935
2066
  ctx.setSorts([]);
1936
- ctx.emitSortChange({ key: prevKey, order: undefined });
2067
+ emitSortChange(prevKey, undefined);
1937
2068
  ctx.emitMultiSortChange([]);
1938
2069
  };
1939
2070
  const setSort = (sort) => {
1940
- if (!sort.key || !sort.order) {
2071
+ const sortKey = getSortKey(sort);
2072
+ if (!sortKey || !sort.order) {
1941
2073
  resetSort();
1942
2074
  return;
1943
2075
  }
1944
- ctx.setSortField(String(sort.key));
2076
+ const normalized = { sort: sortKey, order: sort.order };
2077
+ ctx.setSortField(String(sortKey));
1945
2078
  ctx.setSortOrder(sort.order);
1946
- ctx.setSorts([{ key: sort.key, order: sort.order }]);
1947
- ctx.emitSortChange({ key: sort.key, order: sort.order });
2079
+ ctx.setSorts([normalized]);
2080
+ emitSortChange(sortKey, sort.order);
1948
2081
  ctx.getSortMode() === 'multi' && ctx.emitMultiSortChange(ctx.getSorts());
1949
2082
  };
1950
2083
  const setMultiSort = (sorts) => {
1951
- const normalizedSorts = (sorts ?? []).filter((sort) => !!sort?.key && !!sort?.order);
2084
+ const normalizedSorts = (sorts ?? []).map(normalizeSortItem).filter((sort) => !!sort);
1952
2085
  if (!normalizedSorts.length) {
1953
2086
  resetSort();
1954
2087
  return;
1955
2088
  }
1956
2089
  const active = normalizedSorts[normalizedSorts.length - 1];
1957
- ctx.setSortField(String(active.key));
2090
+ ctx.setSortField(String(active.sort));
1958
2091
  ctx.setSortOrder(active.order);
1959
2092
  ctx.setSorts([...normalizedSorts]);
1960
- ctx.emitSortChange({ key: active.key, order: active.order });
2093
+ emitSortChange(active.sort, active.order);
1961
2094
  ctx.emitMultiSortChange(ctx.getSorts());
1962
2095
  };
1963
2096
  const onSort = (sortKey) => {
@@ -1966,30 +2099,37 @@ function createGridSortFeature(ctx) {
1966
2099
  }
1967
2100
  if (ctx.getSortMode() === 'multi') {
1968
2101
  const currentSorts = ctx.getSorts();
1969
- const existingIndex = currentSorts.findIndex((item) => item.key === sortKey);
2102
+ const existingIndex = currentSorts.findIndex((item) => item.sort === sortKey);
1970
2103
  if (existingIndex >= 0) {
1971
2104
  const current = currentSorts[existingIndex];
1972
2105
  if (current.order === 'asc') {
1973
2106
  ctx.setSorts(currentSorts.map((item, index) => (index === existingIndex ? { ...item, order: 'desc' } : item)));
1974
2107
  }
1975
2108
  else {
1976
- ctx.setSorts(currentSorts.filter((item) => item.key !== sortKey));
2109
+ ctx.setSorts(currentSorts.filter((item) => item.sort !== sortKey));
1977
2110
  }
1978
2111
  }
1979
2112
  else {
1980
- ctx.setSorts([...currentSorts, { key: sortKey, order: 'asc' }]);
2113
+ ctx.setSorts([...currentSorts, { sort: sortKey, order: 'asc' }]);
1981
2114
  }
1982
2115
  const activeOrder = ctx.getSortOrderByKey(sortKey);
1983
- ctx.setSortField(sortKey);
1984
- activeOrder && ctx.setSortOrder(activeOrder);
1985
- ctx.emitSortChange({ key: sortKey, order: activeOrder });
1986
- ctx.emitMultiSortChange(ctx.getSorts());
2116
+ const remainingSorts = ctx.getSorts();
2117
+ if (remainingSorts.length === 0) {
2118
+ ctx.setSortField(undefined);
2119
+ ctx.setSortOrder('asc');
2120
+ }
2121
+ else {
2122
+ ctx.setSortField(sortKey);
2123
+ ctx.setSortOrder(activeOrder ?? 'asc');
2124
+ }
2125
+ emitSortChange(sortKey, activeOrder);
2126
+ ctx.emitMultiSortChange(remainingSorts);
1987
2127
  return;
1988
2128
  }
1989
2129
  if (ctx.getSortField() === sortKey) {
1990
2130
  if (ctx.getSortOrder() === 'asc') {
1991
2131
  ctx.setSortOrder('desc');
1992
- ctx.setSorts([{ key: sortKey, order: 'desc' }]);
2132
+ ctx.setSorts([{ sort: sortKey, order: 'desc' }]);
1993
2133
  }
1994
2134
  else {
1995
2135
  ctx.setSortField(undefined);
@@ -1999,16 +2139,338 @@ function createGridSortFeature(ctx) {
1999
2139
  else {
2000
2140
  ctx.setSortField(sortKey);
2001
2141
  ctx.setSortOrder('asc');
2002
- ctx.setSorts([{ key: sortKey, order: 'asc' }]);
2142
+ ctx.setSorts([{ sort: sortKey, order: 'asc' }]);
2003
2143
  }
2004
- ctx.emitSortChange({
2005
- key: sortKey,
2006
- order: ctx.getSortField() ? ctx.getSortOrder() : undefined,
2007
- });
2144
+ emitSortChange(sortKey, ctx.getSortField() ? ctx.getSortOrder() : undefined);
2008
2145
  };
2009
2146
  return { resetSort, setSort, setMultiSort, onSort };
2010
2147
  }
2011
2148
 
2149
+ // noinspection ES6PreferShortImport
2150
+ function createGridSourceDataFeature(ctx) {
2151
+ const PAGE_WINDOW_MULTIPLIER = 5;
2152
+ const SEQUENTIAL_PREFETCH_REQUESTS = 1;
2153
+ const PARALLEL_PREFETCH_REQUESTS = 3;
2154
+ const MAX_BUFFERED_PAGES = 100;
2155
+ const sourcePages = new Map();
2156
+ const bufferVersion = signal(0, ...(ngDevMode ? [{ debugName: "bufferVersion" }] : []));
2157
+ const pendingPages = new Set();
2158
+ const queuedPages = [];
2159
+ let lastSourceRef = null;
2160
+ let lastSourceVersion = null;
2161
+ let activeRequests = 0;
2162
+ let requestGeneration = 0;
2163
+ const resolvedLoading = () => ctx.getSource()?.loading() ?? ctx.getFallbackLoading();
2164
+ const totalRowCount = () => {
2165
+ const source = ctx.getSource();
2166
+ if (!source) {
2167
+ return ctx.getFallbackData()?.length ?? 0;
2168
+ }
2169
+ if (ctx.getMode() === 'infinity') {
2170
+ bufferVersion();
2171
+ const knownTotal = resolvedTotalElements(source);
2172
+ if (knownTotal !== null) {
2173
+ return knownTotal;
2174
+ }
2175
+ const loadedRows = contiguousLoadedRowCount(source);
2176
+ if (loadedRows <= 0) {
2177
+ return 0;
2178
+ }
2179
+ if (hasReachedInfinityEnd(source)) {
2180
+ return loadedRows;
2181
+ }
2182
+ return loadedRows + Math.max(1, source.pageSize || ctx.getFallbackPageSize());
2183
+ }
2184
+ return source.items()?.length ?? 0;
2185
+ };
2186
+ const selectionRows = () => {
2187
+ const source = ctx.getSource();
2188
+ if (!source) {
2189
+ return ctx.getFallbackData() ?? [];
2190
+ }
2191
+ const items = source.items() ?? [];
2192
+ if (ctx.getMode() !== 'infinity') {
2193
+ return items;
2194
+ }
2195
+ bufferVersion();
2196
+ return flattenBufferedPages();
2197
+ };
2198
+ const stickyRows = () => {
2199
+ if (ctx.getSource() && ctx.getMode() === 'infinity') {
2200
+ return [];
2201
+ }
2202
+ return selectionRows();
2203
+ };
2204
+ const rowAt = (index) => {
2205
+ if (index < 0) {
2206
+ return null;
2207
+ }
2208
+ const source = ctx.getSource();
2209
+ if (!source) {
2210
+ return ctx.getFallbackData()?.[index] ?? null;
2211
+ }
2212
+ if (ctx.getMode() !== 'infinity') {
2213
+ return source.items()?.[index] ?? null;
2214
+ }
2215
+ bufferVersion();
2216
+ const pageSize = Math.max(1, source.pageSize || ctx.getFallbackPageSize());
2217
+ const page = Math.floor(index / pageSize);
2218
+ const pageItems = sourcePages.get(page);
2219
+ if (!pageItems) {
2220
+ return null;
2221
+ }
2222
+ return pageItems[index - page * pageSize] ?? null;
2223
+ };
2224
+ const activePageSize = () => ctx.getSource()?.pageSize || ctx.getFallbackPageSize();
2225
+ const requestRowCount = () => {
2226
+ const source = ctx.getSource();
2227
+ if (!source || ctx.getMode() !== 'infinity') {
2228
+ return totalRowCount();
2229
+ }
2230
+ bufferVersion();
2231
+ return Math.min(totalRowCount(), contiguousLoadedRowCount(source));
2232
+ };
2233
+ const requestPage = (event) => {
2234
+ const source = ctx.getSource();
2235
+ if (source) {
2236
+ if (source.updatePageSize && event.rows > 0 && event.rows !== source.pageSize) {
2237
+ void source.updatePageSize(event.rows);
2238
+ return;
2239
+ }
2240
+ void source.updatePage(event.page);
2241
+ return;
2242
+ }
2243
+ ctx.emitPageChange(event);
2244
+ };
2245
+ const requestSort = (sort) => {
2246
+ const source = ctx.getSource();
2247
+ if (!source) {
2248
+ return;
2249
+ }
2250
+ if (source.updateSort) {
2251
+ void source.updateSort(sort ?? null);
2252
+ return;
2253
+ }
2254
+ if (source.updateSorts) {
2255
+ void source.updateSorts(sort ? [sort] : []);
2256
+ }
2257
+ };
2258
+ const requestMultiSort = (sorts) => {
2259
+ const source = ctx.getSource();
2260
+ if (!source) {
2261
+ return;
2262
+ }
2263
+ if (source.updateSorts) {
2264
+ void source.updateSorts(sorts);
2265
+ return;
2266
+ }
2267
+ if (source.updateSort) {
2268
+ const active = sorts[sorts.length - 1] ?? null;
2269
+ void source.updateSort(active);
2270
+ }
2271
+ };
2272
+ const ensureBufferedRange = (state) => {
2273
+ const source = ctx.getSource();
2274
+ if (!source || ctx.getMode() !== 'infinity' || state.total <= 0) {
2275
+ return;
2276
+ }
2277
+ const pageSize = Math.max(1, source.pageSize || ctx.getFallbackPageSize());
2278
+ const maxPage = Math.max(0, Math.ceil(state.total / pageSize) - 1);
2279
+ const safeStart = Math.max(0, Math.min(state.start, Math.max(0, state.total - 1)));
2280
+ const visiblePageStart = Math.floor(safeStart / pageSize);
2281
+ const visiblePageCount = Math.max(1, Math.ceil(Math.max(1, state.visibleCount) / pageSize));
2282
+ const visiblePageEnd = Math.min(maxPage, visiblePageStart + visiblePageCount - 1);
2283
+ const sideBufferPages = Math.max(1, visiblePageCount * Math.floor(PAGE_WINDOW_MULTIPLIER / 2));
2284
+ const nextQueue = [];
2285
+ for (let page = visiblePageStart; page <= visiblePageEnd; page++) {
2286
+ pushPage(nextQueue, page, maxPage);
2287
+ }
2288
+ for (let offset = 1; offset <= sideBufferPages; offset++) {
2289
+ pushPage(nextQueue, visiblePageStart - offset, maxPage);
2290
+ pushPage(nextQueue, visiblePageEnd + offset, maxPage);
2291
+ }
2292
+ evictExcessPages(new Set(nextQueue));
2293
+ queuedPages.length = 0;
2294
+ for (const page of nextQueue) {
2295
+ if (sourcePages.has(page) || pendingPages.has(page)) {
2296
+ continue;
2297
+ }
2298
+ queuedPages.push(page);
2299
+ }
2300
+ drainQueuedPages();
2301
+ };
2302
+ const sync = () => {
2303
+ const source = ctx.getSource();
2304
+ const mode = ctx.getMode();
2305
+ let didReset = false;
2306
+ if (!source) {
2307
+ clearState();
2308
+ return;
2309
+ }
2310
+ const version = source.version?.();
2311
+ if (lastSourceRef !== source) {
2312
+ lastSourceRef = source;
2313
+ lastSourceVersion = version ?? null;
2314
+ clearBuffer();
2315
+ didReset = true;
2316
+ }
2317
+ else if (version !== undefined && version !== lastSourceVersion) {
2318
+ lastSourceVersion = version;
2319
+ clearBuffer();
2320
+ didReset = true;
2321
+ }
2322
+ if (mode !== 'infinity') {
2323
+ clearBuffer();
2324
+ return;
2325
+ }
2326
+ if (didReset && source.loading()) {
2327
+ return;
2328
+ }
2329
+ sourcePages.set(Math.max(0, source.page || 0), source.items() ?? []);
2330
+ bufferVersion.update((current) => current + 1);
2331
+ };
2332
+ const clearState = () => {
2333
+ lastSourceRef = null;
2334
+ lastSourceVersion = null;
2335
+ clearQueue();
2336
+ clearBuffer();
2337
+ };
2338
+ const clearBuffer = () => {
2339
+ requestGeneration++;
2340
+ if (!sourcePages.size) {
2341
+ return;
2342
+ }
2343
+ sourcePages.clear();
2344
+ bufferVersion.update((current) => current + 1);
2345
+ };
2346
+ const clearQueue = () => {
2347
+ requestGeneration++;
2348
+ queuedPages.length = 0;
2349
+ pendingPages.clear();
2350
+ activeRequests = 0;
2351
+ bufferVersion.update((current) => current + 1);
2352
+ };
2353
+ const pushPage = (pages, page, maxPage) => {
2354
+ if (page < 0 || page > maxPage || pages.includes(page)) {
2355
+ return;
2356
+ }
2357
+ pages.push(page);
2358
+ };
2359
+ const drainQueuedPages = () => {
2360
+ const source = ctx.getSource();
2361
+ if (!source || ctx.getMode() !== 'infinity') {
2362
+ return;
2363
+ }
2364
+ const maxConcurrentRequests = source.prefetchMode === 'parallel' ? PARALLEL_PREFETCH_REQUESTS : SEQUENTIAL_PREFETCH_REQUESTS;
2365
+ while (activeRequests < maxConcurrentRequests && queuedPages.length) {
2366
+ const nextPage = queuedPages.shift();
2367
+ const activeSource = ctx.getSource();
2368
+ if (nextPage === undefined || !activeSource || ctx.getMode() !== 'infinity') {
2369
+ return;
2370
+ }
2371
+ if (sourcePages.has(nextPage) || pendingPages.has(nextPage)) {
2372
+ continue;
2373
+ }
2374
+ activeRequests += 1;
2375
+ pendingPages.add(nextPage);
2376
+ bufferVersion.update((current) => current + 1);
2377
+ const capturedGeneration = requestGeneration;
2378
+ void activeSource
2379
+ .updatePage(nextPage)
2380
+ .then(() => {
2381
+ // Пропускаем запись если буфер был сброшен пока запрос летел
2382
+ // (смена источника, смена версии, clearState). Без этой проверки
2383
+ // устаревший ответ затирал бы свежий буфер.
2384
+ if (requestGeneration !== capturedGeneration) {
2385
+ return;
2386
+ }
2387
+ // Параллельный режим: захватываем данные страницы сразу, пока источник
2388
+ // ещё хранит именно эту страницу. Без этого sync() (Angular effect) видит
2389
+ // только последнюю из страниц, если несколько запросов завершились до
2390
+ // того, как эффект успел выполниться, и все промежуточные страницы теряются.
2391
+ if (ctx.getMode() === 'infinity' && !sourcePages.has(nextPage)) {
2392
+ sourcePages.set(nextPage, activeSource.items() ?? []);
2393
+ }
2394
+ })
2395
+ .finally(() => {
2396
+ pendingPages.delete(nextPage);
2397
+ activeRequests = Math.max(0, activeRequests - 1);
2398
+ bufferVersion.update((current) => current + 1);
2399
+ if (queuedPages.length) {
2400
+ queueMicrotask(() => drainQueuedPages());
2401
+ }
2402
+ });
2403
+ }
2404
+ };
2405
+ const contiguousLoadedRowCount = (source) => {
2406
+ const pageSize = Math.max(1, source.pageSize || ctx.getFallbackPageSize());
2407
+ let loaded = 0;
2408
+ let page = 0;
2409
+ while (sourcePages.has(page)) {
2410
+ const items = sourcePages.get(page) ?? [];
2411
+ loaded += items.length;
2412
+ if (items.length < pageSize) {
2413
+ break;
2414
+ }
2415
+ page++;
2416
+ }
2417
+ return loaded;
2418
+ };
2419
+ const hasReachedInfinityEnd = (source) => {
2420
+ const pageSize = Math.max(1, source.pageSize || ctx.getFallbackPageSize());
2421
+ let page = 0;
2422
+ while (sourcePages.has(page)) {
2423
+ const items = sourcePages.get(page) ?? [];
2424
+ if (items.length < pageSize) {
2425
+ return true;
2426
+ }
2427
+ page++;
2428
+ }
2429
+ return false;
2430
+ };
2431
+ const resolvedTotalElements = (source) => {
2432
+ if (typeof source.totalElements !== 'number' || !Number.isFinite(source.totalElements)) {
2433
+ return null;
2434
+ }
2435
+ return Math.max(0, source.totalElements);
2436
+ };
2437
+ const evictExcessPages = (keepPages) => {
2438
+ if (sourcePages.size <= MAX_BUFFERED_PAGES) {
2439
+ return;
2440
+ }
2441
+ for (const page of sourcePages.keys()) {
2442
+ if (sourcePages.size <= MAX_BUFFERED_PAGES) {
2443
+ break;
2444
+ }
2445
+ if (!keepPages.has(page)) {
2446
+ sourcePages.delete(page);
2447
+ }
2448
+ }
2449
+ };
2450
+ const flattenBufferedPages = () => {
2451
+ const rows = [];
2452
+ const pages = Array.from(sourcePages.entries()).sort(([pageA], [pageB]) => pageA - pageB);
2453
+ for (const [, items] of pages) {
2454
+ rows.push(...items);
2455
+ }
2456
+ return rows;
2457
+ };
2458
+ return {
2459
+ activePageSize,
2460
+ ensureBufferedRange,
2461
+ requestMultiSort,
2462
+ requestPage,
2463
+ requestRowCount,
2464
+ requestSort,
2465
+ resolvedLoading,
2466
+ rowAt,
2467
+ selectionRows,
2468
+ stickyRows,
2469
+ sync,
2470
+ totalRowCount,
2471
+ };
2472
+ }
2473
+
2012
2474
  function createGridStickyOrchestrationFeature(ctx) {
2013
2475
  const reconcile = () => {
2014
2476
  const data = ctx.getData();
@@ -2033,6 +2495,7 @@ function createGridStickyOrchestrationFeature(ctx) {
2033
2495
 
2034
2496
  // noinspection ES6PreferShortImport
2035
2497
  function createGridTooltipAdapterFeature(ctx) {
2498
+ let pendingShowToken = null;
2036
2499
  const preloadForColumns = (columns) => {
2037
2500
  if (!columns.some((col) => !!col.tooltip)) {
2038
2501
  return;
@@ -2048,9 +2511,20 @@ function createGridTooltipAdapterFeature(ctx) {
2048
2511
  feature.showTooltip(event, row, col, index);
2049
2512
  return;
2050
2513
  }
2051
- void ctx.loadTooltipFeature();
2514
+ const token = { cancelled: false };
2515
+ pendingShowToken = token;
2516
+ void ctx.loadTooltipFeature().then((loaded) => {
2517
+ if (token.cancelled) {
2518
+ return;
2519
+ }
2520
+ loaded.showTooltip(event, row, col, index);
2521
+ });
2052
2522
  };
2053
2523
  const hideTooltip = () => {
2524
+ if (pendingShowToken) {
2525
+ pendingShowToken.cancelled = true;
2526
+ pendingShowToken = null;
2527
+ }
2054
2528
  ctx.getTooltipFeature()?.hideTooltip();
2055
2529
  };
2056
2530
  const positionTooltip = () => {
@@ -2088,8 +2562,8 @@ function createGridVirtualScrollFeature(ctx) {
2088
2562
  }
2089
2563
  const scrollTop = el.scrollTop ?? 0;
2090
2564
  const viewportHeight = el.clientHeight ?? 0;
2091
- const data = ctx.getData() ?? [];
2092
- const total = data.length ?? 0;
2565
+ const total = Math.max(0, ctx.getTotalCount() ?? 0);
2566
+ const requestTotal = Math.min(total, Math.max(0, ctx.getRequestTotalCount?.() ?? total));
2093
2567
  const rowHeight = Math.max(1, ctx.getRowHeight());
2094
2568
  const virtualBuffer = Math.max(0, ctx.getVirtualBuffer());
2095
2569
  const pinnedTopH = ctx.getPinnedTopCount() * rowHeight;
@@ -2099,6 +2573,11 @@ function createGridVirtualScrollFeature(ctx) {
2099
2573
  const visibleCount = Math.min(viewportRows + virtualBuffer, cap);
2100
2574
  const start = Math.max(0, Math.floor(scrollTop / rowHeight) - Math.floor(virtualBuffer / 2));
2101
2575
  const end = Math.min(total, start + visibleCount);
2576
+ ctx.ensureBufferedRange?.({
2577
+ start,
2578
+ visibleCount,
2579
+ total,
2580
+ });
2102
2581
  if (viewportHeight <= 0 || !isFinite(viewportHeight) || !isFinite(rowHeight)) {
2103
2582
  const fallbackCount = Math.min(total, Math.max(1, ctx.getPageSize()));
2104
2583
  ctx.setRenderCount(fallbackCount);
@@ -2120,7 +2599,7 @@ function createGridVirtualScrollFeature(ctx) {
2120
2599
  const shouldSkipFinalize = ctx.requestInfinityIfNeeded({
2121
2600
  initial,
2122
2601
  mode: ctx.getMode(),
2123
- total,
2602
+ total: requestTotal,
2124
2603
  start,
2125
2604
  visibleCount,
2126
2605
  });
@@ -2413,8 +2892,8 @@ class Selector {
2413
2892
  class CheckboxIcon {
2414
2893
  state = input(false, ...(ngDevMode ? [{ debugName: "state" }] : []));
2415
2894
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
2416
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: CheckboxIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
2417
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.1", type: CheckboxIcon, isStandalone: true, selector: "re-checkbox-ic", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2895
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CheckboxIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
2896
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: CheckboxIcon, isStandalone: true, selector: "re-checkbox-ic", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2418
2897
  <span
2419
2898
  class="cb"
2420
2899
  [class.cb--disabled]="disabled()"
@@ -2429,7 +2908,7 @@ class CheckboxIcon {
2429
2908
  </span>
2430
2909
  `, isInline: true, styles: [":host{--re-data-grid-checkbox-size: 20px;--re-data-grid-checkbox-stroke: 2px;--re-data-grid-checkbox-border: var(--border-color, #9aa3af);--re-data-grid-checkbox-tick: var(--surface-neutral, #fff);--re-data-grid-checkbox-surface: var(--surface-neutral, #fff);--re-data-grid-checkbox-active-color: var(--primary-color, #2563eb);display:inline-block;width:var(--re-data-grid-checkbox-size);height:var(--re-data-grid-checkbox-size);-webkit-user-select:none;user-select:none}.cb{cursor:default;display:inline-block}.cb--disabled{opacity:.6}.cb__box{position:relative;display:inline-block;width:var(--re-data-grid-checkbox-size);height:var(--re-data-grid-checkbox-size);border:var(--re-data-grid-checkbox-stroke) solid var(--re-data-grid-checkbox-border);border-radius:4px;background:var(--re-data-grid-checkbox-surface);transition:background .25s,border-color .25s}.cb--checked .cb__box{border-color:var(--re-data-grid-checkbox-active-color);background:var(--re-data-grid-checkbox-active-color)}.cb--checked .cb__box:after{content:\"\";position:absolute;inset:0;margin:auto;width:10px;height:6px;border:2px solid var(--re-data-grid-checkbox-tick);border-top:0;border-right:0;transform:rotate(-45deg) translate(1px,-1px) scale(.8);opacity:0;animation:tick .25s forwards ease}.cb--mixed .cb__box{background:var(--re-data-grid-checkbox-active-color);border-color:var(--re-data-grid-checkbox-active-color)}.cb--mixed .cb__box:after{content:\"\";position:absolute;left:3px;right:3px;top:50%;border-top:2px solid var(--re-data-grid-checkbox-tick);transform:translateY(-50%) scaleX(.3);opacity:0;animation:dash .25s forwards ease}@keyframes tick{to{opacity:1;transform:rotate(-45deg) translate(1px,-1px) scale(1)}}@keyframes dash{to{opacity:1;transform:translateY(-50%) scaleX(1)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2431
2910
  }
2432
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: CheckboxIcon, decorators: [{
2911
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: CheckboxIcon, decorators: [{
2433
2912
  type: Component,
2434
2913
  args: [{ selector: 're-checkbox-ic', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
2435
2914
  <span
@@ -2450,8 +2929,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
2450
2929
  /* eslint-disable max-len */
2451
2930
  class ExpandIcon {
2452
2931
  expanded = input(false, { ...(ngDevMode ? { debugName: "expanded" } : {}), transform: booleanAttribute });
2453
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ExpandIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
2454
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: ExpandIcon, isStandalone: true, selector: "re-expand-ic", inputs: { expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2932
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ExpandIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
2933
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: ExpandIcon, isStandalone: true, selector: "re-expand-ic", inputs: { expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2455
2934
  @if (expanded()) {
2456
2935
  <svg width="16" height="16" viewBox="0 0 16 16">
2457
2936
  <path
@@ -2469,7 +2948,7 @@ class ExpandIcon {
2469
2948
  }
2470
2949
  `, isInline: true, styles: [""] });
2471
2950
  }
2472
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: ExpandIcon, decorators: [{
2951
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: ExpandIcon, decorators: [{
2473
2952
  type: Component,
2474
2953
  args: [{ selector: 're-expand-ic', template: `
2475
2954
  @if (expanded()) {
@@ -2492,8 +2971,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
2492
2971
 
2493
2972
  class SortIcon {
2494
2973
  direction = input('asc', ...(ngDevMode ? [{ debugName: "direction" }] : []));
2495
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: SortIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
2496
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: SortIcon, isStandalone: true, selector: "re-sort-ic", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2974
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SortIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
2975
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: SortIcon, isStandalone: true, selector: "re-sort-ic", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2497
2976
  @if (direction()) {
2498
2977
  <svg width="18" height="18" viewBox="0 0 18 18" fill="none" class="{{ direction() }}">
2499
2978
  <path d="M9 14L9 4M9 4L4 9M9 4C9 4 12.0474 6.85212 14 9" stroke="currentColor" />
@@ -2509,7 +2988,7 @@ class SortIcon {
2509
2988
  }
2510
2989
  `, isInline: true, styles: [".asc{transform:rotate(0);animation:sort-anim .2s ease-in-out}.desc{transform:rotate(180deg);transition:transform .3s ease-in-out}.unsort{animation:sort-anim .3s ease-in-out}@keyframes sort-anim{0%{transform:rotate(-90deg)}to{transform:rotate(0)}}\n"] });
2511
2990
  }
2512
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: SortIcon, decorators: [{
2991
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: SortIcon, decorators: [{
2513
2992
  type: Component,
2514
2993
  args: [{ selector: 're-sort-ic', template: `
2515
2994
  @if (direction()) {
@@ -2550,7 +3029,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
2550
3029
  * ```
2551
3030
  */
2552
3031
  class DataGrid {
3032
+ static nextAriaId = 0;
2553
3033
  defaults = inject(DATA_GRID_CONFIG) || DEFAULT_DATA_GRID_DEFAULTS;
3034
+ headerTextResolver = inject(DATA_GRID_HEADER_TEXT_RESOLVER);
3035
+ resolvedHeaderTextCache = new Map();
2554
3036
  /**
2555
3037
  * Array of data to display in the table.
2556
3038
  *
@@ -2558,6 +3040,14 @@ class DataGrid {
2558
3040
  * only visible rows using virtual scrolling.
2559
3041
  */
2560
3042
  data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
3043
+ /**
3044
+ * Optional page-oriented source for direct grid/store integration.
3045
+ *
3046
+ * When provided, the grid reads rows from the source, requests pages directly,
3047
+ * and in infinity mode keeps its own internal page buffer instead of requiring
3048
+ * an ever-growing accumulated `data` array from the parent.
3049
+ */
3050
+ source = input(null, ...(ngDevMode ? [{ debugName: "source" }] : []));
2561
3051
  /**
2562
3052
  * Column configuration for the table.
2563
3053
  *
@@ -2720,7 +3210,7 @@ class DataGrid {
2720
3210
  * @example
2721
3211
  * ```typescript
2722
3212
  * onSortChange(event: GridSortEvent<User>) {
2723
- * this.data = sortBy(this.data, event.key, event.order);
3213
+ * this.data = sortBy(this.data, event.sort, event.order);
2724
3214
  * }
2725
3215
  * ```
2726
3216
  */
@@ -2769,6 +3259,11 @@ class DataGrid {
2769
3259
  * Contains the clicked row, column configuration, row index, and the native mouse event.
2770
3260
  */
2771
3261
  cellDoubleClick = output();
3262
+ /**
3263
+ * Emitted when the user finishes resizing a column (on mouseup).
3264
+ * Use this to persist column widths across sessions.
3265
+ */
3266
+ columnResizeEnd = output();
2772
3267
  vm = inject((DataGridVm));
2773
3268
  selector = new Selector();
2774
3269
  sortFeature = createGridSortFeature({
@@ -2781,7 +3276,7 @@ class DataGrid {
2781
3276
  setSorts: (sorts) => this.setCurrentSorts(sorts),
2782
3277
  getSortOrderByKey: (key) => this.currentSortMap.get(key),
2783
3278
  emitSortChange: (event) => this.sortChange.emit(event),
2784
- emitMultiSortChange: (sorts) => this.multiSortChange.emit({ sorts: [...sorts] }),
3279
+ emitMultiSortChange: (sorts) => this.multiSortChange.emit({ sort: [...sorts] }),
2785
3280
  });
2786
3281
  rowInteractionsFeature = createGridRowInteractionsFeature({
2787
3282
  isRowDisabled: (row, index) => this.isDisabledRow(row, index),
@@ -2804,10 +3299,10 @@ class DataGrid {
2804
3299
  setVmHeaderGroups: (groups) => this.vm.headerGroups.set(groups),
2805
3300
  });
2806
3301
  infinityPageRequestFeature = createGridInfinityPageRequestFeature({
2807
- getPageSize: () => this.pageSize(),
3302
+ getPageSize: () => this.activePageSize(),
2808
3303
  isPageStartFromZero: () => this.pageStartFromZero(),
2809
- isLoading: () => this.loading(),
2810
- emitPageChange: (event) => this.pageChange.emit(event),
3304
+ isLoading: () => this.resolvedLoading(),
3305
+ emitPageChange: (event) => this.requestPage(event),
2811
3306
  });
2812
3307
  expanderFeature = createGridExpanderFeature({
2813
3308
  runUntracked: (fn) => untracked(fn),
@@ -2825,12 +3320,14 @@ class DataGrid {
2825
3320
  scheduleHeaderMeasure: () => this.headerMeasureFeature.scheduleMeasure(),
2826
3321
  setResizing: (value) => this.isColumnResizing.set(value),
2827
3322
  getWindow: () => window,
3323
+ emitResizeEnd: (key, width) => this.columnResizeEnd.emit({ key: key, width }),
2828
3324
  });
2829
3325
  selectionReconcileFeature = createGridSelectionReconcileFeature({
2830
3326
  getSelection: () => this.selection(),
2831
- getData: () => this.data() ?? [],
3327
+ getData: () => this.selectionRows(),
2832
3328
  getSelectedKeys: () => this.selector.selectedKeys(),
2833
3329
  setSelectedKeys: (keys) => this.selector.selectedKeys.set(keys),
3330
+ emitSelectChange: (keys) => this.selectChange.emit({ selected: keys }),
2834
3331
  });
2835
3332
  gridApiFeature = createGridApiFeature({
2836
3333
  getSelectionFeature: () => this.selectionFeatureRef,
@@ -2848,14 +3345,23 @@ class DataGrid {
2848
3345
  loadTooltipFeature: () => this.loadTooltipFeature(),
2849
3346
  getTooltipElement: () => this.tooltipEl()?.nativeElement ?? null,
2850
3347
  });
3348
+ sourceDataFeature = createGridSourceDataFeature({
3349
+ getSource: () => this.source(),
3350
+ getMode: () => this.mode(),
3351
+ getFallbackData: () => this.data() ?? [],
3352
+ getFallbackLoading: () => this.loading(),
3353
+ getFallbackPageSize: () => this.pageSize(),
3354
+ emitPageChange: (event) => this.pageChange.emit(event),
3355
+ });
2851
3356
  virtualScrollFeature = createGridVirtualScrollFeature({
2852
3357
  getScrollElement: () => this.scrollEl()?.nativeElement ?? null,
2853
- getData: () => this.data() ?? [],
3358
+ getTotalCount: () => this.totalRowCount(),
3359
+ getRequestTotalCount: () => this.sourceDataFeature.requestRowCount(),
2854
3360
  getRowHeight: () => this.rowHeight(),
2855
3361
  getVirtualBuffer: () => this.virtualBuffer(),
2856
3362
  getPinnedTopCount: () => this.vm.pinnedTop().length,
2857
3363
  getMode: () => this.mode(),
2858
- getPageSize: () => this.pageSize(),
3364
+ getPageSize: () => this.activePageSize(),
2859
3365
  getRenderSlots: () => this.renderSlots(),
2860
3366
  setRenderSlots: (slots) => this.renderSlots.set(slots),
2861
3367
  getLastRange: () => ({ start: this.lastStartIndex, end: this.lastEndIndex }),
@@ -2865,14 +3371,15 @@ class DataGrid {
2865
3371
  },
2866
3372
  setStartIndex: (value) => (this.startIndex = value),
2867
3373
  setRenderCount: (value) => (this.renderCount = value),
3374
+ ensureBufferedRange: (state) => this.sourceDataFeature.ensureBufferedRange(state),
2868
3375
  updateStickyRow: (scrollTop, rowHeight, pinnedTopH) => this.updateStickyRow(scrollTop, rowHeight, pinnedTopH),
2869
- requestInfinityIfNeeded: (state) => this.infinityPageRequestFeature.requestIfNeeded(state),
3376
+ requestInfinityIfNeeded: (state) => this.source() ? false : this.infinityPageRequestFeature.requestIfNeeded(state),
2870
3377
  finalizeScroll: () => this.finalizeScroll(),
2871
3378
  });
2872
3379
  resizeObserverFeature = createGridResizeObserverFeature({
2873
3380
  getRootElement: () => this.rootEl()?.nativeElement ?? null,
2874
3381
  getResizeDebounceMs: () => this.defaults.debounce.resize,
2875
- addSubscription: (subscription) => this.subscription.add(subscription),
3382
+ addCleanup: (cleanup) => this.cleanupCallbacks.push(cleanup),
2876
3383
  onWidthChanged: (width) => {
2877
3384
  this.vm.containerWidth.set(width);
2878
3385
  this.headerMeasureFeature.scheduleMeasure();
@@ -2885,7 +3392,7 @@ class DataGrid {
2885
3392
  getScrollElement: () => this.scrollEl()?.nativeElement ?? null,
2886
3393
  runOutsideAngular: (fn) => this.ngZone.runOutsideAngular(fn),
2887
3394
  runInAngular: (fn) => this.ngZone.run(fn),
2888
- addSubscription: (subscription) => this.subscription.add(subscription),
3395
+ addCleanup: (cleanup) => this.cleanupCallbacks.push(cleanup),
2889
3396
  onVerticalScroll: () => this.onVerticalScroll(),
2890
3397
  onHorizontalScroll: () => this.onHorizontalScroll(),
2891
3398
  onStickySchedule: () => this.scheduleStickyUpdate(),
@@ -2898,7 +3405,7 @@ class DataGrid {
2898
3405
  registerOnDestroy: (fn) => inject(DestroyRef).onDestroy(fn),
2899
3406
  });
2900
3407
  stickyOrchestrationFeature = createGridStickyOrchestrationFeature({
2901
- getData: () => this.data() ?? [],
3408
+ getData: () => this.sourceDataFeature.stickyRows(),
2902
3409
  getStickyPredicate: () => this.isRowSticky(),
2903
3410
  setStickyIndexes: (indexes) => this.stickyIndexes.set(indexes),
2904
3411
  updateStickyFromScroll: () => this.updateStickyFromScroll(),
@@ -2906,6 +3413,15 @@ class DataGrid {
2906
3413
  void this.loadStickyFeature();
2907
3414
  },
2908
3415
  });
3416
+ gapLoaderFeature = createGridGapLoaderFeature({
3417
+ hasSource: () => !!this.source(),
3418
+ getMode: () => this.mode(),
3419
+ getTotalCount: () => this.totalRowCount(),
3420
+ getStartIndex: () => this.startIndex,
3421
+ getRenderCount: () => this.renderCount,
3422
+ isStickyRowIndex: (index) => this.isStickyRowIndex(index),
3423
+ hasRowAt: (index) => !!this.rowAt(index),
3424
+ });
2909
3425
  headerMeasureFeature = createGridHeaderMeasureFeature({
2910
3426
  getHeaderElement: () => this.headerEl()?.nativeElement ?? null,
2911
3427
  setHeaderHeight: (height) => this.headerHeight.set(height),
@@ -2953,15 +3469,17 @@ class DataGrid {
2953
3469
  y: 0,
2954
3470
  visible: false,
2955
3471
  }, ...(ngDevMode ? [{ debugName: "tooltipState" }] : []));
3472
+ activeTooltipCellId = signal(null, ...(ngDevMode ? [{ debugName: "activeTooltipCellId" }] : []));
3473
+ tooltipId = `re-dg-tooltip-${DataGrid.nextAriaId++}`;
3474
+ expanderRegionId = `re-dg-expander-${DataGrid.nextAriaId++}`;
2956
3475
  stickyRowIndex = signal(null, ...(ngDevMode ? [{ debugName: "stickyRowIndex" }] : []));
2957
3476
  stickyRowTopPx = signal(0, ...(ngDevMode ? [{ debugName: "stickyRowTopPx" }] : []));
2958
3477
  stickyRowData = computed(() => {
2959
3478
  const index = this.stickyRowIndex();
2960
- const rows = this.data();
2961
- if (index === null || index < 0 || index >= rows.length) {
3479
+ if (index === null || index < 0 || index >= this.totalRowCount()) {
2962
3480
  return null;
2963
3481
  }
2964
- return rows[index];
3482
+ return this.rowAt(index);
2965
3483
  }, ...(ngDevMode ? [{ debugName: "stickyRowData" }] : []));
2966
3484
  stickyIndexes = signal([], ...(ngDevMode ? [{ debugName: "stickyIndexes" }] : []));
2967
3485
  contentInitialized = signal(false, ...(ngDevMode ? [{ debugName: "contentInitialized" }] : []));
@@ -3013,6 +3531,12 @@ class DataGrid {
3013
3531
  }
3014
3532
  return 'var(--re-data-grid-height)';
3015
3533
  }, ...(ngDevMode ? [{ debugName: "styleHeight" }] : []));
3534
+ resolvedLoading = computed(() => this.sourceDataFeature.resolvedLoading(), ...(ngDevMode ? [{ debugName: "resolvedLoading" }] : []));
3535
+ totalRowCount = computed(() => this.sourceDataFeature.totalRowCount(), ...(ngDevMode ? [{ debugName: "totalRowCount" }] : []));
3536
+ selectionRows = computed(() => this.sourceDataFeature.selectionRows(), ...(ngDevMode ? [{ debugName: "selectionRows" }] : []));
3537
+ ariaColCount = computed(() => this.vm.columnsToShow().length, ...(ngDevMode ? [{ debugName: "ariaColCount" }] : []));
3538
+ ariaHeaderRowCount = computed(() => 1 + (this.vm.normalizedHeaderGroups().length ? 1 : 0), ...(ngDevMode ? [{ debugName: "ariaHeaderRowCount" }] : []));
3539
+ ariaRowCount = computed(() => this.ariaHeaderRowCount() + this.vm.pinnedTop().length + this.totalRowCount() + this.vm.pinnedBottom().length, ...(ngDevMode ? [{ debugName: "ariaRowCount" }] : []));
3016
3540
  hideSbTimeout;
3017
3541
  scrollbarRafId = null;
3018
3542
  stickyRafId = null;
@@ -3020,7 +3544,7 @@ class DataGrid {
3020
3544
  currentSortOrder = 'asc';
3021
3545
  currentSorts = [];
3022
3546
  currentSortMap = new Map();
3023
- subscription = new Subscription();
3547
+ cleanupCallbacks = [];
3024
3548
  constructor() {
3025
3549
  afterNextRender(() => this.contentInitialized.set(true));
3026
3550
  this.lifecycleInitFeature.init({
@@ -3040,9 +3564,20 @@ class DataGrid {
3040
3564
  ],
3041
3565
  effects: [
3042
3566
  () => {
3043
- this.data();
3567
+ this.sourceDataFeature.sync();
3568
+ this.syncSortFromSource();
3569
+ },
3570
+ () => {
3571
+ if (this.source()) {
3572
+ this.source().items();
3573
+ this.source().loading();
3574
+ }
3575
+ else {
3576
+ this.data();
3577
+ }
3044
3578
  this.rowHeight();
3045
3579
  this.mode();
3580
+ this.totalRowCount();
3046
3581
  this.onVerticalScroll(true);
3047
3582
  },
3048
3583
  () => {
@@ -3051,7 +3586,7 @@ class DataGrid {
3051
3586
  this.vm.containerWidth();
3052
3587
  this.onVerticalScroll();
3053
3588
  },
3054
- () => this.infinityPageRequestFeature.onDataTotalChanged(this.data()?.length ?? 0),
3589
+ () => this.infinityPageRequestFeature.onDataTotalChanged(this.sourceDataFeature.requestRowCount()),
3055
3590
  () => {
3056
3591
  const selection = this.selection();
3057
3592
  if ('defaultSelected' in selection) {
@@ -3063,7 +3598,8 @@ class DataGrid {
3063
3598
  },
3064
3599
  () => {
3065
3600
  this.selection();
3066
- this.data();
3601
+ this.selectionRows();
3602
+ this.selector.data.set(this.selectionRows());
3067
3603
  this.selectionReconcileFeature.reconcile();
3068
3604
  },
3069
3605
  () => {
@@ -3072,9 +3608,16 @@ class DataGrid {
3072
3608
  () => {
3073
3609
  this.tooltipAdapterFeature.preloadForColumns(this.extendedColumns());
3074
3610
  },
3611
+ () => {
3612
+ if (ngDevMode && this.source() && this.mode() === 'infinity' && !this.rowKey()) {
3613
+ console.warn('[DataGrid] rowKey is not set while using a source in infinity mode. ' +
3614
+ 'Row tracking will fall back to column values, which may cause stale rendering when data changes across pages. ' +
3615
+ 'Set rowKey to a unique identifier property or function.');
3616
+ }
3617
+ },
3075
3618
  ],
3076
3619
  onDestroy: () => {
3077
- this.subscription.unsubscribe();
3620
+ this.cleanupCallbacks.splice(0).forEach((cleanup) => cleanup());
3078
3621
  this.resizeObserverFeature.disconnect();
3079
3622
  this.infinityPageRequestFeature.reset();
3080
3623
  clearTimeout(this.hideSbTimeout);
@@ -3083,6 +3626,7 @@ class DataGrid {
3083
3626
  this.clearScrollbarRaf();
3084
3627
  this.clearStickyRaf();
3085
3628
  this.columnResizeFeature.destroy();
3629
+ this.resolvedHeaderTextCache.clear();
3086
3630
  },
3087
3631
  });
3088
3632
  }
@@ -3097,14 +3641,17 @@ class DataGrid {
3097
3641
  /** Resets sorting state and emits sort events. */
3098
3642
  resetSort() {
3099
3643
  this.gridApiFeature.resetSort();
3644
+ this.sourceDataFeature.requestMultiSort([]);
3100
3645
  }
3101
3646
  /** Sets a single-column sorting state and emits sort events. */
3102
3647
  setSort(sort) {
3103
3648
  this.gridApiFeature.setSort(sort);
3649
+ this.sourceDataFeature.requestSort(sort.sort && sort.order ? { sort: sort.sort, order: sort.order } : null);
3104
3650
  }
3105
3651
  /** Sets multi-column sorting state and emits sort events. */
3106
3652
  setMultiSort(sorts) {
3107
3653
  this.gridApiFeature.setMultiSort(sorts);
3654
+ this.sourceDataFeature.requestMultiSort(sorts);
3108
3655
  }
3109
3656
  resolvePinnedData(pr) {
3110
3657
  return typeof pr.data === 'function' ? pr.data() : pr.data;
@@ -3120,6 +3667,11 @@ class DataGrid {
3120
3667
  */
3121
3668
  onSort(col) {
3122
3669
  this.sortFeature.onSort(col.sortKey);
3670
+ if (this.sortMode() === 'multi') {
3671
+ this.sourceDataFeature.requestMultiSort(this.currentSorts);
3672
+ return;
3673
+ }
3674
+ this.sourceDataFeature.requestSort(this.currentSortField ? { sort: this.currentSortField, order: this.currentSortOrder } : null);
3123
3675
  }
3124
3676
  onColumnResizeStart(event, col) {
3125
3677
  this.columnResizeFeature.onResizeStart(event, col);
@@ -3198,7 +3750,7 @@ class DataGrid {
3198
3750
  if (type === 'checkbox') {
3199
3751
  return false;
3200
3752
  }
3201
- return (column.resizable ?? this.defaults.resizable) !== false;
3753
+ return column.resizable ?? this.defaults.resizable;
3202
3754
  }
3203
3755
  /**
3204
3756
  * Handles column expand/collapse toggle.
@@ -3288,8 +3840,13 @@ class DataGrid {
3288
3840
  this.tooltipAdapterFeature.showTooltip(event, row, col, index);
3289
3841
  }
3290
3842
  hideTooltip() {
3843
+ this.activeTooltipCellId.set(null);
3291
3844
  this.tooltipAdapterFeature.hideTooltip();
3292
3845
  }
3846
+ onTooltipEnter(event, row, col, index, cellId) {
3847
+ this.activeTooltipCellId.set(cellId);
3848
+ this.showTooltip(event, row, col, index);
3849
+ }
3293
3850
  isStickyRowIndex(index) {
3294
3851
  return this.stickyFeatureRef?.isStickyRowIndex(index) ?? false;
3295
3852
  }
@@ -3303,6 +3860,82 @@ class DataGrid {
3303
3860
  }
3304
3861
  return this.rowTpl()?.tpl ?? null;
3305
3862
  }
3863
+ rowAt(index) {
3864
+ return this.sourceDataFeature.rowAt(index);
3865
+ }
3866
+ shouldRenderLoadingRow(index, topGap, bottomGap) {
3867
+ return this.gapLoaderFeature.shouldRenderInnerSkeleton(index, topGap, bottomGap);
3868
+ }
3869
+ topGapLoader() {
3870
+ return this.gapLoaderFeature.topGap();
3871
+ }
3872
+ bottomGapLoader() {
3873
+ return this.gapLoaderFeature.bottomGap();
3874
+ }
3875
+ resolveHeaderText(col) {
3876
+ const cacheKey = `column:${String(col.key)}:${col.header}`;
3877
+ return this.readResolvedHeaderText(cacheKey, () => this.headerTextResolver(col.header, { kind: 'column', column: col }));
3878
+ }
3879
+ ariaDataRowIndex(index) {
3880
+ return this.ariaHeaderRowCount() + this.vm.pinnedTop().length + index + 1;
3881
+ }
3882
+ ariaPinnedTopRowIndex(index) {
3883
+ return this.ariaHeaderRowCount() + index + 1;
3884
+ }
3885
+ ariaPinnedBottomRowIndex(index) {
3886
+ return this.ariaHeaderRowCount() + this.vm.pinnedTop().length + this.totalRowCount() + index + 1;
3887
+ }
3888
+ ariaSortLabel(col) {
3889
+ const header = this.resolveHeaderText(col);
3890
+ if (!col.sortKey) {
3891
+ return header;
3892
+ }
3893
+ const direction = this.sortOrderFor(col);
3894
+ const directionText = direction === 'asc' ? 'ascending' : direction === 'desc' ? 'descending' : 'not sorted';
3895
+ return `${header}. Sortable. Current order: ${directionText}.`;
3896
+ }
3897
+ ariaExpandLabel(col) {
3898
+ const header = this.resolveHeaderText(col);
3899
+ const expanded = this.expanderMap().get(col.key);
3900
+ return `${expanded ? 'Collapse' : 'Expand'} column ${header}`;
3901
+ }
3902
+ ariaResizeLabel(col) {
3903
+ return `Resize column ${this.resolveHeaderText(col)}`;
3904
+ }
3905
+ ariaHeaderGroupColIndex(group) {
3906
+ if (!group.startKey) {
3907
+ return null;
3908
+ }
3909
+ const colIndex = this.vm.columnsToShow().findIndex((col) => String(col.key) === group.startKey);
3910
+ return colIndex >= 0 ? colIndex + 1 : null;
3911
+ }
3912
+ cellAriaId(colKey, rowIndex, isPinned) {
3913
+ return `re-dg-cell-${isPinned ? 'p' : 'r'}-${rowIndex}-${String(colKey)}`;
3914
+ }
3915
+ isTooltipTarget(cellId) {
3916
+ return this.tooltipState().visible && this.activeTooltipCellId() === cellId;
3917
+ }
3918
+ resolveHeaderGroupTitle(group) {
3919
+ if (!group.title) {
3920
+ return '';
3921
+ }
3922
+ const cacheKey = `group:${'key' in group ? String(group.key ?? '') : ''}:${group.title}`;
3923
+ return this.readResolvedHeaderText(cacheKey, () => this.headerTextResolver(group.title, { kind: 'group', group }));
3924
+ }
3925
+ readResolvedHeaderText(cacheKey, factory) {
3926
+ let resolved = this.resolvedHeaderTextCache.get(cacheKey);
3927
+ if (resolved === undefined) {
3928
+ resolved = factory();
3929
+ this.resolvedHeaderTextCache.set(cacheKey, resolved);
3930
+ }
3931
+ return typeof resolved === 'function' ? resolved() : resolved;
3932
+ }
3933
+ activePageSize() {
3934
+ return this.sourceDataFeature.activePageSize();
3935
+ }
3936
+ requestPage(event) {
3937
+ this.sourceDataFeature.requestPage(event);
3938
+ }
3306
3939
  initVm() {
3307
3940
  this.vm.scrollEl.set(this.scrollEl());
3308
3941
  this.vm.columns.set(this.extendedColumns());
@@ -3310,23 +3943,26 @@ class DataGrid {
3310
3943
  this.headerMeasureFeature.scheduleMeasure();
3311
3944
  }
3312
3945
  initSelector() {
3313
- this.selector.data.set(this.data());
3946
+ this.selector.data.set(this.selectionRows());
3314
3947
  this.selector.selection.set(this.selection());
3315
3948
  }
3316
3949
  initRefs() {
3317
3950
  this.slotsFeature.initRefs();
3318
3951
  }
3319
3952
  initSort() {
3953
+ if (this.currentSorts.length === 0) {
3954
+ this.syncSortFromSource();
3955
+ }
3320
3956
  if (this.sortMode() === 'single' && this.currentSorts.length > 1) {
3321
3957
  const [first] = this.currentSorts;
3322
3958
  this.setCurrentSorts([first]);
3323
- this.currentSortField = `${first.key}`;
3959
+ this.currentSortField = `${first.sort}`;
3324
3960
  this.currentSortOrder = first.order;
3325
3961
  return;
3326
3962
  }
3327
3963
  if (this.currentSorts.length > 0) {
3328
3964
  const [last] = this.currentSorts;
3329
- this.currentSortField = `${last.key}`;
3965
+ this.currentSortField = `${last.sort}`;
3330
3966
  this.currentSortOrder = last.order;
3331
3967
  return;
3332
3968
  }
@@ -3343,7 +3979,30 @@ class DataGrid {
3343
3979
  }
3344
3980
  setCurrentSorts(sorts) {
3345
3981
  this.currentSorts = sorts;
3346
- this.currentSortMap = new Map(sorts.map((item) => [String(item.key), item.order]));
3982
+ this.currentSortMap = new Map(sorts.map((item) => [String(item.sort), item.order]));
3983
+ }
3984
+ syncSortFromSource() {
3985
+ const sourceSort = this.source()?.sort ?? [];
3986
+ if (!sourceSort.length) {
3987
+ if (this.currentSorts.length === 0) {
3988
+ return;
3989
+ }
3990
+ this.setCurrentSorts([]);
3991
+ this.currentSortField = undefined;
3992
+ return;
3993
+ }
3994
+ const normalized = sourceSort.map((item) => ({ sort: item.sort, order: item.order }));
3995
+ if (normalized.length === this.currentSorts.length &&
3996
+ normalized.every((item, index) => {
3997
+ const current = this.currentSorts[index];
3998
+ return current?.sort === item.sort && current.order === item.order;
3999
+ })) {
4000
+ return;
4001
+ }
4002
+ this.setCurrentSorts(normalized);
4003
+ const active = normalized[normalized.length - 1];
4004
+ this.currentSortField = active ? String(active.sort) : undefined;
4005
+ active && (this.currentSortOrder = active.order);
3347
4006
  }
3348
4007
  loadSelectionFeature() {
3349
4008
  if (this.selectionFeatureRef) {
@@ -3392,7 +4051,7 @@ class DataGrid {
3392
4051
  if (this.overlayScrollFeaturePromise) {
3393
4052
  return this.overlayScrollFeaturePromise;
3394
4053
  }
3395
- this.overlayScrollFeaturePromise = import('./reforgium-data-grid-grid-overlay-scroll.feature-zC9rb3bw.mjs').then(({ createGridOverlayScrollFeature }) => {
4054
+ this.overlayScrollFeaturePromise = import('./reforgium-data-grid-grid-overlay-scroll.feature-BQFxyNCT.mjs').then(({ createGridOverlayScrollFeature }) => {
3396
4055
  const feature = createGridOverlayScrollFeature({
3397
4056
  getScrollElement: () => this.scrollEl()?.nativeElement ?? null,
3398
4057
  getThumbTop: () => this.vm.thumbTopPx(),
@@ -3504,17 +4163,17 @@ class DataGrid {
3504
4163
  }
3505
4164
  void this.loadStickyFeature().then((feature) => feature.updateStickyFromScroll());
3506
4165
  }
3507
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
3508
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DataGrid, isStandalone: true, selector: "re-data-grid", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, pinnedRows: { classPropertyName: "pinnedRows", publicName: "pinnedRows", isSignal: true, isRequired: false, transformFunction: null }, isRowSticky: { classPropertyName: "isRowSticky", publicName: "isRowSticky", isSignal: true, isRequired: false, transformFunction: null }, isRowDisabled: { classPropertyName: "isRowDisabled", publicName: "isRowDisabled", isSignal: true, isRequired: false, transformFunction: null }, getRowTemplate: { classPropertyName: "getRowTemplate", publicName: "getRowTemplate", isSignal: true, isRequired: false, transformFunction: null }, hasIndexColumn: { classPropertyName: "hasIndexColumn", publicName: "hasIndexColumn", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, virtualBuffer: { classPropertyName: "virtualBuffer", publicName: "virtualBuffer", isSignal: true, isRequired: false, transformFunction: null }, lockVerticalScroll: { classPropertyName: "lockVerticalScroll", publicName: "lockVerticalScroll", isSignal: true, isRequired: false, transformFunction: null }, headerGroups: { classPropertyName: "headerGroups", publicName: "headerGroups", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingMode: { classPropertyName: "loadingMode", publicName: "loadingMode", isSignal: true, isRequired: false, transformFunction: null }, deferContent: { classPropertyName: "deferContent", publicName: "deferContent", isSignal: true, isRequired: false, transformFunction: null }, deferHeader: { classPropertyName: "deferHeader", publicName: "deferHeader", isSignal: true, isRequired: false, transformFunction: null }, deferPinned: { classPropertyName: "deferPinned", publicName: "deferPinned", isSignal: true, isRequired: false, transformFunction: null }, deferCells: { classPropertyName: "deferCells", publicName: "deferCells", isSignal: true, isRequired: false, transformFunction: null }, deferIcons: { classPropertyName: "deferIcons", publicName: "deferIcons", isSignal: true, isRequired: false, transformFunction: null }, deferTooltip: { classPropertyName: "deferTooltip", publicName: "deferTooltip", isSignal: true, isRequired: false, transformFunction: null }, rowKey: { classPropertyName: "rowKey", publicName: "rowKey", isSignal: true, isRequired: false, transformFunction: null }, pageStartFromZero: { classPropertyName: "pageStartFromZero", publicName: "pageStartFromZero", isSignal: true, isRequired: false, transformFunction: null }, sortMode: { classPropertyName: "sortMode", publicName: "sortMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", sortChange: "sortChange", multiSortChange: "multiSortChange", selectChange: "selectChange", rowClick: "rowClick", rowContext: "rowContext", rowDoubleClick: "rowDoubleClick", cellClick: "cellClick", cellContext: "cellContext", cellDoubleClick: "cellDoubleClick" }, providers: [DataGridVm], queries: [{ propertyName: "cellTypedSlotRefs", predicate: DataGridTypeCellTemplateDirective, isSignal: true }, { propertyName: "cellDataSlotRefs", predicate: DataGridCellTemplateDirective, isSignal: true }, { propertyName: "declarativeColumnRefs", predicate: DataGridDeclarativeColumn, isSignal: true }, { propertyName: "headerSlotRefs", predicate: DataGridHeaderTemplateDirective, isSignal: true }, { propertyName: "emptySlotRefs", predicate: DataGridCellEmptyDirective, isSignal: true }, { propertyName: "loadingSlotRefs", predicate: DataGridCellLoadingDirective, isSignal: true }, { propertyName: "sortIcSlotRefs", predicate: DataGridSortIconDirective, isSignal: true }, { propertyName: "expanderIcSlotRefs", predicate: DataGridExpanderIconDirective, isSignal: true }, { propertyName: "stickyRowSlotRefs", predicate: DataGridStickyRowDirective, isSignal: true }, { propertyName: "rowSlotRefs", predicate: DataGridRowDirective, isSignal: true }], viewQueries: [{ propertyName: "rootEl", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "scrollEl", first: true, predicate: ["scroll"], descendants: true, isSignal: true }, { propertyName: "headerEl", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "tooltipEl", first: true, predicate: ["tooltip"], descendants: true, isSignal: true }], ngImport: i0, template: "@let items = data();\r\n@let empty = !loading() && !items?.length;\r\n@let notEmpty = !!items?.length;\r\n@let skeletonRowsCount = 4;\r\n@let skeletonMode = loadingMode() === 'skeleton';\r\n@let spinnerMode = loadingMode() === 'spinner';\r\n@let showInfinitySkeleton = loading() && skeletonMode && mode() === 'infinity';\r\n@let showPaginationSkeleton = loading() && skeletonMode && mode() === 'pagination' && !notEmpty;\r\n@let showSpinnerLoading = loading() && spinnerMode;\r\n@let extraInfinitySkeletonRows = showInfinitySkeleton ? skeletonRowsCount : 0;\r\n\r\n@let pinnedTopH = vm.pinnedTop().length * rowHeight();\r\n@let pinnedBottomH = vm.pinnedBottom().length * rowHeight();\r\n@let rowH = rowHeight();\r\n@let contentW = vm.contentWidth();\r\n@let cols = vm.columnsToShow();\r\n@let stickyTop = pinnedTopH + headerHeight();\r\n@let normalizedHeaderGroups = vm.normalizedHeaderGroups();\r\n@let stickyRow = stickyRowData();\r\n@let stickyIndex = stickyRowIndex();\r\n\r\n<div\r\n #root\r\n class=\"re-dg-root\"\r\n [class.re-dg-loading]=\"showSpinnerLoading\"\r\n [class.lock-vertical-scroll]=\"lockVerticalScroll()\"\r\n [class.resizing-columns]=\"isColumnResizing()\"\r\n [style.height]=\"styleHeight()\"\r\n [attr.aria-multiselectable]=\"selection().mode === 'multi' ? true : null\"\r\n role=\"grid\"\r\n>\r\n @if (showSpinnerLoading) {\r\n <div class=\"re-dg-loader\">\r\n @let loadingTemplate = loadingTpl();\r\n\r\n @if (loadingTemplate?.tpl) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\r\n } @else {\r\n <span class=\"re-dg-loader-spinner\" aria-label=\"Loading\"></span>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n #scroll\r\n class=\"re-dg-body\"\r\n role=\"rowgroup\"\r\n (mouseenter)=\"showScrollbar()\"\r\n (mouseleave)=\"hideScrollbarSoon()\"\r\n >\r\n <ng-template #headerContent>\r\n <div\r\n class=\"re-dg-header\"\r\n role=\"rowgroup\"\r\n [style.width.px]=\"vm.contentWidth()\"\r\n [style.min-width.%]=\"100\"\r\n >\r\n <div #header class=\"re-dg-header-rows\">\r\n @if (normalizedHeaderGroups.length) {\r\n <div class=\"re-dg-row re-dg-header-group-row\" role=\"row\" [style.width.px]=\"vm.contentWidth()\" [style.min-width.%]=\"100\">\r\n @for (group of normalizedHeaderGroups; track group.key) {\r\n @let groupStickyLeft = !!group.startKey && !!group.endKey && vm.isStickyLeft(group.startKey) && vm.isStickyLeft(group.endKey);\r\n @let groupStickyRight = !!group.startKey && !!group.endKey && vm.isStickyRight(group.startKey) && vm.isStickyRight(group.endKey);\r\n\r\n <div\r\n class=\"re-dg-header-cell re-dg-header-group-cell\"\r\n role=\"columnheader\"\r\n [class.sticky-left]=\"groupStickyLeft\"\r\n [class.sticky-right]=\"groupStickyRight\"\r\n [style.left.px]=\"groupStickyLeft && group.startKey ? vm.stickyOffset(group.startKey, 'left') : null\"\r\n [style.right.px]=\"groupStickyRight && group.endKey ? vm.stickyOffset(group.endKey, 'right') : null\"\r\n [style.width.px]=\"group.widthPx\"\r\n [style.justify-content]=\"group.align || 'left'\"\r\n [title]=\"group.title || ''\"\r\n >\r\n @if (group.titleTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"group.titleTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: group.title || '' }\"\r\n />\r\n } @else {\r\n <span class=\"re-dg-header-text\">{{ group.title || '' }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"re-dg-row re-dg-header-row\" role=\"row\" [style.width.px]=\"vm.contentWidth()\" [style.min-width.%]=\"100\">\r\n @for (col of vm.columnsToShow(); track col.key) {\r\n <div\r\n class=\"re-dg-header-cell\"\r\n role=\"columnheader\"\r\n [class.sortable]=\"!!col.sortKey\"\r\n [class.active-sort]=\"isActiveSort(col)\"\r\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\r\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\r\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\r\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [style.min-width.px]=\"col.minWidth || null\"\r\n [style.max-width.px]=\"col.maxWidth || null\"\r\n [style.justify-content]=\"col.align || 'left'\"\r\n [attr.aria-sort]=\"ariaSort(col)\"\r\n [attr.tabindex]=\"col.sortKey ? 0 : -1\"\r\n (click)=\"col.sortKey && onSort(col)\"\r\n (keydown.enter)=\"col.sortKey && onSort(col)\"\r\n >\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n @let isMultiSelect = selection().mode === 'multi';\r\n\r\n @if (isCheckbox && isMultiSelect) {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-checkbox-ic\r\n aria-label=\"Select loaded rows\"\r\n [state]=\"selector.isAllSelected()\"\r\n tabindex=\"0\"\r\n (click)=\"onSelectAll($event)\"\r\n (keydown.enter)=\"onSelectAllKeydown($event)\"\r\n (keydown.space)=\"onSelectAllKeydown($event)\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-checkbox-ic\r\n aria-label=\"Select loaded rows\"\r\n [state]=\"selector.isAllSelected()\"\r\n tabindex=\"0\"\r\n (click)=\"onSelectAll($event)\"\r\n (keydown.enter)=\"onSelectAllKeydown($event)\"\r\n (keydown.space)=\"onSelectAllKeydown($event)\" />\r\n }\r\n } @else {\r\n @if (col.headerTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.headerTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: col.header }\"\r\n />\r\n } @else {\r\n <span class=\"re-dg-header-text\">{{ col.header }}</span>\r\n }\r\n }\r\n\r\n @if (col.sortKey) {\r\n <span class=\"re-dg-sort-ind\">\r\n @let direction = sortOrderFor(col);\r\n\r\n @if (sortTpl()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"sortTpl()!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: direction }\"\r\n />\r\n } @else {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-sort-ic [direction]=\"direction\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-sort-ic [direction]=\"direction\" />\r\n }\r\n }\r\n </span>\r\n }\r\n\r\n @if (isExpandable(col)) {\r\n <button (click)=\"$event.stopPropagation(); onExpand(col)\">\r\n @let expanded = expanderMap().get(col.key);\r\n\r\n @if (expanderTpl()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"expanderTpl()!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: expanded }\" />\r\n } @else {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-expand-ic [expanded]=\"expanded\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-expand-ic [expanded]=\"expanded\" />\r\n }\r\n }\r\n </button>\r\n }\r\n\r\n @if (canResizeColumn(col)) {\r\n <button\r\n class=\"re-dg-column-resize-handle\"\r\n (mousedown)=\"onColumnResizeStart($event, col)\"\r\n (click)=\"$event.stopPropagation()\"\r\n ></button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- PINNED TOP ROWS -->\r\n @if (notEmpty) {\r\n <ng-template #pinnedTopContent>\r\n @for (pr of vm.pinnedTop(); track trackPinnedRow(pr)) {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top\" role=\"row\" [style.width.px]=\"contentW\" [style.min-width.%]=\"100\">\r\n @if (pr.rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pinnedRowCells\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n\r\n @if (deferPinned()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"pinnedTopContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n } @loading {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"pinnedTopContent\" />\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n @if (deferHeader()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"headerContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-header re-dg-deferred-placeholder\" [style.min-height.px]=\"headerHeight()\"></div>\r\n } @loading {\r\n <div class=\"re-dg-header re-dg-deferred-placeholder\" [style.min-height.px]=\"headerHeight()\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"headerContent\" />\r\n }\r\n\r\n <ng-template #dataCellContent let-row let-col=\"col\" let-index=\"index\" let-isPinned=\"isPinned\">\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n\r\n @if (isCheckbox) {\r\n <re-checkbox-ic\r\n aria-label=\"Toggle row selection\"\r\n [state]=\"selector.isSelected(row)\"\r\n [attr.aria-disabled]=\"isDisabledRow(row, index)\"\r\n [attr.tabindex]=\"isDisabledRow(row, index) ? -1 : 0\"\r\n (click)=\"onCheckboxToggle(row, index, $event)\"\r\n (keydown.enter)=\"onCheckboxKeydown(row, index, $event)\"\r\n (keydown.space)=\"onCheckboxKeydown(row, index, $event)\" />\r\n } @else {\r\n @if (deferCells()) {\r\n @defer (when true) {\r\n <re-data-grid-cell [index]=\"index\" [item]=\"row\" [column]=\"col\" [isPinned]=\"!!isPinned\" />\r\n } @placeholder {\r\n <span class=\"re-dg-cell-deferred\"></span>\r\n } @loading {\r\n <span class=\"re-dg-cell-deferred\"></span>\r\n }\r\n } @else {\r\n <re-data-grid-cell [index]=\"index\" [item]=\"row\" [column]=\"col\" [isPinned]=\"!!isPinned\" />\r\n }\r\n }\r\n </ng-template>\r\n\r\n <ng-template #gridContent>\r\n\r\n <!-- STICKY ROW -->\r\n @if (stickyRow && stickyIndex !== null) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-sticky-row\"\r\n role=\"row\"\r\n [class.re-dg-row-disabled]=\"isDisabledRow(stickyRow, stickyIndex)\"\r\n [style.width.px]=\"vm.contentWidth()\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowHeight()\"\r\n [style.top.px]=\"stickyRowTopPx()\"\r\n [attr.aria-disabled]=\"isDisabledRow(stickyRow, stickyIndex)\"\r\n [attr.aria-selected]=\"selection().mode !== 'none' ? selector.isSelected(stickyRow) : null\"\r\n [attr.tabindex]=\"0\"\r\n (click)=\"onRowClick(stickyRow, stickyIndex, $event)\"\r\n (contextmenu)=\"onRowContext(stickyRow, stickyIndex, $event)\"\r\n (dblclick)=\"onRowDoubleClick(stickyRow, stickyIndex, $event)\"\r\n (keydown.enter)=\"onRowClick(stickyRow, stickyIndex, $event)\"\r\n >\r\n @let stickyTemplate = stickyRowTpl();\r\n @let rowTemplate = resolveRowTemplate(stickyRow, stickyIndex);\r\n\r\n @if (stickyTemplate?.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"stickyTemplate!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: stickyRow, index: stickyIndex }\"\r\n />\r\n } @else if (rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: stickyRow,\r\n index: stickyIndex,\r\n columns: vm.columnsToShow(),\r\n rowHeight: rowHeight(),\r\n isSticky: true\r\n }\"\r\n />\r\n } @else {\r\n @for (col of vm.columnsToShow(); track col.key) {\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, stickyRow)\"\r\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\r\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\r\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\r\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.tabindex]=\"0\"\r\n (mouseenter)=\"showTooltip($event, stickyRow, col, stickyIndex)\"\r\n (mouseleave)=\"hideTooltip()\"\r\n (click)=\"onCellClick(stickyRow, col, stickyIndex, $event);\"\r\n (contextmenu)=\"onCellContext(stickyRow, col, stickyIndex, $event)\"\r\n (dblclick)=\"onCellDoubleClick(stickyRow, col, stickyIndex, $event)\"\r\n (keydown.enter)=\"onCellClick(stickyRow, col, stickyIndex, $event)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: stickyRow, col: col, index: stickyIndex, isPinned: false }\"\r\n />\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @if (empty) {\r\n @let emptyTemplate = emptyTpl()?.tpl;\r\n\r\n <div class=\"re-dg-empty\">\r\n @if (emptyTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"emptyTemplate\" />\r\n } @else {\r\n <span class=\"re-dg-empty-text\">{{ defaults.translations.emptyState }}</span>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Content -->\r\n @if (notEmpty) {\r\n <div\r\n class=\"re-dg-spacer\"\r\n [style.width.px]=\"contentW\"\r\n [style.height.px]=\"(items.length + extraInfinitySkeletonRows) * rowH - pinnedBottomH\"></div>\r\n\r\n @for (slot of renderSlots(); track slot) {\r\n @let rowIndex = startIndex + slot;\r\n @let row = items[rowIndex];\r\n @let rowTemplate = row ? resolveRowTemplate(row, rowIndex) : null;\r\n\r\n @if (row && !isStickyRowIndex(rowIndex)) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row\"\r\n role=\"row\"\r\n [class.re-dg-row-disabled]=\"isDisabledRow(row, rowIndex)\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (rowIndex * rowH + stickyTop) + 'px)'\"\r\n [attr.aria-disabled]=\"isDisabledRow(row, rowIndex)\"\r\n [attr.aria-selected]=\"selection().mode !== 'none' ? selector.isSelected(row) : null\"\r\n [attr.tabindex]=\"0\"\r\n (click)=\"onRowClick(row, rowIndex, $event)\"\r\n (contextmenu)=\"onRowContext(row, rowIndex, $event)\"\r\n (dblclick)=\"onRowDoubleClick(row, rowIndex, $event)\"\r\n (keydown.enter)=\"onRowClick(row, rowIndex, $event)\"\r\n >\r\n @if (rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n index: rowIndex,\r\n columns: vm.columnsToShow(),\r\n rowHeight: rowHeight(),\r\n isSticky: false\r\n }\"\r\n />\r\n } @else {\r\n @for (col of cols; track col.key) {\r\n @let stickyLeft = vm.stickyOffset(col.key, 'left');\r\n @let stickyRight = vm.stickyOffset(col.key, 'right');\r\n @let isLeft = vm.isStickyLeft(col.key);\r\n @let isRight = vm.isStickyRight(col.key);\r\n\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, row)\"\r\n [class.sticky-left]=\"isLeft\"\r\n [class.sticky-right]=\"isRight\"\r\n [style.left.px]=\"stickyLeft\"\r\n [style.right.px]=\"stickyRight\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.tabindex]=\"0\"\r\n (mouseenter)=\"showTooltip($event, row, col, rowIndex)\"\r\n (mouseleave)=\"hideTooltip()\"\r\n (click)=\"onCellClick(row, col, rowIndex, $event);\"\r\n (contextmenu)=\"onCellContext(row, col, rowIndex, $event)\"\r\n (dblclick)=\"onCellDoubleClick(row, col, rowIndex, $event)\"\r\n (keydown.enter)=\"onCellClick(row, col, rowIndex, $event)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, col: col, index: rowIndex, isPinned: false }\"\r\n />\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n @if (showInfinitySkeleton || showPaginationSkeleton) {\r\n @let loadingTemplate = loadingTpl();\r\n\r\n @if (loadingTemplate?.tpl) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\r\n } @else {\r\n @for (si of [0, 1, 2, 3]; track si) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-skeleton-row\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (((showInfinitySkeleton ? items.length : 0) + si) * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n <!-- PINNED BOTTOM ROWS -->\r\n @if (notEmpty) {\r\n <ng-template #pinnedBottomContent>\r\n <div class=\"re-dg-footer\" role=\"rowgroup\">\r\n @for (pr of vm.pinnedBottom(); track trackPinnedRow(pr)) {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-bottom\" role=\"row\" [style.width.px]=\"contentW\" [style.min-width.%]=\"100\">\r\n @if (pr.rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pinnedRowCells\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n @if (deferPinned()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"pinnedBottomContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-footer re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n } @loading {\r\n <div class=\"re-dg-footer re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"pinnedBottomContent\" />\r\n }\r\n }\r\n </ng-template>\r\n\r\n @if (deferContent()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"gridContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH * 3\"></div>\r\n } @loading {\r\n <div class=\"re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH * 3\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"gridContent\" />\r\n }\r\n </div>\r\n\r\n <ng-template #pinnedRowCells let-row>\r\n @for (col of cols; track col.key) {\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n @let isIndex = 'type' in col && col.type === 'index';\r\n @let stickyLeft = vm.stickyOffset(col.key, 'left');\r\n @let stickyRight = vm.stickyOffset(col.key, 'right');\r\n @let isLeft = vm.isStickyLeft(col.key);\r\n @let isRight = vm.isStickyRight(col.key);\r\n\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, $any(row))\"\r\n [class.sticky-left]=\"isLeft\"\r\n [class.sticky-right]=\"isRight\"\r\n [style.left.px]=\"stickyLeft\"\r\n [style.right.px]=\"stickyRight\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.height.px]=\"rowH\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.tabindex]=\"isCheckbox || isIndex ? -1 : 0\"\r\n (mouseenter)=\"!isCheckbox && !isIndex && showTooltip($event, $any(row), col, -1)\"\r\n (mouseleave)=\"!isCheckbox && !isIndex && hideTooltip()\"\r\n (click)=\"!isCheckbox && !isIndex && onCellClick($any(row), col, -1, $event);\"\r\n (contextmenu)=\"!isCheckbox && !isIndex && onCellContext($any(row), col, -1, $event)\"\r\n (dblclick)=\"!isCheckbox && !isIndex && onCellDoubleClick($any(row), col, -1, $event)\"\r\n (keydown.enter)=\"!isCheckbox && !isIndex && onCellClick($any(row), col, -1, $event)\"\r\n >\r\n @if (!isCheckbox && !isIndex) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: $any(row), col: col, index: -1, isPinned: true }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n\r\n @if (deferTooltip()) {\r\n @defer (when true) {\r\n @let tooltipStateValue = tooltipState();\r\n <div\r\n class=\"re-dg-tooltip\"\r\n #tooltip\r\n [class.visible]=\"tooltipStateValue.visible\"\r\n [style.left.px]=\"tooltipStateValue.x\"\r\n [style.top.px]=\"tooltipStateValue.y\"\r\n >\r\n @if (tooltipStateValue.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"tooltipStateValue.tpl\"\r\n [ngTemplateOutletContext]=\"tooltipStateValue.ctx\"\r\n />\r\n } @else {\r\n {{ tooltipStateValue.text }}\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @let tooltipStateValue = tooltipState();\r\n <div\r\n class=\"re-dg-tooltip\"\r\n #tooltip\r\n [class.visible]=\"tooltipStateValue.visible\"\r\n [style.left.px]=\"tooltipStateValue.x\"\r\n [style.top.px]=\"tooltipStateValue.y\"\r\n >\r\n @if (tooltipStateValue.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"tooltipStateValue.tpl\"\r\n [ngTemplateOutletContext]=\"tooltipStateValue.ctx\"\r\n />\r\n } @else {\r\n {{ tooltipStateValue.text }}\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Overlay scrollbar -->\r\n <div class=\"re-dg-scrollbar\" [class.visible]=\"vm.scrollbarVisible()\">\r\n <div\r\n class=\"re-dg-scrollbar-thumb\"\r\n role=\"scrollbar\"\r\n aria-orientation=\"vertical\"\r\n aria-hidden=\"false\"\r\n [style.height.px]=\"vm.thumbHeightPx()\"\r\n [style.transform]=\"'translateY(' + vm.thumbTopPx() + 'px)'\"\r\n (mousedown)=\"onThumbDown($event)\"\r\n ></div>\r\n </div>\r\n</div>\r\n", styles: [":host{--re-data-grid-min-height: 200px;--re-data-grid-height: 400px;--re-data-grid-rounded: var(--radius-md, 6px);--re-data-grid-separator-color: var(--border-color);--re-data-grid-separator: 1px solid var(--re-data-grid-separator-color);--re-data-grid-surface: var(--surface-neutral, #fff);--re-data-grid-active: var(--primary-color, #2a90f4);--re-data-grid-empty-color: #777;--re-data-grid-empty-surface: transparent;--re-data-grid-loading-color: #444;--re-data-grid-loading-surface: rgba(255, 255, 255, .5);--re-data-grid-spinner-size: 2rem;--re-data-grid-spinner-width: .25rem;--re-data-grid-spinner-track-color: rgba(0, 0, 0, .12);--re-data-grid-skeleton-width: 100%;--re-data-grid-skeleton-height: 100%;--re-data-grid-skeleton-rounded: var(--re-data-grid-rounded, .75rem);--re-data-grid-skeleton-shine: rgba(255, 255, 255, .8);--re-data-grid-skeleton-line: #e7ebf0;--re-data-grid-scrollbar-size: 4px;--re-data-grid-scrollbar-offset: 2px;--re-data-grid-scrollbar-track-rounded: .25rem;--re-data-grid-scrollbar-track-surface: transparent;--re-data-grid-scrollbar-thumb-size: 8px;--re-data-grid-scrollbar-thumb-color: rgba(0, 0, 0, .25);--re-data-grid-scrollbar-thumb-active-color: rgba(0, 0, 0, .45);--re-data-grid-scrollbar-thumb-rounded: var(--re-data-grid-scrollbar-track-rounded);--re-data-grid-tooltip-surface: #0f172a;--re-data-grid-tooltip-color: #f8fafc;--re-data-grid-tooltip-radius: .5rem;--re-data-grid-tooltip-padding: .4rem .6rem;--re-data-grid-tooltip-shadow: 0 8px 24px rgba(15, 23, 42, .25);--re-data-grid-tooltip-z: 60;--re-data-grid-header-rounded: var(--re-data-grid-rounded);--re-data-grid-header-surface: #fff;--re-data-grid-header-body-gap: 0px;--re-data-grid-header-row-height: 40px;--re-data-grid-header-row-separator-color: #ccc;--re-data-grid-header-row-separator: 1px solid var(--re-data-grid-header-row-separator-color);--re-data-grid-header-group-row-height: var(--re-data-grid-header-row-height);--re-data-grid-header-group-row-separator-color: var(--re-data-grid-header-row-separator-color);--re-data-grid-header-group-row-separator: 1px solid var(--re-data-grid-header-group-row-separator-color);--re-data-grid-header-group-cell-font-weight: var(--re-data-grid-header-cell-font-weight);--re-data-grid-header-group-cell-font-size: var(--re-data-grid-header-cell-font-size);--re-data-grid-header-group-cell-color: var(--re-data-grid-header-cell-color);--re-data-grid-header-group-cell-surface: var(--re-data-grid-header-cell-surface);--re-data-grid-header-cell-font-weight: 600;--re-data-grid-header-cell-font-size: .8rem;--re-data-grid-header-cell-color: #000;--re-data-grid-header-cell-surface: #fafafa;--re-data-grid-header-cell-line-height: 1.2;--re-data-grid-header-cell-max-lines: 2;--re-data-grid-footer-separator-color: #ccc;--re-data-grid-footer-separator: 1px solid var(--re-data-grid-footer-separator-color);--re-data-grid-footer-surface: #fff;--re-data-grid-row-separator-color: #bbb;--re-data-grid-row-separator: 1px solid var(--re-data-grid-row-separator-color);--re-data-grid-row-odd-surface: var(--re-data-grid-cell-surface);--re-data-grid-row-hover-surface: var(--re-data-grid-cell-surface);--re-data-grid-row-hover-color: var(--re-data-grid-cell-color);--re-data-grid-row-hover-rounded: 0px;--re-data-grid-column-separator-color: transparent;--re-data-grid-column-separator: 1px solid var(--re-data-grid-column-separator-color);--re-data-grid-column-odd-surface: var(--re-data-grid-cell-surface);--re-data-grid-cell-paddings: .4rem .625rem;--re-data-grid-cell-font-weight: 400;--re-data-grid-cell-font-size: .75rem;--re-data-grid-cell-color: #000;--re-data-grid-cell-surface: #fff;--re-data-grid-cell-line-height: 1.2;--re-data-grid-cell-max-lines: 2;--re-data-grid-sticky-header-cell-surface: #fff;--re-data-grid-sticky-cell-surface: #fdfdfd;--re-data-grid-sticky-cell-row-odd-surface: #fdfdfd;--re-data-grid-sticky-cell-left-shadow: 2px 0 2px rgba(0, 0, 0, .03);--re-data-grid-sticky-cell-right-shadow: -2px 0 2px rgba(0, 0, 0, .03);--re-data-grid-pinned-surface: #fcfcfc;--re-data-grid-pinned-separator-color: #eee;--re-data-grid-pinned-separator: 1px solid var(--re-data-grid-pinned-separator-color);--re-data-grid-expander-color: var(--primary-color, currentColor);--re-data-grid-expanded-color: var(--re-data-grid-cell-color, #000);--re-data-grid-expanded-surface: var(--re-data-grid-cell-surface, #fff);--re-data-grid-focus-ring-color: color-mix(in srgb, var(--primary-color, #2a90f4) 55%, transparent);--re-data-grid-focus-ring-width: 2px;--re-data-grid-focus-ring-offset: -2px;display:block;min-height:0;min-width:0}:host,:host *,:host *:before,:host *:after{box-sizing:border-box;outline:none}:host button{outline:none}.re-dg-root{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;min-height:var(--re-data-grid-min-height);border-radius:var(--re-data-grid-rounded);border:var(--re-data-grid-separator)}.re-dg-root.fill{display:block}.re-dg-root.re-dg-loading{pointer-events:none;-webkit-user-select:none;user-select:none;cursor:wait}.re-dg-root.re-dg-loading .re-dg-body{overflow:hidden}.re-dg-root.re-dg-loading .re-dg-scrollbar{display:none!important}.re-dg-root.re-dg-loading .re-dg-loader{pointer-events:all}.re-dg-root.lock-vertical-scroll .re-dg-body{overflow-x:auto;overflow-y:hidden}.re-dg-root.lock-vertical-scroll .re-dg-scrollbar{display:none!important}.re-dg-root.resizing-columns{-webkit-user-select:none;user-select:none;cursor:col-resize}.re-dg-body{position:relative;flex:1 1 auto;min-height:0;min-width:0;height:inherit;border:var(--re-data-grid-separator);border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-surface);overflow:auto;scrollbar-width:auto;-ms-overflow-style:auto}.re-dg-body::-webkit-scrollbar{width:var(--re-data-grid-scrollbar-size);height:var(--re-data-grid-scrollbar-size)}.re-dg-body::-webkit-scrollbar:vertical{width:0}.re-dg-body::-webkit-scrollbar-track{border-radius:var(--re-data-grid-scrollbar-track-rounded);background:var(--re-data-grid-scrollbar-track-surface)}.re-dg-body::-webkit-scrollbar-thumb{border-radius:var(--re-data-grid-scrollbar-thumb-rounded);background:var(--re-data-grid-scrollbar-thumb-color);transition:opacity .3s ease}.re-dg-body::-webkit-scrollbar-thumb:hover{background:var(--re-data-grid-scrollbar-thumb-active-color)}.re-dg-header,.re-dg-footer{position:sticky;z-index:3}.re-dg-header{top:0;background-color:var(--re-data-grid-header-surface)}.re-dg-header-row{min-height:var(--re-data-grid-header-row-height)}.re-dg-header-group-row{min-height:var(--re-data-grid-header-group-row-height)}.re-dg-header-rows{display:flex;flex-direction:column;padding-bottom:var(--re-data-grid-header-body-gap)}.re-dg-footer{bottom:0;border-radius:0 0 var(--re-data-grid-rounded) var(--re-data-grid-rounded);background-color:var(--re-data-grid-footer-surface)}.re-dg-row{position:relative;display:flex}.re-dg-data-row{position:absolute;left:0;top:0;min-width:100%;cursor:default;will-change:transform}.re-dg-sticky-row{z-index:2;top:0}.re-dg-cell,.re-dg-header-cell{display:flex;flex:0 0 auto;align-items:center;padding:var(--re-data-grid-cell-paddings);border-right:var(--re-data-grid-column-separator);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.re-dg-cell:focus-visible,.re-dg-header-cell:focus-visible,.re-dg-header-cell button:focus-visible,.re-dg-row[tabindex=\"0\"]:focus-visible{outline:var(--re-data-grid-focus-ring-width) solid var(--re-data-grid-focus-ring-color);outline-offset:var(--re-data-grid-focus-ring-offset);z-index:4}.re-dg-cell{width:100%;border-bottom:var(--re-data-grid-row-separator);font-weight:var(--re-data-grid-cell-font-weight);font-size:var(--re-data-grid-cell-font-size);color:var(--re-data-grid-cell-color);background-color:var(--re-data-grid-cell-surface)}.re-dg-row:nth-child(odd) .re-dg-cell{background-color:var(--re-data-grid-row-odd-surface)}.re-dg-row.re-dg-row-disabled .re-dg-cell{opacity:.6;cursor:not-allowed}.re-dg-row:nth-child(odd) .re-dg-cell.sticky-left,.re-dg-row:nth-child(odd) .re-dg-cell.sticky-right{background-color:var(--re-data-grid-sticky-cell-row-odd-surface)}.re-dg-cell:nth-child(odd){background-color:var(--re-data-grid-column-odd-surface)}.re-dg-bottom>.re-dg-cell{border-top:var(--re-data-grid-footer-separator)}.re-dg-header-cell{position:relative;align-items:center;gap:.75rem;border-bottom:var(--re-data-grid-header-row-separator);font-weight:var(--re-data-grid-header-cell-font-weight);font-size:var(--re-data-grid-header-cell-font-size);color:var(--re-data-grid-header-cell-color);background:var(--re-data-grid-header-cell-surface);-webkit-user-select:none;user-select:none;transition:color .3s ease-in-out}.re-dg-column-resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;z-index:5}.re-dg-header-cell.re-dg-header-group-cell{border-bottom:var(--re-data-grid-header-group-row-separator);font-weight:var(--re-data-grid-header-group-cell-font-weight);font-size:var(--re-data-grid-header-group-cell-font-size);color:var(--re-data-grid-header-group-cell-color);background:var(--re-data-grid-header-group-cell-surface)}.re-dg-header-rows>.re-dg-row:first-child .re-dg-header-cell:first-child{border-radius:var(--re-data-grid-header-rounded) 0 0 0}.re-dg-header-rows>.re-dg-row:first-child .re-dg-header-cell:last-child{border-radius:0 var(--re-data-grid-header-rounded) 0 0}.re-dg-data-row:last-child .re-dg-cell:first-child{border-radius:0 0 0 var(--re-data-grid-rounded)}.re-dg-data-row:last-child .re-dg-cell:last-child{border-radius:0 0 var(--re-data-grid-rounded) 0}.re-dg-header-cell .re-dg-header-text{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:var(--re-data-grid-header-cell-line-height);-webkit-box-orient:vertical;-webkit-line-clamp:var(--re-data-grid-header-cell-max-lines)}.re-dg-row.re-dg-pinned>.re-dg-cell{border-bottom:var(--re-data-grid-pinned-separator);background-color:var(--re-data-grid-pinned-surface)}.re-dg-row .re-dg-header-cell.sticky-left{box-shadow:var(--re-data-grid-sticky-cell-left-shadow);background-color:var(--re-data-grid-sticky-header-cell-surface)}.re-dg-row .re-dg-cell.sticky-left{box-shadow:var(--re-data-grid-sticky-cell-left-shadow);background-color:var(--re-data-grid-sticky-cell-surface)}.re-dg-row .re-dg-header-cell.sticky-right{box-shadow:var(--re-data-grid-sticky-cell-right-shadow);background-color:var(--re-data-grid-sticky-header-cell-surface)}.re-dg-row .re-dg-cell.sticky-right{box-shadow:var(--re-data-grid-sticky-cell-right-shadow);background-color:var(--re-data-grid-sticky-cell-surface)}.re-dg-row.re-dg-pinned>.re-dg-cell.sticky-left,.re-dg-row.re-dg-pinned>.re-dg-cell.sticky-right{background-color:var(--re-data-grid-pinned-surface)}.re-dg-row:hover>.re-dg-cell,.re-dg-row:hover>.re-dg-cell.sticky-left,.re-dg-row:hover>.re-dg-cell.sticky-right{background-color:var(--re-data-grid-row-hover-surface)!important;color:var(--re-data-grid-row-hover-color)!important}.re-dg-row:hover>.re-dg-cell:first-child{border-radius:var(--re-data-grid-row-hover-rounded) 0 0 var(--re-data-grid-row-hover-rounded)}.re-dg-row:hover>.re-dg-cell:last-child{border-radius:0 var(--re-data-grid-row-hover-rounded) var(--re-data-grid-row-hover-rounded) 0}.sticky-left,.sticky-right{position:sticky;z-index:2}.sortable{cursor:pointer}.active-sort{color:var(--re-data-grid-active)}.re-dg-sort-ind{margin-left:6px}.re-dg-icon-placeholder{display:inline-block;width:1rem;height:1rem}.re-dg-cell-deferred{display:block;width:100%;height:100%}.re-dg-deferred-placeholder{background:transparent}.re-dg-data-row .re-dg-cell.expanded{color:var(--re-data-grid-expanded-color);background:var(--re-data-grid-expanded-surface)}.re-dg-empty{position:absolute;inset:0;display:grid;place-items:center;height:inherit;width:100%;border-radius:var(--re-data-grid-rounded);color:var(--re-data-grid-empty-color);background:var(--re-data-grid-empty-surface)}.re-dg-empty-text{width:100%;text-align:center}.re-dg-loader{position:absolute;inset:0;display:grid;place-items:center;height:inherit;border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-loading-surface);color:var(--re-data-grid-loading-color);z-index:5}.re-dg-tooltip{position:fixed;left:0;top:0;max-width:min(28rem,70vw);padding:var(--re-data-grid-tooltip-padding);border-radius:var(--re-data-grid-tooltip-radius);background:var(--re-data-grid-tooltip-surface);color:var(--re-data-grid-tooltip-color);box-shadow:var(--re-data-grid-tooltip-shadow);font-size:.75rem;line-height:1.2;z-index:var(--re-data-grid-tooltip-z);pointer-events:none;opacity:0;transform:translateY(4px);transition:opacity .12s ease,transform .12s ease}.re-dg-tooltip.visible{opacity:1;transform:translateY(0)}.re-dg-loader-spinner{width:var(--re-data-grid-spinner-size);height:var(--re-data-grid-spinner-size);border-radius:50%;border:var(--re-data-grid-spinner-width) solid var(--re-data-grid-spinner-track-color);border-top-color:var(--re-data-grid-loading-color);animation:re-dg-spinner .8s linear infinite}.re-dg-skeleton-row{display:flex;align-items:center;padding:var(--re-data-grid-cell-paddings);border-bottom:var(--re-data-grid-row-separator);background-color:var(--re-data-grid-cell-surface);pointer-events:none}.re-dg-skeleton-row-line{display:block;width:var(--re-data-grid-skeleton-width);height:var(--re-data-grid-skeleton-height);border-radius:var(--re-data-grid-skeleton-rounded);background:linear-gradient(90deg,var(--re-data-grid-skeleton-line) 0%,var(--re-data-grid-skeleton-shine) 50%,var(--re-data-grid-skeleton-line) 100%);background-size:200% 100%;animation:re-dg-skeleton 1.2s ease-in-out infinite}@keyframes re-dg-skeleton{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes re-dg-spinner{to{transform:rotate(360deg)}}.re-dg-scrollbar{position:absolute;right:0;top:0;bottom:0;opacity:0;transition:opacity .15s ease-in-out;pointer-events:none;z-index:4}.re-dg-scrollbar.visible{opacity:1}.re-dg-scrollbar-thumb{position:absolute;right:var(--re-data-grid-scrollbar-offset);width:var(--re-data-grid-scrollbar-thumb-size);border-radius:var(--re-data-grid-scrollbar-thumb-rounded);background:var(--re-data-grid-scrollbar-thumb-color);pointer-events:auto;-webkit-user-select:none;user-select:none}.re-dg-spacer{width:1px}.re-dg-top{top:0}.re-dg-bottom{bottom:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DataGridCellComponent, selector: "re-data-grid-cell", inputs: ["index", "item", "isPinned", "column"] }, { kind: "component", type: SortIcon, selector: "re-sort-ic", inputs: ["direction"] }, { kind: "component", type: ExpandIcon, selector: "re-expand-ic", inputs: ["expanded"] }, { kind: "component", type: CheckboxIcon, selector: "re-checkbox-ic", inputs: ["state", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [CheckboxIcon], () => [SortIcon], () => [ExpandIcon], () => [NgTemplateOutlet], () => [NgTemplateOutlet], () => [DataGridCellComponent], () => [NgTemplateOutlet], () => [NgTemplateOutlet], () => [NgTemplateOutlet]] });
4166
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
4167
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: DataGrid, isStandalone: true, selector: "re-data-grid", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, pinnedRows: { classPropertyName: "pinnedRows", publicName: "pinnedRows", isSignal: true, isRequired: false, transformFunction: null }, isRowSticky: { classPropertyName: "isRowSticky", publicName: "isRowSticky", isSignal: true, isRequired: false, transformFunction: null }, isRowDisabled: { classPropertyName: "isRowDisabled", publicName: "isRowDisabled", isSignal: true, isRequired: false, transformFunction: null }, getRowTemplate: { classPropertyName: "getRowTemplate", publicName: "getRowTemplate", isSignal: true, isRequired: false, transformFunction: null }, hasIndexColumn: { classPropertyName: "hasIndexColumn", publicName: "hasIndexColumn", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, virtualBuffer: { classPropertyName: "virtualBuffer", publicName: "virtualBuffer", isSignal: true, isRequired: false, transformFunction: null }, lockVerticalScroll: { classPropertyName: "lockVerticalScroll", publicName: "lockVerticalScroll", isSignal: true, isRequired: false, transformFunction: null }, headerGroups: { classPropertyName: "headerGroups", publicName: "headerGroups", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingMode: { classPropertyName: "loadingMode", publicName: "loadingMode", isSignal: true, isRequired: false, transformFunction: null }, deferContent: { classPropertyName: "deferContent", publicName: "deferContent", isSignal: true, isRequired: false, transformFunction: null }, deferHeader: { classPropertyName: "deferHeader", publicName: "deferHeader", isSignal: true, isRequired: false, transformFunction: null }, deferPinned: { classPropertyName: "deferPinned", publicName: "deferPinned", isSignal: true, isRequired: false, transformFunction: null }, deferCells: { classPropertyName: "deferCells", publicName: "deferCells", isSignal: true, isRequired: false, transformFunction: null }, deferIcons: { classPropertyName: "deferIcons", publicName: "deferIcons", isSignal: true, isRequired: false, transformFunction: null }, deferTooltip: { classPropertyName: "deferTooltip", publicName: "deferTooltip", isSignal: true, isRequired: false, transformFunction: null }, rowKey: { classPropertyName: "rowKey", publicName: "rowKey", isSignal: true, isRequired: false, transformFunction: null }, pageStartFromZero: { classPropertyName: "pageStartFromZero", publicName: "pageStartFromZero", isSignal: true, isRequired: false, transformFunction: null }, sortMode: { classPropertyName: "sortMode", publicName: "sortMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", sortChange: "sortChange", multiSortChange: "multiSortChange", selectChange: "selectChange", rowClick: "rowClick", rowContext: "rowContext", rowDoubleClick: "rowDoubleClick", cellClick: "cellClick", cellContext: "cellContext", cellDoubleClick: "cellDoubleClick", columnResizeEnd: "columnResizeEnd" }, providers: [DataGridVm], queries: [{ propertyName: "cellTypedSlotRefs", predicate: DataGridTypeCellTemplateDirective, isSignal: true }, { propertyName: "cellDataSlotRefs", predicate: DataGridCellTemplateDirective, isSignal: true }, { propertyName: "declarativeColumnRefs", predicate: DataGridDeclarativeColumn, isSignal: true }, { propertyName: "headerSlotRefs", predicate: DataGridHeaderTemplateDirective, isSignal: true }, { propertyName: "emptySlotRefs", predicate: DataGridCellEmptyDirective, isSignal: true }, { propertyName: "loadingSlotRefs", predicate: DataGridCellLoadingDirective, isSignal: true }, { propertyName: "sortIcSlotRefs", predicate: DataGridSortIconDirective, isSignal: true }, { propertyName: "expanderIcSlotRefs", predicate: DataGridExpanderIconDirective, isSignal: true }, { propertyName: "stickyRowSlotRefs", predicate: DataGridStickyRowDirective, isSignal: true }, { propertyName: "rowSlotRefs", predicate: DataGridRowDirective, isSignal: true }], viewQueries: [{ propertyName: "rootEl", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "scrollEl", first: true, predicate: ["scroll"], descendants: true, isSignal: true }, { propertyName: "headerEl", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "tooltipEl", first: true, predicate: ["tooltip"], descendants: true, isSignal: true }], ngImport: i0, template: "@let items = selectionRows();\r\n@let totalRows = totalRowCount();\r\n@let empty = !resolvedLoading() && !totalRows;\r\n@let notEmpty = !!totalRows;\r\n@let skeletonRowsCount = 4;\r\n@let skeletonMode = loadingMode() === 'skeleton';\r\n@let spinnerMode = loadingMode() === 'spinner';\r\n@let showInfinitySkeleton = resolvedLoading() && skeletonMode && mode() === 'infinity';\r\n@let showPaginationSkeleton = resolvedLoading() && skeletonMode && mode() === 'pagination' && !notEmpty;\r\n@let showSpinnerLoading = resolvedLoading() && spinnerMode;\r\n@let extraInfinitySkeletonRows = showInfinitySkeleton ? skeletonRowsCount : 0;\r\n\r\n@let pinnedTopH = vm.pinnedTop().length * rowHeight();\r\n@let pinnedBottomH = vm.pinnedBottom().length * rowHeight();\r\n@let rowH = rowHeight();\r\n@let contentW = vm.contentWidth();\r\n@let cols = vm.columnsToShow();\r\n@let stickyTop = pinnedTopH + headerHeight();\r\n@let normalizedHeaderGroups = vm.normalizedHeaderGroups();\r\n@let stickyRow = stickyRowData();\r\n@let stickyIndex = stickyRowIndex();\r\n\r\n<div\r\n #root\r\n class=\"re-dg-root\"\r\n [attr.id]=\"expanderRegionId\"\r\n [class.re-dg-loading]=\"showSpinnerLoading\"\r\n [class.lock-vertical-scroll]=\"lockVerticalScroll()\"\r\n [class.resizing-columns]=\"isColumnResizing()\"\r\n [style.height]=\"styleHeight()\"\r\n [attr.aria-multiselectable]=\"selection().mode === 'multi' ? true : null\"\r\n [attr.aria-rowcount]=\"ariaRowCount()\"\r\n [attr.aria-colcount]=\"ariaColCount()\"\r\n role=\"grid\"\r\n>\r\n @if (showSpinnerLoading) {\r\n <div class=\"re-dg-loader\" aria-live=\"polite\" role=\"status\">\r\n @let loadingTemplate = loadingTpl();\r\n\r\n @if (loadingTemplate?.tpl) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\r\n } @else {\r\n <span class=\"re-dg-loader-spinner\" aria-label=\"Loading\"></span>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n #scroll\r\n class=\"re-dg-body\"\r\n role=\"rowgroup\"\r\n (mouseenter)=\"showScrollbar()\"\r\n (mouseleave)=\"hideScrollbarSoon()\"\r\n >\r\n <ng-template #headerContent>\r\n <div\r\n class=\"re-dg-header\"\r\n role=\"rowgroup\"\r\n [style.width.px]=\"vm.contentWidth()\"\r\n [style.min-width.%]=\"100\"\r\n >\r\n <div #header class=\"re-dg-header-rows\">\r\n @if (normalizedHeaderGroups.length) {\r\n <div class=\"re-dg-row re-dg-header-group-row\" role=\"row\" [style.width.px]=\"vm.contentWidth()\" [style.min-width.%]=\"100\">\r\n @for (group of normalizedHeaderGroups; track group.key; let groupIndex = $index) {\r\n @let groupStickyLeft = !!group.startKey && !!group.endKey && vm.isStickyLeft(group.startKey) && vm.isStickyLeft(group.endKey);\r\n @let groupStickyRight = !!group.startKey && !!group.endKey && vm.isStickyRight(group.startKey) && vm.isStickyRight(group.endKey);\r\n\r\n @let resolvedGroupTitle = resolveHeaderGroupTitle(group);\r\n\r\n <div\r\n class=\"re-dg-header-cell re-dg-header-group-cell\"\r\n role=\"columnheader\"\r\n [class.sticky-left]=\"groupStickyLeft\"\r\n [class.sticky-right]=\"groupStickyRight\"\r\n [style.left.px]=\"groupStickyLeft && group.startKey ? vm.stickyOffset(group.startKey, 'left') : null\"\r\n [style.right.px]=\"groupStickyRight && group.endKey ? vm.stickyOffset(group.endKey, 'right') : null\"\r\n [style.width.px]=\"group.widthPx\"\r\n [style.justify-content]=\"group.align || 'left'\"\r\n [title]=\"resolvedGroupTitle\"\r\n [attr.aria-colindex]=\"ariaHeaderGroupColIndex(group)\"\r\n [attr.aria-rowindex]=\"groupIndex + 1\"\r\n >\r\n @if (group.titleTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"group.titleTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvedGroupTitle }\"\r\n />\r\n } @else {\r\n <span class=\"re-dg-header-text\">{{ resolvedGroupTitle }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"re-dg-row re-dg-header-row\" role=\"row\" [style.width.px]=\"vm.contentWidth()\" [style.min-width.%]=\"100\">\r\n @for (col of vm.columnsToShow(); track col.key; let colIndex = $index) {\r\n <div\r\n class=\"re-dg-header-cell\"\r\n role=\"columnheader\"\r\n [class.sortable]=\"!!col.sortKey\"\r\n [class.active-sort]=\"isActiveSort(col)\"\r\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\r\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\r\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\r\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [style.min-width.px]=\"col.minWidth || null\"\r\n [style.max-width.px]=\"col.maxWidth || null\"\r\n [style.justify-content]=\"col.align || 'left'\"\r\n [attr.aria-sort]=\"ariaSort(col)\"\r\n [attr.aria-colindex]=\"colIndex + 1\"\r\n [attr.aria-rowindex]=\"normalizedHeaderGroups.length ? 2 : 1\"\r\n [attr.aria-label]=\"col.sortKey ? ariaSortLabel(col) : null\"\r\n [attr.tabindex]=\"col.sortKey ? 0 : -1\"\r\n (click)=\"col.sortKey && onSort(col)\"\r\n (keydown.enter)=\"col.sortKey && onSort(col)\"\r\n >\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n @let isMultiSelect = selection().mode === 'multi';\r\n\r\n @if (isCheckbox && isMultiSelect) {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-checkbox-ic\r\n aria-label=\"Select loaded rows\"\r\n [state]=\"selector.isAllSelected()\"\r\n tabindex=\"0\"\r\n (click)=\"onSelectAll($event)\"\r\n (keydown.enter)=\"onSelectAllKeydown($event)\"\r\n (keydown.space)=\"onSelectAllKeydown($event)\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-checkbox-ic\r\n aria-label=\"Select loaded rows\"\r\n [state]=\"selector.isAllSelected()\"\r\n tabindex=\"0\"\r\n (click)=\"onSelectAll($event)\"\r\n (keydown.enter)=\"onSelectAllKeydown($event)\"\r\n (keydown.space)=\"onSelectAllKeydown($event)\" />\r\n }\r\n } @else {\r\n @let resolvedHeader = resolveHeaderText(col);\r\n\r\n @if (col.headerTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.headerTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvedHeader }\"\r\n />\r\n } @else {\r\n <span class=\"re-dg-header-text\">{{ resolvedHeader }}</span>\r\n }\r\n }\r\n\r\n @if (col.sortKey) {\r\n <span class=\"re-dg-sort-ind\">\r\n @let direction = sortOrderFor(col);\r\n\r\n @if (sortTpl()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"sortTpl()!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: direction }\"\r\n />\r\n } @else {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-sort-ic [direction]=\"direction\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-sort-ic [direction]=\"direction\" />\r\n }\r\n }\r\n </span>\r\n }\r\n\r\n @if (isExpandable(col)) {\r\n <button\r\n [attr.aria-controls]=\"expanderRegionId\"\r\n [attr.aria-expanded]=\"expanderMap().get(col.key) ? 'true' : 'false'\"\r\n [attr.aria-label]=\"ariaExpandLabel(col)\"\r\n (click)=\"$event.stopPropagation(); onExpand(col)\"\r\n >\r\n @let expanded = expanderMap().get(col.key);\r\n\r\n @if (expanderTpl()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"expanderTpl()!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: expanded }\" />\r\n } @else {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-expand-ic [expanded]=\"expanded\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-expand-ic [expanded]=\"expanded\" />\r\n }\r\n }\r\n </button>\r\n }\r\n\r\n @if (canResizeColumn(col)) {\r\n <button\r\n class=\"re-dg-column-resize-handle\"\r\n aria-orientation=\"vertical\"\r\n role=\"separator\"\r\n [attr.aria-label]=\"ariaResizeLabel(col)\"\r\n (mousedown)=\"onColumnResizeStart($event, col)\"\r\n (click)=\"$event.stopPropagation()\"\r\n ></button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- PINNED TOP ROWS -->\r\n @if (notEmpty) {\r\n <ng-template #pinnedTopContent>\r\n @for (pr of vm.pinnedTop(); track trackPinnedRow(pr); let pinnedTopIndex = $index) {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top\" role=\"row\" [style.width.px]=\"contentW\" [style.min-width.%]=\"100\" [attr.aria-rowindex]=\"ariaPinnedTopRowIndex(pinnedTopIndex)\">\r\n @if (pr.rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pinnedRowCells\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n\r\n @if (deferPinned()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"pinnedTopContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n } @loading {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"pinnedTopContent\" />\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n @if (deferHeader()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"headerContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-header re-dg-deferred-placeholder\" [style.min-height.px]=\"headerHeight()\"></div>\r\n } @loading {\r\n <div class=\"re-dg-header re-dg-deferred-placeholder\" [style.min-height.px]=\"headerHeight()\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"headerContent\" />\r\n }\r\n\r\n <ng-template #dataCellContent let-row let-col=\"col\" let-index=\"index\" let-isPinned=\"isPinned\">\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n\r\n @if (isCheckbox) {\r\n <re-checkbox-ic\r\n aria-label=\"Toggle row selection\"\r\n [state]=\"selector.isSelected(row)\"\r\n [attr.aria-disabled]=\"isDisabledRow(row, index)\"\r\n [attr.tabindex]=\"isDisabledRow(row, index) ? -1 : 0\"\r\n (click)=\"onCheckboxToggle(row, index, $event)\"\r\n (keydown.enter)=\"onCheckboxKeydown(row, index, $event)\"\r\n (keydown.space)=\"onCheckboxKeydown(row, index, $event)\" />\r\n } @else {\r\n @if (deferCells()) {\r\n @defer (when true) {\r\n <re-data-grid-cell [index]=\"index\" [item]=\"row\" [column]=\"col\" [isPinned]=\"!!isPinned\" />\r\n } @placeholder {\r\n <span class=\"re-dg-cell-deferred\"></span>\r\n } @loading {\r\n <span class=\"re-dg-cell-deferred\"></span>\r\n }\r\n } @else {\r\n <re-data-grid-cell [index]=\"index\" [item]=\"row\" [column]=\"col\" [isPinned]=\"!!isPinned\" />\r\n }\r\n }\r\n </ng-template>\r\n\r\n <ng-template #gridContent>\r\n\r\n <!-- STICKY ROW -->\r\n @if (stickyRow && stickyIndex !== null) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-sticky-row\"\r\n role=\"row\"\r\n [class.re-dg-row-disabled]=\"isDisabledRow(stickyRow, stickyIndex)\"\r\n [style.width.px]=\"vm.contentWidth()\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowHeight()\"\r\n [style.top.px]=\"stickyRowTopPx()\"\r\n [attr.aria-rowindex]=\"ariaDataRowIndex(stickyIndex)\"\r\n [attr.aria-disabled]=\"isDisabledRow(stickyRow, stickyIndex)\"\r\n [attr.aria-selected]=\"selection().mode !== 'none' ? selector.isSelected(stickyRow) : null\"\r\n [attr.tabindex]=\"0\"\r\n (click)=\"onRowClick(stickyRow, stickyIndex, $event)\"\r\n (contextmenu)=\"onRowContext(stickyRow, stickyIndex, $event)\"\r\n (dblclick)=\"onRowDoubleClick(stickyRow, stickyIndex, $event)\"\r\n (keydown.enter)=\"onRowClick(stickyRow, stickyIndex, $event)\"\r\n >\r\n @let stickyTemplate = stickyRowTpl();\r\n @let rowTemplate = resolveRowTemplate(stickyRow, stickyIndex);\r\n\r\n @if (stickyTemplate?.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"stickyTemplate!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: stickyRow, index: stickyIndex }\"\r\n />\r\n } @else if (rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: stickyRow,\r\n index: stickyIndex,\r\n columns: vm.columnsToShow(),\r\n rowHeight: rowHeight(),\r\n isSticky: true\r\n }\"\r\n />\r\n } @else {\r\n @for (col of vm.columnsToShow(); track col.key; let colIndex = $index) {\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, stickyRow)\"\r\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\r\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\r\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\r\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.id]=\"cellAriaId(col.key, stickyIndex, false)\"\r\n [attr.aria-colindex]=\"colIndex + 1\"\r\n [attr.aria-describedby]=\"isTooltipTarget(cellAriaId(col.key, stickyIndex, false)) ? tooltipId : null\"\r\n [attr.tabindex]=\"0\"\r\n (mouseenter)=\"onTooltipEnter($event, stickyRow, col, stickyIndex, cellAriaId(col.key, stickyIndex, false))\"\r\n (mouseleave)=\"hideTooltip()\"\r\n (click)=\"onCellClick(stickyRow, col, stickyIndex, $event);\"\r\n (contextmenu)=\"onCellContext(stickyRow, col, stickyIndex, $event)\"\r\n (dblclick)=\"onCellDoubleClick(stickyRow, col, stickyIndex, $event)\"\r\n (keydown.enter)=\"onCellClick(stickyRow, col, stickyIndex, $event)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: stickyRow, col: col, index: stickyIndex, isPinned: false }\"\r\n />\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @if (empty) {\r\n @let emptyTemplate = emptyTpl()?.tpl;\r\n\r\n <div class=\"re-dg-empty\" aria-live=\"polite\" role=\"status\">\r\n @if (emptyTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"emptyTemplate\" />\r\n } @else {\r\n <span class=\"re-dg-empty-text\">{{ defaults.translations.emptyState }}</span>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Content -->\r\n @if (notEmpty) {\r\n @let topGap = topGapLoader();\r\n @let bottomGap = bottomGapLoader();\r\n <div\r\n class=\"re-dg-spacer\"\r\n [style.width.px]=\"contentW\"\r\n [style.height.px]=\"(totalRows + extraInfinitySkeletonRows) * rowH - pinnedBottomH\"></div>\r\n\r\n @if (topGap) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-gap-loader\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"topGap.count * rowH\"\r\n [style.transform]=\"'translateY(' + (topGap.start * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n\r\n @for (slot of renderSlots(); track slot) {\r\n @let rowIndex = startIndex + slot;\r\n @let row = rowAt(rowIndex);\r\n @let rowTemplate = row ? resolveRowTemplate(row, rowIndex) : null;\r\n\r\n @if (row && !isStickyRowIndex(rowIndex)) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row\"\r\n role=\"row\"\r\n [class.re-dg-row-disabled]=\"isDisabledRow(row, rowIndex)\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (rowIndex * rowH + stickyTop) + 'px)'\"\r\n [attr.aria-rowindex]=\"ariaDataRowIndex(rowIndex)\"\r\n [attr.aria-disabled]=\"isDisabledRow(row, rowIndex)\"\r\n [attr.aria-selected]=\"selection().mode !== 'none' ? selector.isSelected(row) : null\"\r\n [attr.tabindex]=\"0\"\r\n (click)=\"onRowClick(row, rowIndex, $event)\"\r\n (contextmenu)=\"onRowContext(row, rowIndex, $event)\"\r\n (dblclick)=\"onRowDoubleClick(row, rowIndex, $event)\"\r\n (keydown.enter)=\"onRowClick(row, rowIndex, $event)\"\r\n >\r\n @if (rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n index: rowIndex,\r\n columns: vm.columnsToShow(),\r\n rowHeight: rowHeight(),\r\n isSticky: false\r\n }\"\r\n />\r\n } @else {\r\n @for (col of cols; track col.key; let colIndex = $index) {\r\n @let stickyLeft = vm.stickyOffset(col.key, 'left');\r\n @let stickyRight = vm.stickyOffset(col.key, 'right');\r\n @let isLeft = vm.isStickyLeft(col.key);\r\n @let isRight = vm.isStickyRight(col.key);\r\n\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, row)\"\r\n [class.sticky-left]=\"isLeft\"\r\n [class.sticky-right]=\"isRight\"\r\n [style.left.px]=\"stickyLeft\"\r\n [style.right.px]=\"stickyRight\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.id]=\"cellAriaId(col.key, rowIndex, false)\"\r\n [attr.aria-colindex]=\"colIndex + 1\"\r\n [attr.aria-describedby]=\"isTooltipTarget(cellAriaId(col.key, rowIndex, false)) ? tooltipId : null\"\r\n [attr.tabindex]=\"0\"\r\n (mouseenter)=\"onTooltipEnter($event, row, col, rowIndex, cellAriaId(col.key, rowIndex, false))\"\r\n (mouseleave)=\"hideTooltip()\"\r\n (click)=\"onCellClick(row, col, rowIndex, $event);\"\r\n (contextmenu)=\"onCellContext(row, col, rowIndex, $event)\"\r\n (dblclick)=\"onCellDoubleClick(row, col, rowIndex, $event)\"\r\n (keydown.enter)=\"onCellClick(row, col, rowIndex, $event)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, col: col, index: rowIndex, isPinned: false }\"\r\n />\r\n </div>\r\n }\r\n }\r\n </div>\r\n } @else if (shouldRenderLoadingRow(rowIndex, topGap, bottomGap)) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-skeleton-row\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (rowIndex * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n }\r\n\r\n @if (bottomGap) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-gap-loader\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"bottomGap.count * rowH\"\r\n [style.transform]=\"'translateY(' + (bottomGap.start * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n }\r\n\r\n @if (showInfinitySkeleton || showPaginationSkeleton) {\r\n @let loadingTemplate = loadingTpl();\r\n\r\n @if (loadingTemplate?.tpl) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\r\n } @else {\r\n @for (si of [0, 1, 2, 3]; track si) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-skeleton-row\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (((showInfinitySkeleton ? items.length : 0) + si) * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n <!-- PINNED BOTTOM ROWS -->\r\n @if (notEmpty) {\r\n <ng-template #pinnedBottomContent>\r\n <div class=\"re-dg-footer\" role=\"rowgroup\">\r\n @for (pr of vm.pinnedBottom(); track trackPinnedRow(pr); let pinnedBottomIndex = $index) {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-bottom\" role=\"row\" [style.width.px]=\"contentW\" [style.min-width.%]=\"100\" [attr.aria-rowindex]=\"ariaPinnedBottomRowIndex(pinnedBottomIndex)\">\r\n @if (pr.rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pinnedRowCells\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n @if (deferPinned()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"pinnedBottomContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-footer re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n } @loading {\r\n <div class=\"re-dg-footer re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"pinnedBottomContent\" />\r\n }\r\n }\r\n </ng-template>\r\n\r\n @if (deferContent()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"gridContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH * 3\"></div>\r\n } @loading {\r\n <div class=\"re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH * 3\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"gridContent\" />\r\n }\r\n </div>\r\n\r\n <ng-template #pinnedRowCells let-row>\r\n @for (col of cols; track col.key; let colIndex = $index) {\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n @let isIndex = 'type' in col && col.type === 'index';\r\n @let stickyLeft = vm.stickyOffset(col.key, 'left');\r\n @let stickyRight = vm.stickyOffset(col.key, 'right');\r\n @let isLeft = vm.isStickyLeft(col.key);\r\n @let isRight = vm.isStickyRight(col.key);\r\n\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, $any(row))\"\r\n [class.sticky-left]=\"isLeft\"\r\n [class.sticky-right]=\"isRight\"\r\n [style.left.px]=\"stickyLeft\"\r\n [style.right.px]=\"stickyRight\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.height.px]=\"rowH\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.id]=\"cellAriaId(col.key, -1, true)\"\r\n [attr.aria-colindex]=\"colIndex + 1\"\r\n [attr.aria-describedby]=\"isTooltipTarget(cellAriaId(col.key, -1, true)) ? tooltipId : null\"\r\n [attr.tabindex]=\"isCheckbox || isIndex ? -1 : 0\"\r\n (mouseenter)=\"!isCheckbox && !isIndex && onTooltipEnter($event, $any(row), col, -1, cellAriaId(col.key, -1, true))\"\r\n (mouseleave)=\"!isCheckbox && !isIndex && hideTooltip()\"\r\n (click)=\"!isCheckbox && !isIndex && onCellClick($any(row), col, -1, $event);\"\r\n (contextmenu)=\"!isCheckbox && !isIndex && onCellContext($any(row), col, -1, $event)\"\r\n (dblclick)=\"!isCheckbox && !isIndex && onCellDoubleClick($any(row), col, -1, $event)\"\r\n (keydown.enter)=\"!isCheckbox && !isIndex && onCellClick($any(row), col, -1, $event)\"\r\n >\r\n @if (!isCheckbox && !isIndex) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: $any(row), col: col, index: -1, isPinned: true }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n\r\n @if (deferTooltip()) {\r\n @defer (when true) {\r\n @let tooltipStateValue = tooltipState();\r\n <div\r\n class=\"re-dg-tooltip\"\r\n #tooltip\r\n role=\"tooltip\"\r\n [attr.id]=\"tooltipId\"\r\n [class.visible]=\"tooltipStateValue.visible\"\r\n [style.left.px]=\"tooltipStateValue.x\"\r\n [style.top.px]=\"tooltipStateValue.y\"\r\n >\r\n @if (tooltipStateValue.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"tooltipStateValue.tpl\"\r\n [ngTemplateOutletContext]=\"tooltipStateValue.ctx\"\r\n />\r\n } @else {\r\n {{ tooltipStateValue.text }}\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @let tooltipStateValue = tooltipState();\r\n <div\r\n class=\"re-dg-tooltip\"\r\n #tooltip\r\n role=\"tooltip\"\r\n [attr.id]=\"tooltipId\"\r\n [class.visible]=\"tooltipStateValue.visible\"\r\n [style.left.px]=\"tooltipStateValue.x\"\r\n [style.top.px]=\"tooltipStateValue.y\"\r\n >\r\n @if (tooltipStateValue.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"tooltipStateValue.tpl\"\r\n [ngTemplateOutletContext]=\"tooltipStateValue.ctx\"\r\n />\r\n } @else {\r\n {{ tooltipStateValue.text }}\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Overlay scrollbar -->\r\n <div class=\"re-dg-scrollbar\" [class.visible]=\"vm.scrollbarVisible()\">\r\n <div\r\n class=\"re-dg-scrollbar-thumb\"\r\n role=\"scrollbar\"\r\n aria-orientation=\"vertical\"\r\n aria-hidden=\"false\"\r\n [style.height.px]=\"vm.thumbHeightPx()\"\r\n [style.transform]=\"'translateY(' + vm.thumbTopPx() + 'px)'\"\r\n (mousedown)=\"onThumbDown($event)\"\r\n ></div>\r\n </div>\r\n</div>\r\n", styles: [":host{--re-data-grid-min-height: 200px;--re-data-grid-height: 400px;--re-data-grid-rounded: var(--radius-md, 6px);--re-data-grid-separator-color: var(--border-color);--re-data-grid-separator: 1px solid var(--re-data-grid-separator-color);--re-data-grid-surface: var(--surface-neutral, #fff);--re-data-grid-active: var(--primary-color, #2a90f4);--re-data-grid-empty-color: #777;--re-data-grid-empty-surface: transparent;--re-data-grid-loading-color: #444;--re-data-grid-loading-surface: rgba(255, 255, 255, .5);--re-data-grid-spinner-size: 2rem;--re-data-grid-spinner-width: .25rem;--re-data-grid-spinner-track-color: rgba(0, 0, 0, .12);--re-data-grid-skeleton-width: 100%;--re-data-grid-skeleton-height: 100%;--re-data-grid-skeleton-rounded: var(--re-data-grid-rounded, .75rem);--re-data-grid-skeleton-shine: rgba(255, 255, 255, .8);--re-data-grid-skeleton-line: #e7ebf0;--re-data-grid-scrollbar-size: 4px;--re-data-grid-scrollbar-offset: 2px;--re-data-grid-scrollbar-track-rounded: .25rem;--re-data-grid-scrollbar-track-surface: transparent;--re-data-grid-scrollbar-thumb-size: 8px;--re-data-grid-scrollbar-thumb-color: rgba(0, 0, 0, .25);--re-data-grid-scrollbar-thumb-active-color: rgba(0, 0, 0, .45);--re-data-grid-scrollbar-thumb-rounded: var(--re-data-grid-scrollbar-track-rounded);--re-data-grid-tooltip-surface: #0f172a;--re-data-grid-tooltip-color: #f8fafc;--re-data-grid-tooltip-radius: .5rem;--re-data-grid-tooltip-padding: .4rem .6rem;--re-data-grid-tooltip-shadow: 0 8px 24px rgba(15, 23, 42, .25);--re-data-grid-tooltip-z: 60;--re-data-grid-header-rounded: var(--re-data-grid-rounded);--re-data-grid-header-surface: #fff;--re-data-grid-header-body-gap: 0px;--re-data-grid-header-row-height: 40px;--re-data-grid-header-row-separator-color: #ccc;--re-data-grid-header-row-separator: 1px solid var(--re-data-grid-header-row-separator-color);--re-data-grid-header-group-row-height: var(--re-data-grid-header-row-height);--re-data-grid-header-group-row-separator-color: var(--re-data-grid-header-row-separator-color);--re-data-grid-header-group-row-separator: 1px solid var(--re-data-grid-header-group-row-separator-color);--re-data-grid-header-group-cell-font-weight: var(--re-data-grid-header-cell-font-weight);--re-data-grid-header-group-cell-font-size: var(--re-data-grid-header-cell-font-size);--re-data-grid-header-group-cell-color: var(--re-data-grid-header-cell-color);--re-data-grid-header-group-cell-surface: var(--re-data-grid-header-cell-surface);--re-data-grid-header-cell-font-weight: 600;--re-data-grid-header-cell-font-size: .8rem;--re-data-grid-header-cell-color: #000;--re-data-grid-header-cell-surface: #fafafa;--re-data-grid-header-cell-line-height: 1.2;--re-data-grid-header-cell-max-lines: 2;--re-data-grid-footer-separator-color: #ccc;--re-data-grid-footer-separator: 1px solid var(--re-data-grid-footer-separator-color);--re-data-grid-footer-surface: #fff;--re-data-grid-row-separator-color: #bbb;--re-data-grid-row-separator: 1px solid var(--re-data-grid-row-separator-color);--re-data-grid-row-odd-surface: var(--re-data-grid-cell-surface);--re-data-grid-row-hover-surface: var(--re-data-grid-cell-surface);--re-data-grid-row-hover-color: var(--re-data-grid-cell-color);--re-data-grid-row-hover-rounded: 0px;--re-data-grid-column-separator-color: transparent;--re-data-grid-column-separator: 1px solid var(--re-data-grid-column-separator-color);--re-data-grid-column-odd-surface: var(--re-data-grid-cell-surface);--re-data-grid-cell-paddings: .4rem .625rem;--re-data-grid-cell-font-weight: 400;--re-data-grid-cell-font-size: .75rem;--re-data-grid-cell-color: #000;--re-data-grid-cell-surface: #fff;--re-data-grid-cell-line-height: 1.2;--re-data-grid-cell-max-lines: 2;--re-data-grid-sticky-header-cell-surface: #fff;--re-data-grid-sticky-cell-surface: #fdfdfd;--re-data-grid-sticky-cell-row-odd-surface: #fdfdfd;--re-data-grid-sticky-cell-left-shadow: 2px 0 2px rgba(0, 0, 0, .03);--re-data-grid-sticky-cell-right-shadow: -2px 0 2px rgba(0, 0, 0, .03);--re-data-grid-pinned-surface: #fcfcfc;--re-data-grid-pinned-separator-color: #eee;--re-data-grid-pinned-separator: 1px solid var(--re-data-grid-pinned-separator-color);--re-data-grid-expander-color: var(--primary-color, currentColor);--re-data-grid-expanded-color: var(--re-data-grid-cell-color, #000);--re-data-grid-expanded-surface: var(--re-data-grid-cell-surface, #fff);--re-data-grid-focus-ring-color: color-mix(in srgb, var(--primary-color, #2a90f4) 55%, transparent);--re-data-grid-focus-ring-width: 2px;--re-data-grid-focus-ring-offset: -2px;display:block;min-height:0;min-width:0}:host,:host *,:host *:before,:host *:after{box-sizing:border-box;outline:none}:host button{outline:none}.re-dg-root{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;min-height:var(--re-data-grid-min-height);border-radius:var(--re-data-grid-rounded);border:var(--re-data-grid-separator)}.re-dg-root.fill{display:block}.re-dg-root.re-dg-loading{pointer-events:none;-webkit-user-select:none;user-select:none;cursor:wait}.re-dg-root.re-dg-loading .re-dg-body{overflow:hidden}.re-dg-root.re-dg-loading .re-dg-scrollbar{display:none!important}.re-dg-root.re-dg-loading .re-dg-loader{pointer-events:all}.re-dg-root.lock-vertical-scroll .re-dg-body{overflow-x:auto;overflow-y:hidden}.re-dg-root.lock-vertical-scroll .re-dg-scrollbar{display:none!important}.re-dg-root.resizing-columns{-webkit-user-select:none;user-select:none;cursor:col-resize}.re-dg-body{position:relative;flex:1 1 auto;min-height:0;min-width:0;height:inherit;border:var(--re-data-grid-separator);border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-surface);overflow:auto;scrollbar-width:auto;-ms-overflow-style:auto}.re-dg-body::-webkit-scrollbar{width:var(--re-data-grid-scrollbar-size);height:var(--re-data-grid-scrollbar-size)}.re-dg-body::-webkit-scrollbar:vertical{width:0}.re-dg-body::-webkit-scrollbar-track{border-radius:var(--re-data-grid-scrollbar-track-rounded);background:var(--re-data-grid-scrollbar-track-surface)}.re-dg-body::-webkit-scrollbar-thumb{border-radius:var(--re-data-grid-scrollbar-thumb-rounded);background:var(--re-data-grid-scrollbar-thumb-color);transition:opacity .3s ease}.re-dg-body::-webkit-scrollbar-thumb:hover{background:var(--re-data-grid-scrollbar-thumb-active-color)}.re-dg-header,.re-dg-footer{position:sticky;z-index:3}.re-dg-header{top:0;background-color:var(--re-data-grid-header-surface)}.re-dg-header-row{min-height:var(--re-data-grid-header-row-height)}.re-dg-header-group-row{min-height:var(--re-data-grid-header-group-row-height)}.re-dg-header-rows{display:flex;flex-direction:column;padding-bottom:var(--re-data-grid-header-body-gap)}.re-dg-footer{bottom:0;border-radius:0 0 var(--re-data-grid-rounded) var(--re-data-grid-rounded);background-color:var(--re-data-grid-footer-surface)}.re-dg-row{position:relative;display:flex}.re-dg-data-row{position:absolute;left:0;top:0;min-width:100%;cursor:default;will-change:transform}.re-dg-sticky-row{z-index:2;top:0}.re-dg-cell,.re-dg-header-cell{display:flex;flex:0 0 auto;align-items:center;padding:var(--re-data-grid-cell-paddings);border-right:var(--re-data-grid-column-separator);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.re-dg-cell:focus-visible,.re-dg-header-cell:focus-visible,.re-dg-header-cell button:focus-visible,.re-dg-row[tabindex=\"0\"]:focus-visible{outline:var(--re-data-grid-focus-ring-width) solid var(--re-data-grid-focus-ring-color);outline-offset:var(--re-data-grid-focus-ring-offset);z-index:4}.re-dg-cell{width:100%;border-bottom:var(--re-data-grid-row-separator);font-weight:var(--re-data-grid-cell-font-weight);font-size:var(--re-data-grid-cell-font-size);color:var(--re-data-grid-cell-color);background-color:var(--re-data-grid-cell-surface)}.re-dg-row:nth-child(odd) .re-dg-cell{background-color:var(--re-data-grid-row-odd-surface)}.re-dg-row.re-dg-row-disabled .re-dg-cell{opacity:.6;cursor:not-allowed}.re-dg-row:nth-child(odd) .re-dg-cell.sticky-left,.re-dg-row:nth-child(odd) .re-dg-cell.sticky-right{background-color:var(--re-data-grid-sticky-cell-row-odd-surface)}.re-dg-cell:nth-child(odd){background-color:var(--re-data-grid-column-odd-surface)}.re-dg-bottom>.re-dg-cell{border-top:var(--re-data-grid-footer-separator)}.re-dg-header-cell{position:relative;align-items:center;gap:.75rem;border-bottom:var(--re-data-grid-header-row-separator);font-weight:var(--re-data-grid-header-cell-font-weight);font-size:var(--re-data-grid-header-cell-font-size);color:var(--re-data-grid-header-cell-color);background:var(--re-data-grid-header-cell-surface);-webkit-user-select:none;user-select:none;transition:color .3s ease-in-out}.re-dg-column-resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;z-index:5}.re-dg-header-cell.re-dg-header-group-cell{border-bottom:var(--re-data-grid-header-group-row-separator);font-weight:var(--re-data-grid-header-group-cell-font-weight);font-size:var(--re-data-grid-header-group-cell-font-size);color:var(--re-data-grid-header-group-cell-color);background:var(--re-data-grid-header-group-cell-surface)}.re-dg-header-rows>.re-dg-row:first-child .re-dg-header-cell:first-child{border-radius:var(--re-data-grid-header-rounded) 0 0 0}.re-dg-header-rows>.re-dg-row:first-child .re-dg-header-cell:last-child{border-radius:0 var(--re-data-grid-header-rounded) 0 0}.re-dg-data-row:last-child .re-dg-cell:first-child{border-radius:0 0 0 var(--re-data-grid-rounded)}.re-dg-data-row:last-child .re-dg-cell:last-child{border-radius:0 0 var(--re-data-grid-rounded) 0}.re-dg-header-cell .re-dg-header-text{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:var(--re-data-grid-header-cell-line-height);-webkit-box-orient:vertical;-webkit-line-clamp:var(--re-data-grid-header-cell-max-lines)}.re-dg-row.re-dg-pinned>.re-dg-cell{border-bottom:var(--re-data-grid-pinned-separator);background-color:var(--re-data-grid-pinned-surface)}.re-dg-row .re-dg-header-cell.sticky-left{box-shadow:var(--re-data-grid-sticky-cell-left-shadow);background-color:var(--re-data-grid-sticky-header-cell-surface)}.re-dg-row .re-dg-cell.sticky-left{box-shadow:var(--re-data-grid-sticky-cell-left-shadow);background-color:var(--re-data-grid-sticky-cell-surface)}.re-dg-row .re-dg-header-cell.sticky-right{box-shadow:var(--re-data-grid-sticky-cell-right-shadow);background-color:var(--re-data-grid-sticky-header-cell-surface)}.re-dg-row .re-dg-cell.sticky-right{box-shadow:var(--re-data-grid-sticky-cell-right-shadow);background-color:var(--re-data-grid-sticky-cell-surface)}.re-dg-row.re-dg-pinned>.re-dg-cell.sticky-left,.re-dg-row.re-dg-pinned>.re-dg-cell.sticky-right{background-color:var(--re-data-grid-pinned-surface)}.re-dg-row:hover>.re-dg-cell,.re-dg-row:hover>.re-dg-cell.sticky-left,.re-dg-row:hover>.re-dg-cell.sticky-right{background-color:var(--re-data-grid-row-hover-surface)!important;color:var(--re-data-grid-row-hover-color)!important}.re-dg-row:hover>.re-dg-cell:first-child{border-radius:var(--re-data-grid-row-hover-rounded) 0 0 var(--re-data-grid-row-hover-rounded)}.re-dg-row:hover>.re-dg-cell:last-child{border-radius:0 var(--re-data-grid-row-hover-rounded) var(--re-data-grid-row-hover-rounded) 0}.sticky-left,.sticky-right{position:sticky;z-index:2}.sortable{cursor:pointer}.active-sort{color:var(--re-data-grid-active)}.re-dg-sort-ind{margin-left:6px}.re-dg-icon-placeholder{display:inline-block;width:1rem;height:1rem}.re-dg-cell-deferred{display:block;width:100%;height:100%}.re-dg-deferred-placeholder{background:transparent}.re-dg-data-row .re-dg-cell.expanded{color:var(--re-data-grid-expanded-color);background:var(--re-data-grid-expanded-surface)}.re-dg-empty{position:absolute;inset:0;display:grid;place-items:center;height:inherit;width:100%;border-radius:var(--re-data-grid-rounded);color:var(--re-data-grid-empty-color);background:var(--re-data-grid-empty-surface)}.re-dg-empty-text{width:100%;text-align:center}.re-dg-loader{position:absolute;inset:0;display:grid;place-items:center;height:inherit;border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-loading-surface);color:var(--re-data-grid-loading-color);z-index:5}.re-dg-tooltip{position:fixed;left:0;top:0;max-width:min(28rem,70vw);padding:var(--re-data-grid-tooltip-padding);border-radius:var(--re-data-grid-tooltip-radius);background:var(--re-data-grid-tooltip-surface);color:var(--re-data-grid-tooltip-color);box-shadow:var(--re-data-grid-tooltip-shadow);font-size:.75rem;line-height:1.2;z-index:var(--re-data-grid-tooltip-z);pointer-events:none;opacity:0;transform:translateY(4px);transition:opacity .12s ease,transform .12s ease}.re-dg-tooltip.visible{opacity:1;transform:translateY(0)}.re-dg-loader-spinner{width:var(--re-data-grid-spinner-size);height:var(--re-data-grid-spinner-size);border-radius:50%;border:var(--re-data-grid-spinner-width) solid var(--re-data-grid-spinner-track-color);border-top-color:var(--re-data-grid-loading-color);animation:re-dg-spinner .8s linear infinite}.re-dg-skeleton-row{display:flex;align-items:center;padding:var(--re-data-grid-cell-paddings);border-bottom:var(--re-data-grid-row-separator);background-color:var(--re-data-grid-cell-surface);pointer-events:none}.re-dg-gap-loader{display:flex;align-items:center;padding:var(--re-data-grid-cell-paddings);border-bottom:var(--re-data-grid-row-separator);background-color:color-mix(in srgb,var(--re-data-grid-cell-surface) 88%,var(--re-data-grid-skeleton-line));pointer-events:none;opacity:.9}.re-dg-skeleton-row-line{display:block;width:var(--re-data-grid-skeleton-width);height:var(--re-data-grid-skeleton-height);border-radius:var(--re-data-grid-skeleton-rounded);background:linear-gradient(90deg,var(--re-data-grid-skeleton-line) 0%,var(--re-data-grid-skeleton-shine) 50%,var(--re-data-grid-skeleton-line) 100%);background-size:200% 100%;animation:re-dg-skeleton 1.2s ease-in-out infinite}@keyframes re-dg-skeleton{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes re-dg-spinner{to{transform:rotate(360deg)}}.re-dg-scrollbar{position:absolute;right:0;top:0;bottom:0;opacity:0;transition:opacity .15s ease-in-out;pointer-events:none;z-index:4}.re-dg-scrollbar.visible{opacity:1}.re-dg-scrollbar-thumb{position:absolute;right:var(--re-data-grid-scrollbar-offset);width:var(--re-data-grid-scrollbar-thumb-size);border-radius:var(--re-data-grid-scrollbar-thumb-rounded);background:var(--re-data-grid-scrollbar-thumb-color);pointer-events:auto;-webkit-user-select:none;user-select:none}.re-dg-spacer{width:1px}.re-dg-top{top:0}.re-dg-bottom{bottom:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: DataGridCellComponent, selector: "re-data-grid-cell", inputs: ["index", "item", "isPinned", "column"] }, { kind: "component", type: SortIcon, selector: "re-sort-ic", inputs: ["direction"] }, { kind: "component", type: ExpandIcon, selector: "re-expand-ic", inputs: ["expanded"] }, { kind: "component", type: CheckboxIcon, selector: "re-checkbox-ic", inputs: ["state", "disabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [CheckboxIcon], () => [SortIcon], () => [ExpandIcon], () => [NgTemplateOutlet], () => [NgTemplateOutlet], () => [DataGridCellComponent], () => [NgTemplateOutlet], () => [NgTemplateOutlet], () => [NgTemplateOutlet]] });
3509
4168
  }
3510
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGrid, decorators: [{
4169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DataGrid, decorators: [{
3511
4170
  type: Component,
3512
- args: [{ selector: 're-data-grid', imports: [NgTemplateOutlet, DataGridCellComponent, SortIcon, ExpandIcon, CheckboxIcon], providers: [DataGridVm], changeDetection: ChangeDetectionStrategy.OnPush, template: "@let items = data();\r\n@let empty = !loading() && !items?.length;\r\n@let notEmpty = !!items?.length;\r\n@let skeletonRowsCount = 4;\r\n@let skeletonMode = loadingMode() === 'skeleton';\r\n@let spinnerMode = loadingMode() === 'spinner';\r\n@let showInfinitySkeleton = loading() && skeletonMode && mode() === 'infinity';\r\n@let showPaginationSkeleton = loading() && skeletonMode && mode() === 'pagination' && !notEmpty;\r\n@let showSpinnerLoading = loading() && spinnerMode;\r\n@let extraInfinitySkeletonRows = showInfinitySkeleton ? skeletonRowsCount : 0;\r\n\r\n@let pinnedTopH = vm.pinnedTop().length * rowHeight();\r\n@let pinnedBottomH = vm.pinnedBottom().length * rowHeight();\r\n@let rowH = rowHeight();\r\n@let contentW = vm.contentWidth();\r\n@let cols = vm.columnsToShow();\r\n@let stickyTop = pinnedTopH + headerHeight();\r\n@let normalizedHeaderGroups = vm.normalizedHeaderGroups();\r\n@let stickyRow = stickyRowData();\r\n@let stickyIndex = stickyRowIndex();\r\n\r\n<div\r\n #root\r\n class=\"re-dg-root\"\r\n [class.re-dg-loading]=\"showSpinnerLoading\"\r\n [class.lock-vertical-scroll]=\"lockVerticalScroll()\"\r\n [class.resizing-columns]=\"isColumnResizing()\"\r\n [style.height]=\"styleHeight()\"\r\n [attr.aria-multiselectable]=\"selection().mode === 'multi' ? true : null\"\r\n role=\"grid\"\r\n>\r\n @if (showSpinnerLoading) {\r\n <div class=\"re-dg-loader\">\r\n @let loadingTemplate = loadingTpl();\r\n\r\n @if (loadingTemplate?.tpl) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\r\n } @else {\r\n <span class=\"re-dg-loader-spinner\" aria-label=\"Loading\"></span>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n #scroll\r\n class=\"re-dg-body\"\r\n role=\"rowgroup\"\r\n (mouseenter)=\"showScrollbar()\"\r\n (mouseleave)=\"hideScrollbarSoon()\"\r\n >\r\n <ng-template #headerContent>\r\n <div\r\n class=\"re-dg-header\"\r\n role=\"rowgroup\"\r\n [style.width.px]=\"vm.contentWidth()\"\r\n [style.min-width.%]=\"100\"\r\n >\r\n <div #header class=\"re-dg-header-rows\">\r\n @if (normalizedHeaderGroups.length) {\r\n <div class=\"re-dg-row re-dg-header-group-row\" role=\"row\" [style.width.px]=\"vm.contentWidth()\" [style.min-width.%]=\"100\">\r\n @for (group of normalizedHeaderGroups; track group.key) {\r\n @let groupStickyLeft = !!group.startKey && !!group.endKey && vm.isStickyLeft(group.startKey) && vm.isStickyLeft(group.endKey);\r\n @let groupStickyRight = !!group.startKey && !!group.endKey && vm.isStickyRight(group.startKey) && vm.isStickyRight(group.endKey);\r\n\r\n <div\r\n class=\"re-dg-header-cell re-dg-header-group-cell\"\r\n role=\"columnheader\"\r\n [class.sticky-left]=\"groupStickyLeft\"\r\n [class.sticky-right]=\"groupStickyRight\"\r\n [style.left.px]=\"groupStickyLeft && group.startKey ? vm.stickyOffset(group.startKey, 'left') : null\"\r\n [style.right.px]=\"groupStickyRight && group.endKey ? vm.stickyOffset(group.endKey, 'right') : null\"\r\n [style.width.px]=\"group.widthPx\"\r\n [style.justify-content]=\"group.align || 'left'\"\r\n [title]=\"group.title || ''\"\r\n >\r\n @if (group.titleTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"group.titleTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: group.title || '' }\"\r\n />\r\n } @else {\r\n <span class=\"re-dg-header-text\">{{ group.title || '' }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"re-dg-row re-dg-header-row\" role=\"row\" [style.width.px]=\"vm.contentWidth()\" [style.min-width.%]=\"100\">\r\n @for (col of vm.columnsToShow(); track col.key) {\r\n <div\r\n class=\"re-dg-header-cell\"\r\n role=\"columnheader\"\r\n [class.sortable]=\"!!col.sortKey\"\r\n [class.active-sort]=\"isActiveSort(col)\"\r\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\r\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\r\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\r\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [style.min-width.px]=\"col.minWidth || null\"\r\n [style.max-width.px]=\"col.maxWidth || null\"\r\n [style.justify-content]=\"col.align || 'left'\"\r\n [attr.aria-sort]=\"ariaSort(col)\"\r\n [attr.tabindex]=\"col.sortKey ? 0 : -1\"\r\n (click)=\"col.sortKey && onSort(col)\"\r\n (keydown.enter)=\"col.sortKey && onSort(col)\"\r\n >\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n @let isMultiSelect = selection().mode === 'multi';\r\n\r\n @if (isCheckbox && isMultiSelect) {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-checkbox-ic\r\n aria-label=\"Select loaded rows\"\r\n [state]=\"selector.isAllSelected()\"\r\n tabindex=\"0\"\r\n (click)=\"onSelectAll($event)\"\r\n (keydown.enter)=\"onSelectAllKeydown($event)\"\r\n (keydown.space)=\"onSelectAllKeydown($event)\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-checkbox-ic\r\n aria-label=\"Select loaded rows\"\r\n [state]=\"selector.isAllSelected()\"\r\n tabindex=\"0\"\r\n (click)=\"onSelectAll($event)\"\r\n (keydown.enter)=\"onSelectAllKeydown($event)\"\r\n (keydown.space)=\"onSelectAllKeydown($event)\" />\r\n }\r\n } @else {\r\n @if (col.headerTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.headerTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: col.header }\"\r\n />\r\n } @else {\r\n <span class=\"re-dg-header-text\">{{ col.header }}</span>\r\n }\r\n }\r\n\r\n @if (col.sortKey) {\r\n <span class=\"re-dg-sort-ind\">\r\n @let direction = sortOrderFor(col);\r\n\r\n @if (sortTpl()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"sortTpl()!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: direction }\"\r\n />\r\n } @else {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-sort-ic [direction]=\"direction\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-sort-ic [direction]=\"direction\" />\r\n }\r\n }\r\n </span>\r\n }\r\n\r\n @if (isExpandable(col)) {\r\n <button (click)=\"$event.stopPropagation(); onExpand(col)\">\r\n @let expanded = expanderMap().get(col.key);\r\n\r\n @if (expanderTpl()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"expanderTpl()!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: expanded }\" />\r\n } @else {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-expand-ic [expanded]=\"expanded\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-expand-ic [expanded]=\"expanded\" />\r\n }\r\n }\r\n </button>\r\n }\r\n\r\n @if (canResizeColumn(col)) {\r\n <button\r\n class=\"re-dg-column-resize-handle\"\r\n (mousedown)=\"onColumnResizeStart($event, col)\"\r\n (click)=\"$event.stopPropagation()\"\r\n ></button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- PINNED TOP ROWS -->\r\n @if (notEmpty) {\r\n <ng-template #pinnedTopContent>\r\n @for (pr of vm.pinnedTop(); track trackPinnedRow(pr)) {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top\" role=\"row\" [style.width.px]=\"contentW\" [style.min-width.%]=\"100\">\r\n @if (pr.rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pinnedRowCells\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n\r\n @if (deferPinned()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"pinnedTopContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n } @loading {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"pinnedTopContent\" />\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n @if (deferHeader()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"headerContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-header re-dg-deferred-placeholder\" [style.min-height.px]=\"headerHeight()\"></div>\r\n } @loading {\r\n <div class=\"re-dg-header re-dg-deferred-placeholder\" [style.min-height.px]=\"headerHeight()\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"headerContent\" />\r\n }\r\n\r\n <ng-template #dataCellContent let-row let-col=\"col\" let-index=\"index\" let-isPinned=\"isPinned\">\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n\r\n @if (isCheckbox) {\r\n <re-checkbox-ic\r\n aria-label=\"Toggle row selection\"\r\n [state]=\"selector.isSelected(row)\"\r\n [attr.aria-disabled]=\"isDisabledRow(row, index)\"\r\n [attr.tabindex]=\"isDisabledRow(row, index) ? -1 : 0\"\r\n (click)=\"onCheckboxToggle(row, index, $event)\"\r\n (keydown.enter)=\"onCheckboxKeydown(row, index, $event)\"\r\n (keydown.space)=\"onCheckboxKeydown(row, index, $event)\" />\r\n } @else {\r\n @if (deferCells()) {\r\n @defer (when true) {\r\n <re-data-grid-cell [index]=\"index\" [item]=\"row\" [column]=\"col\" [isPinned]=\"!!isPinned\" />\r\n } @placeholder {\r\n <span class=\"re-dg-cell-deferred\"></span>\r\n } @loading {\r\n <span class=\"re-dg-cell-deferred\"></span>\r\n }\r\n } @else {\r\n <re-data-grid-cell [index]=\"index\" [item]=\"row\" [column]=\"col\" [isPinned]=\"!!isPinned\" />\r\n }\r\n }\r\n </ng-template>\r\n\r\n <ng-template #gridContent>\r\n\r\n <!-- STICKY ROW -->\r\n @if (stickyRow && stickyIndex !== null) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-sticky-row\"\r\n role=\"row\"\r\n [class.re-dg-row-disabled]=\"isDisabledRow(stickyRow, stickyIndex)\"\r\n [style.width.px]=\"vm.contentWidth()\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowHeight()\"\r\n [style.top.px]=\"stickyRowTopPx()\"\r\n [attr.aria-disabled]=\"isDisabledRow(stickyRow, stickyIndex)\"\r\n [attr.aria-selected]=\"selection().mode !== 'none' ? selector.isSelected(stickyRow) : null\"\r\n [attr.tabindex]=\"0\"\r\n (click)=\"onRowClick(stickyRow, stickyIndex, $event)\"\r\n (contextmenu)=\"onRowContext(stickyRow, stickyIndex, $event)\"\r\n (dblclick)=\"onRowDoubleClick(stickyRow, stickyIndex, $event)\"\r\n (keydown.enter)=\"onRowClick(stickyRow, stickyIndex, $event)\"\r\n >\r\n @let stickyTemplate = stickyRowTpl();\r\n @let rowTemplate = resolveRowTemplate(stickyRow, stickyIndex);\r\n\r\n @if (stickyTemplate?.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"stickyTemplate!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: stickyRow, index: stickyIndex }\"\r\n />\r\n } @else if (rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: stickyRow,\r\n index: stickyIndex,\r\n columns: vm.columnsToShow(),\r\n rowHeight: rowHeight(),\r\n isSticky: true\r\n }\"\r\n />\r\n } @else {\r\n @for (col of vm.columnsToShow(); track col.key) {\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, stickyRow)\"\r\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\r\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\r\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\r\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.tabindex]=\"0\"\r\n (mouseenter)=\"showTooltip($event, stickyRow, col, stickyIndex)\"\r\n (mouseleave)=\"hideTooltip()\"\r\n (click)=\"onCellClick(stickyRow, col, stickyIndex, $event);\"\r\n (contextmenu)=\"onCellContext(stickyRow, col, stickyIndex, $event)\"\r\n (dblclick)=\"onCellDoubleClick(stickyRow, col, stickyIndex, $event)\"\r\n (keydown.enter)=\"onCellClick(stickyRow, col, stickyIndex, $event)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: stickyRow, col: col, index: stickyIndex, isPinned: false }\"\r\n />\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @if (empty) {\r\n @let emptyTemplate = emptyTpl()?.tpl;\r\n\r\n <div class=\"re-dg-empty\">\r\n @if (emptyTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"emptyTemplate\" />\r\n } @else {\r\n <span class=\"re-dg-empty-text\">{{ defaults.translations.emptyState }}</span>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Content -->\r\n @if (notEmpty) {\r\n <div\r\n class=\"re-dg-spacer\"\r\n [style.width.px]=\"contentW\"\r\n [style.height.px]=\"(items.length + extraInfinitySkeletonRows) * rowH - pinnedBottomH\"></div>\r\n\r\n @for (slot of renderSlots(); track slot) {\r\n @let rowIndex = startIndex + slot;\r\n @let row = items[rowIndex];\r\n @let rowTemplate = row ? resolveRowTemplate(row, rowIndex) : null;\r\n\r\n @if (row && !isStickyRowIndex(rowIndex)) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row\"\r\n role=\"row\"\r\n [class.re-dg-row-disabled]=\"isDisabledRow(row, rowIndex)\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (rowIndex * rowH + stickyTop) + 'px)'\"\r\n [attr.aria-disabled]=\"isDisabledRow(row, rowIndex)\"\r\n [attr.aria-selected]=\"selection().mode !== 'none' ? selector.isSelected(row) : null\"\r\n [attr.tabindex]=\"0\"\r\n (click)=\"onRowClick(row, rowIndex, $event)\"\r\n (contextmenu)=\"onRowContext(row, rowIndex, $event)\"\r\n (dblclick)=\"onRowDoubleClick(row, rowIndex, $event)\"\r\n (keydown.enter)=\"onRowClick(row, rowIndex, $event)\"\r\n >\r\n @if (rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n index: rowIndex,\r\n columns: vm.columnsToShow(),\r\n rowHeight: rowHeight(),\r\n isSticky: false\r\n }\"\r\n />\r\n } @else {\r\n @for (col of cols; track col.key) {\r\n @let stickyLeft = vm.stickyOffset(col.key, 'left');\r\n @let stickyRight = vm.stickyOffset(col.key, 'right');\r\n @let isLeft = vm.isStickyLeft(col.key);\r\n @let isRight = vm.isStickyRight(col.key);\r\n\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, row)\"\r\n [class.sticky-left]=\"isLeft\"\r\n [class.sticky-right]=\"isRight\"\r\n [style.left.px]=\"stickyLeft\"\r\n [style.right.px]=\"stickyRight\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.tabindex]=\"0\"\r\n (mouseenter)=\"showTooltip($event, row, col, rowIndex)\"\r\n (mouseleave)=\"hideTooltip()\"\r\n (click)=\"onCellClick(row, col, rowIndex, $event);\"\r\n (contextmenu)=\"onCellContext(row, col, rowIndex, $event)\"\r\n (dblclick)=\"onCellDoubleClick(row, col, rowIndex, $event)\"\r\n (keydown.enter)=\"onCellClick(row, col, rowIndex, $event)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, col: col, index: rowIndex, isPinned: false }\"\r\n />\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n @if (showInfinitySkeleton || showPaginationSkeleton) {\r\n @let loadingTemplate = loadingTpl();\r\n\r\n @if (loadingTemplate?.tpl) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\r\n } @else {\r\n @for (si of [0, 1, 2, 3]; track si) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-skeleton-row\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (((showInfinitySkeleton ? items.length : 0) + si) * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n <!-- PINNED BOTTOM ROWS -->\r\n @if (notEmpty) {\r\n <ng-template #pinnedBottomContent>\r\n <div class=\"re-dg-footer\" role=\"rowgroup\">\r\n @for (pr of vm.pinnedBottom(); track trackPinnedRow(pr)) {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-bottom\" role=\"row\" [style.width.px]=\"contentW\" [style.min-width.%]=\"100\">\r\n @if (pr.rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pinnedRowCells\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n @if (deferPinned()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"pinnedBottomContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-footer re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n } @loading {\r\n <div class=\"re-dg-footer re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"pinnedBottomContent\" />\r\n }\r\n }\r\n </ng-template>\r\n\r\n @if (deferContent()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"gridContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH * 3\"></div>\r\n } @loading {\r\n <div class=\"re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH * 3\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"gridContent\" />\r\n }\r\n </div>\r\n\r\n <ng-template #pinnedRowCells let-row>\r\n @for (col of cols; track col.key) {\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n @let isIndex = 'type' in col && col.type === 'index';\r\n @let stickyLeft = vm.stickyOffset(col.key, 'left');\r\n @let stickyRight = vm.stickyOffset(col.key, 'right');\r\n @let isLeft = vm.isStickyLeft(col.key);\r\n @let isRight = vm.isStickyRight(col.key);\r\n\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, $any(row))\"\r\n [class.sticky-left]=\"isLeft\"\r\n [class.sticky-right]=\"isRight\"\r\n [style.left.px]=\"stickyLeft\"\r\n [style.right.px]=\"stickyRight\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.height.px]=\"rowH\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.tabindex]=\"isCheckbox || isIndex ? -1 : 0\"\r\n (mouseenter)=\"!isCheckbox && !isIndex && showTooltip($event, $any(row), col, -1)\"\r\n (mouseleave)=\"!isCheckbox && !isIndex && hideTooltip()\"\r\n (click)=\"!isCheckbox && !isIndex && onCellClick($any(row), col, -1, $event);\"\r\n (contextmenu)=\"!isCheckbox && !isIndex && onCellContext($any(row), col, -1, $event)\"\r\n (dblclick)=\"!isCheckbox && !isIndex && onCellDoubleClick($any(row), col, -1, $event)\"\r\n (keydown.enter)=\"!isCheckbox && !isIndex && onCellClick($any(row), col, -1, $event)\"\r\n >\r\n @if (!isCheckbox && !isIndex) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: $any(row), col: col, index: -1, isPinned: true }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n\r\n @if (deferTooltip()) {\r\n @defer (when true) {\r\n @let tooltipStateValue = tooltipState();\r\n <div\r\n class=\"re-dg-tooltip\"\r\n #tooltip\r\n [class.visible]=\"tooltipStateValue.visible\"\r\n [style.left.px]=\"tooltipStateValue.x\"\r\n [style.top.px]=\"tooltipStateValue.y\"\r\n >\r\n @if (tooltipStateValue.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"tooltipStateValue.tpl\"\r\n [ngTemplateOutletContext]=\"tooltipStateValue.ctx\"\r\n />\r\n } @else {\r\n {{ tooltipStateValue.text }}\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @let tooltipStateValue = tooltipState();\r\n <div\r\n class=\"re-dg-tooltip\"\r\n #tooltip\r\n [class.visible]=\"tooltipStateValue.visible\"\r\n [style.left.px]=\"tooltipStateValue.x\"\r\n [style.top.px]=\"tooltipStateValue.y\"\r\n >\r\n @if (tooltipStateValue.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"tooltipStateValue.tpl\"\r\n [ngTemplateOutletContext]=\"tooltipStateValue.ctx\"\r\n />\r\n } @else {\r\n {{ tooltipStateValue.text }}\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Overlay scrollbar -->\r\n <div class=\"re-dg-scrollbar\" [class.visible]=\"vm.scrollbarVisible()\">\r\n <div\r\n class=\"re-dg-scrollbar-thumb\"\r\n role=\"scrollbar\"\r\n aria-orientation=\"vertical\"\r\n aria-hidden=\"false\"\r\n [style.height.px]=\"vm.thumbHeightPx()\"\r\n [style.transform]=\"'translateY(' + vm.thumbTopPx() + 'px)'\"\r\n (mousedown)=\"onThumbDown($event)\"\r\n ></div>\r\n </div>\r\n</div>\r\n", styles: [":host{--re-data-grid-min-height: 200px;--re-data-grid-height: 400px;--re-data-grid-rounded: var(--radius-md, 6px);--re-data-grid-separator-color: var(--border-color);--re-data-grid-separator: 1px solid var(--re-data-grid-separator-color);--re-data-grid-surface: var(--surface-neutral, #fff);--re-data-grid-active: var(--primary-color, #2a90f4);--re-data-grid-empty-color: #777;--re-data-grid-empty-surface: transparent;--re-data-grid-loading-color: #444;--re-data-grid-loading-surface: rgba(255, 255, 255, .5);--re-data-grid-spinner-size: 2rem;--re-data-grid-spinner-width: .25rem;--re-data-grid-spinner-track-color: rgba(0, 0, 0, .12);--re-data-grid-skeleton-width: 100%;--re-data-grid-skeleton-height: 100%;--re-data-grid-skeleton-rounded: var(--re-data-grid-rounded, .75rem);--re-data-grid-skeleton-shine: rgba(255, 255, 255, .8);--re-data-grid-skeleton-line: #e7ebf0;--re-data-grid-scrollbar-size: 4px;--re-data-grid-scrollbar-offset: 2px;--re-data-grid-scrollbar-track-rounded: .25rem;--re-data-grid-scrollbar-track-surface: transparent;--re-data-grid-scrollbar-thumb-size: 8px;--re-data-grid-scrollbar-thumb-color: rgba(0, 0, 0, .25);--re-data-grid-scrollbar-thumb-active-color: rgba(0, 0, 0, .45);--re-data-grid-scrollbar-thumb-rounded: var(--re-data-grid-scrollbar-track-rounded);--re-data-grid-tooltip-surface: #0f172a;--re-data-grid-tooltip-color: #f8fafc;--re-data-grid-tooltip-radius: .5rem;--re-data-grid-tooltip-padding: .4rem .6rem;--re-data-grid-tooltip-shadow: 0 8px 24px rgba(15, 23, 42, .25);--re-data-grid-tooltip-z: 60;--re-data-grid-header-rounded: var(--re-data-grid-rounded);--re-data-grid-header-surface: #fff;--re-data-grid-header-body-gap: 0px;--re-data-grid-header-row-height: 40px;--re-data-grid-header-row-separator-color: #ccc;--re-data-grid-header-row-separator: 1px solid var(--re-data-grid-header-row-separator-color);--re-data-grid-header-group-row-height: var(--re-data-grid-header-row-height);--re-data-grid-header-group-row-separator-color: var(--re-data-grid-header-row-separator-color);--re-data-grid-header-group-row-separator: 1px solid var(--re-data-grid-header-group-row-separator-color);--re-data-grid-header-group-cell-font-weight: var(--re-data-grid-header-cell-font-weight);--re-data-grid-header-group-cell-font-size: var(--re-data-grid-header-cell-font-size);--re-data-grid-header-group-cell-color: var(--re-data-grid-header-cell-color);--re-data-grid-header-group-cell-surface: var(--re-data-grid-header-cell-surface);--re-data-grid-header-cell-font-weight: 600;--re-data-grid-header-cell-font-size: .8rem;--re-data-grid-header-cell-color: #000;--re-data-grid-header-cell-surface: #fafafa;--re-data-grid-header-cell-line-height: 1.2;--re-data-grid-header-cell-max-lines: 2;--re-data-grid-footer-separator-color: #ccc;--re-data-grid-footer-separator: 1px solid var(--re-data-grid-footer-separator-color);--re-data-grid-footer-surface: #fff;--re-data-grid-row-separator-color: #bbb;--re-data-grid-row-separator: 1px solid var(--re-data-grid-row-separator-color);--re-data-grid-row-odd-surface: var(--re-data-grid-cell-surface);--re-data-grid-row-hover-surface: var(--re-data-grid-cell-surface);--re-data-grid-row-hover-color: var(--re-data-grid-cell-color);--re-data-grid-row-hover-rounded: 0px;--re-data-grid-column-separator-color: transparent;--re-data-grid-column-separator: 1px solid var(--re-data-grid-column-separator-color);--re-data-grid-column-odd-surface: var(--re-data-grid-cell-surface);--re-data-grid-cell-paddings: .4rem .625rem;--re-data-grid-cell-font-weight: 400;--re-data-grid-cell-font-size: .75rem;--re-data-grid-cell-color: #000;--re-data-grid-cell-surface: #fff;--re-data-grid-cell-line-height: 1.2;--re-data-grid-cell-max-lines: 2;--re-data-grid-sticky-header-cell-surface: #fff;--re-data-grid-sticky-cell-surface: #fdfdfd;--re-data-grid-sticky-cell-row-odd-surface: #fdfdfd;--re-data-grid-sticky-cell-left-shadow: 2px 0 2px rgba(0, 0, 0, .03);--re-data-grid-sticky-cell-right-shadow: -2px 0 2px rgba(0, 0, 0, .03);--re-data-grid-pinned-surface: #fcfcfc;--re-data-grid-pinned-separator-color: #eee;--re-data-grid-pinned-separator: 1px solid var(--re-data-grid-pinned-separator-color);--re-data-grid-expander-color: var(--primary-color, currentColor);--re-data-grid-expanded-color: var(--re-data-grid-cell-color, #000);--re-data-grid-expanded-surface: var(--re-data-grid-cell-surface, #fff);--re-data-grid-focus-ring-color: color-mix(in srgb, var(--primary-color, #2a90f4) 55%, transparent);--re-data-grid-focus-ring-width: 2px;--re-data-grid-focus-ring-offset: -2px;display:block;min-height:0;min-width:0}:host,:host *,:host *:before,:host *:after{box-sizing:border-box;outline:none}:host button{outline:none}.re-dg-root{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;min-height:var(--re-data-grid-min-height);border-radius:var(--re-data-grid-rounded);border:var(--re-data-grid-separator)}.re-dg-root.fill{display:block}.re-dg-root.re-dg-loading{pointer-events:none;-webkit-user-select:none;user-select:none;cursor:wait}.re-dg-root.re-dg-loading .re-dg-body{overflow:hidden}.re-dg-root.re-dg-loading .re-dg-scrollbar{display:none!important}.re-dg-root.re-dg-loading .re-dg-loader{pointer-events:all}.re-dg-root.lock-vertical-scroll .re-dg-body{overflow-x:auto;overflow-y:hidden}.re-dg-root.lock-vertical-scroll .re-dg-scrollbar{display:none!important}.re-dg-root.resizing-columns{-webkit-user-select:none;user-select:none;cursor:col-resize}.re-dg-body{position:relative;flex:1 1 auto;min-height:0;min-width:0;height:inherit;border:var(--re-data-grid-separator);border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-surface);overflow:auto;scrollbar-width:auto;-ms-overflow-style:auto}.re-dg-body::-webkit-scrollbar{width:var(--re-data-grid-scrollbar-size);height:var(--re-data-grid-scrollbar-size)}.re-dg-body::-webkit-scrollbar:vertical{width:0}.re-dg-body::-webkit-scrollbar-track{border-radius:var(--re-data-grid-scrollbar-track-rounded);background:var(--re-data-grid-scrollbar-track-surface)}.re-dg-body::-webkit-scrollbar-thumb{border-radius:var(--re-data-grid-scrollbar-thumb-rounded);background:var(--re-data-grid-scrollbar-thumb-color);transition:opacity .3s ease}.re-dg-body::-webkit-scrollbar-thumb:hover{background:var(--re-data-grid-scrollbar-thumb-active-color)}.re-dg-header,.re-dg-footer{position:sticky;z-index:3}.re-dg-header{top:0;background-color:var(--re-data-grid-header-surface)}.re-dg-header-row{min-height:var(--re-data-grid-header-row-height)}.re-dg-header-group-row{min-height:var(--re-data-grid-header-group-row-height)}.re-dg-header-rows{display:flex;flex-direction:column;padding-bottom:var(--re-data-grid-header-body-gap)}.re-dg-footer{bottom:0;border-radius:0 0 var(--re-data-grid-rounded) var(--re-data-grid-rounded);background-color:var(--re-data-grid-footer-surface)}.re-dg-row{position:relative;display:flex}.re-dg-data-row{position:absolute;left:0;top:0;min-width:100%;cursor:default;will-change:transform}.re-dg-sticky-row{z-index:2;top:0}.re-dg-cell,.re-dg-header-cell{display:flex;flex:0 0 auto;align-items:center;padding:var(--re-data-grid-cell-paddings);border-right:var(--re-data-grid-column-separator);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.re-dg-cell:focus-visible,.re-dg-header-cell:focus-visible,.re-dg-header-cell button:focus-visible,.re-dg-row[tabindex=\"0\"]:focus-visible{outline:var(--re-data-grid-focus-ring-width) solid var(--re-data-grid-focus-ring-color);outline-offset:var(--re-data-grid-focus-ring-offset);z-index:4}.re-dg-cell{width:100%;border-bottom:var(--re-data-grid-row-separator);font-weight:var(--re-data-grid-cell-font-weight);font-size:var(--re-data-grid-cell-font-size);color:var(--re-data-grid-cell-color);background-color:var(--re-data-grid-cell-surface)}.re-dg-row:nth-child(odd) .re-dg-cell{background-color:var(--re-data-grid-row-odd-surface)}.re-dg-row.re-dg-row-disabled .re-dg-cell{opacity:.6;cursor:not-allowed}.re-dg-row:nth-child(odd) .re-dg-cell.sticky-left,.re-dg-row:nth-child(odd) .re-dg-cell.sticky-right{background-color:var(--re-data-grid-sticky-cell-row-odd-surface)}.re-dg-cell:nth-child(odd){background-color:var(--re-data-grid-column-odd-surface)}.re-dg-bottom>.re-dg-cell{border-top:var(--re-data-grid-footer-separator)}.re-dg-header-cell{position:relative;align-items:center;gap:.75rem;border-bottom:var(--re-data-grid-header-row-separator);font-weight:var(--re-data-grid-header-cell-font-weight);font-size:var(--re-data-grid-header-cell-font-size);color:var(--re-data-grid-header-cell-color);background:var(--re-data-grid-header-cell-surface);-webkit-user-select:none;user-select:none;transition:color .3s ease-in-out}.re-dg-column-resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;z-index:5}.re-dg-header-cell.re-dg-header-group-cell{border-bottom:var(--re-data-grid-header-group-row-separator);font-weight:var(--re-data-grid-header-group-cell-font-weight);font-size:var(--re-data-grid-header-group-cell-font-size);color:var(--re-data-grid-header-group-cell-color);background:var(--re-data-grid-header-group-cell-surface)}.re-dg-header-rows>.re-dg-row:first-child .re-dg-header-cell:first-child{border-radius:var(--re-data-grid-header-rounded) 0 0 0}.re-dg-header-rows>.re-dg-row:first-child .re-dg-header-cell:last-child{border-radius:0 var(--re-data-grid-header-rounded) 0 0}.re-dg-data-row:last-child .re-dg-cell:first-child{border-radius:0 0 0 var(--re-data-grid-rounded)}.re-dg-data-row:last-child .re-dg-cell:last-child{border-radius:0 0 var(--re-data-grid-rounded) 0}.re-dg-header-cell .re-dg-header-text{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:var(--re-data-grid-header-cell-line-height);-webkit-box-orient:vertical;-webkit-line-clamp:var(--re-data-grid-header-cell-max-lines)}.re-dg-row.re-dg-pinned>.re-dg-cell{border-bottom:var(--re-data-grid-pinned-separator);background-color:var(--re-data-grid-pinned-surface)}.re-dg-row .re-dg-header-cell.sticky-left{box-shadow:var(--re-data-grid-sticky-cell-left-shadow);background-color:var(--re-data-grid-sticky-header-cell-surface)}.re-dg-row .re-dg-cell.sticky-left{box-shadow:var(--re-data-grid-sticky-cell-left-shadow);background-color:var(--re-data-grid-sticky-cell-surface)}.re-dg-row .re-dg-header-cell.sticky-right{box-shadow:var(--re-data-grid-sticky-cell-right-shadow);background-color:var(--re-data-grid-sticky-header-cell-surface)}.re-dg-row .re-dg-cell.sticky-right{box-shadow:var(--re-data-grid-sticky-cell-right-shadow);background-color:var(--re-data-grid-sticky-cell-surface)}.re-dg-row.re-dg-pinned>.re-dg-cell.sticky-left,.re-dg-row.re-dg-pinned>.re-dg-cell.sticky-right{background-color:var(--re-data-grid-pinned-surface)}.re-dg-row:hover>.re-dg-cell,.re-dg-row:hover>.re-dg-cell.sticky-left,.re-dg-row:hover>.re-dg-cell.sticky-right{background-color:var(--re-data-grid-row-hover-surface)!important;color:var(--re-data-grid-row-hover-color)!important}.re-dg-row:hover>.re-dg-cell:first-child{border-radius:var(--re-data-grid-row-hover-rounded) 0 0 var(--re-data-grid-row-hover-rounded)}.re-dg-row:hover>.re-dg-cell:last-child{border-radius:0 var(--re-data-grid-row-hover-rounded) var(--re-data-grid-row-hover-rounded) 0}.sticky-left,.sticky-right{position:sticky;z-index:2}.sortable{cursor:pointer}.active-sort{color:var(--re-data-grid-active)}.re-dg-sort-ind{margin-left:6px}.re-dg-icon-placeholder{display:inline-block;width:1rem;height:1rem}.re-dg-cell-deferred{display:block;width:100%;height:100%}.re-dg-deferred-placeholder{background:transparent}.re-dg-data-row .re-dg-cell.expanded{color:var(--re-data-grid-expanded-color);background:var(--re-data-grid-expanded-surface)}.re-dg-empty{position:absolute;inset:0;display:grid;place-items:center;height:inherit;width:100%;border-radius:var(--re-data-grid-rounded);color:var(--re-data-grid-empty-color);background:var(--re-data-grid-empty-surface)}.re-dg-empty-text{width:100%;text-align:center}.re-dg-loader{position:absolute;inset:0;display:grid;place-items:center;height:inherit;border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-loading-surface);color:var(--re-data-grid-loading-color);z-index:5}.re-dg-tooltip{position:fixed;left:0;top:0;max-width:min(28rem,70vw);padding:var(--re-data-grid-tooltip-padding);border-radius:var(--re-data-grid-tooltip-radius);background:var(--re-data-grid-tooltip-surface);color:var(--re-data-grid-tooltip-color);box-shadow:var(--re-data-grid-tooltip-shadow);font-size:.75rem;line-height:1.2;z-index:var(--re-data-grid-tooltip-z);pointer-events:none;opacity:0;transform:translateY(4px);transition:opacity .12s ease,transform .12s ease}.re-dg-tooltip.visible{opacity:1;transform:translateY(0)}.re-dg-loader-spinner{width:var(--re-data-grid-spinner-size);height:var(--re-data-grid-spinner-size);border-radius:50%;border:var(--re-data-grid-spinner-width) solid var(--re-data-grid-spinner-track-color);border-top-color:var(--re-data-grid-loading-color);animation:re-dg-spinner .8s linear infinite}.re-dg-skeleton-row{display:flex;align-items:center;padding:var(--re-data-grid-cell-paddings);border-bottom:var(--re-data-grid-row-separator);background-color:var(--re-data-grid-cell-surface);pointer-events:none}.re-dg-skeleton-row-line{display:block;width:var(--re-data-grid-skeleton-width);height:var(--re-data-grid-skeleton-height);border-radius:var(--re-data-grid-skeleton-rounded);background:linear-gradient(90deg,var(--re-data-grid-skeleton-line) 0%,var(--re-data-grid-skeleton-shine) 50%,var(--re-data-grid-skeleton-line) 100%);background-size:200% 100%;animation:re-dg-skeleton 1.2s ease-in-out infinite}@keyframes re-dg-skeleton{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes re-dg-spinner{to{transform:rotate(360deg)}}.re-dg-scrollbar{position:absolute;right:0;top:0;bottom:0;opacity:0;transition:opacity .15s ease-in-out;pointer-events:none;z-index:4}.re-dg-scrollbar.visible{opacity:1}.re-dg-scrollbar-thumb{position:absolute;right:var(--re-data-grid-scrollbar-offset);width:var(--re-data-grid-scrollbar-thumb-size);border-radius:var(--re-data-grid-scrollbar-thumb-rounded);background:var(--re-data-grid-scrollbar-thumb-color);pointer-events:auto;-webkit-user-select:none;user-select:none}.re-dg-spacer{width:1px}.re-dg-top{top:0}.re-dg-bottom{bottom:0}\n"] }]
3513
- }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], pinnedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedRows", required: false }] }], isRowSticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "isRowSticky", required: false }] }], isRowDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isRowDisabled", required: false }] }], getRowTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "getRowTemplate", required: false }] }], hasIndexColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasIndexColumn", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], virtualBuffer: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualBuffer", required: false }] }], lockVerticalScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "lockVerticalScroll", required: false }] }], headerGroups: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerGroups", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingMode", required: false }] }], deferContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferContent", required: false }] }], deferHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferHeader", required: false }] }], deferPinned: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferPinned", required: false }] }], deferCells: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferCells", required: false }] }], deferIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferIcons", required: false }] }], deferTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferTooltip", required: false }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], pageStartFromZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageStartFromZero", required: false }] }], sortMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortMode", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], multiSortChange: [{ type: i0.Output, args: ["multiSortChange"] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], rowContext: [{ type: i0.Output, args: ["rowContext"] }], rowDoubleClick: [{ type: i0.Output, args: ["rowDoubleClick"] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], cellContext: [{ type: i0.Output, args: ["cellContext"] }], cellDoubleClick: [{ type: i0.Output, args: ["cellDoubleClick"] }], rootEl: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], scrollEl: [{ type: i0.ViewChild, args: ['scroll', { isSignal: true }] }], headerEl: [{ type: i0.ViewChild, args: ['header', { isSignal: true }] }], cellTypedSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridTypeCellTemplateDirective), { isSignal: true }] }], cellDataSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridCellTemplateDirective), { isSignal: true }] }], declarativeColumnRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridDeclarativeColumn), { isSignal: true }] }], headerSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridHeaderTemplateDirective), { isSignal: true }] }], emptySlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridCellEmptyDirective), { isSignal: true }] }], loadingSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridCellLoadingDirective), { isSignal: true }] }], sortIcSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridSortIconDirective), { isSignal: true }] }], expanderIcSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridExpanderIconDirective), { isSignal: true }] }], stickyRowSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridStickyRowDirective), { isSignal: true }] }], rowSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridRowDirective), { isSignal: true }] }], tooltipEl: [{ type: i0.ViewChild, args: ['tooltip', { isSignal: true }] }] } });
4171
+ args: [{ selector: 're-data-grid', imports: [NgTemplateOutlet, DataGridCellComponent, SortIcon, ExpandIcon, CheckboxIcon], providers: [DataGridVm], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@let items = selectionRows();\r\n@let totalRows = totalRowCount();\r\n@let empty = !resolvedLoading() && !totalRows;\r\n@let notEmpty = !!totalRows;\r\n@let skeletonRowsCount = 4;\r\n@let skeletonMode = loadingMode() === 'skeleton';\r\n@let spinnerMode = loadingMode() === 'spinner';\r\n@let showInfinitySkeleton = resolvedLoading() && skeletonMode && mode() === 'infinity';\r\n@let showPaginationSkeleton = resolvedLoading() && skeletonMode && mode() === 'pagination' && !notEmpty;\r\n@let showSpinnerLoading = resolvedLoading() && spinnerMode;\r\n@let extraInfinitySkeletonRows = showInfinitySkeleton ? skeletonRowsCount : 0;\r\n\r\n@let pinnedTopH = vm.pinnedTop().length * rowHeight();\r\n@let pinnedBottomH = vm.pinnedBottom().length * rowHeight();\r\n@let rowH = rowHeight();\r\n@let contentW = vm.contentWidth();\r\n@let cols = vm.columnsToShow();\r\n@let stickyTop = pinnedTopH + headerHeight();\r\n@let normalizedHeaderGroups = vm.normalizedHeaderGroups();\r\n@let stickyRow = stickyRowData();\r\n@let stickyIndex = stickyRowIndex();\r\n\r\n<div\r\n #root\r\n class=\"re-dg-root\"\r\n [attr.id]=\"expanderRegionId\"\r\n [class.re-dg-loading]=\"showSpinnerLoading\"\r\n [class.lock-vertical-scroll]=\"lockVerticalScroll()\"\r\n [class.resizing-columns]=\"isColumnResizing()\"\r\n [style.height]=\"styleHeight()\"\r\n [attr.aria-multiselectable]=\"selection().mode === 'multi' ? true : null\"\r\n [attr.aria-rowcount]=\"ariaRowCount()\"\r\n [attr.aria-colcount]=\"ariaColCount()\"\r\n role=\"grid\"\r\n>\r\n @if (showSpinnerLoading) {\r\n <div class=\"re-dg-loader\" aria-live=\"polite\" role=\"status\">\r\n @let loadingTemplate = loadingTpl();\r\n\r\n @if (loadingTemplate?.tpl) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\r\n } @else {\r\n <span class=\"re-dg-loader-spinner\" aria-label=\"Loading\"></span>\r\n }\r\n </div>\r\n }\r\n\r\n <div\r\n #scroll\r\n class=\"re-dg-body\"\r\n role=\"rowgroup\"\r\n (mouseenter)=\"showScrollbar()\"\r\n (mouseleave)=\"hideScrollbarSoon()\"\r\n >\r\n <ng-template #headerContent>\r\n <div\r\n class=\"re-dg-header\"\r\n role=\"rowgroup\"\r\n [style.width.px]=\"vm.contentWidth()\"\r\n [style.min-width.%]=\"100\"\r\n >\r\n <div #header class=\"re-dg-header-rows\">\r\n @if (normalizedHeaderGroups.length) {\r\n <div class=\"re-dg-row re-dg-header-group-row\" role=\"row\" [style.width.px]=\"vm.contentWidth()\" [style.min-width.%]=\"100\">\r\n @for (group of normalizedHeaderGroups; track group.key; let groupIndex = $index) {\r\n @let groupStickyLeft = !!group.startKey && !!group.endKey && vm.isStickyLeft(group.startKey) && vm.isStickyLeft(group.endKey);\r\n @let groupStickyRight = !!group.startKey && !!group.endKey && vm.isStickyRight(group.startKey) && vm.isStickyRight(group.endKey);\r\n\r\n @let resolvedGroupTitle = resolveHeaderGroupTitle(group);\r\n\r\n <div\r\n class=\"re-dg-header-cell re-dg-header-group-cell\"\r\n role=\"columnheader\"\r\n [class.sticky-left]=\"groupStickyLeft\"\r\n [class.sticky-right]=\"groupStickyRight\"\r\n [style.left.px]=\"groupStickyLeft && group.startKey ? vm.stickyOffset(group.startKey, 'left') : null\"\r\n [style.right.px]=\"groupStickyRight && group.endKey ? vm.stickyOffset(group.endKey, 'right') : null\"\r\n [style.width.px]=\"group.widthPx\"\r\n [style.justify-content]=\"group.align || 'left'\"\r\n [title]=\"resolvedGroupTitle\"\r\n [attr.aria-colindex]=\"ariaHeaderGroupColIndex(group)\"\r\n [attr.aria-rowindex]=\"groupIndex + 1\"\r\n >\r\n @if (group.titleTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"group.titleTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvedGroupTitle }\"\r\n />\r\n } @else {\r\n <span class=\"re-dg-header-text\">{{ resolvedGroupTitle }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <div class=\"re-dg-row re-dg-header-row\" role=\"row\" [style.width.px]=\"vm.contentWidth()\" [style.min-width.%]=\"100\">\r\n @for (col of vm.columnsToShow(); track col.key; let colIndex = $index) {\r\n <div\r\n class=\"re-dg-header-cell\"\r\n role=\"columnheader\"\r\n [class.sortable]=\"!!col.sortKey\"\r\n [class.active-sort]=\"isActiveSort(col)\"\r\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\r\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\r\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\r\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [style.min-width.px]=\"col.minWidth || null\"\r\n [style.max-width.px]=\"col.maxWidth || null\"\r\n [style.justify-content]=\"col.align || 'left'\"\r\n [attr.aria-sort]=\"ariaSort(col)\"\r\n [attr.aria-colindex]=\"colIndex + 1\"\r\n [attr.aria-rowindex]=\"normalizedHeaderGroups.length ? 2 : 1\"\r\n [attr.aria-label]=\"col.sortKey ? ariaSortLabel(col) : null\"\r\n [attr.tabindex]=\"col.sortKey ? 0 : -1\"\r\n (click)=\"col.sortKey && onSort(col)\"\r\n (keydown.enter)=\"col.sortKey && onSort(col)\"\r\n >\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n @let isMultiSelect = selection().mode === 'multi';\r\n\r\n @if (isCheckbox && isMultiSelect) {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-checkbox-ic\r\n aria-label=\"Select loaded rows\"\r\n [state]=\"selector.isAllSelected()\"\r\n tabindex=\"0\"\r\n (click)=\"onSelectAll($event)\"\r\n (keydown.enter)=\"onSelectAllKeydown($event)\"\r\n (keydown.space)=\"onSelectAllKeydown($event)\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-checkbox-ic\r\n aria-label=\"Select loaded rows\"\r\n [state]=\"selector.isAllSelected()\"\r\n tabindex=\"0\"\r\n (click)=\"onSelectAll($event)\"\r\n (keydown.enter)=\"onSelectAllKeydown($event)\"\r\n (keydown.space)=\"onSelectAllKeydown($event)\" />\r\n }\r\n } @else {\r\n @let resolvedHeader = resolveHeaderText(col);\r\n\r\n @if (col.headerTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"col.headerTemplate\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvedHeader }\"\r\n />\r\n } @else {\r\n <span class=\"re-dg-header-text\">{{ resolvedHeader }}</span>\r\n }\r\n }\r\n\r\n @if (col.sortKey) {\r\n <span class=\"re-dg-sort-ind\">\r\n @let direction = sortOrderFor(col);\r\n\r\n @if (sortTpl()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"sortTpl()!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: direction }\"\r\n />\r\n } @else {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-sort-ic [direction]=\"direction\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-sort-ic [direction]=\"direction\" />\r\n }\r\n }\r\n </span>\r\n }\r\n\r\n @if (isExpandable(col)) {\r\n <button\r\n [attr.aria-controls]=\"expanderRegionId\"\r\n [attr.aria-expanded]=\"expanderMap().get(col.key) ? 'true' : 'false'\"\r\n [attr.aria-label]=\"ariaExpandLabel(col)\"\r\n (click)=\"$event.stopPropagation(); onExpand(col)\"\r\n >\r\n @let expanded = expanderMap().get(col.key);\r\n\r\n @if (expanderTpl()) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"expanderTpl()!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: expanded }\" />\r\n } @else {\r\n @if (deferIcons()) {\r\n @defer (when true) {\r\n <re-expand-ic [expanded]=\"expanded\" />\r\n } @placeholder {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n } @loading {\r\n <span class=\"re-dg-icon-placeholder\"></span>\r\n }\r\n } @else {\r\n <re-expand-ic [expanded]=\"expanded\" />\r\n }\r\n }\r\n </button>\r\n }\r\n\r\n @if (canResizeColumn(col)) {\r\n <button\r\n class=\"re-dg-column-resize-handle\"\r\n aria-orientation=\"vertical\"\r\n role=\"separator\"\r\n [attr.aria-label]=\"ariaResizeLabel(col)\"\r\n (mousedown)=\"onColumnResizeStart($event, col)\"\r\n (click)=\"$event.stopPropagation()\"\r\n ></button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- PINNED TOP ROWS -->\r\n @if (notEmpty) {\r\n <ng-template #pinnedTopContent>\r\n @for (pr of vm.pinnedTop(); track trackPinnedRow(pr); let pinnedTopIndex = $index) {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top\" role=\"row\" [style.width.px]=\"contentW\" [style.min-width.%]=\"100\" [attr.aria-rowindex]=\"ariaPinnedTopRowIndex(pinnedTopIndex)\">\r\n @if (pr.rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pinnedRowCells\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n\r\n @if (deferPinned()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"pinnedTopContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n } @loading {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-top re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"pinnedTopContent\" />\r\n }\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n @if (deferHeader()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"headerContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-header re-dg-deferred-placeholder\" [style.min-height.px]=\"headerHeight()\"></div>\r\n } @loading {\r\n <div class=\"re-dg-header re-dg-deferred-placeholder\" [style.min-height.px]=\"headerHeight()\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"headerContent\" />\r\n }\r\n\r\n <ng-template #dataCellContent let-row let-col=\"col\" let-index=\"index\" let-isPinned=\"isPinned\">\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n\r\n @if (isCheckbox) {\r\n <re-checkbox-ic\r\n aria-label=\"Toggle row selection\"\r\n [state]=\"selector.isSelected(row)\"\r\n [attr.aria-disabled]=\"isDisabledRow(row, index)\"\r\n [attr.tabindex]=\"isDisabledRow(row, index) ? -1 : 0\"\r\n (click)=\"onCheckboxToggle(row, index, $event)\"\r\n (keydown.enter)=\"onCheckboxKeydown(row, index, $event)\"\r\n (keydown.space)=\"onCheckboxKeydown(row, index, $event)\" />\r\n } @else {\r\n @if (deferCells()) {\r\n @defer (when true) {\r\n <re-data-grid-cell [index]=\"index\" [item]=\"row\" [column]=\"col\" [isPinned]=\"!!isPinned\" />\r\n } @placeholder {\r\n <span class=\"re-dg-cell-deferred\"></span>\r\n } @loading {\r\n <span class=\"re-dg-cell-deferred\"></span>\r\n }\r\n } @else {\r\n <re-data-grid-cell [index]=\"index\" [item]=\"row\" [column]=\"col\" [isPinned]=\"!!isPinned\" />\r\n }\r\n }\r\n </ng-template>\r\n\r\n <ng-template #gridContent>\r\n\r\n <!-- STICKY ROW -->\r\n @if (stickyRow && stickyIndex !== null) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-sticky-row\"\r\n role=\"row\"\r\n [class.re-dg-row-disabled]=\"isDisabledRow(stickyRow, stickyIndex)\"\r\n [style.width.px]=\"vm.contentWidth()\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowHeight()\"\r\n [style.top.px]=\"stickyRowTopPx()\"\r\n [attr.aria-rowindex]=\"ariaDataRowIndex(stickyIndex)\"\r\n [attr.aria-disabled]=\"isDisabledRow(stickyRow, stickyIndex)\"\r\n [attr.aria-selected]=\"selection().mode !== 'none' ? selector.isSelected(stickyRow) : null\"\r\n [attr.tabindex]=\"0\"\r\n (click)=\"onRowClick(stickyRow, stickyIndex, $event)\"\r\n (contextmenu)=\"onRowContext(stickyRow, stickyIndex, $event)\"\r\n (dblclick)=\"onRowDoubleClick(stickyRow, stickyIndex, $event)\"\r\n (keydown.enter)=\"onRowClick(stickyRow, stickyIndex, $event)\"\r\n >\r\n @let stickyTemplate = stickyRowTpl();\r\n @let rowTemplate = resolveRowTemplate(stickyRow, stickyIndex);\r\n\r\n @if (stickyTemplate?.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"stickyTemplate!.tpl\"\r\n [ngTemplateOutletContext]=\"{ $implicit: stickyRow, index: stickyIndex }\"\r\n />\r\n } @else if (rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: stickyRow,\r\n index: stickyIndex,\r\n columns: vm.columnsToShow(),\r\n rowHeight: rowHeight(),\r\n isSticky: true\r\n }\"\r\n />\r\n } @else {\r\n @for (col of vm.columnsToShow(); track col.key; let colIndex = $index) {\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, stickyRow)\"\r\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\r\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\r\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\r\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.id]=\"cellAriaId(col.key, stickyIndex, false)\"\r\n [attr.aria-colindex]=\"colIndex + 1\"\r\n [attr.aria-describedby]=\"isTooltipTarget(cellAriaId(col.key, stickyIndex, false)) ? tooltipId : null\"\r\n [attr.tabindex]=\"0\"\r\n (mouseenter)=\"onTooltipEnter($event, stickyRow, col, stickyIndex, cellAriaId(col.key, stickyIndex, false))\"\r\n (mouseleave)=\"hideTooltip()\"\r\n (click)=\"onCellClick(stickyRow, col, stickyIndex, $event);\"\r\n (contextmenu)=\"onCellContext(stickyRow, col, stickyIndex, $event)\"\r\n (dblclick)=\"onCellDoubleClick(stickyRow, col, stickyIndex, $event)\"\r\n (keydown.enter)=\"onCellClick(stickyRow, col, stickyIndex, $event)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: stickyRow, col: col, index: stickyIndex, isPinned: false }\"\r\n />\r\n </div>\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n @if (empty) {\r\n @let emptyTemplate = emptyTpl()?.tpl;\r\n\r\n <div class=\"re-dg-empty\" aria-live=\"polite\" role=\"status\">\r\n @if (emptyTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"emptyTemplate\" />\r\n } @else {\r\n <span class=\"re-dg-empty-text\">{{ defaults.translations.emptyState }}</span>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Content -->\r\n @if (notEmpty) {\r\n @let topGap = topGapLoader();\r\n @let bottomGap = bottomGapLoader();\r\n <div\r\n class=\"re-dg-spacer\"\r\n [style.width.px]=\"contentW\"\r\n [style.height.px]=\"(totalRows + extraInfinitySkeletonRows) * rowH - pinnedBottomH\"></div>\r\n\r\n @if (topGap) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-gap-loader\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"topGap.count * rowH\"\r\n [style.transform]=\"'translateY(' + (topGap.start * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n\r\n @for (slot of renderSlots(); track slot) {\r\n @let rowIndex = startIndex + slot;\r\n @let row = rowAt(rowIndex);\r\n @let rowTemplate = row ? resolveRowTemplate(row, rowIndex) : null;\r\n\r\n @if (row && !isStickyRowIndex(rowIndex)) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row\"\r\n role=\"row\"\r\n [class.re-dg-row-disabled]=\"isDisabledRow(row, rowIndex)\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (rowIndex * rowH + stickyTop) + 'px)'\"\r\n [attr.aria-rowindex]=\"ariaDataRowIndex(rowIndex)\"\r\n [attr.aria-disabled]=\"isDisabledRow(row, rowIndex)\"\r\n [attr.aria-selected]=\"selection().mode !== 'none' ? selector.isSelected(row) : null\"\r\n [attr.tabindex]=\"0\"\r\n (click)=\"onRowClick(row, rowIndex, $event)\"\r\n (contextmenu)=\"onRowContext(row, rowIndex, $event)\"\r\n (dblclick)=\"onRowDoubleClick(row, rowIndex, $event)\"\r\n (keydown.enter)=\"onRowClick(row, rowIndex, $event)\"\r\n >\r\n @if (rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"rowTemplate\"\r\n [ngTemplateOutletContext]=\"{\r\n $implicit: row,\r\n index: rowIndex,\r\n columns: vm.columnsToShow(),\r\n rowHeight: rowHeight(),\r\n isSticky: false\r\n }\"\r\n />\r\n } @else {\r\n @for (col of cols; track col.key; let colIndex = $index) {\r\n @let stickyLeft = vm.stickyOffset(col.key, 'left');\r\n @let stickyRight = vm.stickyOffset(col.key, 'right');\r\n @let isLeft = vm.isStickyLeft(col.key);\r\n @let isRight = vm.isStickyRight(col.key);\r\n\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, row)\"\r\n [class.sticky-left]=\"isLeft\"\r\n [class.sticky-right]=\"isRight\"\r\n [style.left.px]=\"stickyLeft\"\r\n [style.right.px]=\"stickyRight\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.id]=\"cellAriaId(col.key, rowIndex, false)\"\r\n [attr.aria-colindex]=\"colIndex + 1\"\r\n [attr.aria-describedby]=\"isTooltipTarget(cellAriaId(col.key, rowIndex, false)) ? tooltipId : null\"\r\n [attr.tabindex]=\"0\"\r\n (mouseenter)=\"onTooltipEnter($event, row, col, rowIndex, cellAriaId(col.key, rowIndex, false))\"\r\n (mouseleave)=\"hideTooltip()\"\r\n (click)=\"onCellClick(row, col, rowIndex, $event);\"\r\n (contextmenu)=\"onCellContext(row, col, rowIndex, $event)\"\r\n (dblclick)=\"onCellDoubleClick(row, col, rowIndex, $event)\"\r\n (keydown.enter)=\"onCellClick(row, col, rowIndex, $event)\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: row, col: col, index: rowIndex, isPinned: false }\"\r\n />\r\n </div>\r\n }\r\n }\r\n </div>\r\n } @else if (shouldRenderLoadingRow(rowIndex, topGap, bottomGap)) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-skeleton-row\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (rowIndex * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n }\r\n\r\n @if (bottomGap) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-gap-loader\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"bottomGap.count * rowH\"\r\n [style.transform]=\"'translateY(' + (bottomGap.start * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n }\r\n\r\n @if (showInfinitySkeleton || showPaginationSkeleton) {\r\n @let loadingTemplate = loadingTpl();\r\n\r\n @if (loadingTemplate?.tpl) {\r\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\r\n } @else {\r\n @for (si of [0, 1, 2, 3]; track si) {\r\n <div\r\n class=\"re-dg-row re-dg-data-row re-dg-skeleton-row\"\r\n role=\"row\"\r\n [style.width.px]=\"contentW\"\r\n [style.min-width.%]=\"100\"\r\n [style.height.px]=\"rowH\"\r\n [style.transform]=\"'translateY(' + (((showInfinitySkeleton ? items.length : 0) + si) * rowH + stickyTop) + 'px)'\"\r\n >\r\n <span class=\"re-dg-skeleton-row-line\"></span>\r\n </div>\r\n }\r\n }\r\n }\r\n\r\n <!-- PINNED BOTTOM ROWS -->\r\n @if (notEmpty) {\r\n <ng-template #pinnedBottomContent>\r\n <div class=\"re-dg-footer\" role=\"rowgroup\">\r\n @for (pr of vm.pinnedBottom(); track trackPinnedRow(pr); let pinnedBottomIndex = $index) {\r\n <div class=\"re-dg-row re-dg-pinned re-dg-bottom\" role=\"row\" [style.width.px]=\"contentW\" [style.min-width.%]=\"100\" [attr.aria-rowindex]=\"ariaPinnedBottomRowIndex(pinnedBottomIndex)\">\r\n @if (pr.rowTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n } @else {\r\n <ng-container\r\n [ngTemplateOutlet]=\"pinnedRowCells\"\r\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n\r\n @if (deferPinned()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"pinnedBottomContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-footer re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n } @loading {\r\n <div class=\"re-dg-footer re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"pinnedBottomContent\" />\r\n }\r\n }\r\n </ng-template>\r\n\r\n @if (deferContent()) {\r\n @defer (when true) {\r\n <ng-container [ngTemplateOutlet]=\"gridContent\" />\r\n } @placeholder {\r\n <div class=\"re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH * 3\"></div>\r\n } @loading {\r\n <div class=\"re-dg-deferred-placeholder\" [style.min-height.px]=\"rowH * 3\"></div>\r\n }\r\n } @else {\r\n <ng-container [ngTemplateOutlet]=\"gridContent\" />\r\n }\r\n </div>\r\n\r\n <ng-template #pinnedRowCells let-row>\r\n @for (col of cols; track col.key; let colIndex = $index) {\r\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\r\n @let isIndex = 'type' in col && col.type === 'index';\r\n @let stickyLeft = vm.stickyOffset(col.key, 'left');\r\n @let stickyRight = vm.stickyOffset(col.key, 'right');\r\n @let isLeft = vm.isStickyLeft(col.key);\r\n @let isRight = vm.isStickyRight(col.key);\r\n\r\n <div\r\n class=\"re-dg-cell\"\r\n role=\"gridcell\"\r\n [class.expanded]=\"!!col.expandBy\"\r\n [class]=\"cellClass(col, $any(row))\"\r\n [class.sticky-left]=\"isLeft\"\r\n [class.sticky-right]=\"isRight\"\r\n [style.left.px]=\"stickyLeft\"\r\n [style.right.px]=\"stickyRight\"\r\n [style.justify-items]=\"col.align || 'left'\"\r\n [style.text-align]=\"col.align || 'left'\"\r\n [style.height.px]=\"rowH\"\r\n [style.width.px]=\"vm.widthByKey(col.key)\"\r\n [attr.id]=\"cellAriaId(col.key, -1, true)\"\r\n [attr.aria-colindex]=\"colIndex + 1\"\r\n [attr.aria-describedby]=\"isTooltipTarget(cellAriaId(col.key, -1, true)) ? tooltipId : null\"\r\n [attr.tabindex]=\"isCheckbox || isIndex ? -1 : 0\"\r\n (mouseenter)=\"!isCheckbox && !isIndex && onTooltipEnter($event, $any(row), col, -1, cellAriaId(col.key, -1, true))\"\r\n (mouseleave)=\"!isCheckbox && !isIndex && hideTooltip()\"\r\n (click)=\"!isCheckbox && !isIndex && onCellClick($any(row), col, -1, $event);\"\r\n (contextmenu)=\"!isCheckbox && !isIndex && onCellContext($any(row), col, -1, $event)\"\r\n (dblclick)=\"!isCheckbox && !isIndex && onCellDoubleClick($any(row), col, -1, $event)\"\r\n (keydown.enter)=\"!isCheckbox && !isIndex && onCellClick($any(row), col, -1, $event)\"\r\n >\r\n @if (!isCheckbox && !isIndex) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"dataCellContent\"\r\n [ngTemplateOutletContext]=\"{ $implicit: $any(row), col: col, index: -1, isPinned: true }\"\r\n />\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n\r\n @if (deferTooltip()) {\r\n @defer (when true) {\r\n @let tooltipStateValue = tooltipState();\r\n <div\r\n class=\"re-dg-tooltip\"\r\n #tooltip\r\n role=\"tooltip\"\r\n [attr.id]=\"tooltipId\"\r\n [class.visible]=\"tooltipStateValue.visible\"\r\n [style.left.px]=\"tooltipStateValue.x\"\r\n [style.top.px]=\"tooltipStateValue.y\"\r\n >\r\n @if (tooltipStateValue.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"tooltipStateValue.tpl\"\r\n [ngTemplateOutletContext]=\"tooltipStateValue.ctx\"\r\n />\r\n } @else {\r\n {{ tooltipStateValue.text }}\r\n }\r\n </div>\r\n }\r\n } @else {\r\n @let tooltipStateValue = tooltipState();\r\n <div\r\n class=\"re-dg-tooltip\"\r\n #tooltip\r\n role=\"tooltip\"\r\n [attr.id]=\"tooltipId\"\r\n [class.visible]=\"tooltipStateValue.visible\"\r\n [style.left.px]=\"tooltipStateValue.x\"\r\n [style.top.px]=\"tooltipStateValue.y\"\r\n >\r\n @if (tooltipStateValue.tpl) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"tooltipStateValue.tpl\"\r\n [ngTemplateOutletContext]=\"tooltipStateValue.ctx\"\r\n />\r\n } @else {\r\n {{ tooltipStateValue.text }}\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Overlay scrollbar -->\r\n <div class=\"re-dg-scrollbar\" [class.visible]=\"vm.scrollbarVisible()\">\r\n <div\r\n class=\"re-dg-scrollbar-thumb\"\r\n role=\"scrollbar\"\r\n aria-orientation=\"vertical\"\r\n aria-hidden=\"false\"\r\n [style.height.px]=\"vm.thumbHeightPx()\"\r\n [style.transform]=\"'translateY(' + vm.thumbTopPx() + 'px)'\"\r\n (mousedown)=\"onThumbDown($event)\"\r\n ></div>\r\n </div>\r\n</div>\r\n", styles: [":host{--re-data-grid-min-height: 200px;--re-data-grid-height: 400px;--re-data-grid-rounded: var(--radius-md, 6px);--re-data-grid-separator-color: var(--border-color);--re-data-grid-separator: 1px solid var(--re-data-grid-separator-color);--re-data-grid-surface: var(--surface-neutral, #fff);--re-data-grid-active: var(--primary-color, #2a90f4);--re-data-grid-empty-color: #777;--re-data-grid-empty-surface: transparent;--re-data-grid-loading-color: #444;--re-data-grid-loading-surface: rgba(255, 255, 255, .5);--re-data-grid-spinner-size: 2rem;--re-data-grid-spinner-width: .25rem;--re-data-grid-spinner-track-color: rgba(0, 0, 0, .12);--re-data-grid-skeleton-width: 100%;--re-data-grid-skeleton-height: 100%;--re-data-grid-skeleton-rounded: var(--re-data-grid-rounded, .75rem);--re-data-grid-skeleton-shine: rgba(255, 255, 255, .8);--re-data-grid-skeleton-line: #e7ebf0;--re-data-grid-scrollbar-size: 4px;--re-data-grid-scrollbar-offset: 2px;--re-data-grid-scrollbar-track-rounded: .25rem;--re-data-grid-scrollbar-track-surface: transparent;--re-data-grid-scrollbar-thumb-size: 8px;--re-data-grid-scrollbar-thumb-color: rgba(0, 0, 0, .25);--re-data-grid-scrollbar-thumb-active-color: rgba(0, 0, 0, .45);--re-data-grid-scrollbar-thumb-rounded: var(--re-data-grid-scrollbar-track-rounded);--re-data-grid-tooltip-surface: #0f172a;--re-data-grid-tooltip-color: #f8fafc;--re-data-grid-tooltip-radius: .5rem;--re-data-grid-tooltip-padding: .4rem .6rem;--re-data-grid-tooltip-shadow: 0 8px 24px rgba(15, 23, 42, .25);--re-data-grid-tooltip-z: 60;--re-data-grid-header-rounded: var(--re-data-grid-rounded);--re-data-grid-header-surface: #fff;--re-data-grid-header-body-gap: 0px;--re-data-grid-header-row-height: 40px;--re-data-grid-header-row-separator-color: #ccc;--re-data-grid-header-row-separator: 1px solid var(--re-data-grid-header-row-separator-color);--re-data-grid-header-group-row-height: var(--re-data-grid-header-row-height);--re-data-grid-header-group-row-separator-color: var(--re-data-grid-header-row-separator-color);--re-data-grid-header-group-row-separator: 1px solid var(--re-data-grid-header-group-row-separator-color);--re-data-grid-header-group-cell-font-weight: var(--re-data-grid-header-cell-font-weight);--re-data-grid-header-group-cell-font-size: var(--re-data-grid-header-cell-font-size);--re-data-grid-header-group-cell-color: var(--re-data-grid-header-cell-color);--re-data-grid-header-group-cell-surface: var(--re-data-grid-header-cell-surface);--re-data-grid-header-cell-font-weight: 600;--re-data-grid-header-cell-font-size: .8rem;--re-data-grid-header-cell-color: #000;--re-data-grid-header-cell-surface: #fafafa;--re-data-grid-header-cell-line-height: 1.2;--re-data-grid-header-cell-max-lines: 2;--re-data-grid-footer-separator-color: #ccc;--re-data-grid-footer-separator: 1px solid var(--re-data-grid-footer-separator-color);--re-data-grid-footer-surface: #fff;--re-data-grid-row-separator-color: #bbb;--re-data-grid-row-separator: 1px solid var(--re-data-grid-row-separator-color);--re-data-grid-row-odd-surface: var(--re-data-grid-cell-surface);--re-data-grid-row-hover-surface: var(--re-data-grid-cell-surface);--re-data-grid-row-hover-color: var(--re-data-grid-cell-color);--re-data-grid-row-hover-rounded: 0px;--re-data-grid-column-separator-color: transparent;--re-data-grid-column-separator: 1px solid var(--re-data-grid-column-separator-color);--re-data-grid-column-odd-surface: var(--re-data-grid-cell-surface);--re-data-grid-cell-paddings: .4rem .625rem;--re-data-grid-cell-font-weight: 400;--re-data-grid-cell-font-size: .75rem;--re-data-grid-cell-color: #000;--re-data-grid-cell-surface: #fff;--re-data-grid-cell-line-height: 1.2;--re-data-grid-cell-max-lines: 2;--re-data-grid-sticky-header-cell-surface: #fff;--re-data-grid-sticky-cell-surface: #fdfdfd;--re-data-grid-sticky-cell-row-odd-surface: #fdfdfd;--re-data-grid-sticky-cell-left-shadow: 2px 0 2px rgba(0, 0, 0, .03);--re-data-grid-sticky-cell-right-shadow: -2px 0 2px rgba(0, 0, 0, .03);--re-data-grid-pinned-surface: #fcfcfc;--re-data-grid-pinned-separator-color: #eee;--re-data-grid-pinned-separator: 1px solid var(--re-data-grid-pinned-separator-color);--re-data-grid-expander-color: var(--primary-color, currentColor);--re-data-grid-expanded-color: var(--re-data-grid-cell-color, #000);--re-data-grid-expanded-surface: var(--re-data-grid-cell-surface, #fff);--re-data-grid-focus-ring-color: color-mix(in srgb, var(--primary-color, #2a90f4) 55%, transparent);--re-data-grid-focus-ring-width: 2px;--re-data-grid-focus-ring-offset: -2px;display:block;min-height:0;min-width:0}:host,:host *,:host *:before,:host *:after{box-sizing:border-box;outline:none}:host button{outline:none}.re-dg-root{position:relative;display:flex;flex-direction:column;width:100%;min-width:0;min-height:var(--re-data-grid-min-height);border-radius:var(--re-data-grid-rounded);border:var(--re-data-grid-separator)}.re-dg-root.fill{display:block}.re-dg-root.re-dg-loading{pointer-events:none;-webkit-user-select:none;user-select:none;cursor:wait}.re-dg-root.re-dg-loading .re-dg-body{overflow:hidden}.re-dg-root.re-dg-loading .re-dg-scrollbar{display:none!important}.re-dg-root.re-dg-loading .re-dg-loader{pointer-events:all}.re-dg-root.lock-vertical-scroll .re-dg-body{overflow-x:auto;overflow-y:hidden}.re-dg-root.lock-vertical-scroll .re-dg-scrollbar{display:none!important}.re-dg-root.resizing-columns{-webkit-user-select:none;user-select:none;cursor:col-resize}.re-dg-body{position:relative;flex:1 1 auto;min-height:0;min-width:0;height:inherit;border:var(--re-data-grid-separator);border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-surface);overflow:auto;scrollbar-width:auto;-ms-overflow-style:auto}.re-dg-body::-webkit-scrollbar{width:var(--re-data-grid-scrollbar-size);height:var(--re-data-grid-scrollbar-size)}.re-dg-body::-webkit-scrollbar:vertical{width:0}.re-dg-body::-webkit-scrollbar-track{border-radius:var(--re-data-grid-scrollbar-track-rounded);background:var(--re-data-grid-scrollbar-track-surface)}.re-dg-body::-webkit-scrollbar-thumb{border-radius:var(--re-data-grid-scrollbar-thumb-rounded);background:var(--re-data-grid-scrollbar-thumb-color);transition:opacity .3s ease}.re-dg-body::-webkit-scrollbar-thumb:hover{background:var(--re-data-grid-scrollbar-thumb-active-color)}.re-dg-header,.re-dg-footer{position:sticky;z-index:3}.re-dg-header{top:0;background-color:var(--re-data-grid-header-surface)}.re-dg-header-row{min-height:var(--re-data-grid-header-row-height)}.re-dg-header-group-row{min-height:var(--re-data-grid-header-group-row-height)}.re-dg-header-rows{display:flex;flex-direction:column;padding-bottom:var(--re-data-grid-header-body-gap)}.re-dg-footer{bottom:0;border-radius:0 0 var(--re-data-grid-rounded) var(--re-data-grid-rounded);background-color:var(--re-data-grid-footer-surface)}.re-dg-row{position:relative;display:flex}.re-dg-data-row{position:absolute;left:0;top:0;min-width:100%;cursor:default;will-change:transform}.re-dg-sticky-row{z-index:2;top:0}.re-dg-cell,.re-dg-header-cell{display:flex;flex:0 0 auto;align-items:center;padding:var(--re-data-grid-cell-paddings);border-right:var(--re-data-grid-column-separator);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.re-dg-cell:focus-visible,.re-dg-header-cell:focus-visible,.re-dg-header-cell button:focus-visible,.re-dg-row[tabindex=\"0\"]:focus-visible{outline:var(--re-data-grid-focus-ring-width) solid var(--re-data-grid-focus-ring-color);outline-offset:var(--re-data-grid-focus-ring-offset);z-index:4}.re-dg-cell{width:100%;border-bottom:var(--re-data-grid-row-separator);font-weight:var(--re-data-grid-cell-font-weight);font-size:var(--re-data-grid-cell-font-size);color:var(--re-data-grid-cell-color);background-color:var(--re-data-grid-cell-surface)}.re-dg-row:nth-child(odd) .re-dg-cell{background-color:var(--re-data-grid-row-odd-surface)}.re-dg-row.re-dg-row-disabled .re-dg-cell{opacity:.6;cursor:not-allowed}.re-dg-row:nth-child(odd) .re-dg-cell.sticky-left,.re-dg-row:nth-child(odd) .re-dg-cell.sticky-right{background-color:var(--re-data-grid-sticky-cell-row-odd-surface)}.re-dg-cell:nth-child(odd){background-color:var(--re-data-grid-column-odd-surface)}.re-dg-bottom>.re-dg-cell{border-top:var(--re-data-grid-footer-separator)}.re-dg-header-cell{position:relative;align-items:center;gap:.75rem;border-bottom:var(--re-data-grid-header-row-separator);font-weight:var(--re-data-grid-header-cell-font-weight);font-size:var(--re-data-grid-header-cell-font-size);color:var(--re-data-grid-header-cell-color);background:var(--re-data-grid-header-cell-surface);-webkit-user-select:none;user-select:none;transition:color .3s ease-in-out}.re-dg-column-resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;z-index:5}.re-dg-header-cell.re-dg-header-group-cell{border-bottom:var(--re-data-grid-header-group-row-separator);font-weight:var(--re-data-grid-header-group-cell-font-weight);font-size:var(--re-data-grid-header-group-cell-font-size);color:var(--re-data-grid-header-group-cell-color);background:var(--re-data-grid-header-group-cell-surface)}.re-dg-header-rows>.re-dg-row:first-child .re-dg-header-cell:first-child{border-radius:var(--re-data-grid-header-rounded) 0 0 0}.re-dg-header-rows>.re-dg-row:first-child .re-dg-header-cell:last-child{border-radius:0 var(--re-data-grid-header-rounded) 0 0}.re-dg-data-row:last-child .re-dg-cell:first-child{border-radius:0 0 0 var(--re-data-grid-rounded)}.re-dg-data-row:last-child .re-dg-cell:last-child{border-radius:0 0 var(--re-data-grid-rounded) 0}.re-dg-header-cell .re-dg-header-text{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;white-space:normal;line-height:var(--re-data-grid-header-cell-line-height);-webkit-box-orient:vertical;-webkit-line-clamp:var(--re-data-grid-header-cell-max-lines)}.re-dg-row.re-dg-pinned>.re-dg-cell{border-bottom:var(--re-data-grid-pinned-separator);background-color:var(--re-data-grid-pinned-surface)}.re-dg-row .re-dg-header-cell.sticky-left{box-shadow:var(--re-data-grid-sticky-cell-left-shadow);background-color:var(--re-data-grid-sticky-header-cell-surface)}.re-dg-row .re-dg-cell.sticky-left{box-shadow:var(--re-data-grid-sticky-cell-left-shadow);background-color:var(--re-data-grid-sticky-cell-surface)}.re-dg-row .re-dg-header-cell.sticky-right{box-shadow:var(--re-data-grid-sticky-cell-right-shadow);background-color:var(--re-data-grid-sticky-header-cell-surface)}.re-dg-row .re-dg-cell.sticky-right{box-shadow:var(--re-data-grid-sticky-cell-right-shadow);background-color:var(--re-data-grid-sticky-cell-surface)}.re-dg-row.re-dg-pinned>.re-dg-cell.sticky-left,.re-dg-row.re-dg-pinned>.re-dg-cell.sticky-right{background-color:var(--re-data-grid-pinned-surface)}.re-dg-row:hover>.re-dg-cell,.re-dg-row:hover>.re-dg-cell.sticky-left,.re-dg-row:hover>.re-dg-cell.sticky-right{background-color:var(--re-data-grid-row-hover-surface)!important;color:var(--re-data-grid-row-hover-color)!important}.re-dg-row:hover>.re-dg-cell:first-child{border-radius:var(--re-data-grid-row-hover-rounded) 0 0 var(--re-data-grid-row-hover-rounded)}.re-dg-row:hover>.re-dg-cell:last-child{border-radius:0 var(--re-data-grid-row-hover-rounded) var(--re-data-grid-row-hover-rounded) 0}.sticky-left,.sticky-right{position:sticky;z-index:2}.sortable{cursor:pointer}.active-sort{color:var(--re-data-grid-active)}.re-dg-sort-ind{margin-left:6px}.re-dg-icon-placeholder{display:inline-block;width:1rem;height:1rem}.re-dg-cell-deferred{display:block;width:100%;height:100%}.re-dg-deferred-placeholder{background:transparent}.re-dg-data-row .re-dg-cell.expanded{color:var(--re-data-grid-expanded-color);background:var(--re-data-grid-expanded-surface)}.re-dg-empty{position:absolute;inset:0;display:grid;place-items:center;height:inherit;width:100%;border-radius:var(--re-data-grid-rounded);color:var(--re-data-grid-empty-color);background:var(--re-data-grid-empty-surface)}.re-dg-empty-text{width:100%;text-align:center}.re-dg-loader{position:absolute;inset:0;display:grid;place-items:center;height:inherit;border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-loading-surface);color:var(--re-data-grid-loading-color);z-index:5}.re-dg-tooltip{position:fixed;left:0;top:0;max-width:min(28rem,70vw);padding:var(--re-data-grid-tooltip-padding);border-radius:var(--re-data-grid-tooltip-radius);background:var(--re-data-grid-tooltip-surface);color:var(--re-data-grid-tooltip-color);box-shadow:var(--re-data-grid-tooltip-shadow);font-size:.75rem;line-height:1.2;z-index:var(--re-data-grid-tooltip-z);pointer-events:none;opacity:0;transform:translateY(4px);transition:opacity .12s ease,transform .12s ease}.re-dg-tooltip.visible{opacity:1;transform:translateY(0)}.re-dg-loader-spinner{width:var(--re-data-grid-spinner-size);height:var(--re-data-grid-spinner-size);border-radius:50%;border:var(--re-data-grid-spinner-width) solid var(--re-data-grid-spinner-track-color);border-top-color:var(--re-data-grid-loading-color);animation:re-dg-spinner .8s linear infinite}.re-dg-skeleton-row{display:flex;align-items:center;padding:var(--re-data-grid-cell-paddings);border-bottom:var(--re-data-grid-row-separator);background-color:var(--re-data-grid-cell-surface);pointer-events:none}.re-dg-gap-loader{display:flex;align-items:center;padding:var(--re-data-grid-cell-paddings);border-bottom:var(--re-data-grid-row-separator);background-color:color-mix(in srgb,var(--re-data-grid-cell-surface) 88%,var(--re-data-grid-skeleton-line));pointer-events:none;opacity:.9}.re-dg-skeleton-row-line{display:block;width:var(--re-data-grid-skeleton-width);height:var(--re-data-grid-skeleton-height);border-radius:var(--re-data-grid-skeleton-rounded);background:linear-gradient(90deg,var(--re-data-grid-skeleton-line) 0%,var(--re-data-grid-skeleton-shine) 50%,var(--re-data-grid-skeleton-line) 100%);background-size:200% 100%;animation:re-dg-skeleton 1.2s ease-in-out infinite}@keyframes re-dg-skeleton{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes re-dg-spinner{to{transform:rotate(360deg)}}.re-dg-scrollbar{position:absolute;right:0;top:0;bottom:0;opacity:0;transition:opacity .15s ease-in-out;pointer-events:none;z-index:4}.re-dg-scrollbar.visible{opacity:1}.re-dg-scrollbar-thumb{position:absolute;right:var(--re-data-grid-scrollbar-offset);width:var(--re-data-grid-scrollbar-thumb-size);border-radius:var(--re-data-grid-scrollbar-thumb-rounded);background:var(--re-data-grid-scrollbar-thumb-color);pointer-events:auto;-webkit-user-select:none;user-select:none}.re-dg-spacer{width:1px}.re-dg-top{top:0}.re-dg-bottom{bottom:0}\n"] }]
4172
+ }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], pinnedRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "pinnedRows", required: false }] }], isRowSticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "isRowSticky", required: false }] }], isRowDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isRowDisabled", required: false }] }], getRowTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "getRowTemplate", required: false }] }], hasIndexColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasIndexColumn", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], virtualBuffer: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualBuffer", required: false }] }], lockVerticalScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "lockVerticalScroll", required: false }] }], headerGroups: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerGroups", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingMode", required: false }] }], deferContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferContent", required: false }] }], deferHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferHeader", required: false }] }], deferPinned: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferPinned", required: false }] }], deferCells: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferCells", required: false }] }], deferIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferIcons", required: false }] }], deferTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "deferTooltip", required: false }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], pageStartFromZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageStartFromZero", required: false }] }], sortMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortMode", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], multiSortChange: [{ type: i0.Output, args: ["multiSortChange"] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], rowContext: [{ type: i0.Output, args: ["rowContext"] }], rowDoubleClick: [{ type: i0.Output, args: ["rowDoubleClick"] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], cellContext: [{ type: i0.Output, args: ["cellContext"] }], cellDoubleClick: [{ type: i0.Output, args: ["cellDoubleClick"] }], columnResizeEnd: [{ type: i0.Output, args: ["columnResizeEnd"] }], rootEl: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], scrollEl: [{ type: i0.ViewChild, args: ['scroll', { isSignal: true }] }], headerEl: [{ type: i0.ViewChild, args: ['header', { isSignal: true }] }], cellTypedSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridTypeCellTemplateDirective), { isSignal: true }] }], cellDataSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridCellTemplateDirective), { isSignal: true }] }], declarativeColumnRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridDeclarativeColumn), { isSignal: true }] }], headerSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridHeaderTemplateDirective), { isSignal: true }] }], emptySlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridCellEmptyDirective), { isSignal: true }] }], loadingSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridCellLoadingDirective), { isSignal: true }] }], sortIcSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridSortIconDirective), { isSignal: true }] }], expanderIcSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridExpanderIconDirective), { isSignal: true }] }], stickyRowSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridStickyRowDirective), { isSignal: true }] }], rowSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridRowDirective), { isSignal: true }] }], tooltipEl: [{ type: i0.ViewChild, args: ['tooltip', { isSignal: true }] }] } });
3514
4173
 
3515
4174
  /**
3516
4175
  * Generated bundle index. Do not edit.
3517
4176
  */
3518
4177
 
3519
- export { DataGridTypeCellTemplateDirective as D, clampThumbTop as a, DataGridCellTemplateDirective as b, computeScrollbarState as c, DataGridHeaderTemplateDirective as d, DataGridRowDirective as e, DataGridDeclarativeColumn as f, DataGridDeclarativeHeaderDirective as g, DataGridDeclarativeCellDirective as h, DataGridCellEmptyDirective as i, DataGridCellLoadingDirective as j, DataGridStickyRowDirective as k, DataGridSortIconDirective as l, mapThumbTopToScrollTop as m, DataGridExpanderIconDirective as n, DATA_GRID_CONFIG as o, DATA_GRID_TYPE_RENDERERS as p, DATA_GRID_TYPE_TRANSFORMERS as q, DEFAULT_DATA_GRID_DEFAULTS as r, provideDataGridDefaults as s, provideDataGridTypeRenderers as t, provideDataGridTypeTransformers as u, DataGrid as v };
3520
- //# sourceMappingURL=reforgium-data-grid-reforgium-data-grid-C2zJNoKs.mjs.map
4178
+ export { DataGridTypeCellTemplateDirective as D, clampThumbTop as a, DataGridCellTemplateDirective as b, computeScrollbarState as c, DataGridHeaderTemplateDirective as d, DataGridRowDirective as e, DataGridDeclarativeColumn as f, DataGridDeclarativeHeaderDirective as g, DataGridDeclarativeCellDirective as h, DataGridCellEmptyDirective as i, DataGridCellLoadingDirective as j, DataGridStickyRowDirective as k, DataGridSortIconDirective as l, mapThumbTopToScrollTop as m, DataGridExpanderIconDirective as n, DATA_GRID_CONFIG as o, DATA_GRID_HEADER_TEXT_RESOLVER as p, DATA_GRID_TYPE_RENDERERS as q, DATA_GRID_TYPE_TRANSFORMERS as r, DEFAULT_DATA_GRID_DEFAULTS as s, provideDataGridDefaults as t, provideDataGridHeaderTextResolver as u, provideDataGridHeaderTextResolverWithParent as v, provideDataGridTypeRenderers as w, provideDataGridTypeTransformers as x, DataGrid as y };
4179
+ //# sourceMappingURL=reforgium-data-grid-reforgium-data-grid-d5V0EST_.mjs.map