@reforgium/data-grid 2.5.0 → 2.5.2

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.
package/README.md CHANGED
@@ -72,27 +72,27 @@ import { provideDataGridDefaults } from '@reforgium/data-grid';
72
72
 
73
73
  export const appConfig: ApplicationConfig = {
74
74
  providers: [
75
- provideDataGridDefaults({
76
- mode: 'pagination',
77
- hasIndexColumn: true,
78
- resizable: true,
79
- pageSize: 50,
80
- translations: {
81
- indexColumnHeader: 'No.',
82
- },
83
- }),
84
- ],
85
- };
75
+ provideDataGridDefaults({
76
+ mode: 'pagination',
77
+ hasIndexColumn: true,
78
+ resizable: true,
79
+ pageSize: 50,
80
+ translations: {
81
+ indexColumnHeader: 'No.',
82
+ },
83
+ }),
84
+ ],
85
+ };
86
86
  ```
87
87
 
88
88
  Supported default fields:
89
89
 
90
90
  - `mode`
91
91
  - `hasIndexColumn`
92
- - `selection`
93
- - `pageSize`
94
- - `resizable`
95
- - `rowHeight`
92
+ - `selection`
93
+ - `pageSize`
94
+ - `resizable`
95
+ - `rowHeight`
96
96
  - `headerHeight`
97
97
  - `height`
98
98
  - `virtualBuffer`
@@ -102,100 +102,100 @@ Supported default fields:
102
102
  - `deferPinned`
103
103
  - `deferCells`
104
104
  - `pageStartFromZero`
105
- - `translations`
106
- - `debounce`
107
-
108
- `translations` supports: `emptyState`, `itemsPerPageLabel`, `nextPageLabel`, `prevPageLabel`, `indexColumnHeader`.
109
-
110
- ### Type registries (global + local)
111
-
112
- You can register type-based transformers and renderers globally via DI.
113
-
114
- - `provideDataGridTypeTransformers(...)` registers `type -> (row, ctx) => value`
115
- - `provideDataGridTypeRenderers(...)` registers `type -> TemplateRef`
116
- - `reDataGridTypeCell="..."` registers an instance-local renderer (only for that grid instance)
117
-
118
- ```ts
119
- import {
120
- provideDataGridTypeTransformers,
121
- } from '@reforgium/data-grid';
122
-
123
- export const routes: Routes = [
124
- {
125
- path: 'users',
126
- providers: [
127
- provideDataGridTypeTransformers({
128
- money: (_row, ctx) => `$${Number(ctx.value ?? 0).toLocaleString('en-US')}`,
129
- }),
130
- ],
131
- loadComponent: () => import('./users.page').then((m) => m.UsersPage),
132
- },
133
- ];
134
- ```
135
-
136
- ```ts
137
- columns = [
138
- { key: 'salary', header: 'Salary', type: 'money' },
139
- ];
140
- ```
141
-
142
- ```html
143
- <re-data-grid [data]="users" [columns]="columns">
144
- <!-- Local renderer overrides global renderer for this grid only -->
145
- <ng-template reDataGridTypeCell="money" let-value="value" let-row="row">
146
- <b>{{ value }}</b> <small>{{ row.status }}</small>
147
- </ng-template>
148
- </re-data-grid>
149
- ```
150
-
151
- Renderer precedence:
152
-
153
- 1. `column.renderTemplate`
154
- 2. local `reDataGridTypeCell`
155
- 3. DI `provideDataGridTypeRenderers(...)`
156
- 4. built-in renderer (`date`, `number`, `index`, ...)
157
- 5. default text renderer
158
-
159
- Value transform precedence:
160
-
161
- 1. `column.transformer(row, ctx)`
162
- 2. DI `provideDataGridTypeTransformers(...)`
163
- 3. default value pipeline
164
-
165
- `ctx` includes: `value`, `col`, `index`, `type`.
166
-
167
- Type/value callback context (`ctx`) and pinned rows:
168
-
169
- - `value(row, ctx)` receives: `ctx.col`, `ctx.index`, `ctx.isPinned`
170
- - `transformer(row, ctx)` receives: `ctx.value`, `ctx.col`, `ctx.index`, `ctx.type`, `ctx.isPinned`
171
- - Cell template contexts (including `reDataGridTypeCell`, `reDataGridCell`) expose `isPinned`
172
-
173
- ```ts
174
- columns = [
175
- {
176
- key: 'code',
177
- header: 'Code',
178
- value: (row, ctx) => (ctx.isPinned ? 'PINNED' : row.code),
179
- },
180
- {
181
- key: 'salary',
182
- header: 'Salary',
183
- type: 'money',
184
- transformer: (row, ctx) => (ctx.isPinned ? `PIN: ${ctx.value}` : ctx.value),
185
- },
186
- ];
187
- ```
188
-
189
- ```html
190
- <ng-template reDataGridTypeCell="money" let-value="value" let-isPinned="isPinned">
191
- <b>{{ value }}</b>
192
- @if (isPinned) {
193
- <small>PIN</small>
194
- }
195
- </ng-template>
196
- ```
197
-
198
- ### Inputs
105
+ - `translations`
106
+ - `debounce`
107
+
108
+ `translations` supports: `emptyState`, `itemsPerPageLabel`, `nextPageLabel`, `prevPageLabel`, `indexColumnHeader`.
109
+
110
+ ### Type registries (global + local)
111
+
112
+ You can register type-based transformers and renderers globally via DI.
113
+
114
+ - `provideDataGridTypeTransformers(...)` registers `type -> (row, ctx) => value`
115
+ - `provideDataGridTypeRenderers(...)` registers `type -> TemplateRef`
116
+ - `reDataGridTypeCell="..."` registers an instance-local renderer (only for that grid instance)
117
+
118
+ ```ts
119
+ import {
120
+ provideDataGridTypeTransformers,
121
+ } from '@reforgium/data-grid';
122
+
123
+ export const routes: Routes = [
124
+ {
125
+ path: 'users',
126
+ providers: [
127
+ provideDataGridTypeTransformers({
128
+ money: (_row, ctx) => `$${Number(ctx.value ?? 0).toLocaleString('en-US')}`,
129
+ }),
130
+ ],
131
+ loadComponent: () => import('./users.page').then((m) => m.UsersPage),
132
+ },
133
+ ];
134
+ ```
135
+
136
+ ```ts
137
+ columns = [
138
+ { key: 'salary', header: 'Salary', type: 'money' },
139
+ ];
140
+ ```
141
+
142
+ ```html
143
+ <re-data-grid [data]="users" [columns]="columns">
144
+ <!-- Local renderer overrides global renderer for this grid only -->
145
+ <ng-template reDataGridTypeCell="money" let-value="value" let-row="row">
146
+ <b>{{ value }}</b> <small>{{ row.status }}</small>
147
+ </ng-template>
148
+ </re-data-grid>
149
+ ```
150
+
151
+ Renderer precedence:
152
+
153
+ 1. `column.renderTemplate`
154
+ 2. local `reDataGridTypeCell`
155
+ 3. DI `provideDataGridTypeRenderers(...)`
156
+ 4. built-in renderer (`date`, `number`, `index`, ...)
157
+ 5. default text renderer
158
+
159
+ Value transform precedence:
160
+
161
+ 1. `column.transformer(row, ctx)`
162
+ 2. DI `provideDataGridTypeTransformers(...)`
163
+ 3. default value pipeline
164
+
165
+ `ctx` includes: `value`, `col`, `index`, `type`.
166
+
167
+ Type/value callback context (`ctx`) and pinned rows:
168
+
169
+ - `value(row, ctx)` receives: `ctx.col`, `ctx.index`, `ctx.isPinned`
170
+ - `transformer(row, ctx)` receives: `ctx.value`, `ctx.col`, `ctx.index`, `ctx.type`, `ctx.isPinned`
171
+ - Cell template contexts (including `reDataGridTypeCell`, `reDataGridCell`) expose `isPinned`
172
+
173
+ ```ts
174
+ columns = [
175
+ {
176
+ key: 'code',
177
+ header: 'Code',
178
+ value: (row, ctx) => (ctx.isPinned ? 'PINNED' : row.code),
179
+ },
180
+ {
181
+ key: 'salary',
182
+ header: 'Salary',
183
+ type: 'money',
184
+ transformer: (row, ctx) => (ctx.isPinned ? `PIN: ${ctx.value}` : ctx.value),
185
+ },
186
+ ];
187
+ ```
188
+
189
+ ```html
190
+ <ng-template reDataGridTypeCell="money" let-value="value" let-isPinned="isPinned">
191
+ <b>{{ value }}</b>
192
+ @if (isPinned) {
193
+ <small>PIN</small>
194
+ }
195
+ </ng-template>
196
+ ```
197
+
198
+ ### Inputs
199
199
 
200
200
  | Parameter | Type | Default | Description | |
201
201
  |--------------------|--------------------------------------------------|--------------------|-------------------------------------------------------------------------------------------------|------------------|
@@ -223,14 +223,14 @@ columns = [
223
223
  | deferCells | `boolean` | `false` | Defers rendering of cell content | |
224
224
  | rowKey | `DataKey<T> \| ((item: T) => string \| number)` | `undefined` | Property name or function to resolve unique row key | |
225
225
 
226
- When selection mode is `'single'` or `'multi'`, provide a `key` (data property) and optionally `defaultSelected`.
227
-
228
- Selection mode guidance:
229
-
230
- - Prefer using row selection with `mode="pagination"` for clearer UX and predictable “select all” behavior.
231
- - In `mode="infinity"`, selection typically applies only to currently loaded rows, so use it only when that behavior is acceptable.
232
-
233
- Feature lazy-loading behavior (runtime `import()`):
226
+ When selection mode is `'single'` or `'multi'`, provide a `key` (data property) and optionally `defaultSelected`.
227
+
228
+ Selection mode guidance:
229
+
230
+ - Prefer using row selection with `mode="pagination"` for clearer UX and predictable “select all” behavior.
231
+ - In `mode="infinity"`, selection typically applies only to currently loaded rows, so use it only when that behavior is acceptable.
232
+
233
+ Feature lazy-loading behavior (runtime `import()`):
234
234
 
235
235
  - Selection feature is loaded when `selection.mode !== 'none'`.
236
236
  - Sticky feature is loaded when `isRowSticky` is provided.
@@ -315,25 +315,25 @@ Common (base) fields:
315
315
  | `sortKey` | `string` | Alternative key used for sorting when display `key` differs from sortable data. | |
316
316
  | `sticky` | `'left' \| 'right' \| true` | Keeps the column fixed while horizontally scrolling. `true` pins to the left. | |
317
317
  | `expandBy` | `DataKey<T>` | Data key that controls expand/collapse behavior for the column. | |
318
- | `flex` | `number` | Flex grow factor for width distribution in flexible layouts. | |
319
- | `minWidth` / `maxWidth` | `number` | Column width limits in pixels. | |
320
- | `resizable` | `boolean` | Enables drag resize from header. `false` disables resize handle for the column. | |
321
- | `cellClass` | `string \| ((row: T) => string)` | Static CSS class or resolver per row. | |
322
- | `tooltip` | `true \| string \| ((row: T) => string) \| TemplateRef<GridTooltipContext>` | Popover tooltip content shown on cell hover. `true` uses the cell value automatically. | *[NEW in 2.2.0]* |
318
+ | `flex` | `number` | Flex grow factor for width distribution in flexible layouts. | |
319
+ | `minWidth` / `maxWidth` | `number` | Column width limits in pixels. | |
320
+ | `resizable` | `boolean` | Enables drag resize from header. `false` disables resize handle for the column. | |
321
+ | `cellClass` | `string \| ((row: T) => string)` | Static CSS class or resolver per row. | |
322
+ | `tooltip` | `true \| string \| ((row: T) => string) \| TemplateRef<GridTooltipContext>` | Popover tooltip content shown on cell hover. `true` uses the cell value automatically. | *[NEW in 2.2.0]* |
323
323
 
324
324
  Renderer-specific fields:
325
325
 
326
326
  | Variant | Fields | Notes |
327
327
  |-------------------|-----------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|
328
- | Built-in / type renderer | `type?: GridBuiltInCellType \| string`, `typeParams?: any`, `defaultValue?: any` | Built-in types are `plain/date/number/index/checkbox`; custom string types can be handled by local/DI type registries. |
329
- | Value renderer | `value: (row: T, ctx) => string \| number`, `track: (row: T) => string` | `track` is required for stable row identity and efficient updates. `ctx` includes `col`, `index`, `isPinned`. |
330
- | Template renderer | `renderTemplate: TemplateRef<...>`, `track: (row: T) => string` | `track` is required when rendering through Angular templates. |
328
+ | Built-in / type renderer | `type?: GridBuiltInCellType \| string`, `typeParams?: any`, `defaultValue?: any` | Built-in types are `plain/date/number/index/checkbox`; custom string types can be handled by local/DI type registries. |
329
+ | Value renderer | `value: (row: T, ctx) => string \| number`, `track: (row: T) => string` | `track` is required for stable row identity and efficient updates. `ctx` includes `col`, `index`, `isPinned`. |
330
+ | Template renderer | `renderTemplate: TemplateRef<...>`, `track: (row: T) => string` | `track` is required when rendering through Angular templates. |
331
331
 
332
332
  Cell text wrapping/clamp behavior:
333
333
 
334
334
  - Default header text and default body renderers (`plain`, `date`, `number`, `index`) are limited to 2 lines with ellipsis.
335
- - Template-based renderers (`renderTemplate`, `reDataGridCell`, `reDataGridTypeCell`, etc.) are not clamped by default and are fully controlled by your template styles.
336
- - Cell template contexts also include `isPinned` so pinned top/bottom rows can be rendered differently.
335
+ - Template-based renderers (`renderTemplate`, `reDataGridCell`, `reDataGridTypeCell`, etc.) are not clamped by default and are fully controlled by your template styles.
336
+ - Cell template contexts also include `isPinned` so pinned top/bottom rows can be rendered differently.
337
337
 
338
338
  ### Declarative columns *[NEW in 2.0.0]*
339
339
 
@@ -365,7 +365,7 @@ Notes:
365
365
  - When used with column manager state, `visible`, `disabled`, and `sticky` are taken from state when defined.
366
366
  - `reHeader` maps to `headerTemplate`.
367
367
  - `reCell` receives value as `$implicit`, and the row is available as `let-row="row"` via `RenderTemplateData`.
368
- - Most `GridColumn<T>` fields are available as `<re-dg-column>` inputs (`sortKey`, `sticky`, `expandBy`, `disabled`, `width`, `minWidth`, `maxWidth`, `flex`, `resizable`, `align`, `cellClass`, `type`, `typeParams`, `defaultValue`, `value`, `track`, `tooltip`).
368
+ - Most `GridColumn<T>` fields are available as `<re-dg-column>` inputs (`sortKey`, `sticky`, `expandBy`, `disabled`, `width`, `minWidth`, `maxWidth`, `flex`, `resizable`, `align`, `cellClass`, `type`, `typeParams`, `defaultValue`, `value`, `track`, `tooltip`).
369
369
  - `sticky` accepts `'left' | 'right'`; legacy `true` maps to `'left'` for backward compatibility.
370
370
 
371
371
  ### Tooltip
@@ -1,4 +1,4 @@
1
- import { c as computeScrollbarState, a as clampThumbTop, m as mapThumbTopToScrollTop } from './reforgium-data-grid-reforgium-data-grid-Civdbsy1.mjs';
1
+ import { c as computeScrollbarState, a as clampThumbTop, m as mapThumbTopToScrollTop } from './reforgium-data-grid-reforgium-data-grid-BkUQEsdU.mjs';
2
2
 
3
3
  function createGridOverlayScrollFeature(ctx) {
4
4
  const showScrollbar = () => {
@@ -76,4 +76,4 @@ function createGridOverlayScrollFeature(ctx) {
76
76
  }
77
77
 
78
78
  export { createGridOverlayScrollFeature };
79
- //# sourceMappingURL=reforgium-data-grid-grid-overlay-scroll.feature-CM8whbLz.mjs.map
79
+ //# sourceMappingURL=reforgium-data-grid-grid-overlay-scroll.feature-HnvU7zek.mjs.map
@@ -1360,6 +1360,7 @@ class DataGridCellComponent {
1360
1360
  }
1361
1361
  return displayValue;
1362
1362
  }, ...(ngDevMode ? [{ debugName: "value" }] : []));
1363
+ resolvedAlign = computed(() => this.column().align ?? 'left', ...(ngDevMode ? [{ debugName: "resolvedAlign" }] : []));
1363
1364
  resolveTypeTemplate(type) {
1364
1365
  if (!type) {
1365
1366
  return undefined;
@@ -1368,37 +1369,45 @@ class DataGridCellComponent {
1368
1369
  this.typeRenderers[type]);
1369
1370
  }
1370
1371
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1371
- 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: `
1372
- @let row = item();
1373
- @let col = $any(column());
1374
- @let val = $any(value());
1375
- @let pinned = isPinned();
1372
+ 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: `
1373
+ @let row = item();
1374
+ @let col = $any(column());
1375
+ @let val = $any(value());
1376
+ @let pinned = isPinned();
1376
1377
 
1377
- @switch (type()) {
1378
- @case ('tpl') {
1379
- <ng-container
1380
- [ngTemplateOutlet]="col.renderTemplate"
1381
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1382
- />
1383
- }
1384
- @case ('globalTypeTpl') {
1385
- <ng-container
1386
- [ngTemplateOutlet]="resolveTypeTemplate(col.type)"
1387
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1388
- />
1389
- }
1390
- @case ('globalDataTpl') {
1391
- <ng-container
1392
- [ngTemplateOutlet]="vm.globalDataCellTpls.get(col.key)"
1393
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1394
- />
1395
- }
1396
- @case ('globalRowTpl') {
1397
- <ng-container
1398
- [ngTemplateOutlet]="vm.globalRowCellTpls.get(col.key)"
1399
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1400
- />
1401
- }
1378
+ @switch (type()) {
1379
+ @case ('tpl') {
1380
+ <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1381
+ <ng-container
1382
+ [ngTemplateOutlet]="col.renderTemplate"
1383
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1384
+ />
1385
+ </div>
1386
+ }
1387
+ @case ('globalTypeTpl') {
1388
+ <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1389
+ <ng-container
1390
+ [ngTemplateOutlet]="resolveTypeTemplate(col.type)"
1391
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1392
+ />
1393
+ </div>
1394
+ }
1395
+ @case ('globalDataTpl') {
1396
+ <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1397
+ <ng-container
1398
+ [ngTemplateOutlet]="vm.globalDataCellTpls.get(col.key)"
1399
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1400
+ />
1401
+ </div>
1402
+ }
1403
+ @case ('globalRowTpl') {
1404
+ <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1405
+ <ng-container
1406
+ [ngTemplateOutlet]="vm.globalRowCellTpls.get(col.key)"
1407
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1408
+ />
1409
+ </div>
1410
+ }
1402
1411
  @case ('date') {
1403
1412
  <span class="re-dg-cell-text">{{ val | date: col?.typeParams }}</span>
1404
1413
  }
@@ -1412,41 +1421,49 @@ class DataGridCellComponent {
1412
1421
  <span class="re-dg-cell-text">{{ val }}</span>
1413
1422
  }
1414
1423
  }
1415
- `, 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)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: DecimalPipe, name: "number" }] });
1424
+ `, 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" }] });
1416
1425
  }
1417
1426
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridCellComponent, decorators: [{
1418
1427
  type: Component,
1419
- args: [{ selector: 're-data-grid-cell', template: `
1420
- @let row = item();
1421
- @let col = $any(column());
1422
- @let val = $any(value());
1423
- @let pinned = isPinned();
1428
+ args: [{ selector: 're-data-grid-cell', template: `
1429
+ @let row = item();
1430
+ @let col = $any(column());
1431
+ @let val = $any(value());
1432
+ @let pinned = isPinned();
1424
1433
 
1425
- @switch (type()) {
1426
- @case ('tpl') {
1427
- <ng-container
1428
- [ngTemplateOutlet]="col.renderTemplate"
1429
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1430
- />
1431
- }
1432
- @case ('globalTypeTpl') {
1433
- <ng-container
1434
- [ngTemplateOutlet]="resolveTypeTemplate(col.type)"
1435
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1436
- />
1437
- }
1438
- @case ('globalDataTpl') {
1439
- <ng-container
1440
- [ngTemplateOutlet]="vm.globalDataCellTpls.get(col.key)"
1441
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1442
- />
1443
- }
1444
- @case ('globalRowTpl') {
1445
- <ng-container
1446
- [ngTemplateOutlet]="vm.globalRowCellTpls.get(col.key)"
1447
- [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1448
- />
1449
- }
1434
+ @switch (type()) {
1435
+ @case ('tpl') {
1436
+ <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1437
+ <ng-container
1438
+ [ngTemplateOutlet]="col.renderTemplate"
1439
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1440
+ />
1441
+ </div>
1442
+ }
1443
+ @case ('globalTypeTpl') {
1444
+ <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1445
+ <ng-container
1446
+ [ngTemplateOutlet]="resolveTypeTemplate(col.type)"
1447
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1448
+ />
1449
+ </div>
1450
+ }
1451
+ @case ('globalDataTpl') {
1452
+ <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1453
+ <ng-container
1454
+ [ngTemplateOutlet]="vm.globalDataCellTpls.get(col.key)"
1455
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1456
+ />
1457
+ </div>
1458
+ }
1459
+ @case ('globalRowTpl') {
1460
+ <div class="re-dg-cell-template" [style.justify-content]="resolvedAlign()" [style.text-align]="resolvedAlign()">
1461
+ <ng-container
1462
+ [ngTemplateOutlet]="vm.globalRowCellTpls.get(col.key)"
1463
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index: index(), isPinned: pinned }"
1464
+ />
1465
+ </div>
1466
+ }
1450
1467
  @case ('date') {
1451
1468
  <span class="re-dg-cell-text">{{ val | date: col?.typeParams }}</span>
1452
1469
  }
@@ -1460,7 +1477,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
1460
1477
  <span class="re-dg-cell-text">{{ val }}</span>
1461
1478
  }
1462
1479
  }
1463
- `, 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)}\n"] }]
1480
+ `, 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"] }]
1464
1481
  }], 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 }] }] } });
1465
1482
 
1466
1483
  // noinspection ES6PreferShortImport
@@ -1687,6 +1704,9 @@ function createGridInfinityPageRequestFeature(ctx) {
1687
1704
  if (state.initial || state.mode !== 'infinity') {
1688
1705
  return false;
1689
1706
  }
1707
+ if (state.total <= 0) {
1708
+ return false;
1709
+ }
1690
1710
  const threshold = Math.max(0, state.total - Math.max(1, Math.floor(state.visibleCount * PREFETCH_FACTOR)));
1691
1711
  const nearEnd = state.start + state.visibleCount >= threshold;
1692
1712
  if (!nearEnd || ctx.isLoading()) {
@@ -3374,7 +3394,7 @@ class DataGrid {
3374
3394
  if (this.overlayScrollFeaturePromise) {
3375
3395
  return this.overlayScrollFeaturePromise;
3376
3396
  }
3377
- this.overlayScrollFeaturePromise = import('./reforgium-data-grid-grid-overlay-scroll.feature-CM8whbLz.mjs').then(({ createGridOverlayScrollFeature }) => {
3397
+ this.overlayScrollFeaturePromise = import('./reforgium-data-grid-grid-overlay-scroll.feature-HnvU7zek.mjs').then(({ createGridOverlayScrollFeature }) => {
3378
3398
  const feature = createGridOverlayScrollFeature({
3379
3399
  getScrollElement: () => this.scrollEl()?.nativeElement ?? null,
3380
3400
  getThumbTop: () => this.vm.thumbTopPx(),
@@ -3499,4 +3519,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
3499
3519
  */
3500
3520
 
3501
3521
  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 };
3502
- //# sourceMappingURL=reforgium-data-grid-reforgium-data-grid-Civdbsy1.mjs.map
3522
+ //# sourceMappingURL=reforgium-data-grid-reforgium-data-grid-BkUQEsdU.mjs.map
@@ -1,2 +1,2 @@
1
- export { o as DATA_GRID_CONFIG, p as DATA_GRID_TYPE_RENDERERS, q as DATA_GRID_TYPE_TRANSFORMERS, r as DEFAULT_DATA_GRID_DEFAULTS, v as DataGrid, i as DataGridCellEmptyDirective, j as DataGridCellLoadingDirective, b as DataGridCellTemplateDirective, h as DataGridDeclarativeCellDirective, f as DataGridDeclarativeColumn, g as DataGridDeclarativeHeaderDirective, n as DataGridExpanderIconDirective, d as DataGridHeaderTemplateDirective, e as DataGridRowDirective, l as DataGridSortIconDirective, k as DataGridStickyRowDirective, D as DataGridTypeCellTemplateDirective, s as provideDataGridDefaults, t as provideDataGridTypeRenderers, u as provideDataGridTypeTransformers } from './reforgium-data-grid-reforgium-data-grid-Civdbsy1.mjs';
1
+ export { o as DATA_GRID_CONFIG, p as DATA_GRID_TYPE_RENDERERS, q as DATA_GRID_TYPE_TRANSFORMERS, r as DEFAULT_DATA_GRID_DEFAULTS, v as DataGrid, i as DataGridCellEmptyDirective, j as DataGridCellLoadingDirective, b as DataGridCellTemplateDirective, h as DataGridDeclarativeCellDirective, f as DataGridDeclarativeColumn, g as DataGridDeclarativeHeaderDirective, n as DataGridExpanderIconDirective, d as DataGridHeaderTemplateDirective, e as DataGridRowDirective, l as DataGridSortIconDirective, k as DataGridStickyRowDirective, D as DataGridTypeCellTemplateDirective, s as provideDataGridDefaults, t as provideDataGridTypeRenderers, u as provideDataGridTypeTransformers } from './reforgium-data-grid-reforgium-data-grid-BkUQEsdU.mjs';
2
2
  //# sourceMappingURL=reforgium-data-grid.mjs.map
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.5.0",
2
+ "version": "2.5.2",
3
3
  "name": "@reforgium/data-grid",
4
4
  "description": "reforgium DataGrid component",
5
5
  "author": "rtommievich",