@reforgium/data-grid 1.0.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.
@@ -0,0 +1,950 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, inject, TemplateRef, Directive, signal, computed, effect, Injectable, Component, viewChild, ElementRef, ChangeDetectionStrategy, booleanAttribute, numberAttribute, output, contentChildren, afterRenderEffect, DestroyRef, untracked } from '@angular/core';
3
+ import { NgTemplateOutlet, DatePipe, DecimalPipe } from '@angular/common';
4
+ import { Subscription, fromEvent, auditTime } from 'rxjs';
5
+
6
+ class DataGridTypeCellTemplateDirective {
7
+ type = input('', { ...(ngDevMode ? { debugName: "type" } : {}), alias: 'ssDataGridTypeCell' });
8
+ tpl = inject((TemplateRef));
9
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridTypeCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
10
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.3", type: DataGridTypeCellTemplateDirective, isStandalone: true, selector: "ng-template[ssDataGridTypeCell]", inputs: { type: { classPropertyName: "type", publicName: "ssDataGridTypeCell", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
11
+ }
12
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridTypeCellTemplateDirective, decorators: [{
13
+ type: Directive,
14
+ args: [{ selector: 'ng-template[ssDataGridTypeCell]' }]
15
+ }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "ssDataGridTypeCell", required: false }] }] } });
16
+
17
+ class DataGridHeaderTemplateDirective {
18
+ key = input('', { ...(ngDevMode ? { debugName: "key" } : {}), alias: 'ssDataGridHeader' });
19
+ tpl = inject((TemplateRef));
20
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridHeaderTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
21
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.3", type: DataGridHeaderTemplateDirective, isStandalone: true, selector: "ng-template[ssDataGridHeader]", inputs: { key: { classPropertyName: "key", publicName: "ssDataGridHeader", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
22
+ }
23
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridHeaderTemplateDirective, decorators: [{
24
+ type: Directive,
25
+ args: [{ selector: 'ng-template[ssDataGridHeader]' }]
26
+ }], propDecorators: { key: [{ type: i0.Input, args: [{ isSignal: true, alias: "ssDataGridHeader", required: false }] }] } });
27
+
28
+ class DataGridCellEmptyDirective {
29
+ tpl = inject((TemplateRef));
30
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridCellEmptyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
31
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.3", type: DataGridCellEmptyDirective, isStandalone: true, selector: "ng-template[ssDataGridEmpty]", ngImport: i0 });
32
+ }
33
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridCellEmptyDirective, decorators: [{
34
+ type: Directive,
35
+ args: [{ selector: 'ng-template[ssDataGridEmpty]' }]
36
+ }] });
37
+ class DataGridCellLoadingDirective {
38
+ tpl = inject((TemplateRef));
39
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridCellLoadingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
40
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.3", type: DataGridCellLoadingDirective, isStandalone: true, selector: "ng-template[ssDataGridLoading]", ngImport: i0 });
41
+ }
42
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridCellLoadingDirective, decorators: [{
43
+ type: Directive,
44
+ args: [{ selector: 'ng-template[ssDataGridLoading]' }]
45
+ }] });
46
+
47
+ const GRID_INDEX_COLUMN = {
48
+ key: '_index',
49
+ type: 'index',
50
+ align: 'center',
51
+ header: '№',
52
+ width: 72,
53
+ sticky: true,
54
+ };
55
+ const GRID_CHECKBOX_COLUMN = {
56
+ key: '_checkbox',
57
+ type: 'checkbox',
58
+ align: 'center',
59
+ header: 'checkbox',
60
+ width: 44,
61
+ sticky: true,
62
+ };
63
+
64
+ function layoutColumns(columns, containerWidth, defaultCol) {
65
+ const idx = visibleIndexes(columns);
66
+ const { fixedIdx, autoIdx } = splitFixed(columns, idx);
67
+ const fixedWidths = computeFixedWidths(columns, fixedIdx);
68
+ const baseAuto = computeBaseAuto(columns, autoIdx, defaultCol);
69
+ const sumFixed = sum(fixedWidths);
70
+ const sumBase = sum(baseAuto.map((w) => w.width));
71
+ const free = Math.max(containerWidth - sumFixed - sumBase, 0);
72
+ const grownAuto = distributeFree(columns, baseAuto, free); // water-fill
73
+ const widths = new Array(columns.length).fill(0);
74
+ if (containerWidth <= 0) {
75
+ const byKey = {};
76
+ for (let i = 0; i < columns.length; i++) {
77
+ // noinspection PointlessBooleanExpressionJS
78
+ columns[i].visible !== false && (byKey[columns[i].key] = 0);
79
+ }
80
+ return { widths, total: 0, byKey };
81
+ }
82
+ for (const { index, width } of fixedWidths) {
83
+ widths[index] = width;
84
+ }
85
+ for (const { index, width } of grownAuto) {
86
+ widths[index] = width;
87
+ }
88
+ roundAndFix(columns, widths, fixedIdx, autoIdx, containerWidth);
89
+ let total = 0;
90
+ const byKey = {};
91
+ for (const i of idx) {
92
+ total += widths[i];
93
+ byKey[columns[i].key] = widths[i];
94
+ }
95
+ return { widths, total, byKey };
96
+ }
97
+ function visibleIndexes(cols) {
98
+ const out = [];
99
+ for (let i = 0; i < cols.length; i++) {
100
+ // noinspection PointlessBooleanExpressionJS
101
+ cols[i].visible !== false && out.push(i);
102
+ }
103
+ return out;
104
+ }
105
+ function splitFixed(cols, visibleIdx) {
106
+ const fixedIdx = [];
107
+ const autoIdx = [];
108
+ for (const i of visibleIdx) {
109
+ cols[i].width === undefined ? autoIdx.push(i) : fixedIdx.push(i);
110
+ }
111
+ return { fixedIdx, autoIdx };
112
+ }
113
+ const computeFixedWidths = (cols, fixedIdx) => fixedIdx.map((index) => {
114
+ const col = cols[index];
115
+ const width = clamp$1(col.width, col.minWidth, col.maxWidth);
116
+ return { index, width };
117
+ });
118
+ const computeBaseAuto = (cols, autoIdx, def) => autoIdx.map((index) => {
119
+ const c = cols[index];
120
+ const base = clamp$1(c.minWidth ?? def, c.minWidth, c.maxWidth);
121
+ return { index, width: base };
122
+ });
123
+ function distributeFree(cols, base, free) {
124
+ if (free <= 0 || base.length === 0) {
125
+ return base;
126
+ }
127
+ const widths = base.map((b) => ({ ...b }));
128
+ let remaining = free;
129
+ let growable = widths.filter((w) => widthsCanGrow(cols, w.index, w.width)).map((w) => w.index);
130
+ while (remaining > 0 && growable.length > 0) {
131
+ const flexSum = growable.reduce((s, i) => s + (cols[i].flex ?? 1), 0) || 1;
132
+ let distributed = 0;
133
+ for (const i of growable) {
134
+ const rec = widths.find((w) => w.index === i);
135
+ const cap = (cols[i].maxWidth ?? Infinity) - rec.width;
136
+ if (cap <= 0) {
137
+ continue;
138
+ }
139
+ const ideal = remaining * ((cols[i].flex ?? 1) / flexSum);
140
+ const add = ideal < cap ? ideal : cap;
141
+ if (add > 0) {
142
+ rec.width += add;
143
+ distributed += add;
144
+ }
145
+ }
146
+ if (distributed <= 1e-6) {
147
+ break;
148
+ }
149
+ remaining -= distributed;
150
+ growable = widths.filter((w) => widthsCanGrow(cols, w.index, w.width)).map((w) => w.index);
151
+ }
152
+ return widths;
153
+ }
154
+ function widthsCanGrow(cols, i, cur) {
155
+ const max = cols[i].maxWidth ?? Infinity;
156
+ return cur < max - 1e-6;
157
+ }
158
+ function roundAndFix(cols, widths, fixedIdx, autoIdx, containerWidth) {
159
+ const sumFixed = fixedIdx.reduce((s, i) => s + widths[i], 0);
160
+ let sumAuto = 0;
161
+ for (const i of autoIdx) {
162
+ widths[i] = Math.floor(widths[i]);
163
+ sumAuto += widths[i];
164
+ }
165
+ let need = Math.round(Math.max(containerWidth - sumFixed - sumAuto, 0));
166
+ if (need === 0) {
167
+ return;
168
+ }
169
+ for (let k = autoIdx.length - 1; k >= 0 && need > 0; k--) {
170
+ const i = autoIdx[k];
171
+ const max = cols[i].maxWidth ?? Infinity;
172
+ if (widths[i] + 1 <= max) {
173
+ widths[i] += 1;
174
+ need--;
175
+ }
176
+ }
177
+ }
178
+ function clamp$1(v, min, max) {
179
+ min != null && v < min && (v = min);
180
+ max != null && v > max && (v = max);
181
+ return v;
182
+ }
183
+ function sum(items) {
184
+ if (Array.isArray(items) && typeof items[0] === 'number') {
185
+ return items.reduce((s, x) => s + x, 0);
186
+ }
187
+ return items.reduce((s, x) => s + x.width, 0);
188
+ }
189
+
190
+ /**
191
+ * Вычисляет визуальное состояние оверлейного скроллбара. Все аргументы - сырые DOM-числа.
192
+ * Возвращает состояние, описывающее видимость, размер и позицию ползунка.
193
+ */
194
+ function computeScrollbarState(scrollHeight = 0, clientHeight = 0, scrollTop = 0, minThumb = 24) {
195
+ const safeClient = toSafe(clientHeight);
196
+ const safeScrollH = toSafe(scrollHeight);
197
+ const safeTop = clamp(scrollTop, 0, Math.max(0, safeScrollH - safeClient));
198
+ if (safeClient <= 0 || !isFinite(safeClient)) {
199
+ return hiddenState();
200
+ }
201
+ if (safeScrollH <= safeClient + 1) {
202
+ return hiddenState(safeClient);
203
+ }
204
+ const track = safeClient;
205
+ const ratio = track / safeScrollH;
206
+ const thumb = Math.max(minThumb, Math.floor(track * ratio));
207
+ const maxScrollTop = Math.max(1, safeScrollH - track);
208
+ const maxThumbTop = Math.max(1, track - thumb);
209
+ const topRaw = Math.round((safeTop / maxScrollTop) * maxThumbTop);
210
+ const thumbTop = clamp(isFinite(topRaw) ? topRaw : 0, 0, maxThumbTop);
211
+ return {
212
+ visible: true,
213
+ thumbHeight: thumb,
214
+ thumbTop,
215
+ track,
216
+ maxThumbTop,
217
+ maxScrollTop,
218
+ };
219
+ }
220
+ /** Преобразует позицию ползунка thumbTop (0..maxThumbTop) в позицию прокрутки scrollTop (0..maxScrollTop) */
221
+ function mapThumbTopToScrollTop(thumbTop, maxThumbTop, maxScrollTop) {
222
+ const mt = Math.max(1, toSafe(maxThumbTop));
223
+ const ms = Math.max(1, toSafe(maxScrollTop));
224
+ const tt = clamp(toSafe(thumbTop), 0, mt);
225
+ return (tt / mt) * ms;
226
+ }
227
+ /** Ограничивает новую позицию ползунка в пределах 0..maxThumbTop */
228
+ function clampThumbTop(value, maxThumbTop) {
229
+ const mt = Math.max(1, toSafe(maxThumbTop));
230
+ return clamp(toSafe(value), 0, mt);
231
+ }
232
+ function hiddenState(track = 0) {
233
+ return {
234
+ visible: false,
235
+ thumbHeight: 0,
236
+ thumbTop: 0,
237
+ track,
238
+ maxThumbTop: 1,
239
+ maxScrollTop: 1,
240
+ };
241
+ }
242
+ function toSafe(n) {
243
+ return Number.isFinite(n) ? n : 0;
244
+ }
245
+ function clamp(v, min, max) {
246
+ if (v < min)
247
+ return min;
248
+ if (v > max)
249
+ return max;
250
+ return v;
251
+ }
252
+
253
+ class ScrollDirectionDetector {
254
+ el;
255
+ #prevTop = 0;
256
+ #prevLeft = 0;
257
+ constructor(el) {
258
+ this.el = el;
259
+ this.#prevTop = el.scrollTop;
260
+ this.#prevLeft = el.scrollLeft;
261
+ }
262
+ detect() {
263
+ const { scrollTop, scrollLeft } = this.el;
264
+ const deltaX = Math.abs(scrollLeft - this.#prevLeft);
265
+ const deltaY = Math.abs(scrollTop - this.#prevTop);
266
+ this.#prevTop = scrollTop;
267
+ this.#prevLeft = scrollLeft;
268
+ if (deltaX === 0 && deltaY === 0)
269
+ return 'none';
270
+ if (deltaX > deltaY)
271
+ return 'horizontal';
272
+ if (deltaY > deltaX)
273
+ return 'vertical';
274
+ return 'none';
275
+ }
276
+ }
277
+
278
+ function splitSticky(cols) {
279
+ const visible = cols.filter((c) => c.visible !== false);
280
+ const middleIndex = Math.floor(visible.length / 2);
281
+ const left = visible.slice(0, middleIndex).filter((col) => col.sticky);
282
+ const right = visible.slice(middleIndex, visible.length).filter((col) => col.sticky);
283
+ return { left, right, visible };
284
+ }
285
+
286
+ class DataGridVm {
287
+ scrollEl = signal(undefined, ...(ngDevMode ? [{ debugName: "scrollEl" }] : []));
288
+ columns = signal([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
289
+ pinnedRows = signal([], ...(ngDevMode ? [{ debugName: "pinnedRows" }] : []));
290
+ containerWidth = signal(0, ...(ngDevMode ? [{ debugName: "containerWidth" }] : []));
291
+ scrollbarVisible = signal(false, ...(ngDevMode ? [{ debugName: "scrollbarVisible" }] : []));
292
+ thumbHeightPx = signal(0, ...(ngDevMode ? [{ debugName: "thumbHeightPx" }] : []));
293
+ thumbTopPx = signal(0, ...(ngDevMode ? [{ debugName: "thumbTopPx" }] : []));
294
+ dragging = false;
295
+ globalTypeCellTpls = new Map();
296
+ #byKey = signal({}, ...(ngDevMode ? [{ debugName: "#byKey" }] : []));
297
+ #defaultColWidth = 140;
298
+ #stickyLeftMap = new Map();
299
+ #stickyRightMap = new Map();
300
+ columnsToShow = computed(() => {
301
+ this.containerWidth();
302
+ const cols = this.columns() ?? [];
303
+ const { left, visible, right } = splitSticky(cols);
304
+ this.recomputeStickyOffsets(left, right);
305
+ return visible;
306
+ }, ...(ngDevMode ? [{ debugName: "columnsToShow" }] : []));
307
+ pinnedTop = computed(() => (this.pinnedRows() ?? []).filter((r) => r.position === 'top').sort((a, b) => (a.order ?? 0) - (b.order ?? 0)), ...(ngDevMode ? [{ debugName: "pinnedTop" }] : []));
308
+ pinnedBottom = computed(() => (this.pinnedRows() ?? []).filter((r) => r.position === 'bottom').sort((a, b) => (a.order ?? 0) - (b.order ?? 0)), ...(ngDevMode ? [{ debugName: "pinnedBottom" }] : []));
309
+ constructor() {
310
+ effect(() => {
311
+ const cols = this.columns();
312
+ const width = this.containerWidth();
313
+ if (!cols.length || !width) {
314
+ return;
315
+ }
316
+ const res = layoutColumns(cols, width, this.#defaultColWidth);
317
+ this.#byKey.set(res.byKey);
318
+ });
319
+ }
320
+ widthByKey = (key) => this.#byKey()[key] ?? this.#defaultColWidth;
321
+ isStickyLeft = (key) => this.#stickyLeftMap.has(key);
322
+ isStickyRight = (key) => this.#stickyRightMap.has(key);
323
+ stickyOffset = (key, dir) => dir === 'left' && this.isStickyLeft(key)
324
+ ? (this.#stickyLeftMap.get(key) ?? null)
325
+ : dir === 'right' && this.isStickyRight(key)
326
+ ? (this.#stickyRightMap.get(key) ?? null)
327
+ : null;
328
+ calcScrollbar() {
329
+ const el = this.scrollEl()?.nativeElement;
330
+ if (!el)
331
+ return;
332
+ const state = computeScrollbarState(el.scrollHeight, el.clientHeight, el.scrollTop);
333
+ if (!state.visible) {
334
+ this.scrollbarVisible.set(false);
335
+ this.thumbHeightPx.set(0);
336
+ this.thumbTopPx.set(0);
337
+ return;
338
+ }
339
+ this.thumbHeightPx.set(state.thumbHeight);
340
+ this.thumbTopPx.set(state.thumbTop);
341
+ }
342
+ recomputeStickyOffsets(leftCols, rightCols) {
343
+ let acc = 0;
344
+ this.#stickyLeftMap.clear();
345
+ for (const col of leftCols) {
346
+ this.#stickyLeftMap.set(col.key, acc);
347
+ acc += this.widthByKey(col.key);
348
+ }
349
+ acc = 0;
350
+ this.#stickyRightMap.clear();
351
+ for (let i = rightCols.length - 1; i >= 0; i--) {
352
+ const col = rightCols[i];
353
+ this.#stickyRightMap.set(col.key, acc);
354
+ acc += this.widthByKey(col.key);
355
+ }
356
+ }
357
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridVm, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
358
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridVm });
359
+ }
360
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridVm, decorators: [{
361
+ type: Injectable
362
+ }], ctorParameters: () => [] });
363
+
364
+ class DataGridCellComponent {
365
+ index = input.required(...(ngDevMode ? [{ debugName: "index" }] : []));
366
+ item = input.required(...(ngDevMode ? [{ debugName: "item" }] : []));
367
+ column = input.required(...(ngDevMode ? [{ debugName: "column" }] : []));
368
+ vm = inject(DataGridVm);
369
+ type = computed(() => {
370
+ const col = this.column();
371
+ if ('renderTemplate' in col) {
372
+ return 'tpl';
373
+ }
374
+ if ('type' in col && this.vm.globalTypeCellTpls.has(col.type)) {
375
+ return 'globalTypeTpl';
376
+ }
377
+ return 'type' in col ? col['type'] : 'plain';
378
+ }, ...(ngDevMode ? [{ debugName: "type" }] : []));
379
+ value = computed(() => {
380
+ const col = this.column();
381
+ const row = this.item();
382
+ return 'value' in col ? col.value(row) : row[col.key];
383
+ }, ...(ngDevMode ? [{ debugName: "value" }] : []));
384
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
385
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", 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 }, column: { classPropertyName: "column", publicName: "column", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
386
+ @let row = item();
387
+ @let col = column();
388
+ @let val = value();
389
+
390
+ @switch (type()) {
391
+ @case ('tpl') {
392
+ <ng-container
393
+ [ngTemplateOutlet]="$any(col).renderTemplate"
394
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index }"
395
+ />
396
+ }
397
+ @case ('globalTypeTpl') {
398
+ <ng-container
399
+ [ngTemplateOutlet]="vm.globalTypeCellTpls.get($any(col).type)"
400
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col }"
401
+ />
402
+ }
403
+ @case ('date') {
404
+ {{ val | date }}
405
+ }
406
+ @case ('number') {
407
+ {{ val | number }}
408
+ }
409
+ @case ('index') {
410
+ {{ index() + 1 }}
411
+ }
412
+ @default {
413
+ {{ val }}
414
+ }
415
+ }
416
+ `, isInline: true, styles: [":host{width:100%;text-align:inherit}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: DecimalPipe, name: "number" }] });
417
+ }
418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGridCellComponent, decorators: [{
419
+ type: Component,
420
+ args: [{ selector: 're-data-grid-cell', template: `
421
+ @let row = item();
422
+ @let col = column();
423
+ @let val = value();
424
+
425
+ @switch (type()) {
426
+ @case ('tpl') {
427
+ <ng-container
428
+ [ngTemplateOutlet]="$any(col).renderTemplate"
429
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col, index }"
430
+ />
431
+ }
432
+ @case ('globalTypeTpl') {
433
+ <ng-container
434
+ [ngTemplateOutlet]="vm.globalTypeCellTpls.get($any(col).type)"
435
+ [ngTemplateOutletContext]="{ $implicit: val, value: val, row, col }"
436
+ />
437
+ }
438
+ @case ('date') {
439
+ {{ val | date }}
440
+ }
441
+ @case ('number') {
442
+ {{ val | number }}
443
+ }
444
+ @case ('index') {
445
+ {{ index() + 1 }}
446
+ }
447
+ @default {
448
+ {{ val }}
449
+ }
450
+ }
451
+ `, imports: [NgTemplateOutlet, DatePipe, DecimalPipe], styles: [":host{width:100%;text-align:inherit}\n"] }]
452
+ }], propDecorators: { index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: true }] }], item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: true }] }], column: [{ type: i0.Input, args: [{ isSignal: true, alias: "column", required: true }] }] } });
453
+
454
+ class Selector {
455
+ data = signal([], ...(ngDevMode ? [{ debugName: "data" }] : []));
456
+ selection = signal({ mode: 'none' }, ...(ngDevMode ? [{ debugName: "selection" }] : []));
457
+ selectedKeys = signal([], ...(ngDevMode ? [{ debugName: "selectedKeys" }] : []));
458
+ isAllSelected = computed(() => {
459
+ const selectedCount = this.selectedKeys().length;
460
+ return selectedCount === this.data().length ? true : selectedCount === 0 ? false : 'mixed';
461
+ }, ...(ngDevMode ? [{ debugName: "isAllSelected" }] : []));
462
+ isSelected(row) {
463
+ const selection = this.selection();
464
+ const selected = this.selectedKeys();
465
+ return 'key' in selection ? selected.includes(row[selection.key]) : false;
466
+ }
467
+ selectAll() {
468
+ if (this.selection().mode !== 'multi') {
469
+ throw new Error('Cannot select all in not "multi" mode');
470
+ }
471
+ const selection = this.selection();
472
+ const state = this.isAllSelected();
473
+ const nextState = state === false || state === 'mixed';
474
+ this.selectedKeys.set(!nextState ? [] : this.data().map((row) => row[selection.key]));
475
+ return this.selectedKeys();
476
+ }
477
+ select(row) {
478
+ if (this.selection().mode === 'none') {
479
+ throw new Error('Cannot select row in "none" mode');
480
+ }
481
+ const selection = this.selection();
482
+ if (this.selection().mode === 'single') {
483
+ const selected = [row[selection.key]];
484
+ this.selectedKeys.set(selected);
485
+ return selected;
486
+ }
487
+ else {
488
+ const selectedKeys = this.selectedKeys();
489
+ const has = selectedKeys.some((it) => it === row[selection.key]);
490
+ const selected = has
491
+ ? selectedKeys.filter((it) => it !== row[selection.key])
492
+ : [...selectedKeys, row[selection.key]];
493
+ this.selectedKeys.set(selected);
494
+ return selected;
495
+ }
496
+ }
497
+ }
498
+
499
+ // noinspection CssUnresolvedCustomProperty
500
+ class CheckboxIcon {
501
+ state = input(false, ...(ngDevMode ? [{ debugName: "state" }] : []));
502
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
503
+ boxRef = viewChild((ElementRef), ...(ngDevMode ? [{ debugName: "boxRef" }] : []));
504
+ constructor() {
505
+ effect(() => {
506
+ const el = this.boxRef()?.nativeElement;
507
+ if (!el) {
508
+ return;
509
+ }
510
+ const state = this.state();
511
+ if (state === 'mixed') {
512
+ el.indeterminate = true;
513
+ el.checked = false;
514
+ el.dataset.indeterminate = 'true';
515
+ }
516
+ else if (state) {
517
+ el.indeterminate = false;
518
+ el.checked = true;
519
+ el.dataset.indeterminate = 'false';
520
+ }
521
+ else {
522
+ el.indeterminate = false;
523
+ el.checked = false;
524
+ el.dataset.indeterminate = 'false';
525
+ }
526
+ });
527
+ }
528
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: CheckboxIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
529
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.3", 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 } }, viewQueries: [{ propertyName: "boxRef", first: true, predicate: (ElementRef), descendants: true, isSignal: true }], ngImport: i0, template: `
530
+ <label class="cb" [class.cb--disabled]="disabled()">
531
+ <input
532
+ #box
533
+ class="cb__input"
534
+ type="checkbox"
535
+ aria-hidden="true"
536
+ [disabled]="disabled()"
537
+ [checked]="state() === true"
538
+ [attr.data-indeterminate]="state() === 'mixed' ? 'true' : 'false'"
539
+ (click)="$event.stopPropagation()"
540
+ />
541
+ <span class="cb__box" aria-hidden="true"></span>
542
+ </label>
543
+ `, 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__input{position:absolute;width:0;height:0;opacity:0;pointer-events:none}.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__input:checked+.cb__box{border-color:var(--re-data-grid-checkbox-active-color);background:var(--re-data-grid-checkbox-active-color)}.cb__input: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__input[data-indeterminate=true]+.cb__box{background:var(--re-data-grid-checkbox-active-color);border-color:var(--re-data-grid-checkbox-active-color)}.cb__input[data-indeterminate=true]+.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 });
544
+ }
545
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: CheckboxIcon, decorators: [{
546
+ type: Component,
547
+ args: [{ selector: 're-checkbox-ic', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: `
548
+ <label class="cb" [class.cb--disabled]="disabled()">
549
+ <input
550
+ #box
551
+ class="cb__input"
552
+ type="checkbox"
553
+ aria-hidden="true"
554
+ [disabled]="disabled()"
555
+ [checked]="state() === true"
556
+ [attr.data-indeterminate]="state() === 'mixed' ? 'true' : 'false'"
557
+ (click)="$event.stopPropagation()"
558
+ />
559
+ <span class="cb__box" aria-hidden="true"></span>
560
+ </label>
561
+ `, 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__input{position:absolute;width:0;height:0;opacity:0;pointer-events:none}.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__input:checked+.cb__box{border-color:var(--re-data-grid-checkbox-active-color);background:var(--re-data-grid-checkbox-active-color)}.cb__input: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__input[data-indeterminate=true]+.cb__box{background:var(--re-data-grid-checkbox-active-color);border-color:var(--re-data-grid-checkbox-active-color)}.cb__input[data-indeterminate=true]+.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"] }]
562
+ }], ctorParameters: () => [], propDecorators: { state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], boxRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ElementRef), { isSignal: true }] }] } });
563
+
564
+ /* eslint-disable max-len */
565
+ class ExpandIcon {
566
+ expanded = input(false, { ...(ngDevMode ? { debugName: "expanded" } : {}), transform: booleanAttribute });
567
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ExpandIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
568
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ExpandIcon, isStandalone: true, selector: "re-expand-ic", inputs: { expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
569
+ @if (expanded()) {
570
+ <svg width="16" height="16" viewBox="0 0 16 16">
571
+ <path
572
+ d="M15.5 8C15.5 9.48336 15.0601 10.9334 14.236 12.1668C13.4119 13.4001 12.2406 14.3614 10.8701 14.9291C9.49968 15.4968 7.99168 15.6453 6.53683 15.3559C5.08197 15.0665 3.7456 14.3522 2.6967 13.3033C1.64781 12.2544 0.933503 10.918 0.644114 9.46318C0.354725 8.00832 0.50325 6.50032 1.07091 5.12987C1.63856 3.75943 2.59986 2.58809 3.83323 1.76398C5.0666 0.939867 6.51664 0.5 8 0.5C8.98492 0.5 9.96019 0.693993 10.8701 1.0709C11.7801 1.44781 12.6069 2.00026 13.3033 2.6967C13.9997 3.39314 14.5522 4.21993 14.9291 5.12987C15.306 6.03982 15.5 7.01509 15.5 8ZM12.5 8C12.5 7.80109 12.421 7.61032 12.2803 7.46967C12.1397 7.32902 11.9489 7.25 11.75 7.25H4.25C4.05109 7.25 3.86033 7.32902 3.71967 7.46967C3.57902 7.61032 3.5 7.80109 3.5 8C3.5 8.19891 3.57902 8.38968 3.71967 8.53033C3.86033 8.67098 4.05109 8.75 4.25 8.75H11.75C11.9489 8.75 12.1397 8.67098 12.2803 8.53033C12.421 8.38968 12.5 8.19891 12.5 8Z"
573
+ fill="var(--re-data-grid-expander-color)"
574
+ />
575
+ </svg>
576
+ } @else {
577
+ <svg width="16" height="16" viewBox="0 0 16 16">
578
+ <path
579
+ d="M8 0.5C6.51664 0.5 5.0666 0.939867 3.83323 1.76398C2.59986 2.58809 1.63856 3.75943 1.07091 5.12987C0.50325 6.50032 0.354725 8.00832 0.644114 9.46318C0.933503 10.918 1.64781 12.2544 2.6967 13.3033C3.7456 14.3522 5.08197 15.0665 6.53683 15.3559C7.99168 15.6453 9.49968 15.4968 10.8701 14.9291C12.2406 14.3614 13.4119 13.4001 14.236 12.1668C15.0601 10.9334 15.5 9.48336 15.5 8C15.5 7.01509 15.306 6.03982 14.9291 5.12987C14.5522 4.21993 13.9997 3.39314 13.3033 2.6967C12.6069 2.00026 11.7801 1.44781 10.8701 1.0709C9.96019 0.693993 8.98492 0.5 8 0.5ZM11.75 8.75H8.75V11.75C8.75 11.9489 8.67099 12.1397 8.53033 12.2803C8.38968 12.421 8.19892 12.5 8 12.5C7.80109 12.5 7.61033 12.421 7.46967 12.2803C7.32902 12.1397 7.25 11.9489 7.25 11.75V8.75H4.25C4.05109 8.75 3.86033 8.67098 3.71967 8.53033C3.57902 8.38968 3.5 8.19891 3.5 8C3.5 7.80109 3.57902 7.61032 3.71967 7.46967C3.86033 7.32902 4.05109 7.25 4.25 7.25H7.25V4.25C7.25 4.05109 7.32902 3.86032 7.46967 3.71967C7.61033 3.57902 7.80109 3.5 8 3.5C8.19892 3.5 8.38968 3.57902 8.53033 3.71967C8.67099 3.86032 8.75 4.05109 8.75 4.25V7.25H11.75C11.9489 7.25 12.1397 7.32902 12.2803 7.46967C12.421 7.61032 12.5 7.80109 12.5 8C12.5 8.19891 12.421 8.38968 12.2803 8.53033C12.1397 8.67098 11.9489 8.75 11.75 8.75Z"
580
+ fill="var(--re-data-grid-expander-color)"
581
+ />
582
+ </svg>
583
+ }
584
+ `, isInline: true, styles: [""] });
585
+ }
586
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ExpandIcon, decorators: [{
587
+ type: Component,
588
+ args: [{ selector: 're-expand-ic', template: `
589
+ @if (expanded()) {
590
+ <svg width="16" height="16" viewBox="0 0 16 16">
591
+ <path
592
+ d="M15.5 8C15.5 9.48336 15.0601 10.9334 14.236 12.1668C13.4119 13.4001 12.2406 14.3614 10.8701 14.9291C9.49968 15.4968 7.99168 15.6453 6.53683 15.3559C5.08197 15.0665 3.7456 14.3522 2.6967 13.3033C1.64781 12.2544 0.933503 10.918 0.644114 9.46318C0.354725 8.00832 0.50325 6.50032 1.07091 5.12987C1.63856 3.75943 2.59986 2.58809 3.83323 1.76398C5.0666 0.939867 6.51664 0.5 8 0.5C8.98492 0.5 9.96019 0.693993 10.8701 1.0709C11.7801 1.44781 12.6069 2.00026 13.3033 2.6967C13.9997 3.39314 14.5522 4.21993 14.9291 5.12987C15.306 6.03982 15.5 7.01509 15.5 8ZM12.5 8C12.5 7.80109 12.421 7.61032 12.2803 7.46967C12.1397 7.32902 11.9489 7.25 11.75 7.25H4.25C4.05109 7.25 3.86033 7.32902 3.71967 7.46967C3.57902 7.61032 3.5 7.80109 3.5 8C3.5 8.19891 3.57902 8.38968 3.71967 8.53033C3.86033 8.67098 4.05109 8.75 4.25 8.75H11.75C11.9489 8.75 12.1397 8.67098 12.2803 8.53033C12.421 8.38968 12.5 8.19891 12.5 8Z"
593
+ fill="var(--re-data-grid-expander-color)"
594
+ />
595
+ </svg>
596
+ } @else {
597
+ <svg width="16" height="16" viewBox="0 0 16 16">
598
+ <path
599
+ d="M8 0.5C6.51664 0.5 5.0666 0.939867 3.83323 1.76398C2.59986 2.58809 1.63856 3.75943 1.07091 5.12987C0.50325 6.50032 0.354725 8.00832 0.644114 9.46318C0.933503 10.918 1.64781 12.2544 2.6967 13.3033C3.7456 14.3522 5.08197 15.0665 6.53683 15.3559C7.99168 15.6453 9.49968 15.4968 10.8701 14.9291C12.2406 14.3614 13.4119 13.4001 14.236 12.1668C15.0601 10.9334 15.5 9.48336 15.5 8C15.5 7.01509 15.306 6.03982 14.9291 5.12987C14.5522 4.21993 13.9997 3.39314 13.3033 2.6967C12.6069 2.00026 11.7801 1.44781 10.8701 1.0709C9.96019 0.693993 8.98492 0.5 8 0.5ZM11.75 8.75H8.75V11.75C8.75 11.9489 8.67099 12.1397 8.53033 12.2803C8.38968 12.421 8.19892 12.5 8 12.5C7.80109 12.5 7.61033 12.421 7.46967 12.2803C7.32902 12.1397 7.25 11.9489 7.25 11.75V8.75H4.25C4.05109 8.75 3.86033 8.67098 3.71967 8.53033C3.57902 8.38968 3.5 8.19891 3.5 8C3.5 7.80109 3.57902 7.61032 3.71967 7.46967C3.86033 7.32902 4.05109 7.25 4.25 7.25H7.25V4.25C7.25 4.05109 7.32902 3.86032 7.46967 3.71967C7.61033 3.57902 7.80109 3.5 8 3.5C8.19892 3.5 8.38968 3.57902 8.53033 3.71967C8.67099 3.86032 8.75 4.05109 8.75 4.25V7.25H11.75C11.9489 7.25 12.1397 7.32902 12.2803 7.46967C12.421 7.61032 12.5 7.80109 12.5 8C12.5 8.19891 12.421 8.38968 12.2803 8.53033C12.1397 8.67098 11.9489 8.75 11.75 8.75Z"
600
+ fill="var(--re-data-grid-expander-color)"
601
+ />
602
+ </svg>
603
+ }
604
+ ` }]
605
+ }], propDecorators: { expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }] } });
606
+
607
+ /* eslint-disable max-len */
608
+ class SortIcon {
609
+ direction = input('asc', ...(ngDevMode ? [{ debugName: "direction" }] : []));
610
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SortIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
611
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.3", type: SortIcon, isStandalone: true, selector: "re-sort-ic", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
612
+ <svg width="18" height="18" viewBox="0 0 18 18" class="{{ direction() }}">
613
+ <path
614
+ d="M12.84 8.51259L9.66754 11.6851V4.59009C9.66754 4.39118 9.58852 4.20041 9.44787 4.05976C9.30722 3.91911 9.11645 3.84009 8.91754 3.84009C8.71863 3.84009 8.52786 3.91911 8.38721 4.05976C8.24656 4.20041 8.16754 4.39118 8.16754 4.59009V11.6851L4.99504 8.51259C4.92511 8.44266 4.84209 8.38719 4.75073 8.34934C4.65936 8.3115 4.56144 8.29202 4.46254 8.29202C4.36365 8.29202 4.26572 8.3115 4.17435 8.34934C4.08299 8.38719 3.99997 8.44266 3.93004 8.51259C3.86011 8.58252 3.80464 8.66553 3.7668 8.7569C3.72895 8.84827 3.70947 8.94619 3.70947 9.04509C3.70947 9.14398 3.72895 9.24191 3.7668 9.33327C3.80464 9.42464 3.86011 9.50766 3.93004 9.57759L8.38504 14.0251C8.45349 14.0952 8.53503 14.1513 8.62504 14.1901C8.71842 14.2256 8.81762 14.2435 8.91754 14.2426C9.01505 14.2438 9.11186 14.226 9.20254 14.1901C9.29255 14.1513 9.37409 14.0952 9.44254 14.0251L13.8975 9.57759C13.9678 9.50787 14.0236 9.42491 14.0617 9.33352C14.0998 9.24213 14.1194 9.1441 14.1194 9.04509C14.1194 8.94608 14.0998 8.84805 14.0617 8.75666C14.0236 8.66526 13.9678 8.58231 13.8975 8.51259C13.757 8.3729 13.5669 8.29449 13.3688 8.29449C13.1707 8.29449 12.9806 8.3729 12.84 8.51259Z"
615
+ fill="currentColor"
616
+ />
617
+ </svg>
618
+ `, isInline: true, styles: ["svg{transition:transform .3s ease-in-out}svg:not(.asc):not(.desc){display:none}.asc{transform:rotate(-180deg)}.desc{transform:rotate(0)}\n"] });
619
+ }
620
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: SortIcon, decorators: [{
621
+ type: Component,
622
+ args: [{ selector: 're-sort-ic', template: `
623
+ <svg width="18" height="18" viewBox="0 0 18 18" class="{{ direction() }}">
624
+ <path
625
+ d="M12.84 8.51259L9.66754 11.6851V4.59009C9.66754 4.39118 9.58852 4.20041 9.44787 4.05976C9.30722 3.91911 9.11645 3.84009 8.91754 3.84009C8.71863 3.84009 8.52786 3.91911 8.38721 4.05976C8.24656 4.20041 8.16754 4.39118 8.16754 4.59009V11.6851L4.99504 8.51259C4.92511 8.44266 4.84209 8.38719 4.75073 8.34934C4.65936 8.3115 4.56144 8.29202 4.46254 8.29202C4.36365 8.29202 4.26572 8.3115 4.17435 8.34934C4.08299 8.38719 3.99997 8.44266 3.93004 8.51259C3.86011 8.58252 3.80464 8.66553 3.7668 8.7569C3.72895 8.84827 3.70947 8.94619 3.70947 9.04509C3.70947 9.14398 3.72895 9.24191 3.7668 9.33327C3.80464 9.42464 3.86011 9.50766 3.93004 9.57759L8.38504 14.0251C8.45349 14.0952 8.53503 14.1513 8.62504 14.1901C8.71842 14.2256 8.81762 14.2435 8.91754 14.2426C9.01505 14.2438 9.11186 14.226 9.20254 14.1901C9.29255 14.1513 9.37409 14.0952 9.44254 14.0251L13.8975 9.57759C13.9678 9.50787 14.0236 9.42491 14.0617 9.33352C14.0998 9.24213 14.1194 9.1441 14.1194 9.04509C14.1194 8.94608 14.0998 8.84805 14.0617 8.75666C14.0236 8.66526 13.9678 8.58231 13.8975 8.51259C13.757 8.3729 13.5669 8.29449 13.3688 8.29449C13.1707 8.29449 12.9806 8.3729 12.84 8.51259Z"
626
+ fill="currentColor"
627
+ />
628
+ </svg>
629
+ `, styles: ["svg{transition:transform .3s ease-in-out}svg:not(.asc):not(.desc){display:none}.asc{transform:rotate(-180deg)}.desc{transform:rotate(0)}\n"] }]
630
+ }], propDecorators: { direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }] } });
631
+
632
+ class DataGrid {
633
+ /** Массив данных для отображения в таблице */
634
+ data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
635
+ /** Конфигурация колонок таблицы */
636
+ columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
637
+ /** Режим пагинации: 'none', 'pagination' или 'infinity' */
638
+ mode = input('none', ...(ngDevMode ? [{ debugName: "mode" }] : []));
639
+ /** Массив закрепленных строк */
640
+ pinnedRows = input([], ...(ngDevMode ? [{ debugName: "pinnedRows" }] : []));
641
+ /** Добавить ли номерную колонку */
642
+ hasIndexColumn = input(false, { ...(ngDevMode ? { debugName: "hasIndexColumn" } : {}), transform: booleanAttribute });
643
+ /** Поддержка выбора строк */
644
+ selection = input({ mode: 'none' }, ...(ngDevMode ? [{ debugName: "selection" }] : []));
645
+ /** Количество элементов на странице */
646
+ pageSize = input(20, { ...(ngDevMode ? { debugName: "pageSize" } : {}), transform: numberAttribute });
647
+ /** Высота строки в пикселях */
648
+ rowHeight = input(40, { ...(ngDevMode ? { debugName: "rowHeight" } : {}), transform: numberAttribute });
649
+ /** Заполнять ли доступную высоту */
650
+ fillHeight = input(true, { ...(ngDevMode ? { debugName: "fillHeight" } : {}), transform: booleanAttribute });
651
+ /** Размер буфера виртуального скролла */
652
+ virtualBuffer = input(6, ...(ngDevMode ? [{ debugName: "virtualBuffer" }] : []));
653
+ /** Состояние загрузки данных */
654
+ loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : {}), transform: booleanAttribute });
655
+ /** Функция или имя свойства для получения уникального ключа строки */
656
+ rowKey = input(undefined, ...(ngDevMode ? [{ debugName: "rowKey" }] : []));
657
+ /** Начинать отсчёт пагинации с 1 (false) или 0 (true) */
658
+ pageStartFromZero = input(true, { ...(ngDevMode ? { debugName: "pageStartFromZero" } : {}), transform: booleanAttribute });
659
+ /** Событие запроса данных */
660
+ pageChange = output();
661
+ /** Событие изменения сортировки */
662
+ sortChange = output();
663
+ /** Событие изменения выбранных строк */
664
+ selectChange = output();
665
+ /** Событие клика по строке */
666
+ rowClick = output();
667
+ /** Событие клика по ячейке */
668
+ cellClick = output();
669
+ vm = inject((DataGridVm));
670
+ selector = new Selector();
671
+ rootEl = viewChild('root', ...(ngDevMode ? [{ debugName: "rootEl" }] : []));
672
+ scrollEl = viewChild('scroll', ...(ngDevMode ? [{ debugName: "scrollEl" }] : []));
673
+ headerEl = viewChild('header', ...(ngDevMode ? [{ debugName: "headerEl" }] : []));
674
+ cellSlotRefs = contentChildren(DataGridTypeCellTemplateDirective, ...(ngDevMode ? [{ debugName: "cellSlotRefs" }] : []));
675
+ headerSlotRefs = contentChildren(DataGridHeaderTemplateDirective, ...(ngDevMode ? [{ debugName: "headerSlotRefs" }] : []));
676
+ emptySlotRefs = contentChildren(DataGridCellEmptyDirective, ...(ngDevMode ? [{ debugName: "emptySlotRefs" }] : []));
677
+ loadingSlotRefs = contentChildren(DataGridCellLoadingDirective, ...(ngDevMode ? [{ debugName: "loadingSlotRefs" }] : []));
678
+ emptyTpl = computed(() => this.emptySlotRefs()?.[0], ...(ngDevMode ? [{ debugName: "emptyTpl" }] : []));
679
+ loadingTpl = computed(() => this.loadingSlotRefs()?.[0], ...(ngDevMode ? [{ debugName: "loadingTpl" }] : []));
680
+ visibleRows = signal([], ...(ngDevMode ? [{ debugName: "visibleRows" }] : []));
681
+ startIndex = 0;
682
+ headerHeight = signal(40, ...(ngDevMode ? [{ debugName: "headerHeight" }] : []));
683
+ expanderMap = signal(new Map(), ...(ngDevMode ? [{ debugName: "expanderMap" }] : []));
684
+ extendedColumns = computed(() => {
685
+ const hasSelection = this.selection().mode !== 'none';
686
+ const hasIndex = this.hasIndexColumn();
687
+ const newColumns = [];
688
+ hasSelection && newColumns.push(GRID_CHECKBOX_COLUMN);
689
+ hasIndex && newColumns.push(GRID_INDEX_COLUMN);
690
+ return [...newColumns, ...this.columns()];
691
+ }, ...(ngDevMode ? [{ debugName: "extendedColumns" }] : []));
692
+ hideSbTimeout;
693
+ currentSortField;
694
+ currentSortOrder = 'asc';
695
+ subscription = new Subscription();
696
+ observer;
697
+ constructor() {
698
+ afterRenderEffect(() => {
699
+ this.initRefs();
700
+ this.initHeader();
701
+ this.initScroll();
702
+ this.initObserver();
703
+ });
704
+ afterRenderEffect(() => this.initSelector());
705
+ afterRenderEffect(() => {
706
+ this.initVm();
707
+ this.initSort();
708
+ this.initExpander();
709
+ });
710
+ effect(() => {
711
+ this.data();
712
+ this.rowHeight();
713
+ this.pinnedRows();
714
+ this.vm.containerWidth();
715
+ this.onVerticalScroll(true);
716
+ });
717
+ effect(() => {
718
+ const selection = this.selection();
719
+ if ('defaultSelected' in selection) {
720
+ this.selector.selectedKeys.set(selection.defaultSelected || []);
721
+ }
722
+ });
723
+ inject(DestroyRef).onDestroy(() => {
724
+ this.subscription.unsubscribe();
725
+ this.observer?.disconnect();
726
+ clearTimeout(this.hideSbTimeout);
727
+ });
728
+ }
729
+ get styleHeight() {
730
+ return this.fillHeight() ? null : 'auto';
731
+ }
732
+ resolvePinnedData(pr) {
733
+ return typeof pr.data === 'function' ? pr.data() : pr.data;
734
+ }
735
+ onSort(col) {
736
+ if (!col.sortKey) {
737
+ return;
738
+ }
739
+ if (this.currentSortField === col.sortKey) {
740
+ this.currentSortOrder = this.currentSortOrder === 'asc' ? 'desc' : 'asc';
741
+ }
742
+ else {
743
+ this.currentSortField = col.sortKey;
744
+ this.currentSortOrder = 'asc';
745
+ }
746
+ this.sortChange.emit({ key: this.currentSortField, order: this.currentSortOrder });
747
+ }
748
+ onCellClick(row, col, index) {
749
+ this.cellClick.emit({ row, col, index });
750
+ if (this.selection().mode !== 'none') {
751
+ const selected = this.selector.select(row);
752
+ this.selectChange.emit({ selected });
753
+ }
754
+ }
755
+ isExpandable(column) {
756
+ const keys = this.expanderMap();
757
+ return keys.has(column.key);
758
+ }
759
+ onExpand(column) {
760
+ const expanded = !this.expanderMap().get(column.key);
761
+ this.expanderMap.update((prev) => {
762
+ const map = new Map(prev);
763
+ map.set(column.key, expanded);
764
+ return map;
765
+ });
766
+ const columns = this.extendedColumns().map((col) => col.expandBy === column.key ? { ...col, visible: expanded } : col);
767
+ this.vm.columns.set(columns);
768
+ }
769
+ onVerticalScroll(initial = false) {
770
+ const el = this.scrollEl()?.nativeElement;
771
+ if (!el)
772
+ return;
773
+ const scrollTop = el.scrollTop ?? 0;
774
+ const viewportHeight = el.clientHeight ?? 0;
775
+ const data = this.data() ?? [];
776
+ const total = data.length ?? 0;
777
+ const rowHeight = Math.max(1, this.rowHeight());
778
+ const virtualBuffer = Math.max(0, this.virtualBuffer());
779
+ const limit = this.mode() === 'pagination';
780
+ const cap = limit ? Math.max(1, this.pageSize()) : Number.POSITIVE_INFINITY;
781
+ const viewportRows = Math.ceil(viewportHeight / rowHeight);
782
+ const visibleCount = Math.min(viewportRows + virtualBuffer, cap);
783
+ const start = Math.max(0, Math.floor(scrollTop / rowHeight) - Math.floor(virtualBuffer / 2));
784
+ const end = Math.min(total, start + visibleCount);
785
+ if (!el || viewportHeight <= 0 || !isFinite(viewportHeight) || !isFinite(rowHeight)) {
786
+ this.visibleRows.set(data);
787
+ this.vm.calcScrollbar();
788
+ this.showScrollbar();
789
+ this.hideScrollbarSoon();
790
+ return;
791
+ }
792
+ this.startIndex = start;
793
+ this.visibleRows.set(data.slice(start, end));
794
+ if (!initial && this.mode() === 'infinity') {
795
+ const threshold = Math.max(0, total - Math.max(1, Math.floor(visibleCount * 1.5)));
796
+ const nearEnd = start + visibleCount >= threshold;
797
+ if (nearEnd && !this.loading()) {
798
+ const modifier = this.pageStartFromZero() ? 0 : 1;
799
+ const page = Math.floor(total / this.pageSize()) + modifier;
800
+ this.pageChange.emit({ page, rows: this.pageSize() });
801
+ }
802
+ }
803
+ this.vm.calcScrollbar();
804
+ this.showScrollbar();
805
+ this.hideScrollbarSoon();
806
+ }
807
+ onHorizontalScroll() { }
808
+ onThumbDown(e) {
809
+ e.preventDefault();
810
+ e.stopPropagation();
811
+ const el = this.scrollEl()?.nativeElement;
812
+ if (!el)
813
+ return;
814
+ this.vm.dragging = true;
815
+ this.showScrollbar();
816
+ const startY = e.clientY;
817
+ const startTop = this.vm.thumbTopPx();
818
+ const state = computeScrollbarState(el.scrollHeight || 1, el.clientHeight || 1, el.scrollTop || 0);
819
+ const maxThumbTop = state.maxThumbTop || 1;
820
+ const maxScrollTop = state.maxScrollTop || 1;
821
+ const onMove = (ev) => {
822
+ const delta = ev.clientY - startY;
823
+ const newTop = clampThumbTop(startTop + delta, maxThumbTop);
824
+ this.vm.thumbTopPx.set(newTop);
825
+ el.scrollTop = mapThumbTopToScrollTop(newTop, maxThumbTop, maxScrollTop);
826
+ this.vm.calcScrollbar();
827
+ this.showScrollbar();
828
+ };
829
+ const onUp = () => {
830
+ window.removeEventListener('mousemove', onMove);
831
+ window.removeEventListener('mouseup', onUp);
832
+ this.vm.dragging = false;
833
+ this.hideScrollbarSoon();
834
+ };
835
+ window.addEventListener('mousemove', onMove);
836
+ window.addEventListener('mouseup', onUp);
837
+ }
838
+ showScrollbar() {
839
+ this.vm.scrollbarVisible.set(true);
840
+ clearTimeout(this.hideSbTimeout);
841
+ }
842
+ hideScrollbarSoon(delay = 1200) {
843
+ if (this.vm.dragging) {
844
+ return;
845
+ }
846
+ clearTimeout(this.hideSbTimeout);
847
+ this.hideSbTimeout = setTimeout(() => this.vm.scrollbarVisible.set(false), delay);
848
+ }
849
+ // todo
850
+ trackPinnedRow = (row) => row.order;
851
+ trackByRow = (row) => {
852
+ const rowKey = this.rowKey();
853
+ if (!rowKey) {
854
+ return row;
855
+ }
856
+ return typeof rowKey === 'function' ? rowKey(row) : row[rowKey];
857
+ };
858
+ cellClass(col, row) {
859
+ if (typeof col.cellClass === 'function') {
860
+ return col.cellClass(row);
861
+ }
862
+ return col.cellClass;
863
+ }
864
+ ariaSort(col) {
865
+ if (this.currentSortField !== col.sortKey) {
866
+ return 'none';
867
+ }
868
+ return this.currentSortOrder === 'asc' ? 'ascending' : 'descending';
869
+ }
870
+ initVm() {
871
+ this.vm.scrollEl.set(this.scrollEl());
872
+ this.vm.columns.set(this.extendedColumns());
873
+ this.vm.pinnedRows.set(this.pinnedRows());
874
+ }
875
+ initSelector() {
876
+ this.selector.data.set(this.data());
877
+ this.selector.selection.set(this.selection());
878
+ }
879
+ initRefs() {
880
+ this.cellSlotRefs()?.forEach((dir) => this.vm.globalTypeCellTpls.set(dir.type(), dir.tpl));
881
+ const headerMap = new Map();
882
+ this.headerSlotRefs()?.forEach((h) => headerMap.set(h.key(), h.tpl));
883
+ this.extendedColumns()?.forEach((c) => {
884
+ if (!c.headerTemplate && headerMap.has(c.key)) {
885
+ c.headerTemplate = headerMap.get(c.key);
886
+ }
887
+ });
888
+ }
889
+ initSort() {
890
+ const firstSortable = this.extendedColumns()?.find((c) => !!c.sortKey);
891
+ if (firstSortable) {
892
+ this.currentSortField = firstSortable.sortKey;
893
+ this.currentSortOrder = 'asc';
894
+ }
895
+ }
896
+ initHeader() {
897
+ const el = this.headerEl()?.nativeElement;
898
+ if (!el)
899
+ return;
900
+ this.headerHeight.set(el.offsetHeight);
901
+ }
902
+ initScroll() {
903
+ const scrollEl = this.scrollEl()?.nativeElement;
904
+ if (scrollEl) {
905
+ const scrollDetector = new ScrollDirectionDetector(scrollEl);
906
+ this.subscription = fromEvent(scrollEl, 'scroll')
907
+ .pipe(auditTime(16))
908
+ .subscribe(() => {
909
+ const direction = scrollDetector.detect();
910
+ direction === 'vertical' ? this.onVerticalScroll() : this.onHorizontalScroll();
911
+ });
912
+ }
913
+ queueMicrotask(() => this.onVerticalScroll(true));
914
+ }
915
+ initObserver() {
916
+ const root = this.rootEl();
917
+ if (!root)
918
+ return;
919
+ this.observer = new ResizeObserver((entries) => {
920
+ const width = entries[0].contentRect.width;
921
+ this.onVerticalScroll(true);
922
+ this.onHorizontalScroll();
923
+ this.vm.calcScrollbar();
924
+ this.vm.containerWidth.set(width);
925
+ });
926
+ this.observer.observe(root.nativeElement);
927
+ }
928
+ initExpander() {
929
+ const map = new Map();
930
+ const columns = untracked(() => this.vm.columns().map((col) => {
931
+ col.expandBy && map.set(col.expandBy, false);
932
+ return { ...col, visible: col.expandBy ? false : col.visible };
933
+ }));
934
+ this.vm.columns.set(columns);
935
+ this.expanderMap.set(map);
936
+ }
937
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
938
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", 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 }, 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 }, fillHeight: { classPropertyName: "fillHeight", publicName: "fillHeight", isSignal: true, isRequired: false, transformFunction: null }, virtualBuffer: { classPropertyName: "virtualBuffer", publicName: "virtualBuffer", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", 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 } }, outputs: { pageChange: "pageChange", sortChange: "sortChange", selectChange: "selectChange", rowClick: "rowClick", cellClick: "cellClick" }, providers: [DataGridVm], queries: [{ propertyName: "cellSlotRefs", predicate: DataGridTypeCellTemplateDirective, isSignal: true }, { propertyName: "headerSlotRefs", predicate: DataGridHeaderTemplateDirective, isSignal: true }, { propertyName: "emptySlotRefs", predicate: DataGridCellEmptyDirective, isSignal: true }, { propertyName: "loadingSlotRefs", predicate: DataGridCellLoadingDirective, 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 }], ngImport: i0, template: "@let items = data();\n@let empty = !loading() && !items?.length;\n@let notEmpty = !!items?.length;\n\n@let pinnedTopH = vm.pinnedTop().length * rowHeight();\n@let pinnedBottomH = vm.pinnedBottom().length * rowHeight();\n\n<div\n #root\n class=\"re-dg-root\"\n [class.fill]=\"fillHeight()\"\n [class.loading]=\"loading()\"\n [style.height]=\"styleHeight\"\n role=\"table\"\n>\n @if (loading()) {\n <div class=\"re-dg-loader\">\n @let loadingTemplate = loadingTpl();\n\n @if (loadingTemplate?.tpl) {\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\n } @else {\n <span class=\"re-dg-loader-text\">\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u2026</span>\n }\n </div>\n }\n\n <div\n #scroll\n class=\"re-dg-body\"\n role=\"rowgroup\"\n (mouseenter)=\"showScrollbar()\"\n (mouseleave)=\"hideScrollbarSoon()\"\n >\n <div class=\"re-dg-header\" role=\"rowgroup\">\n <div #header class=\"re-dg-row re-dg-header-row\" role=\"row\">\n @for (col of vm.columnsToShow(); track col.key) {\n <div\n class=\"re-dg-header-cell\"\n role=\"columnheader\"\n [class.sortable]=\"!!col.sortKey\"\n [class.active-sort]=\"currentSortField && (currentSortField === col.sortKey)\"\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\n [style.width.px]=\"vm.widthByKey(col.key)\"\n [style.min-width.px]=\"col.minWidth || null\"\n [style.max-width.px]=\"col.maxWidth || null\"\n [style.justify-content]=\"col.align || 'left'\"\n [attr.aria-sort]=\"ariaSort(col)\"\n [attr.tabindex]=\"col.sortKey ? 0 : -1\"\n [title]=\"col.header\"\n (click)=\"col.sortKey && onSort(col)\"\n (keydown.enter)=\"col.sortKey && onSort(col)\"\n >\n {{currentSortField }} {{ col.sortKey}}\n @if (col.headerTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"col.headerTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: col.header }\"\n />\n } @else {\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\n @let isMultiSelect = selection().mode === 'multi';\n\n @if (isCheckbox && isMultiSelect) {\n <re-checkbox-ic mixable [state]=\"selector.isAllSelected()\" (click)=\"selector.selectAll()\" />\n } @else {\n <span class=\"re-dg-header-text\">{{ col.header }}</span>\n }\n\n @if (col.sortKey) {\n <span class=\"re-dg-sort-ind\">\n <re-sort-ic [direction]=\"currentSortField === col.sortKey ? currentSortOrder : 'desc'\" />\n </span>\n }\n\n @if (isExpandable(col)) {\n <button (click)=\"$event.stopPropagation(); onExpand(col)\">\n <re-expand-ic [expanded]=\"expanderMap().get(col.key)\" />\n </button>\n }\n }\n </div>\n }\n </div>\n\n <!-- PINNED TOP ROWS -->\n @if (notEmpty) {\n @for (pr of vm.pinnedTop(); track trackPinnedRow(pr)) {\n <div class=\"re-dg-row re-dg-pinned re-dg-top\" role=\"row\">\n @if (pr.rowTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\n />\n } @else {\n @for (col of vm.columnsToShow(); track col.key) {\n <div\n class=\"re-dg-cell\"\n role=\"cell\"\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\n [style.justify-items]=\"col.align || 'left'\"\n [style.height.px]=\"rowHeight()\"\n [style.width.px]=\"vm.widthByKey(col.key)\"\n >\n {{ resolvePinnedData(pr)[col.key] ?? '' }}\n </div>\n }\n }\n </div>\n }\n }\n </div>\n\n @if (empty) {\n @let emptyTemplate = emptyTpl()?.tpl;\n\n <div class=\"re-dg-empty\">\n @if (emptyTemplate) {\n <ng-container [ngTemplateOutlet]=\"emptyTemplate\" />\n } @else {\n <span class=\"re-dg-empty-text\">\u041D\u0435\u0442 \u0434\u0430\u043D\u043D\u044B\u0445</span>\n }\n </div>\n }\n\n <!-- Content -->\n @if (notEmpty) {\n <div class=\"re-dg-spacer\" [style.height.px]=\"items.length * rowHeight() - pinnedBottomH\"></div>\n\n @for (row of visibleRows(); track trackByRow(row); let vi = $index) {\n <div\n class=\"re-dg-row re-dg-data-row\"\n role=\"row\"\n [style.height.px]=\"rowHeight()\"\n [style.top.px]=\"(startIndex + vi) * rowHeight() + pinnedTopH + headerHeight()\"\n [attr.tabindex]=\"0\"\n (click)=\"$event.stopPropagation(); rowClick.emit({ row, index: startIndex + vi })\"\n (keydown.enter)=\"$event.stopPropagation(); rowClick.emit({ row, index: startIndex + vi })\"\n >\n @for (col of vm.columnsToShow(); track col.key) {\n <div\n class=\"re-dg-cell\"\n role=\"cell\"\n [class]=\"cellClass(col, row)\"\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\n [style.justify-items]=\"col.align || 'left'\"\n [style.text-align]=\"col.align || 'left'\"\n [style.width.px]=\"vm.widthByKey(col.key)\"\n [attr.tabindex]=\"0\"\n (click)=\"onCellClick(row, col, startIndex + vi);\"\n (keydown.enter)=\"onCellClick(row, col, startIndex + vi)\"\n >\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\n\n @if (isCheckbox) {\n <re-checkbox-ic mixable=\"false\" [state]=\"selector.isSelected(row)\" />\n } @else {\n <re-data-grid-cell [index]=\"startIndex + vi\" [item]=\"row\" [column]=\"col\" />\n }\n </div>\n }\n </div>\n }\n }\n\n <!-- PINNED BOTTOM ROWS -->\n @if (notEmpty) {\n <div class=\"re-dg-footer\" role=\"rowgroup\">\n @for (pr of vm.pinnedBottom(); track trackPinnedRow(pr)) {\n <div class=\"re-dg-row re-dg-pinned re-dg-bottom\" role=\"row\">\n @if (pr.rowTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\n />\n } @else {\n @for (col of vm.columnsToShow(); track col.key) {\n <div\n class=\"re-dg-cell\"\n role=\"cell\"\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\n [style.justify-items]=\"col.align || 'left'\"\n [style.height.px]=\"rowHeight()\"\n [style.width.px]=\"vm.widthByKey(col.key)\"\n >\n {{ resolvePinnedData(pr)[col.key] ?? '' }}\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Overlay scrollbar -->\n <div class=\"re-dg-scrollbar\" [class.visible]=\"vm.scrollbarVisible()\">\n <div\n class=\"re-dg-scrollbar-thumb\"\n role=\"scrollbar\"\n aria-orientation=\"vertical\"\n aria-hidden=\"false\"\n [style.height.px]=\"vm.thumbHeightPx()\"\n [style.transform]=\"'translateY(' + vm.thumbTopPx() + 'px)'\"\n (mousedown)=\"onThumbDown($event)\"\n ></div>\n </div>\n</div>\n", styles: [":host{--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: #fff;--re-data-grid-active: #2a90f4;--re-data-grid-empty-color: #777;--re-data-grid-loading-color: #444;--re-data-grid-loading-surface: rgba(255, 255, 255, .5);--re-data-grid-scrollbar-size: 10px;--re-data-grid-scrollbar-offset: 2px;--re-data-grid-scrollbar-thumb-size: 8px;--re-data-grid-scrollbar-thumb-color: rgba(0, 0, 0, .35);--re-data-grid-scrollbar-thumb-rounded: 4px;--re-data-grid-header-height: 40px;--re-data-grid-header-separator-color: #ccc;--re-data-grid-header-separator: 1px solid var(--re-data-grid-header-separator-color);--re-data-grid-header-surface: #fff;--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-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-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-sticky-header-cell-surface: #fff;--re-data-grid-sticky-cell-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)}:host :host,:host *,:host *:before,:host *:after{box-sizing:border-box;outline:none}:host button{outline:none}.re-dg-root{position:relative;display:block;width:100%;height:var(--re-data-grid-height);max-height:var(--re-data-grid-height);border-radius:var(--re-data-grid-rounded);border:var(--re-data-grid-separator)}.re-dg-root.fill{display:flex;flex-direction:column;height:100%}.re-dg-root.loading{pointer-events:none;-webkit-user-select:none;user-select:none;cursor:wait}.re-dg-root.loading .re-dg-body{overflow:hidden}.re-dg-root.loading .re-dg-scrollbar{display:none!important}.re-dg-root.loading .re-dg-loader{pointer-events:all}.re-dg-body{position:relative;flex:1 1 auto;min-width:0;height:var(--re-data-grid-height);border:var(--re-data-grid-separator);border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-surface);overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.re-dg-body::-webkit-scrollbar{width:0;height:0}.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-height)}.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;right:0;cursor:default}.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{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-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{align-items:center;gap:.75rem;border-bottom:var(--re-data-grid-header-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-header-cell:first-child{border-radius:var(--re-data-grid-rounded) 0 0 0}.re-dg-header-cell:last-child{border-radius:0 var(--re-data-grid-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;max-height:2.4em;line-height:1.2;white-space:normal;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}.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)}.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-empty{position:absolute;inset:0;display:flex;place-items:center;color:var(--re-data-grid-empty-color)}.re-dg-empty-text{width:100%;text-align:center}.re-dg-loader{position:absolute;inset:0;top:var(--re-data-grid-header-height);display:grid;place-items:center;background-color:var(--re-data-grid-loading-surface);color:var(--re-data-grid-loading-color);z-index:5}.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", "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"] }] });
939
+ }
940
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DataGrid, decorators: [{
941
+ type: Component,
942
+ args: [{ selector: 're-data-grid', imports: [NgTemplateOutlet, DataGridCellComponent, SortIcon, ExpandIcon, CheckboxIcon], providers: [DataGridVm], template: "@let items = data();\n@let empty = !loading() && !items?.length;\n@let notEmpty = !!items?.length;\n\n@let pinnedTopH = vm.pinnedTop().length * rowHeight();\n@let pinnedBottomH = vm.pinnedBottom().length * rowHeight();\n\n<div\n #root\n class=\"re-dg-root\"\n [class.fill]=\"fillHeight()\"\n [class.loading]=\"loading()\"\n [style.height]=\"styleHeight\"\n role=\"table\"\n>\n @if (loading()) {\n <div class=\"re-dg-loader\">\n @let loadingTemplate = loadingTpl();\n\n @if (loadingTemplate?.tpl) {\n <ng-container [ngTemplateOutlet]=\"loadingTemplate!.tpl\" />\n } @else {\n <span class=\"re-dg-loader-text\">\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430\u2026</span>\n }\n </div>\n }\n\n <div\n #scroll\n class=\"re-dg-body\"\n role=\"rowgroup\"\n (mouseenter)=\"showScrollbar()\"\n (mouseleave)=\"hideScrollbarSoon()\"\n >\n <div class=\"re-dg-header\" role=\"rowgroup\">\n <div #header class=\"re-dg-row re-dg-header-row\" role=\"row\">\n @for (col of vm.columnsToShow(); track col.key) {\n <div\n class=\"re-dg-header-cell\"\n role=\"columnheader\"\n [class.sortable]=\"!!col.sortKey\"\n [class.active-sort]=\"currentSortField && (currentSortField === col.sortKey)\"\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\n [style.width.px]=\"vm.widthByKey(col.key)\"\n [style.min-width.px]=\"col.minWidth || null\"\n [style.max-width.px]=\"col.maxWidth || null\"\n [style.justify-content]=\"col.align || 'left'\"\n [attr.aria-sort]=\"ariaSort(col)\"\n [attr.tabindex]=\"col.sortKey ? 0 : -1\"\n [title]=\"col.header\"\n (click)=\"col.sortKey && onSort(col)\"\n (keydown.enter)=\"col.sortKey && onSort(col)\"\n >\n {{currentSortField }} {{ col.sortKey}}\n @if (col.headerTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"col.headerTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: col.header }\"\n />\n } @else {\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\n @let isMultiSelect = selection().mode === 'multi';\n\n @if (isCheckbox && isMultiSelect) {\n <re-checkbox-ic mixable [state]=\"selector.isAllSelected()\" (click)=\"selector.selectAll()\" />\n } @else {\n <span class=\"re-dg-header-text\">{{ col.header }}</span>\n }\n\n @if (col.sortKey) {\n <span class=\"re-dg-sort-ind\">\n <re-sort-ic [direction]=\"currentSortField === col.sortKey ? currentSortOrder : 'desc'\" />\n </span>\n }\n\n @if (isExpandable(col)) {\n <button (click)=\"$event.stopPropagation(); onExpand(col)\">\n <re-expand-ic [expanded]=\"expanderMap().get(col.key)\" />\n </button>\n }\n }\n </div>\n }\n </div>\n\n <!-- PINNED TOP ROWS -->\n @if (notEmpty) {\n @for (pr of vm.pinnedTop(); track trackPinnedRow(pr)) {\n <div class=\"re-dg-row re-dg-pinned re-dg-top\" role=\"row\">\n @if (pr.rowTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\n />\n } @else {\n @for (col of vm.columnsToShow(); track col.key) {\n <div\n class=\"re-dg-cell\"\n role=\"cell\"\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\n [style.justify-items]=\"col.align || 'left'\"\n [style.height.px]=\"rowHeight()\"\n [style.width.px]=\"vm.widthByKey(col.key)\"\n >\n {{ resolvePinnedData(pr)[col.key] ?? '' }}\n </div>\n }\n }\n </div>\n }\n }\n </div>\n\n @if (empty) {\n @let emptyTemplate = emptyTpl()?.tpl;\n\n <div class=\"re-dg-empty\">\n @if (emptyTemplate) {\n <ng-container [ngTemplateOutlet]=\"emptyTemplate\" />\n } @else {\n <span class=\"re-dg-empty-text\">\u041D\u0435\u0442 \u0434\u0430\u043D\u043D\u044B\u0445</span>\n }\n </div>\n }\n\n <!-- Content -->\n @if (notEmpty) {\n <div class=\"re-dg-spacer\" [style.height.px]=\"items.length * rowHeight() - pinnedBottomH\"></div>\n\n @for (row of visibleRows(); track trackByRow(row); let vi = $index) {\n <div\n class=\"re-dg-row re-dg-data-row\"\n role=\"row\"\n [style.height.px]=\"rowHeight()\"\n [style.top.px]=\"(startIndex + vi) * rowHeight() + pinnedTopH + headerHeight()\"\n [attr.tabindex]=\"0\"\n (click)=\"$event.stopPropagation(); rowClick.emit({ row, index: startIndex + vi })\"\n (keydown.enter)=\"$event.stopPropagation(); rowClick.emit({ row, index: startIndex + vi })\"\n >\n @for (col of vm.columnsToShow(); track col.key) {\n <div\n class=\"re-dg-cell\"\n role=\"cell\"\n [class]=\"cellClass(col, row)\"\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\n [style.justify-items]=\"col.align || 'left'\"\n [style.text-align]=\"col.align || 'left'\"\n [style.width.px]=\"vm.widthByKey(col.key)\"\n [attr.tabindex]=\"0\"\n (click)=\"onCellClick(row, col, startIndex + vi);\"\n (keydown.enter)=\"onCellClick(row, col, startIndex + vi)\"\n >\n @let isCheckbox = 'type' in col && col.type === 'checkbox';\n\n @if (isCheckbox) {\n <re-checkbox-ic mixable=\"false\" [state]=\"selector.isSelected(row)\" />\n } @else {\n <re-data-grid-cell [index]=\"startIndex + vi\" [item]=\"row\" [column]=\"col\" />\n }\n </div>\n }\n </div>\n }\n }\n\n <!-- PINNED BOTTOM ROWS -->\n @if (notEmpty) {\n <div class=\"re-dg-footer\" role=\"rowgroup\">\n @for (pr of vm.pinnedBottom(); track trackPinnedRow(pr)) {\n <div class=\"re-dg-row re-dg-pinned re-dg-bottom\" role=\"row\">\n @if (pr.rowTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"pr.rowTemplate!\"\n [ngTemplateOutletContext]=\"{ $implicit: resolvePinnedData(pr) }\"\n />\n } @else {\n @for (col of vm.columnsToShow(); track col.key) {\n <div\n class=\"re-dg-cell\"\n role=\"cell\"\n [class.sticky-left]=\"vm.isStickyLeft(col.key)\"\n [class.sticky-right]=\"vm.isStickyRight(col.key)\"\n [style.left.px]=\"vm.stickyOffset(col.key, 'left')\"\n [style.right.px]=\"vm.stickyOffset(col.key, 'right')\"\n [style.justify-items]=\"col.align || 'left'\"\n [style.height.px]=\"rowHeight()\"\n [style.width.px]=\"vm.widthByKey(col.key)\"\n >\n {{ resolvePinnedData(pr)[col.key] ?? '' }}\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Overlay scrollbar -->\n <div class=\"re-dg-scrollbar\" [class.visible]=\"vm.scrollbarVisible()\">\n <div\n class=\"re-dg-scrollbar-thumb\"\n role=\"scrollbar\"\n aria-orientation=\"vertical\"\n aria-hidden=\"false\"\n [style.height.px]=\"vm.thumbHeightPx()\"\n [style.transform]=\"'translateY(' + vm.thumbTopPx() + 'px)'\"\n (mousedown)=\"onThumbDown($event)\"\n ></div>\n </div>\n</div>\n", styles: [":host{--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: #fff;--re-data-grid-active: #2a90f4;--re-data-grid-empty-color: #777;--re-data-grid-loading-color: #444;--re-data-grid-loading-surface: rgba(255, 255, 255, .5);--re-data-grid-scrollbar-size: 10px;--re-data-grid-scrollbar-offset: 2px;--re-data-grid-scrollbar-thumb-size: 8px;--re-data-grid-scrollbar-thumb-color: rgba(0, 0, 0, .35);--re-data-grid-scrollbar-thumb-rounded: 4px;--re-data-grid-header-height: 40px;--re-data-grid-header-separator-color: #ccc;--re-data-grid-header-separator: 1px solid var(--re-data-grid-header-separator-color);--re-data-grid-header-surface: #fff;--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-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-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-sticky-header-cell-surface: #fff;--re-data-grid-sticky-cell-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)}:host :host,:host *,:host *:before,:host *:after{box-sizing:border-box;outline:none}:host button{outline:none}.re-dg-root{position:relative;display:block;width:100%;height:var(--re-data-grid-height);max-height:var(--re-data-grid-height);border-radius:var(--re-data-grid-rounded);border:var(--re-data-grid-separator)}.re-dg-root.fill{display:flex;flex-direction:column;height:100%}.re-dg-root.loading{pointer-events:none;-webkit-user-select:none;user-select:none;cursor:wait}.re-dg-root.loading .re-dg-body{overflow:hidden}.re-dg-root.loading .re-dg-scrollbar{display:none!important}.re-dg-root.loading .re-dg-loader{pointer-events:all}.re-dg-body{position:relative;flex:1 1 auto;min-width:0;height:var(--re-data-grid-height);border:var(--re-data-grid-separator);border-radius:var(--re-data-grid-rounded);background-color:var(--re-data-grid-surface);overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.re-dg-body::-webkit-scrollbar{width:0;height:0}.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-height)}.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;right:0;cursor:default}.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{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-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{align-items:center;gap:.75rem;border-bottom:var(--re-data-grid-header-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-header-cell:first-child{border-radius:var(--re-data-grid-rounded) 0 0 0}.re-dg-header-cell:last-child{border-radius:0 var(--re-data-grid-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;max-height:2.4em;line-height:1.2;white-space:normal;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}.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)}.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-empty{position:absolute;inset:0;display:flex;place-items:center;color:var(--re-data-grid-empty-color)}.re-dg-empty-text{width:100%;text-align:center}.re-dg-loader{position:absolute;inset:0;top:var(--re-data-grid-header-height);display:grid;place-items:center;background-color:var(--re-data-grid-loading-surface);color:var(--re-data-grid-loading-color);z-index:5}.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"] }]
943
+ }], 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 }] }], 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 }] }], fillHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillHeight", required: false }] }], virtualBuffer: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualBuffer", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], pageStartFromZero: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageStartFromZero", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], cellClick: [{ type: i0.Output, args: ["cellClick"] }], rootEl: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], scrollEl: [{ type: i0.ViewChild, args: ['scroll', { isSignal: true }] }], headerEl: [{ type: i0.ViewChild, args: ['header', { isSignal: true }] }], cellSlotRefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DataGridTypeCellTemplateDirective), { 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 }] }] } });
944
+
945
+ /**
946
+ * Generated bundle index. Do not edit.
947
+ */
948
+
949
+ export { DataGrid, DataGridCellEmptyDirective, DataGridCellLoadingDirective, DataGridHeaderTemplateDirective, DataGridTypeCellTemplateDirective };
950
+ //# sourceMappingURL=reforgium-data-grid.mjs.map