@zambon-dev/library 1.6.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -23,6 +23,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
23
23
|
|
|
24
24
|
### ⚠ Breaking Changes / Migration
|
|
25
25
|
|
|
26
|
+
## [1.6.1] - 2026-09-19
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- **`lib-data-grid` headings now sit over their own column.** On a grid with many columns each
|
|
31
|
+
heading drifted further from its cells than the last -- up to 263px on a fourteen-column screen --
|
|
32
|
+
and scrolling sideways separated them completely.
|
|
33
|
+
|
|
34
|
+
The body lays the columns out as a CSS grid inside the CDK viewport; the heading row is a flex
|
|
35
|
+
row outside it that copies each column's measured width. Four things pulled the two apart:
|
|
36
|
+
|
|
37
|
+
- The heading cells could **shrink**, so once the columns together were wider than the view every
|
|
38
|
+
heading was compressed a little and the error accumulated across the row.
|
|
39
|
+
- The heading row **did not follow the body sideways**. The rows scroll inside the viewport and
|
|
40
|
+
the headings simply stayed where they were.
|
|
41
|
+
- A column was **measured once and never again**, while the body keeps resizing its
|
|
42
|
+
`minmax(x, min-content)` columns as virtual scrolling brings different content into view.
|
|
43
|
+
- A column measured at **zero** -- a `1fr` column collapsed for want of room -- left its heading
|
|
44
|
+
with no width at all, so it kept its text width and shoved everything to its right along.
|
|
45
|
+
|
|
46
|
+
Headings are now fixed to the measured width, translate with the body's horizontal scroll, track
|
|
47
|
+
every resize, and a heading whose column has collapsed is removed rather than left taking a gap
|
|
48
|
+
the body does not have. Measured in a running application the drift is zero across every column,
|
|
49
|
+
at rest and scrolled.
|
|
50
|
+
|
|
26
51
|
## [1.6.0] - 2026-09-16
|
|
27
52
|
|
|
28
53
|
### Added
|
|
@@ -265,7 +290,8 @@ config options and the `getUserProfile()` method still exist but are no longer c
|
|
|
265
290
|
available via [GitHub Releases](https://github.com/RicardoZambon/ZLibraries/releases) and the
|
|
266
291
|
`library-v*` tags.
|
|
267
292
|
|
|
268
|
-
[Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/library-v1.6.
|
|
293
|
+
[Unreleased]: https://github.com/RicardoZambon/ZLibraries/compare/library-v1.6.1...HEAD
|
|
294
|
+
[1.6.1]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.1
|
|
269
295
|
[1.6.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.6.0
|
|
270
296
|
[1.5.0]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.5.0
|
|
271
297
|
[1.4.1]: https://github.com/RicardoZambon/ZLibraries/releases/tag/library-v1.4.1
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Component, inject, Injectable, EventEmitter, InjectionToken, Input, Output, KeyValueDiffers, ViewContainerRef, TemplateRef, ElementRef, HostListener, ViewChild, ChangeDetectorRef, ChangeDetectionStrategy, NgZone, Directive, ContentChildren, Pipe, NgModule } from '@angular/core';
|
|
3
|
-
import { Subject, ReplaySubject, take, throwError, tap, map, takeUntil, filter, debounceTime, startWith, pairwise, Observable, forkJoin, switchMap, of, delay, merge } from 'rxjs';
|
|
3
|
+
import { Subject, ReplaySubject, take, throwError, tap, map, takeUntil, filter, debounceTime, startWith, pairwise, Observable, forkJoin, switchMap, of, fromEvent, delay, merge } from 'rxjs';
|
|
4
4
|
import { Overlay, OverlayPositionBuilder } from '@angular/cdk/overlay';
|
|
5
5
|
import { TemplatePortal } from '@angular/cdk/portal';
|
|
6
6
|
import * as i1 from '@angular/common';
|
|
@@ -2215,7 +2215,7 @@ class DataGridRowComponent extends BaseComponent {
|
|
|
2215
2215
|
dataGridDataset = inject(DataGridDataset);
|
|
2216
2216
|
selected = false;
|
|
2217
2217
|
_rowData;
|
|
2218
|
-
|
|
2218
|
+
hasMeasured = {};
|
|
2219
2219
|
//#endregion
|
|
2220
2220
|
//#region Properties
|
|
2221
2221
|
get rowData() {
|
|
@@ -2249,16 +2249,22 @@ class DataGridRowComponent extends BaseComponent {
|
|
|
2249
2249
|
//#endregion
|
|
2250
2250
|
//#region Event handlers
|
|
2251
2251
|
onResize(colIndex, event) {
|
|
2252
|
-
if (this.isWidthSet[colIndex]) {
|
|
2253
|
-
return;
|
|
2254
|
-
}
|
|
2255
2252
|
const width = event.contentRect.width;
|
|
2256
|
-
|
|
2253
|
+
// The very first callback can arrive before the grid is laid out and reports zero for every
|
|
2254
|
+
// column; taking that at face value would pin the heading at zero. Once a column has measured
|
|
2255
|
+
// something real, a later zero is believable -- that is a 1fr column collapsing, and the
|
|
2256
|
+
// heading has to collapse with it or every column to its right sits under the wrong one.
|
|
2257
|
+
if (width <= 0 && !this.hasMeasured[colIndex]) {
|
|
2257
2258
|
return;
|
|
2258
2259
|
}
|
|
2259
|
-
|
|
2260
|
+
this.hasMeasured[colIndex] = true;
|
|
2261
|
+
// Reported on every change, not just the first. The body lays the columns out as a CSS grid of
|
|
2262
|
+
// minmax(x, min-content), so a column is only as wide as the content currently rendered --
|
|
2263
|
+
// which virtual scrolling keeps changing. Measuring once and latching left the header copying
|
|
2264
|
+
// a width the body no longer had, and with many columns that drift accumulated into cells
|
|
2265
|
+
// sitting under the wrong heading.
|
|
2266
|
+
if (this.columns[colIndex].realSize !== width) {
|
|
2260
2267
|
this.columns[colIndex].realSize = width;
|
|
2261
|
-
this.isWidthSet[colIndex] = true;
|
|
2262
2268
|
}
|
|
2263
2269
|
}
|
|
2264
2270
|
onResizeSelection(event) {
|
|
@@ -2329,6 +2335,7 @@ class DataGridComponent extends BaseComponent {
|
|
|
2329
2335
|
dataGridDataset = inject(DataGridDataset);
|
|
2330
2336
|
hasFailed = false;
|
|
2331
2337
|
headerRightMargin = 0;
|
|
2338
|
+
headerScrollLeft = 0;
|
|
2332
2339
|
loading = false;
|
|
2333
2340
|
bodyResized$ = new Subject();
|
|
2334
2341
|
bodyResizeObserver;
|
|
@@ -2445,6 +2452,26 @@ class DataGridComponent extends BaseComponent {
|
|
|
2445
2452
|
}
|
|
2446
2453
|
}
|
|
2447
2454
|
ngAfterViewInit() {
|
|
2455
|
+
// The rows scroll sideways inside the CDK viewport while the header sits outside it, so the
|
|
2456
|
+
// header has to be moved by hand or the headings stay behind as the cells travel. Read outside
|
|
2457
|
+
// Angular and written back inside it, because this fires for every frame of a scroll.
|
|
2458
|
+
const viewportElement = this.viewport?.elementRef?.nativeElement;
|
|
2459
|
+
if (viewportElement) {
|
|
2460
|
+
this.ngZone.runOutsideAngular(() => {
|
|
2461
|
+
fromEvent(viewportElement, 'scroll')
|
|
2462
|
+
.pipe(takeUntil(this.destroy$))
|
|
2463
|
+
.subscribe(() => {
|
|
2464
|
+
const scrollLeft = viewportElement.scrollLeft;
|
|
2465
|
+
if (this.headerScrollLeft === scrollLeft) {
|
|
2466
|
+
return;
|
|
2467
|
+
}
|
|
2468
|
+
this.ngZone.run(() => {
|
|
2469
|
+
this.headerScrollLeft = scrollLeft;
|
|
2470
|
+
this.changeDetectorRef.detectChanges();
|
|
2471
|
+
});
|
|
2472
|
+
});
|
|
2473
|
+
});
|
|
2474
|
+
}
|
|
2448
2475
|
this.viewport?.renderedRangeStream
|
|
2449
2476
|
.pipe(takeUntil(this.destroy$))
|
|
2450
2477
|
.subscribe((listRange) => {
|
|
@@ -2497,7 +2524,7 @@ class DataGridComponent extends BaseComponent {
|
|
|
2497
2524
|
return item.key;
|
|
2498
2525
|
}
|
|
2499
2526
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: DataGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2500
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.6", type: DataGridComponent, isStandalone: true, selector: "lib-data-grid", inputs: { disabled: "disabled", lazyLoadRows: "lazyLoadRows", showButtons: "showButtons" }, host: { properties: { "class.no-borders": "showButtons" } }, viewQueries: [{ propertyName: "bodyElement", first: true, predicate: ["body"], descendants: true }, { propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"buttons\"\n*ngIf=\"showButtons\">\n <ng-content select=\"[buttons]\"></ng-content>\n</div>\n\n<div class=\"header\"\n[class.hide]=\"isHideColumns\"\n[style.padding-right.px]=\"headerRightMargin\">\n <div class=\"header-row\">\n <div *ngIf=\"isShowMultiSelect\"\n class=\"header-cell selection\"\n [ngStyle]=\"{\n 'width': selectionColWidth ? selectionColWidth : null\n }\">\n \n </div>\n \n <div *ngFor=\"let column of columns\"\n class=\"header-cell\"\n [ngStyle]=\"{\n '
|
|
2527
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.6", type: DataGridComponent, isStandalone: true, selector: "lib-data-grid", inputs: { disabled: "disabled", lazyLoadRows: "lazyLoadRows", showButtons: "showButtons" }, host: { properties: { "class.no-borders": "showButtons" } }, viewQueries: [{ propertyName: "bodyElement", first: true, predicate: ["body"], descendants: true }, { propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"buttons\"\n*ngIf=\"showButtons\">\n <ng-content select=\"[buttons]\"></ng-content>\n</div>\n\n<div class=\"header\"\n[class.hide]=\"isHideColumns\"\n[style.padding-right.px]=\"headerRightMargin\">\n <!-- Translated by however far the body is scrolled sideways. The rows scroll inside the CDK\n viewport and the header sits outside it, so without this the headings simply stay put\n while the cells move away from them. -->\n <div class=\"header-row\"\n [style.transform]=\"headerScrollLeft ? 'translateX(-' + headerScrollLeft + 'px)' : null\">\n <div *ngIf=\"isShowMultiSelect\"\n class=\"header-cell selection\"\n [ngStyle]=\"{\n 'width': selectionColWidth ? selectionColWidth : null\n }\">\n \n </div>\n \n <!-- A measured zero is a width, not the absence of one: it is a 1fr column that collapsed,\n and its heading has to collapse too. The old test read `realSize ?? 0 > 0`, which binds\n as `realSize ?? (0 > 0)` and so turned zero into no width at all.\n\n Such a heading is removed rather than merely made zero wide, because a flex item still\n takes a gap on each side while the body grid allows the collapsed track only one, and\n that spare gap pushed every heading to its right out by 16px. -->\n <div *ngFor=\"let column of columns\"\n class=\"header-cell\"\n [ngStyle]=\"{\n 'display': column.realSize === 0 ? 'none' : null,\n 'width.px': column.realSize ?? null\n }\">\n <span>{{ column.headerName | translate }}</span>\n </div>\n </div>\n</div>\n\n<div #body\nclass=\"body\"\n[style.min-height.px]=\"bodyMinHeight\">\n <cdk-virtual-scroll-viewport\n [itemSize]=\"configs.rowHeight\"\n [style.grid-template-columns]=\"gridColumns\">\n <lib-data-grid-row #row\n *cdkVirtualFor=\"let row of dataGridDataset.loadedRows; index as i; trackBy: trackByFn\"\n [disabled]=\"disabled\"\n [isFirstRow]=\"isFirstVisibleRow(i)\"\n [rowData]=\"row\"\n [style.height.px]=\"configs.rowHeight\"\n (selectionResized)=\"onSelectionResized($event)\">\n </lib-data-grid-row>\n\n <div *ngIf=\"loading\"\n class=\"loading\"\n [style.height.px]=\"configs.rowHeight\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n \n <span>\n {{ dataGridDataset.configs.loadingDisplayText ?? '' | translate }} \n </span>\n </div>\n \n <div *ngIf=\"!loading && !hasBeenLoaded && lazyLoadRows\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n {{ messageToDisplayWhenLazyLoad | translate }}\n </span>\n </div>\n\n <ng-container *ngIf=\"!loading && hasBeenLoaded && (!hasLoadedRows || hasFailed)\">\n <div *ngIf=\"!hasFailed && !hasLoadedRows && hasMessageToDisplayWhenEmpty && shouldDisplayMessageWhenEmpty\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n {{ messageToDisplayWhenEmpty | translate }}\n </span>\n </div>\n\n <div *ngIf=\"hasFailed\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n <i class=\"fas fa-exclamation-triangle mr-2 text-yellow-600\"></i>{{ messageToDisplayWhenFailed | translate }}\n </span>\n </div>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n</div>", styles: [":host-context{display:flex;-webkit-user-select:none;user-select:none;flex-direction:column;overflow:hidden}:host-context:not(.no-borders){border-radius:.5rem;border-width:1px;border-color:#d1d5dbe6;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}:host-context.no-borders .header .header-row{padding-top:.375rem;padding-bottom:.375rem}:host-context.no-borders .body lib-data-grid-row{padding-top:.25rem;padding-bottom:.25rem}.header-row,lib-data-grid-row,.loading,.message{gap:1rem;padding-left:1rem;padding-right:1rem}.header{overflow:hidden;border-bottom-width:1px;border-color:#d1d5dbe6;background-color:#e5e7eb66;font-weight:700}.header.hide{display:none}.header .header-row{display:flex;flex-direction:row;padding-top:.75rem;padding-bottom:.75rem}.header .header-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header .header-cell:not(.selection){flex:none}.body{position:relative;flex-grow:1}.body cdk-virtual-scroll-viewport{position:absolute;inset:0}.body cdk-virtual-scroll-viewport ::ng-deep .cdk-virtual-scroll-content-wrapper{display:grid;grid-template-columns:inherit}.body lib-data-grid-row{margin-top:-1px;cursor:pointer;border-top-width:1px;border-bottom-width:1px;border-color:#cbd5e180;padding-top:.5rem;padding-bottom:.5rem}.body lib-data-grid-row:nth-child(2n){background-color:#f8fafcb3}.body lib-data-grid-row:hover{background-color:#bfdbfe33}.body lib-data-grid-row.focused{z-index:1;border-color:#94a3b899}.body lib-data-grid-row.selected{position:relative;z-index:10;--tw-border-opacity: 1;border-color:rgb(147 197 253 / var(--tw-border-opacity, 1));background-color:#bfdbfe4d}.body lib-data-grid-row.selected:hover{background-color:#bfdbfe66}.body .loading,.body .message{display:flex;align-items:center;gap:.5rem;white-space:nowrap;height:2.5rem;border-bottom-width:1px;border-color:#cbd5e180;grid-column:1 / -1}.body .loading span,.body .message span{overflow:hidden;text-overflow:ellipsis}.body .loading svg{height:1.5rem;min-height:1.5rem;width:1.5rem;min-width:1.5rem}@keyframes spin{to{transform:rotate(360deg)}}.body .loading svg{animation:spin 1s linear infinite;transition-property:opacity;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.buttons{display:flex;border-top-width:1px;border-bottom-width:1px;border-color:#d1d5dbe6;padding:.25rem}\n"], dependencies: [{ kind: "component", type: DataGridRowComponent, selector: "lib-data-grid-row", inputs: ["disabled", "isFirstRow", "rowData"], outputs: ["selectionResized"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1$2.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1$2.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1$2.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
2501
2528
|
}
|
|
2502
2529
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImport: i0, type: DataGridComponent, decorators: [{
|
|
2503
2530
|
type: Component,
|
|
@@ -2510,7 +2537,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.6", ngImpor
|
|
|
2510
2537
|
NgStyle,
|
|
2511
2538
|
ScrollingModule,
|
|
2512
2539
|
TranslatePipe,
|
|
2513
|
-
], template: "<div class=\"buttons\"\n*ngIf=\"showButtons\">\n <ng-content select=\"[buttons]\"></ng-content>\n</div>\n\n<div class=\"header\"\n[class.hide]=\"isHideColumns\"\n[style.padding-right.px]=\"headerRightMargin\">\n <div class=\"header-row\">\n <div *ngIf=\"isShowMultiSelect\"\n class=\"header-cell selection\"\n [ngStyle]=\"{\n 'width': selectionColWidth ? selectionColWidth : null\n }\">\n \n </div>\n \n <div *ngFor=\"let column of columns\"\n class=\"header-cell\"\n [ngStyle]=\"{\n '
|
|
2540
|
+
], template: "<div class=\"buttons\"\n*ngIf=\"showButtons\">\n <ng-content select=\"[buttons]\"></ng-content>\n</div>\n\n<div class=\"header\"\n[class.hide]=\"isHideColumns\"\n[style.padding-right.px]=\"headerRightMargin\">\n <!-- Translated by however far the body is scrolled sideways. The rows scroll inside the CDK\n viewport and the header sits outside it, so without this the headings simply stay put\n while the cells move away from them. -->\n <div class=\"header-row\"\n [style.transform]=\"headerScrollLeft ? 'translateX(-' + headerScrollLeft + 'px)' : null\">\n <div *ngIf=\"isShowMultiSelect\"\n class=\"header-cell selection\"\n [ngStyle]=\"{\n 'width': selectionColWidth ? selectionColWidth : null\n }\">\n \n </div>\n \n <!-- A measured zero is a width, not the absence of one: it is a 1fr column that collapsed,\n and its heading has to collapse too. The old test read `realSize ?? 0 > 0`, which binds\n as `realSize ?? (0 > 0)` and so turned zero into no width at all.\n\n Such a heading is removed rather than merely made zero wide, because a flex item still\n takes a gap on each side while the body grid allows the collapsed track only one, and\n that spare gap pushed every heading to its right out by 16px. -->\n <div *ngFor=\"let column of columns\"\n class=\"header-cell\"\n [ngStyle]=\"{\n 'display': column.realSize === 0 ? 'none' : null,\n 'width.px': column.realSize ?? null\n }\">\n <span>{{ column.headerName | translate }}</span>\n </div>\n </div>\n</div>\n\n<div #body\nclass=\"body\"\n[style.min-height.px]=\"bodyMinHeight\">\n <cdk-virtual-scroll-viewport\n [itemSize]=\"configs.rowHeight\"\n [style.grid-template-columns]=\"gridColumns\">\n <lib-data-grid-row #row\n *cdkVirtualFor=\"let row of dataGridDataset.loadedRows; index as i; trackBy: trackByFn\"\n [disabled]=\"disabled\"\n [isFirstRow]=\"isFirstVisibleRow(i)\"\n [rowData]=\"row\"\n [style.height.px]=\"configs.rowHeight\"\n (selectionResized)=\"onSelectionResized($event)\">\n </lib-data-grid-row>\n\n <div *ngIf=\"loading\"\n class=\"loading\"\n [style.height.px]=\"configs.rowHeight\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n \n <span>\n {{ dataGridDataset.configs.loadingDisplayText ?? '' | translate }} \n </span>\n </div>\n \n <div *ngIf=\"!loading && !hasBeenLoaded && lazyLoadRows\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n {{ messageToDisplayWhenLazyLoad | translate }}\n </span>\n </div>\n\n <ng-container *ngIf=\"!loading && hasBeenLoaded && (!hasLoadedRows || hasFailed)\">\n <div *ngIf=\"!hasFailed && !hasLoadedRows && hasMessageToDisplayWhenEmpty && shouldDisplayMessageWhenEmpty\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n {{ messageToDisplayWhenEmpty | translate }}\n </span>\n </div>\n\n <div *ngIf=\"hasFailed\"\n class=\"message\"\n [style.height.px]=\"configs.rowHeight\">\n <span>\n <i class=\"fas fa-exclamation-triangle mr-2 text-yellow-600\"></i>{{ messageToDisplayWhenFailed | translate }}\n </span>\n </div>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n</div>", styles: [":host-context{display:flex;-webkit-user-select:none;user-select:none;flex-direction:column;overflow:hidden}:host-context:not(.no-borders){border-radius:.5rem;border-width:1px;border-color:#d1d5dbe6;--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}:host-context.no-borders .header .header-row{padding-top:.375rem;padding-bottom:.375rem}:host-context.no-borders .body lib-data-grid-row{padding-top:.25rem;padding-bottom:.25rem}.header-row,lib-data-grid-row,.loading,.message{gap:1rem;padding-left:1rem;padding-right:1rem}.header{overflow:hidden;border-bottom-width:1px;border-color:#d1d5dbe6;background-color:#e5e7eb66;font-weight:700}.header.hide{display:none}.header .header-row{display:flex;flex-direction:row;padding-top:.75rem;padding-bottom:.75rem}.header .header-cell{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.header .header-cell:not(.selection){flex:none}.body{position:relative;flex-grow:1}.body cdk-virtual-scroll-viewport{position:absolute;inset:0}.body cdk-virtual-scroll-viewport ::ng-deep .cdk-virtual-scroll-content-wrapper{display:grid;grid-template-columns:inherit}.body lib-data-grid-row{margin-top:-1px;cursor:pointer;border-top-width:1px;border-bottom-width:1px;border-color:#cbd5e180;padding-top:.5rem;padding-bottom:.5rem}.body lib-data-grid-row:nth-child(2n){background-color:#f8fafcb3}.body lib-data-grid-row:hover{background-color:#bfdbfe33}.body lib-data-grid-row.focused{z-index:1;border-color:#94a3b899}.body lib-data-grid-row.selected{position:relative;z-index:10;--tw-border-opacity: 1;border-color:rgb(147 197 253 / var(--tw-border-opacity, 1));background-color:#bfdbfe4d}.body lib-data-grid-row.selected:hover{background-color:#bfdbfe66}.body .loading,.body .message{display:flex;align-items:center;gap:.5rem;white-space:nowrap;height:2.5rem;border-bottom-width:1px;border-color:#cbd5e180;grid-column:1 / -1}.body .loading span,.body .message span{overflow:hidden;text-overflow:ellipsis}.body .loading svg{height:1.5rem;min-height:1.5rem;width:1.5rem;min-width:1.5rem}@keyframes spin{to{transform:rotate(360deg)}}.body .loading svg{animation:spin 1s linear infinite;transition-property:opacity;transition-duration:.2s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.buttons{display:flex;border-top-width:1px;border-bottom-width:1px;border-color:#d1d5dbe6;padding:.25rem}\n"] }]
|
|
2514
2541
|
}], ctorParameters: () => [], propDecorators: { bodyElement: [{
|
|
2515
2542
|
type: ViewChild,
|
|
2516
2543
|
args: ['body']
|