@testgorilla/tgo-ui 11.8.0 → 11.10.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.
- package/README.md +114 -0
- package/fesm2022/testgorilla-tgo-ui-components-ai-feedback.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-ai-feedback.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-alert-banner.mjs +21 -2
- package/fesm2022/testgorilla-tgo-ui-components-alert-banner.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs +4 -3
- package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs +5 -2
- package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-avatar.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-avatar.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-breadcrumb.mjs +10 -4
- package/fesm2022/testgorilla-tgo-ui-components-breadcrumb.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-button.mjs +5 -2
- package/fesm2022/testgorilla-tgo-ui-components-button.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-card.mjs +36 -19
- package/fesm2022/testgorilla-tgo-ui-components-card.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-checkbox.mjs +26 -3
- package/fesm2022/testgorilla-tgo-ui-components-checkbox.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-checklist.mjs +8 -3
- package/fesm2022/testgorilla-tgo-ui-components-checklist.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-datepicker.mjs +12 -3
- package/fesm2022/testgorilla-tgo-ui-components-datepicker.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-device-control.mjs +7 -4
- package/fesm2022/testgorilla-tgo-ui-components-device-control.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-dialog.mjs +13 -4
- package/fesm2022/testgorilla-tgo-ui-components-dialog.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs +8 -2
- package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-empty-state.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-empty-state.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-field.mjs +6 -3
- package/fesm2022/testgorilla-tgo-ui-components-field.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-file-upload.mjs +9 -3
- package/fesm2022/testgorilla-tgo-ui-components-file-upload.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-filter-button.mjs +14 -2
- package/fesm2022/testgorilla-tgo-ui-components-filter-button.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-infinite-scroll-table.mjs +17 -3
- package/fesm2022/testgorilla-tgo-ui-components-infinite-scroll-table.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-inline-field.mjs +7 -4
- package/fesm2022/testgorilla-tgo-ui-components-inline-field.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-media-card.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-media-card.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-media-dialog.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-media-dialog.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-multi-input.mjs +7 -4
- package/fesm2022/testgorilla-tgo-ui-components-multi-input.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-navbar.mjs +2 -2
- package/fesm2022/testgorilla-tgo-ui-components-navbar.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-overflow-menu.mjs +9 -2
- package/fesm2022/testgorilla-tgo-ui-components-overflow-menu.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-page-header.mjs +5 -2
- package/fesm2022/testgorilla-tgo-ui-components-page-header.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-paginator.mjs +8 -2
- package/fesm2022/testgorilla-tgo-ui-components-paginator.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-password-criteria.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-password-criteria.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-phone-input.mjs +13 -3
- package/fesm2022/testgorilla-tgo-ui-components-phone-input.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-popover.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-popover.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-popup-tip.mjs +4 -3
- package/fesm2022/testgorilla-tgo-ui-components-popup-tip.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-prompt.mjs +18 -4
- package/fesm2022/testgorilla-tgo-ui-components-prompt.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-radial-progress.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-radial-progress.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-radio-button.mjs +21 -1
- package/fesm2022/testgorilla-tgo-ui-components-radio-button.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-rating.mjs +8 -2
- package/fesm2022/testgorilla-tgo-ui-components-rating.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-scale-table.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-scale-table.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-scale.mjs +11 -2
- package/fesm2022/testgorilla-tgo-ui-components-scale.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-segmented-bar.mjs +5 -2
- package/fesm2022/testgorilla-tgo-ui-components-segmented-bar.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-segmented-button.mjs +15 -3
- package/fesm2022/testgorilla-tgo-ui-components-segmented-button.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-segmented-toggle.mjs +11 -3
- package/fesm2022/testgorilla-tgo-ui-components-segmented-toggle.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-selectable-card.mjs +7 -4
- package/fesm2022/testgorilla-tgo-ui-components-selectable-card.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-side-navigation.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-side-navigation.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-side-panel.mjs +5 -2
- package/fesm2022/testgorilla-tgo-ui-components-side-panel.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-side-sheet.mjs +11 -2
- package/fesm2022/testgorilla-tgo-ui-components-side-sheet.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-slider.mjs +18 -3
- package/fesm2022/testgorilla-tgo-ui-components-slider.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-snackbar.mjs +8 -2
- package/fesm2022/testgorilla-tgo-ui-components-snackbar.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-stepper.mjs +11 -2
- package/fesm2022/testgorilla-tgo-ui-components-stepper.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-table.mjs +8 -2
- package/fesm2022/testgorilla-tgo-ui-components-table.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-tabs.mjs +4 -3
- package/fesm2022/testgorilla-tgo-ui-components-tabs.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-tag.mjs +5 -3
- package/fesm2022/testgorilla-tgo-ui-components-tag.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-toggle.mjs +10 -3
- package/fesm2022/testgorilla-tgo-ui-components-toggle.mjs.map +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-write-with-ai.mjs +1 -1
- package/fesm2022/testgorilla-tgo-ui-components-write-with-ai.mjs.map +1 -1
- package/mcp/catalog.json +1 -1
- package/package.json +1 -1
- package/types/testgorilla-tgo-ui-components-alert-banner.d.ts +16 -3
- package/types/testgorilla-tgo-ui-components-autocomplete-v2.d.ts +2 -1
- package/types/testgorilla-tgo-ui-components-autocomplete.d.ts +2 -1
- package/types/testgorilla-tgo-ui-components-breadcrumb.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-button.d.ts +2 -1
- package/types/testgorilla-tgo-ui-components-card.d.ts +16 -3
- package/types/testgorilla-tgo-ui-components-checkbox.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-checklist.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-datepicker.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-device-control.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-dialog.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-dropdown.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-field.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-file-upload.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-filter-button.d.ts +5 -1
- package/types/testgorilla-tgo-ui-components-infinite-scroll-table.d.ts +6 -1
- package/types/testgorilla-tgo-ui-components-inline-field.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-multi-input.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-overflow-menu.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-page-header.d.ts +2 -1
- package/types/testgorilla-tgo-ui-components-paginator.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-phone-input.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-popup-tip.d.ts +2 -1
- package/types/testgorilla-tgo-ui-components-prompt.d.ts +6 -1
- package/types/testgorilla-tgo-ui-components-radio-button.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-rating.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-scale.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-segmented-bar.d.ts +2 -1
- package/types/testgorilla-tgo-ui-components-segmented-button.d.ts +6 -1
- package/types/testgorilla-tgo-ui-components-segmented-toggle.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-selectable-card.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-side-panel.d.ts +3 -0
- package/types/testgorilla-tgo-ui-components-side-sheet.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-slider.d.ts +6 -1
- package/types/testgorilla-tgo-ui-components-snackbar.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-stepper.d.ts +4 -1
- package/types/testgorilla-tgo-ui-components-table.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-tabs.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-tag.d.ts +3 -1
- package/types/testgorilla-tgo-ui-components-toggle.d.ts +5 -1
|
@@ -83,6 +83,8 @@ class InfiniteScrollTableComponent {
|
|
|
83
83
|
* `noDataTemplate` / `errorTemplate`): a single-page list would otherwise flash "no more results".
|
|
84
84
|
*/
|
|
85
85
|
this.endOfListTemplate = input(...(ngDevMode ? [undefined, { debugName: "endOfListTemplate" }] : /* istanbul ignore next */ []));
|
|
86
|
+
this.testId = input(null, ...(ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []));
|
|
87
|
+
this.ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
86
88
|
/** Guarded: only when `hasMore && !loading && !loadingMore`, and only once per approach to the end. */
|
|
87
89
|
this.loadMore = output();
|
|
88
90
|
this.retry = output();
|
|
@@ -433,6 +435,18 @@ class InfiniteScrollTableComponent {
|
|
|
433
435
|
}
|
|
434
436
|
this.rowClick.emit({ row: row.item, index: row.index });
|
|
435
437
|
}
|
|
438
|
+
rowTestId(row) {
|
|
439
|
+
const testId = this.testId();
|
|
440
|
+
return testId && row.kind === 'data' ? `${testId}-row-${row.index}` : null;
|
|
441
|
+
}
|
|
442
|
+
cellTestId(row, columnKey) {
|
|
443
|
+
const testId = this.testId();
|
|
444
|
+
return testId && row.kind === 'data' ? `${testId}-cell-${row.index}-${columnKey}` : null;
|
|
445
|
+
}
|
|
446
|
+
rowCheckboxTestId(row) {
|
|
447
|
+
const rowTestId = this.rowTestId(row);
|
|
448
|
+
return rowTestId ? `${rowTestId}-select` : null;
|
|
449
|
+
}
|
|
436
450
|
isRowSelected(row) {
|
|
437
451
|
return this.selectable() && row.kind === 'data' && Boolean(this.asRowLike(row.item).selected);
|
|
438
452
|
}
|
|
@@ -623,7 +637,7 @@ class InfiniteScrollTableComponent {
|
|
|
623
637
|
}
|
|
624
638
|
}
|
|
625
639
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InfiniteScrollTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
626
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InfiniteScrollTableComponent, isStandalone: true, selector: "ui-infinite-scroll-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: true, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, rowIdKey: { classPropertyName: "rowIdKey", publicName: "rowIdKey", isSignal: true, isRequired: false, transformFunction: null }, minBufferPx: { classPropertyName: "minBufferPx", publicName: "minBufferPx", isSignal: true, isRequired: false, transformFunction: null }, maxBufferPx: { classPropertyName: "maxBufferPx", publicName: "maxBufferPx", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, fillHeight: { classPropertyName: "fillHeight", publicName: "fillHeight", isSignal: true, isRequired: false, transformFunction: null }, isCondensed: { classPropertyName: "isCondensed", publicName: "isCondensed", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, rowsClickable: { classPropertyName: "rowsClickable", publicName: "rowsClickable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingMore: { classPropertyName: "loadingMore", publicName: "loadingMore", isSignal: true, isRequired: false, transformFunction: null }, hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: true, transformFunction: null }, skeletonRowCount: { classPropertyName: "skeletonRowCount", publicName: "skeletonRowCount", isSignal: true, isRequired: false, transformFunction: null }, loadMoreSkeletonCount: { classPropertyName: "loadMoreSkeletonCount", publicName: "loadMoreSkeletonCount", isSignal: true, isRequired: false, transformFunction: null }, loadingColumnCount: { classPropertyName: "loadingColumnCount", publicName: "loadingColumnCount", isSignal: true, isRequired: false, transformFunction: null }, loadMoreThreshold: { classPropertyName: "loadMoreThreshold", publicName: "loadMoreThreshold", isSignal: true, isRequired: false, transformFunction: null }, noDataTemplate: { classPropertyName: "noDataTemplate", publicName: "noDataTemplate", isSignal: true, isRequired: false, transformFunction: null }, errorTemplate: { classPropertyName: "errorTemplate", publicName: "errorTemplate", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, endOfListTemplate: { classPropertyName: "endOfListTemplate", publicName: "endOfListTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loadMore: "loadMore", retry: "retry", rowClick: "rowClick", selectionChange: "selectionChange" }, host: { properties: { "class.ui-ist--fill-host": "fillHeight()" } }, viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }, { propertyName: "headerScroll", first: true, predicate: ["headerScroll"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- role=\"table\", not \"grid\": row access is Tab-only with no arrow-key cell traversal, so \"grid\" would\n promise 2D keyboard navigation this does not implement. Selection is conveyed by the row's checkbox,\n not `aria-selected` \u2014 which is valid only on grid/treegrid anyway. -->\n<div\n class=\"ui-ist\"\n role=\"table\"\n [class.ui-ist--condensed]=\"isCondensed()\"\n [class.ui-ist--scrolled-start]=\"!scrollStart()\"\n [class.ui-ist--scrolled-end]=\"horizontalScroll() && !scrollEnd()\"\n [class.ui-ist--fill-height]=\"fillHeight()\"\n [attr.aria-rowcount]=\"hasMore() ? -1 : data().length + 1\"\n [attr.aria-busy]=\"loading() || loadingMore()\"\n>\n <!-- Pinned header, outside the viewport so it never scrolls vertically. The outer element reserves the\n body's scrollbar width as padding (keeping the background and border across that strip); the inner\n one carries the horizontal scrollLeft synced from the body. -->\n <div class=\"ui-ist__header\" [style.padding-right.px]=\"scrollbarWidth()\" role=\"presentation\">\n <div #headerScroll class=\"ui-ist__header-scroll\" role=\"presentation\">\n <div class=\"ui-ist__row ui-ist__row--header\" role=\"row\" aria-rowindex=\"1\">\n @if (selectable()) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"columnheader\"\n ></div>\n }\n @for (column of columns(); track column.key; let colIndex = $index) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header\"\n role=\"columnheader\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n >\n @if (column.headerCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.headerCellTemplate; context: { $implicit: column.title, column, colIndex }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ column.title }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </div>\n </div>\n\n <!-- The CDK viewport owns BOTH vertical (virtualized) and horizontal scroll, so sticky columns pin\n against it and the horizontal scrollbar sits at the viewport bottom. -->\n @if (showViewport()) {\n <cdk-virtual-scroll-viewport\n class=\"ui-ist__body\"\n role=\"rowgroup\"\n [itemSize]=\"rowHeight()\"\n [minBufferPx]=\"effectiveMinBufferPx()\"\n [maxBufferPx]=\"effectiveMaxBufferPx()\"\n [style.height]=\"viewportHeight()\"\n [style.max-height]=\"fillHeight() ? maxHeight() : null\"\n >\n <div\n *cdkVirtualFor=\"let row of renderRows(); let rowIndex = index; trackBy: renderRowTrackBy\"\n class=\"ui-ist__row\"\n role=\"row\"\n [class.ui-ist__row--clickable]=\"rowsClickable() && row.kind === 'data'\"\n [class.ui-ist__row--selected]=\"isRowSelected(row)\"\n [attr.aria-rowindex]=\"row.kind === 'data' ? row.index + 2 : null\"\n [attr.aria-hidden]=\"row.kind === 'skeleton' ? true : null\"\n [attr.tabindex]=\"rowsClickable() && row.kind === 'data' ? 0 : null\"\n [style.height.px]=\"rowHeight()\"\n (click)=\"emitRowClick($event, row)\"\n (keydown.enter)=\"activateRow($event, row)\"\n (keydown.space)=\"activateRow($event, row)\"\n >\n @if (selectable()) {\n <!-- This `stopPropagation` is what actually stops a checkbox click activating the row: it runs\n before the click reaches the row's listener, so `isInteractiveTarget` is never consulted on\n this path. That guard is a real second line of defence (`ui-checkbox` renders a focusable\n wrapper and a native input, both matching INTERACTIVE_TARGET_SELECTOR), not a substitute. -->\n <div\n class=\"ui-ist__cell ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"cell\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n >\n @if (row.kind === 'data') {\n <ui-checkbox\n [checked]=\"isRowSelected(row)\"\n [ariaLabel]=\"'Select row ' + (row.index + 1)\"\n (changed)=\"emitSelectionChange(row, $event)\"\n ></ui-checkbox>\n }\n </div>\n }\n @for (column of columns(); track column.key) {\n <div\n class=\"ui-ist__cell\"\n role=\"cell\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n >\n @if (row.kind === 'skeleton') {\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n } @else if (column.rowCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.rowCellTemplate; context: { $implicit: row.item, rowIndex: row.index }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ getCellValue(row.item, column.key) }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- `showErrorFooter()` and `showErrorState()` differ only on `hasData()`, so they are mutually\n exclusive and safe to merge here. Both fall back to a plain-language message, so a failed fetch is\n never a silent blank box. -->\n @if (showErrorFooter() || showErrorState()) {\n <div class=\"ui-ist__state\" role=\"alert\">\n @if (errorTemplate(); as errorTpl) {\n <ng-container *ngTemplateOutlet=\"errorTpl; context: errorContext\"></ng-container>\n } @else {\n <span>{{ translationContext + 'LOAD_ERROR' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n @if (showEmptyState()) {\n <div class=\"ui-ist__state\">\n @if (noDataTemplate(); as emptyTpl) {\n <ng-container *ngTemplateOutlet=\"emptyTpl\"></ng-container>\n } @else {\n <span>{{ translationContext + 'NO_ROWS' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n <!-- Opt-in, with no fallback (see `endOfListTemplate`). Not role=\"alert\": reaching the end is not an\n alert, and `aria-rowcount` already conveys completeness to assistive tech. -->\n @if (showEndOfList() && endOfListTemplate(); as endTpl) {\n <div class=\"ui-ist__state\">\n <ng-container *ngTemplateOutlet=\"endTpl\"></ng-container>\n </div>\n }\n\n <span class=\"ui-ist__sr-only\" role=\"status\" aria-live=\"polite\">\n @if (statusMessageKey(); as statusKey) {\n {{ statusKey | uiTranslate | async }}\n }\n </span>\n</div>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{display:block}.ui-ist{--ui-ist-checkbox-width: 56px;--ui-ist-skeleton-bg: #f4f4f4;display:flex;flex-direction:column;border:1px solid #e0e0e0;border-radius:8px;overflow:hidden;background:#fff}.ui-ist__header{flex:0 0 auto;box-sizing:border-box;overflow:hidden;border-bottom:1px solid #e0e0e0;background:var(--ui-ist-header-bg, #ffffff)}.ui-ist__header-scroll{overflow:hidden}.ui-ist__body{flex:1 1 auto;overflow:auto;scrollbar-width:auto}.ui-ist__body::-webkit-scrollbar{width:8px;height:8px}.ui-ist__body::-webkit-scrollbar-button{display:none}.ui-ist__body::-webkit-scrollbar-thumb{background-color:#00000059;border-radius:4px}.ui-ist__body::-webkit-scrollbar-track:hover{background-color:#00000026}.ui-ist__row{display:flex;width:max-content;min-width:100%;box-sizing:border-box}.ui-ist__row--header{min-height:56px}.ui-ist__row:not(.ui-ist__row--header){border-bottom:1px solid #d3d3d3}.ui-ist__row--clickable{cursor:pointer}.ui-ist__row--clickable:not(.ui-ist__row--selected):hover{background:#fff2fc}.ui-ist__row--clickable:not(.ui-ist__row--selected):hover .ui-ist__cell{background:#fff2fc}.ui-ist__row--selected .ui-ist__cell{background:#f4f4f4}.ui-ist__cell{flex-grow:0;flex-shrink:0;box-sizing:border-box;display:flex;align-items:center;padding:8px 24px;font-size:14px;line-height:20px;overflow:hidden;background:#fff}.ui-ist__cell--header{background:var(--ui-ist-header-bg, #ffffff);font-weight:700;font-size:14px;line-height:16px}.ui-ist__cell--right{justify-content:flex-end;text-align:right}.ui-ist__cell--center{justify-content:center;text-align:center}.ui-ist__cell--sticky-start{position:sticky;z-index:2}.ui-ist__cell--checkbox.ui-ist__cell--sticky-start{left:0}.ui-ist__cell--sticky-end{position:sticky;right:0;z-index:2;order:1}.ui-ist__cell--checkbox{flex:0 0 var(--ui-ist-checkbox-width);min-width:var(--ui-ist-checkbox-width);justify-content:center;padding:0}.ui-ist__cell--spacer{flex:1 1 auto;min-width:0;padding:0}.ui-ist__row--header .ui-ist__cell--spacer{background:var(--ui-ist-header-bg, #ffffff)}.ui-ist__cell-text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ui-ist__skeleton{display:block;width:100%}.ui-ist--scrolled-start .ui-ist__cell--sticky-start-edge{box-shadow:24px 8px 24px #24242414}.ui-ist--scrolled-end .ui-ist__cell--sticky-end{box-shadow:0 8px 24px 4px #24242414}.ui-ist__state{padding:8px 24px;font-size:14px;line-height:20px}.ui-ist--condensed .ui-ist__cell{padding:8px 12px}.ui-ist--condensed .ui-ist__cell:first-child{padding-left:24px}.ui-ist--condensed .ui-ist__cell--sticky-end{padding-right:24px}.ui-ist--condensed .ui-ist__cell--spacer{padding:0}:host(.ui-ist--fill-host){height:100%}.ui-ist--fill-height{height:100%}.ui-ist--fill-height .ui-ist__body{min-height:0}.ui-ist__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: SkeletonComponent, selector: "ui-skeleton", inputs: ["count", "theme", "appearance", "isAiTheme", "applicationTheme"] }, { kind: "component", type: CheckboxComponent, selector: "ui-checkbox", inputs: ["disabled", "checked", "indeterminate", "companyColor", "name", "label", "multiple", "applicationTheme", "ariaLabel", "ariaRequired", "hasError", "hideBuiltInErrors", "hideLabelInErrors", "ariaLabelledby", "ariaDescribedby", "truncateText", "alignment", "tabIndex"], outputs: ["changed"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: UiTranslatePipe, name: "uiTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
640
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.19", type: InfiniteScrollTableComponent, isStandalone: true, selector: "ui-infinite-scroll-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: true, transformFunction: null }, trackBy: { classPropertyName: "trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null }, rowIdKey: { classPropertyName: "rowIdKey", publicName: "rowIdKey", isSignal: true, isRequired: false, transformFunction: null }, minBufferPx: { classPropertyName: "minBufferPx", publicName: "minBufferPx", isSignal: true, isRequired: false, transformFunction: null }, maxBufferPx: { classPropertyName: "maxBufferPx", publicName: "maxBufferPx", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, fillHeight: { classPropertyName: "fillHeight", publicName: "fillHeight", isSignal: true, isRequired: false, transformFunction: null }, isCondensed: { classPropertyName: "isCondensed", publicName: "isCondensed", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, rowsClickable: { classPropertyName: "rowsClickable", publicName: "rowsClickable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadingMore: { classPropertyName: "loadingMore", publicName: "loadingMore", isSignal: true, isRequired: false, transformFunction: null }, hasMore: { classPropertyName: "hasMore", publicName: "hasMore", isSignal: true, isRequired: true, transformFunction: null }, skeletonRowCount: { classPropertyName: "skeletonRowCount", publicName: "skeletonRowCount", isSignal: true, isRequired: false, transformFunction: null }, loadMoreSkeletonCount: { classPropertyName: "loadMoreSkeletonCount", publicName: "loadMoreSkeletonCount", isSignal: true, isRequired: false, transformFunction: null }, loadingColumnCount: { classPropertyName: "loadingColumnCount", publicName: "loadingColumnCount", isSignal: true, isRequired: false, transformFunction: null }, loadMoreThreshold: { classPropertyName: "loadMoreThreshold", publicName: "loadMoreThreshold", isSignal: true, isRequired: false, transformFunction: null }, noDataTemplate: { classPropertyName: "noDataTemplate", publicName: "noDataTemplate", isSignal: true, isRequired: false, transformFunction: null }, errorTemplate: { classPropertyName: "errorTemplate", publicName: "errorTemplate", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, endOfListTemplate: { classPropertyName: "endOfListTemplate", publicName: "endOfListTemplate", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { loadMore: "loadMore", retry: "retry", rowClick: "rowClick", selectionChange: "selectionChange" }, host: { properties: { "class.ui-ist--fill-host": "fillHeight()" } }, viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }, { propertyName: "headerScroll", first: true, predicate: ["headerScroll"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- role=\"table\", not \"grid\": row access is Tab-only with no arrow-key cell traversal, so \"grid\" would\n promise 2D keyboard navigation this does not implement. Selection is conveyed by the row's checkbox,\n not `aria-selected` \u2014 which is valid only on grid/treegrid anyway. -->\n<div\n class=\"ui-ist\"\n role=\"table\"\n [class.ui-ist--condensed]=\"isCondensed()\"\n [class.ui-ist--scrolled-start]=\"!scrollStart()\"\n [class.ui-ist--scrolled-end]=\"horizontalScroll() && !scrollEnd()\"\n [class.ui-ist--fill-height]=\"fillHeight()\"\n [attr.aria-rowcount]=\"hasMore() ? -1 : data().length + 1\"\n [attr.aria-busy]=\"loading() || loadingMore()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.data-testid]=\"testId()\"\n>\n <!-- Pinned header, outside the viewport so it never scrolls vertically. The outer element reserves the\n body's scrollbar width as padding (keeping the background and border across that strip); the inner\n one carries the horizontal scrollLeft synced from the body. -->\n <div class=\"ui-ist__header\" [style.padding-right.px]=\"scrollbarWidth()\" role=\"presentation\">\n <div #headerScroll class=\"ui-ist__header-scroll\" role=\"presentation\">\n <div class=\"ui-ist__row ui-ist__row--header\" role=\"row\" aria-rowindex=\"1\">\n @if (selectable()) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"columnheader\"\n ></div>\n }\n @for (column of columns(); track column.key; let colIndex = $index) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header\"\n role=\"columnheader\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n >\n @if (column.headerCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.headerCellTemplate; context: { $implicit: column.title, column, colIndex }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ column.title }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </div>\n </div>\n\n <!-- The CDK viewport owns BOTH vertical (virtualized) and horizontal scroll, so sticky columns pin\n against it and the horizontal scrollbar sits at the viewport bottom. -->\n @if (showViewport()) {\n <cdk-virtual-scroll-viewport\n class=\"ui-ist__body\"\n role=\"rowgroup\"\n [itemSize]=\"rowHeight()\"\n [minBufferPx]=\"effectiveMinBufferPx()\"\n [maxBufferPx]=\"effectiveMaxBufferPx()\"\n [style.height]=\"viewportHeight()\"\n [style.max-height]=\"fillHeight() ? maxHeight() : null\"\n >\n <div\n *cdkVirtualFor=\"let row of renderRows(); let rowIndex = index; trackBy: renderRowTrackBy\"\n class=\"ui-ist__row\"\n role=\"row\"\n [class.ui-ist__row--clickable]=\"rowsClickable() && row.kind === 'data'\"\n [class.ui-ist__row--selected]=\"isRowSelected(row)\"\n [attr.aria-rowindex]=\"row.kind === 'data' ? row.index + 2 : null\"\n [attr.aria-hidden]=\"row.kind === 'skeleton' ? true : null\"\n [attr.tabindex]=\"rowsClickable() && row.kind === 'data' ? 0 : null\"\n [style.height.px]=\"rowHeight()\"\n [attr.data-testid]=\"rowTestId(row)\"\n (click)=\"emitRowClick($event, row)\"\n (keydown.enter)=\"activateRow($event, row)\"\n (keydown.space)=\"activateRow($event, row)\"\n >\n @if (selectable()) {\n <!-- This `stopPropagation` is what actually stops a checkbox click activating the row: it runs\n before the click reaches the row's listener, so `isInteractiveTarget` is never consulted on\n this path. That guard is a real second line of defence (`ui-checkbox` renders a focusable\n wrapper and a native input, both matching INTERACTIVE_TARGET_SELECTOR), not a substitute. -->\n <div\n class=\"ui-ist__cell ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"cell\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n >\n @if (row.kind === 'data') {\n <ui-checkbox\n [checked]=\"isRowSelected(row)\"\n [ariaLabel]=\"'Select row ' + (row.index + 1)\"\n [testId]=\"rowCheckboxTestId(row)\"\n (changed)=\"emitSelectionChange(row, $event)\"\n ></ui-checkbox>\n }\n </div>\n }\n @for (column of columns(); track column.key) {\n <div\n class=\"ui-ist__cell\"\n role=\"cell\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n [attr.data-testid]=\"cellTestId(row, column.key)\"\n >\n @if (row.kind === 'skeleton') {\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n } @else if (column.rowCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.rowCellTemplate; context: { $implicit: row.item, rowIndex: row.index }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ getCellValue(row.item, column.key) }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- `showErrorFooter()` and `showErrorState()` differ only on `hasData()`, so they are mutually\n exclusive and safe to merge here. Both fall back to a plain-language message, so a failed fetch is\n never a silent blank box. -->\n @if (showErrorFooter() || showErrorState()) {\n <div class=\"ui-ist__state\" role=\"alert\">\n @if (errorTemplate(); as errorTpl) {\n <ng-container *ngTemplateOutlet=\"errorTpl; context: errorContext\"></ng-container>\n } @else {\n <span>{{ translationContext + 'LOAD_ERROR' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n @if (showEmptyState()) {\n <div class=\"ui-ist__state\">\n @if (noDataTemplate(); as emptyTpl) {\n <ng-container *ngTemplateOutlet=\"emptyTpl\"></ng-container>\n } @else {\n <span>{{ translationContext + 'NO_ROWS' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n <!-- Opt-in, with no fallback (see `endOfListTemplate`). Not role=\"alert\": reaching the end is not an\n alert, and `aria-rowcount` already conveys completeness to assistive tech. -->\n @if (showEndOfList() && endOfListTemplate(); as endTpl) {\n <div class=\"ui-ist__state\">\n <ng-container *ngTemplateOutlet=\"endTpl\"></ng-container>\n </div>\n }\n\n <span class=\"ui-ist__sr-only\" role=\"status\" aria-live=\"polite\">\n @if (statusMessageKey(); as statusKey) {\n {{ statusKey | uiTranslate | async }}\n }\n </span>\n</div>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{display:block}.ui-ist{--ui-ist-checkbox-width: 56px;--ui-ist-skeleton-bg: #f4f4f4;display:flex;flex-direction:column;border:1px solid #e0e0e0;border-radius:8px;overflow:hidden;background:#fff}.ui-ist__header{flex:0 0 auto;box-sizing:border-box;overflow:hidden;border-bottom:1px solid #e0e0e0;background:var(--ui-ist-header-bg, #ffffff)}.ui-ist__header-scroll{overflow:hidden}.ui-ist__body{flex:1 1 auto;overflow:auto;scrollbar-width:auto}.ui-ist__body::-webkit-scrollbar{width:8px;height:8px}.ui-ist__body::-webkit-scrollbar-button{display:none}.ui-ist__body::-webkit-scrollbar-thumb{background-color:#00000059;border-radius:4px}.ui-ist__body::-webkit-scrollbar-track:hover{background-color:#00000026}.ui-ist__row{display:flex;width:max-content;min-width:100%;box-sizing:border-box}.ui-ist__row--header{min-height:56px}.ui-ist__row:not(.ui-ist__row--header){border-bottom:1px solid #d3d3d3}.ui-ist__row--clickable{cursor:pointer}.ui-ist__row--clickable:not(.ui-ist__row--selected):hover{background:#fff2fc}.ui-ist__row--clickable:not(.ui-ist__row--selected):hover .ui-ist__cell{background:#fff2fc}.ui-ist__row--selected .ui-ist__cell{background:#f4f4f4}.ui-ist__cell{flex-grow:0;flex-shrink:0;box-sizing:border-box;display:flex;align-items:center;padding:8px 24px;font-size:14px;line-height:20px;overflow:hidden;background:#fff}.ui-ist__cell--header{background:var(--ui-ist-header-bg, #ffffff);font-weight:700;font-size:14px;line-height:16px}.ui-ist__cell--right{justify-content:flex-end;text-align:right}.ui-ist__cell--center{justify-content:center;text-align:center}.ui-ist__cell--sticky-start{position:sticky;z-index:2}.ui-ist__cell--checkbox.ui-ist__cell--sticky-start{left:0}.ui-ist__cell--sticky-end{position:sticky;right:0;z-index:2;order:1}.ui-ist__cell--checkbox{flex:0 0 var(--ui-ist-checkbox-width);min-width:var(--ui-ist-checkbox-width);justify-content:center;padding:0}.ui-ist__cell--spacer{flex:1 1 auto;min-width:0;padding:0}.ui-ist__row--header .ui-ist__cell--spacer{background:var(--ui-ist-header-bg, #ffffff)}.ui-ist__cell-text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ui-ist__skeleton{display:block;width:100%}.ui-ist--scrolled-start .ui-ist__cell--sticky-start-edge{box-shadow:24px 8px 24px #24242414}.ui-ist--scrolled-end .ui-ist__cell--sticky-end{box-shadow:0 8px 24px 4px #24242414}.ui-ist__state{padding:8px 24px;font-size:14px;line-height:20px}.ui-ist--condensed .ui-ist__cell{padding:8px 12px}.ui-ist--condensed .ui-ist__cell:first-child{padding-left:24px}.ui-ist--condensed .ui-ist__cell--sticky-end{padding-right:24px}.ui-ist--condensed .ui-ist__cell--spacer{padding:0}:host(.ui-ist--fill-host){height:100%}.ui-ist--fill-height{height:100%}.ui-ist--fill-height .ui-ist__body{min-height:0}.ui-ist__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: SkeletonComponent, selector: "ui-skeleton", inputs: ["count", "theme", "appearance", "isAiTheme", "applicationTheme"] }, { kind: "component", type: CheckboxComponent, selector: "ui-checkbox", inputs: ["disabled", "checked", "indeterminate", "companyColor", "name", "label", "multiple", "applicationTheme", "ariaLabel", "testId", "ariaRequired", "hasError", "hideBuiltInErrors", "hideLabelInErrors", "ariaLabelledby", "ariaDescribedby", "truncateText", "alignment", "tabIndex"], outputs: ["changed"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: UiTranslatePipe, name: "uiTranslate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
627
641
|
}
|
|
628
642
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InfiniteScrollTableComponent, decorators: [{
|
|
629
643
|
type: Component,
|
|
@@ -638,8 +652,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.19", ngImpo
|
|
|
638
652
|
SkeletonComponent,
|
|
639
653
|
CheckboxComponent,
|
|
640
654
|
UiTranslatePipe,
|
|
641
|
-
], template: "<!-- role=\"table\", not \"grid\": row access is Tab-only with no arrow-key cell traversal, so \"grid\" would\n promise 2D keyboard navigation this does not implement. Selection is conveyed by the row's checkbox,\n not `aria-selected` \u2014 which is valid only on grid/treegrid anyway. -->\n<div\n class=\"ui-ist\"\n role=\"table\"\n [class.ui-ist--condensed]=\"isCondensed()\"\n [class.ui-ist--scrolled-start]=\"!scrollStart()\"\n [class.ui-ist--scrolled-end]=\"horizontalScroll() && !scrollEnd()\"\n [class.ui-ist--fill-height]=\"fillHeight()\"\n [attr.aria-rowcount]=\"hasMore() ? -1 : data().length + 1\"\n [attr.aria-busy]=\"loading() || loadingMore()\"\n>\n <!-- Pinned header, outside the viewport so it never scrolls vertically. The outer element reserves the\n body's scrollbar width as padding (keeping the background and border across that strip); the inner\n one carries the horizontal scrollLeft synced from the body. -->\n <div class=\"ui-ist__header\" [style.padding-right.px]=\"scrollbarWidth()\" role=\"presentation\">\n <div #headerScroll class=\"ui-ist__header-scroll\" role=\"presentation\">\n <div class=\"ui-ist__row ui-ist__row--header\" role=\"row\" aria-rowindex=\"1\">\n @if (selectable()) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"columnheader\"\n ></div>\n }\n @for (column of columns(); track column.key; let colIndex = $index) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header\"\n role=\"columnheader\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n >\n @if (column.headerCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.headerCellTemplate; context: { $implicit: column.title, column, colIndex }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ column.title }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </div>\n </div>\n\n <!-- The CDK viewport owns BOTH vertical (virtualized) and horizontal scroll, so sticky columns pin\n against it and the horizontal scrollbar sits at the viewport bottom. -->\n @if (showViewport()) {\n <cdk-virtual-scroll-viewport\n class=\"ui-ist__body\"\n role=\"rowgroup\"\n [itemSize]=\"rowHeight()\"\n [minBufferPx]=\"effectiveMinBufferPx()\"\n [maxBufferPx]=\"effectiveMaxBufferPx()\"\n [style.height]=\"viewportHeight()\"\n [style.max-height]=\"fillHeight() ? maxHeight() : null\"\n >\n <div\n *cdkVirtualFor=\"let row of renderRows(); let rowIndex = index; trackBy: renderRowTrackBy\"\n class=\"ui-ist__row\"\n role=\"row\"\n [class.ui-ist__row--clickable]=\"rowsClickable() && row.kind === 'data'\"\n [class.ui-ist__row--selected]=\"isRowSelected(row)\"\n [attr.aria-rowindex]=\"row.kind === 'data' ? row.index + 2 : null\"\n [attr.aria-hidden]=\"row.kind === 'skeleton' ? true : null\"\n [attr.tabindex]=\"rowsClickable() && row.kind === 'data' ? 0 : null\"\n [style.height.px]=\"rowHeight()\"\n (click)=\"emitRowClick($event, row)\"\n (keydown.enter)=\"activateRow($event, row)\"\n (keydown.space)=\"activateRow($event, row)\"\n >\n @if (selectable()) {\n <!-- This `stopPropagation` is what actually stops a checkbox click activating the row: it runs\n before the click reaches the row's listener, so `isInteractiveTarget` is never consulted on\n this path. That guard is a real second line of defence (`ui-checkbox` renders a focusable\n wrapper and a native input, both matching INTERACTIVE_TARGET_SELECTOR), not a substitute. -->\n <div\n class=\"ui-ist__cell ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"cell\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n >\n @if (row.kind === 'data') {\n <ui-checkbox\n [checked]=\"isRowSelected(row)\"\n [ariaLabel]=\"'Select row ' + (row.index + 1)\"\n (changed)=\"emitSelectionChange(row, $event)\"\n ></ui-checkbox>\n }\n </div>\n }\n @for (column of columns(); track column.key) {\n <div\n class=\"ui-ist__cell\"\n role=\"cell\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n >\n @if (row.kind === 'skeleton') {\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n } @else if (column.rowCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.rowCellTemplate; context: { $implicit: row.item, rowIndex: row.index }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ getCellValue(row.item, column.key) }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- `showErrorFooter()` and `showErrorState()` differ only on `hasData()`, so they are mutually\n exclusive and safe to merge here. Both fall back to a plain-language message, so a failed fetch is\n never a silent blank box. -->\n @if (showErrorFooter() || showErrorState()) {\n <div class=\"ui-ist__state\" role=\"alert\">\n @if (errorTemplate(); as errorTpl) {\n <ng-container *ngTemplateOutlet=\"errorTpl; context: errorContext\"></ng-container>\n } @else {\n <span>{{ translationContext + 'LOAD_ERROR' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n @if (showEmptyState()) {\n <div class=\"ui-ist__state\">\n @if (noDataTemplate(); as emptyTpl) {\n <ng-container *ngTemplateOutlet=\"emptyTpl\"></ng-container>\n } @else {\n <span>{{ translationContext + 'NO_ROWS' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n <!-- Opt-in, with no fallback (see `endOfListTemplate`). Not role=\"alert\": reaching the end is not an\n alert, and `aria-rowcount` already conveys completeness to assistive tech. -->\n @if (showEndOfList() && endOfListTemplate(); as endTpl) {\n <div class=\"ui-ist__state\">\n <ng-container *ngTemplateOutlet=\"endTpl\"></ng-container>\n </div>\n }\n\n <span class=\"ui-ist__sr-only\" role=\"status\" aria-live=\"polite\">\n @if (statusMessageKey(); as statusKey) {\n {{ statusKey | uiTranslate | async }}\n }\n </span>\n</div>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{display:block}.ui-ist{--ui-ist-checkbox-width: 56px;--ui-ist-skeleton-bg: #f4f4f4;display:flex;flex-direction:column;border:1px solid #e0e0e0;border-radius:8px;overflow:hidden;background:#fff}.ui-ist__header{flex:0 0 auto;box-sizing:border-box;overflow:hidden;border-bottom:1px solid #e0e0e0;background:var(--ui-ist-header-bg, #ffffff)}.ui-ist__header-scroll{overflow:hidden}.ui-ist__body{flex:1 1 auto;overflow:auto;scrollbar-width:auto}.ui-ist__body::-webkit-scrollbar{width:8px;height:8px}.ui-ist__body::-webkit-scrollbar-button{display:none}.ui-ist__body::-webkit-scrollbar-thumb{background-color:#00000059;border-radius:4px}.ui-ist__body::-webkit-scrollbar-track:hover{background-color:#00000026}.ui-ist__row{display:flex;width:max-content;min-width:100%;box-sizing:border-box}.ui-ist__row--header{min-height:56px}.ui-ist__row:not(.ui-ist__row--header){border-bottom:1px solid #d3d3d3}.ui-ist__row--clickable{cursor:pointer}.ui-ist__row--clickable:not(.ui-ist__row--selected):hover{background:#fff2fc}.ui-ist__row--clickable:not(.ui-ist__row--selected):hover .ui-ist__cell{background:#fff2fc}.ui-ist__row--selected .ui-ist__cell{background:#f4f4f4}.ui-ist__cell{flex-grow:0;flex-shrink:0;box-sizing:border-box;display:flex;align-items:center;padding:8px 24px;font-size:14px;line-height:20px;overflow:hidden;background:#fff}.ui-ist__cell--header{background:var(--ui-ist-header-bg, #ffffff);font-weight:700;font-size:14px;line-height:16px}.ui-ist__cell--right{justify-content:flex-end;text-align:right}.ui-ist__cell--center{justify-content:center;text-align:center}.ui-ist__cell--sticky-start{position:sticky;z-index:2}.ui-ist__cell--checkbox.ui-ist__cell--sticky-start{left:0}.ui-ist__cell--sticky-end{position:sticky;right:0;z-index:2;order:1}.ui-ist__cell--checkbox{flex:0 0 var(--ui-ist-checkbox-width);min-width:var(--ui-ist-checkbox-width);justify-content:center;padding:0}.ui-ist__cell--spacer{flex:1 1 auto;min-width:0;padding:0}.ui-ist__row--header .ui-ist__cell--spacer{background:var(--ui-ist-header-bg, #ffffff)}.ui-ist__cell-text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ui-ist__skeleton{display:block;width:100%}.ui-ist--scrolled-start .ui-ist__cell--sticky-start-edge{box-shadow:24px 8px 24px #24242414}.ui-ist--scrolled-end .ui-ist__cell--sticky-end{box-shadow:0 8px 24px 4px #24242414}.ui-ist__state{padding:8px 24px;font-size:14px;line-height:20px}.ui-ist--condensed .ui-ist__cell{padding:8px 12px}.ui-ist--condensed .ui-ist__cell:first-child{padding-left:24px}.ui-ist--condensed .ui-ist__cell--sticky-end{padding-right:24px}.ui-ist--condensed .ui-ist__cell--spacer{padding:0}:host(.ui-ist--fill-host){height:100%}.ui-ist--fill-height{height:100%}.ui-ist--fill-height .ui-ist__body{min-height:0}.ui-ist__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
|
|
642
|
-
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: true }] }], trackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackBy", required: false }] }], rowIdKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIdKey", required: false }] }], minBufferPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "minBufferPx", required: false }] }], maxBufferPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxBufferPx", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], fillHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillHeight", required: false }] }], isCondensed: [{ type: i0.Input, args: [{ isSignal: true, alias: "isCondensed", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], rowsClickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsClickable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingMore: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingMore", required: false }] }], hasMore: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMore", required: true }] }], skeletonRowCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonRowCount", required: false }] }], loadMoreSkeletonCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadMoreSkeletonCount", required: false }] }], loadingColumnCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingColumnCount", required: false }] }], loadMoreThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadMoreThreshold", required: false }] }], noDataTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "noDataTemplate", required: false }] }], errorTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorTemplate", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], endOfListTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "endOfListTemplate", required: false }] }], loadMore: [{ type: i0.Output, args: ["loadMore"] }], retry: [{ type: i0.Output, args: ["retry"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], viewport: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkVirtualScrollViewport), { isSignal: true }] }], headerScroll: [{ type: i0.ViewChild, args: ['headerScroll', { isSignal: true }] }] } });
|
|
655
|
+
], template: "<!-- role=\"table\", not \"grid\": row access is Tab-only with no arrow-key cell traversal, so \"grid\" would\n promise 2D keyboard navigation this does not implement. Selection is conveyed by the row's checkbox,\n not `aria-selected` \u2014 which is valid only on grid/treegrid anyway. -->\n<div\n class=\"ui-ist\"\n role=\"table\"\n [class.ui-ist--condensed]=\"isCondensed()\"\n [class.ui-ist--scrolled-start]=\"!scrollStart()\"\n [class.ui-ist--scrolled-end]=\"horizontalScroll() && !scrollEnd()\"\n [class.ui-ist--fill-height]=\"fillHeight()\"\n [attr.aria-rowcount]=\"hasMore() ? -1 : data().length + 1\"\n [attr.aria-busy]=\"loading() || loadingMore()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.data-testid]=\"testId()\"\n>\n <!-- Pinned header, outside the viewport so it never scrolls vertically. The outer element reserves the\n body's scrollbar width as padding (keeping the background and border across that strip); the inner\n one carries the horizontal scrollLeft synced from the body. -->\n <div class=\"ui-ist__header\" [style.padding-right.px]=\"scrollbarWidth()\" role=\"presentation\">\n <div #headerScroll class=\"ui-ist__header-scroll\" role=\"presentation\">\n <div class=\"ui-ist__row ui-ist__row--header\" role=\"row\" aria-rowindex=\"1\">\n @if (selectable()) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"columnheader\"\n ></div>\n }\n @for (column of columns(); track column.key; let colIndex = $index) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header\"\n role=\"columnheader\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n >\n @if (column.headerCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.headerCellTemplate; context: { $implicit: column.title, column, colIndex }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ column.title }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </div>\n </div>\n\n <!-- The CDK viewport owns BOTH vertical (virtualized) and horizontal scroll, so sticky columns pin\n against it and the horizontal scrollbar sits at the viewport bottom. -->\n @if (showViewport()) {\n <cdk-virtual-scroll-viewport\n class=\"ui-ist__body\"\n role=\"rowgroup\"\n [itemSize]=\"rowHeight()\"\n [minBufferPx]=\"effectiveMinBufferPx()\"\n [maxBufferPx]=\"effectiveMaxBufferPx()\"\n [style.height]=\"viewportHeight()\"\n [style.max-height]=\"fillHeight() ? maxHeight() : null\"\n >\n <div\n *cdkVirtualFor=\"let row of renderRows(); let rowIndex = index; trackBy: renderRowTrackBy\"\n class=\"ui-ist__row\"\n role=\"row\"\n [class.ui-ist__row--clickable]=\"rowsClickable() && row.kind === 'data'\"\n [class.ui-ist__row--selected]=\"isRowSelected(row)\"\n [attr.aria-rowindex]=\"row.kind === 'data' ? row.index + 2 : null\"\n [attr.aria-hidden]=\"row.kind === 'skeleton' ? true : null\"\n [attr.tabindex]=\"rowsClickable() && row.kind === 'data' ? 0 : null\"\n [style.height.px]=\"rowHeight()\"\n [attr.data-testid]=\"rowTestId(row)\"\n (click)=\"emitRowClick($event, row)\"\n (keydown.enter)=\"activateRow($event, row)\"\n (keydown.space)=\"activateRow($event, row)\"\n >\n @if (selectable()) {\n <!-- This `stopPropagation` is what actually stops a checkbox click activating the row: it runs\n before the click reaches the row's listener, so `isInteractiveTarget` is never consulted on\n this path. That guard is a real second line of defence (`ui-checkbox` renders a focusable\n wrapper and a native input, both matching INTERACTIVE_TARGET_SELECTOR), not a substitute. -->\n <div\n class=\"ui-ist__cell ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"cell\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n >\n @if (row.kind === 'data') {\n <ui-checkbox\n [checked]=\"isRowSelected(row)\"\n [ariaLabel]=\"'Select row ' + (row.index + 1)\"\n [testId]=\"rowCheckboxTestId(row)\"\n (changed)=\"emitSelectionChange(row, $event)\"\n ></ui-checkbox>\n }\n </div>\n }\n @for (column of columns(); track column.key) {\n <div\n class=\"ui-ist__cell\"\n role=\"cell\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n [attr.data-testid]=\"cellTestId(row, column.key)\"\n >\n @if (row.kind === 'skeleton') {\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n } @else if (column.rowCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.rowCellTemplate; context: { $implicit: row.item, rowIndex: row.index }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ getCellValue(row.item, column.key) }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- `showErrorFooter()` and `showErrorState()` differ only on `hasData()`, so they are mutually\n exclusive and safe to merge here. Both fall back to a plain-language message, so a failed fetch is\n never a silent blank box. -->\n @if (showErrorFooter() || showErrorState()) {\n <div class=\"ui-ist__state\" role=\"alert\">\n @if (errorTemplate(); as errorTpl) {\n <ng-container *ngTemplateOutlet=\"errorTpl; context: errorContext\"></ng-container>\n } @else {\n <span>{{ translationContext + 'LOAD_ERROR' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n @if (showEmptyState()) {\n <div class=\"ui-ist__state\">\n @if (noDataTemplate(); as emptyTpl) {\n <ng-container *ngTemplateOutlet=\"emptyTpl\"></ng-container>\n } @else {\n <span>{{ translationContext + 'NO_ROWS' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n <!-- Opt-in, with no fallback (see `endOfListTemplate`). Not role=\"alert\": reaching the end is not an\n alert, and `aria-rowcount` already conveys completeness to assistive tech. -->\n @if (showEndOfList() && endOfListTemplate(); as endTpl) {\n <div class=\"ui-ist__state\">\n <ng-container *ngTemplateOutlet=\"endTpl\"></ng-container>\n </div>\n }\n\n <span class=\"ui-ist__sr-only\" role=\"status\" aria-live=\"polite\">\n @if (statusMessageKey(); as statusKey) {\n {{ statusKey | uiTranslate | async }}\n }\n </span>\n</div>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{display:block}.ui-ist{--ui-ist-checkbox-width: 56px;--ui-ist-skeleton-bg: #f4f4f4;display:flex;flex-direction:column;border:1px solid #e0e0e0;border-radius:8px;overflow:hidden;background:#fff}.ui-ist__header{flex:0 0 auto;box-sizing:border-box;overflow:hidden;border-bottom:1px solid #e0e0e0;background:var(--ui-ist-header-bg, #ffffff)}.ui-ist__header-scroll{overflow:hidden}.ui-ist__body{flex:1 1 auto;overflow:auto;scrollbar-width:auto}.ui-ist__body::-webkit-scrollbar{width:8px;height:8px}.ui-ist__body::-webkit-scrollbar-button{display:none}.ui-ist__body::-webkit-scrollbar-thumb{background-color:#00000059;border-radius:4px}.ui-ist__body::-webkit-scrollbar-track:hover{background-color:#00000026}.ui-ist__row{display:flex;width:max-content;min-width:100%;box-sizing:border-box}.ui-ist__row--header{min-height:56px}.ui-ist__row:not(.ui-ist__row--header){border-bottom:1px solid #d3d3d3}.ui-ist__row--clickable{cursor:pointer}.ui-ist__row--clickable:not(.ui-ist__row--selected):hover{background:#fff2fc}.ui-ist__row--clickable:not(.ui-ist__row--selected):hover .ui-ist__cell{background:#fff2fc}.ui-ist__row--selected .ui-ist__cell{background:#f4f4f4}.ui-ist__cell{flex-grow:0;flex-shrink:0;box-sizing:border-box;display:flex;align-items:center;padding:8px 24px;font-size:14px;line-height:20px;overflow:hidden;background:#fff}.ui-ist__cell--header{background:var(--ui-ist-header-bg, #ffffff);font-weight:700;font-size:14px;line-height:16px}.ui-ist__cell--right{justify-content:flex-end;text-align:right}.ui-ist__cell--center{justify-content:center;text-align:center}.ui-ist__cell--sticky-start{position:sticky;z-index:2}.ui-ist__cell--checkbox.ui-ist__cell--sticky-start{left:0}.ui-ist__cell--sticky-end{position:sticky;right:0;z-index:2;order:1}.ui-ist__cell--checkbox{flex:0 0 var(--ui-ist-checkbox-width);min-width:var(--ui-ist-checkbox-width);justify-content:center;padding:0}.ui-ist__cell--spacer{flex:1 1 auto;min-width:0;padding:0}.ui-ist__row--header .ui-ist__cell--spacer{background:var(--ui-ist-header-bg, #ffffff)}.ui-ist__cell-text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ui-ist__skeleton{display:block;width:100%}.ui-ist--scrolled-start .ui-ist__cell--sticky-start-edge{box-shadow:24px 8px 24px #24242414}.ui-ist--scrolled-end .ui-ist__cell--sticky-end{box-shadow:0 8px 24px 4px #24242414}.ui-ist__state{padding:8px 24px;font-size:14px;line-height:20px}.ui-ist--condensed .ui-ist__cell{padding:8px 12px}.ui-ist--condensed .ui-ist__cell:first-child{padding-left:24px}.ui-ist--condensed .ui-ist__cell--sticky-end{padding-right:24px}.ui-ist--condensed .ui-ist__cell--spacer{padding:0}:host(.ui-ist--fill-host){height:100%}.ui-ist--fill-height{height:100%}.ui-ist--fill-height .ui-ist__body{min-height:0}.ui-ist__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
|
|
656
|
+
}], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: true }] }], trackBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackBy", required: false }] }], rowIdKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowIdKey", required: false }] }], minBufferPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "minBufferPx", required: false }] }], maxBufferPx: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxBufferPx", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], fillHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "fillHeight", required: false }] }], isCondensed: [{ type: i0.Input, args: [{ isSignal: true, alias: "isCondensed", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], rowsClickable: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsClickable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadingMore: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingMore", required: false }] }], hasMore: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMore", required: true }] }], skeletonRowCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "skeletonRowCount", required: false }] }], loadMoreSkeletonCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadMoreSkeletonCount", required: false }] }], loadingColumnCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingColumnCount", required: false }] }], loadMoreThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadMoreThreshold", required: false }] }], noDataTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "noDataTemplate", required: false }] }], errorTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorTemplate", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], endOfListTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "endOfListTemplate", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], loadMore: [{ type: i0.Output, args: ["loadMore"] }], retry: [{ type: i0.Output, args: ["retry"] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], viewport: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkVirtualScrollViewport), { isSignal: true }] }], headerScroll: [{ type: i0.ViewChild, args: ['headerScroll', { isSignal: true }] }] } });
|
|
643
657
|
|
|
644
658
|
class InfiniteScrollTableComponentModule {
|
|
645
659
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.19", ngImport: i0, type: InfiniteScrollTableComponentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testgorilla-tgo-ui-components-infinite-scroll-table.mjs","sources":["../../../components/infinite-scroll-table/infinite-scroll-table.component.ts","../../../components/infinite-scroll-table/infinite-scroll-table.component.html","../../../components/infinite-scroll-table/infinite-scroll-table.component.module.ts","../../../components/infinite-scroll-table/testgorilla-tgo-ui-components-infinite-scroll-table.ts"],"sourcesContent":["import { CdkFixedSizeVirtualScroll, CdkVirtualForOf, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';\nimport { AsyncPipe, NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n input,\n isDevMode,\n numberAttribute,\n output,\n signal,\n TemplateRef,\n TrackByFunction,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { animationFrameScheduler, Subscription } from 'rxjs';\nimport { auditTime } from 'rxjs/operators';\n\nimport { CheckboxComponent } from '@testgorilla/tgo-ui/components/checkbox';\nimport { UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\nimport { SkeletonComponent } from '@testgorilla/tgo-ui/components/skeleton';\n\nimport {\n InfiniteScrollTableColumn,\n InfiniteScrollTableErrorContext,\n InfiniteScrollTableRowClick,\n InfiniteScrollTableRowLike,\n InfiniteScrollTableRowSelection,\n} from './infinite-scroll-table.model';\n\n/** Internal row wrapper so real rows and skeleton placeholders flow through one virtual list. */\ntype RenderRow<T> = { kind: 'data'; item: T; index: number } | { kind: 'skeleton'; id: string };\n\nconst DEFAULT_FIRST_LOAD_SKELETON_COUNT = 10;\nconst DEFAULT_LOAD_MORE_SKELETON_COUNT = 3;\nconst DEFAULT_LOAD_MORE_THRESHOLD = 5;\n\n/**\n * Fallback width for a column that declares none, shared with placeholder columns so both resolve to one\n * identical width — header/body alignment depends on that.\n */\nconst DEFAULT_COLUMN_WIDTH = '160px';\n\n/** Elements owning their own click semantics: a click inside one must not also activate the row. */\nconst INTERACTIVE_TARGET_SELECTOR = 'a, button, input, select, textarea, [role=\"button\"], [tabindex]';\n\n/**\n * A generic, virtualized table with scroll-driven infinite loading. Independent of `ui-table`: it reuses\n * only stable leaf primitives (`ui-skeleton`) and duplicates the column/context type shapes so consumers\n * can migrate with a selector swap.\n */\n@Component({\n selector: 'ui-infinite-scroll-table',\n templateUrl: './infinite-scroll-table.component.html',\n styleUrls: ['./infinite-scroll-table.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n // `:host` cannot be class-bound from the template, so the fill-mode host class is set here instead.\n host: {\n '[class.ui-ist--fill-host]': 'fillHeight()',\n },\n imports: [\n AsyncPipe,\n NgTemplateOutlet,\n CdkVirtualScrollViewport,\n CdkFixedSizeVirtualScroll,\n CdkVirtualForOf,\n SkeletonComponent,\n CheckboxComponent,\n UiTranslatePipe,\n ],\n})\nexport class InfiniteScrollTableComponent<T> {\n /**\n * Rows loaded so far. **Must change by reference** (`[...rows, ...page]`): a signal input cannot observe\n * `rows.push(...)`, so an in-place append renders nothing and leaves `loadMore` disarmed.\n */\n readonly data = input.required<readonly T[]>();\n\n readonly columns = input.required<InfiniteScrollTableColumn<T>[]>();\n\n /** Fixed row height in px (the virtualization `itemSize`). Variable row heights are unsupported. */\n readonly rowHeight = input.required<number>();\n\n /** Stable row identity so recycled rows re-render correctly. Takes precedence over `rowIdKey`. */\n readonly trackBy = input<TrackByFunction<T>>();\n /** Key on each row holding a stable id. Used when `trackBy` is not provided. */\n readonly rowIdKey = input<string>();\n\n /**\n * CDK's rendered buffers. Both default to a multiple of `rowHeight` (~5 and ~10 rows) rather than a\n * fixed px value, which would mean a different row count at every `rowHeight`.\n */\n readonly minBufferPx = input<number | undefined>(undefined);\n readonly maxBufferPx = input<number | undefined>(undefined);\n\n /** Max height of the internal scroll region (e.g. `'70vh'`). The body shrinks to fit fewer rows. */\n readonly maxHeight = input<string>('70vh');\n\n /** Stretch to the parent's height instead of the content's; `maxHeight` becomes a cap, not the target. */\n readonly fillHeight = input(false, { transform: booleanAttribute });\n\n readonly isCondensed = input(false, { transform: booleanAttribute });\n\n /**\n * Prepends a left-pinned checkbox column driven by each row's `selected` property. Consumer-managed\n * (like `ui-table`): toggling only emits `selectionChange`.\n */\n readonly selectable = input(false, { transform: booleanAttribute });\n\n /**\n * Makes rows focusable and activatable by click or Enter/Space. Off by default: a read-only table\n * must not create a tab stop per rendered row or imply interactivity it does not have.\n */\n readonly rowsClickable = input(false, { transform: booleanAttribute });\n\n /** First-load state: renders a full body of skeleton rows. */\n readonly loading = input(false, { transform: booleanAttribute });\n\n /** Appends skeleton rows below the existing rows while the next page is fetched. */\n readonly loadingMore = input(false, { transform: booleanAttribute });\n\n /** Required, not defaulted: a silent \"never load\" default would disable the headline behaviour. */\n readonly hasMore = input.required<boolean, unknown>({ transform: booleanAttribute });\n\n readonly skeletonRowCount = input<number>(DEFAULT_FIRST_LOAD_SKELETON_COUNT);\n\n /** Number of skeleton rows appended below the loaded rows while `loadingMore` is true. */\n readonly loadMoreSkeletonCount = input<number>(DEFAULT_LOAD_MORE_SKELETON_COUNT);\n\n /**\n * Skeleton placeholder columns for a lazily-loaded column set. They deliberately sit OUTSIDE `columns`,\n * so they cannot change which column is last and unpin a sticky last column.\n */\n readonly loadingColumnCount = input(0, { transform: numberAttribute });\n\n readonly loadMoreThreshold = input<number>(DEFAULT_LOAD_MORE_THRESHOLD);\n\n /** Shown when `data` is empty and not loading. */\n readonly noDataTemplate = input<TemplateRef<unknown>>();\n\n /** Shown when `error` is `true`. Receives `{ $implicit: retry, retry }` as context. */\n readonly errorTemplate = input<TemplateRef<InfiniteScrollTableErrorContext>>();\n\n readonly error = input(false, { transform: booleanAttribute });\n\n /**\n * Shown once `hasMore` goes `false` with rows loaded. Deliberately has NO built-in fallback (unlike\n * `noDataTemplate` / `errorTemplate`): a single-page list would otherwise flash \"no more results\".\n */\n readonly endOfListTemplate = input<TemplateRef<unknown>>();\n\n /** Guarded: only when `hasMore && !loading && !loadingMore`, and only once per approach to the end. */\n readonly loadMore = output<void>();\n\n readonly retry = output<void>();\n\n readonly rowClick = output<InfiniteScrollTableRowClick<T>>();\n\n /** The consumer is expected to apply `selected` back onto its own data. */\n readonly selectionChange = output<InfiniteScrollTableRowSelection<T>>();\n\n protected readonly viewport = viewChild(CdkVirtualScrollViewport);\n protected readonly headerScroll = viewChild<ElementRef<HTMLElement>>('headerScroll');\n\n protected readonly scrollStart = signal(true);\n protected readonly scrollEnd = signal(false);\n protected readonly horizontalScroll = signal(false);\n\n /** Reserved as right padding on the header, so its content width exactly equals the body's. */\n protected readonly scrollbarWidth = signal(0);\n\n /** Added to the viewport height so on a short list the scrollbar doesn't eat into the rows. */\n protected readonly hScrollbarHeight = signal(0);\n\n /**\n * Paging latch. Three fields, one rule: `loadMore` emits at most once per page that lands while the\n * user is inside the trigger zone. `isLoadMoreArmed` is the latch itself, written here and by\n * `checkLoadMore`; `dataLengthAtEmit` records how long `data` was when the last emission went out, so\n * \"the requested page arrived\" is a length comparison rather than a guess about scroll positions;\n * `firstVisibleIndex` is where the user actually is.\n *\n * The invariant that matters: arming and firing must read the SAME trigger zone. They used to derive it\n * from two different thresholds, which opened bands the latch could never leave.\n */\n private isLoadMoreArmed = true;\n private dataLengthAtEmit = 0;\n\n /** In-place-mutation detector; see the effect that reads these for the discriminator. */\n private wasLoadingMore = false;\n private lastDataReference: readonly T[] | undefined;\n private lastDataLength = 0;\n\n /** Pending frame for a deferred CDK viewport re-measure, so repeated triggers coalesce to one. */\n private remeasureFrame: number | undefined;\n\n /** Pending frame for the deferred scroll reset. Cancelled on destroy, like every other frame here. */\n private resetScrollFrame: number | undefined;\n\n private previousHeadIdentity: unknown;\n /** Latches once any non-empty `data` is seen, so only the very first render is exempt from resetting. */\n private hasSeenHead = false;\n /** Previous `loading` value, for spotting the false -> true edge that starts a reset. */\n private wasLoading = false;\n\n /**\n * First visible row index, kept current from `viewport.scrolledIndexChange` (no layout read) rather\n * than `viewport.getRenderedRange().start`, which includes CDK's read-ahead buffer.\n */\n private firstVisibleIndex = 0;\n\n protected readonly skeletonTheme = {\n background: 'var(--ui-ist-skeleton-bg)',\n 'border-radius': '4px',\n height: '24px',\n 'margin-bottom': '0',\n };\n\n // Pinning is positional by contract: only the FIRST column pins left, only the LAST pins right.\n // `isSticky` elsewhere is ignored (with a dev warning), not applied as `left: 0` — that would overlay\n // the columns before it.\n protected readonly stickyStartKey = computed(() => {\n const columns = this.columns();\n return columns[0]?.isSticky ? columns[0].key : undefined;\n });\n\n protected readonly stickyEndKey = computed(() => {\n const columns = this.columns();\n const lastIndex = columns.length - 1;\n // `lastIndex > 0` so a single sticky column pins to the start, not the end.\n return lastIndex > 0 && columns[lastIndex]?.isSticky ? columns[lastIndex].key : undefined;\n });\n\n protected readonly defaultColumnWidth = DEFAULT_COLUMN_WIDTH;\n\n protected readonly effectiveMinBufferPx = computed(() => this.minBufferPx() ?? this.rowHeight() * 5);\n\n /**\n * The `Math.max` is load-bearing: CDK throws in dev mode when `maxBufferPx < minBufferPx`, which a\n * consumer triggers just by raising `minBufferPx` above the derived default.\n */\n protected readonly effectiveMaxBufferPx = computed(() =>\n Math.max(this.maxBufferPx() ?? this.rowHeight() * 10, this.effectiveMinBufferPx())\n );\n\n /** Stable keys for the placeholder columns, so `@for` can track them across renders. */\n protected readonly loadingColumns = computed(() =>\n Array.from({ length: Math.max(0, this.loadingColumnCount()) }, (_, index) => `loading-column-${index}`)\n );\n\n protected readonly renderRows = computed<RenderRow<T>[]>(() => {\n if (this.loading()) {\n return Array.from({ length: Math.max(1, this.skeletonRowCount()) }, (_, i) => ({\n kind: 'skeleton' as const,\n id: `skeleton-first-${i}`,\n }));\n }\n\n const rows: RenderRow<T>[] = this.data().map((item, index) => ({ kind: 'data' as const, item, index }));\n\n if (this.loadingMore() && this.hasMore()) {\n for (let i = 0; i < Math.max(1, this.loadMoreSkeletonCount()); i++) {\n rows.push({ kind: 'skeleton' as const, id: `skeleton-more-${i}` });\n }\n }\n\n return rows;\n });\n\n protected readonly hasData = computed(() => this.data().length > 0);\n protected readonly showViewport = computed(() => this.loading() || this.hasData());\n /**\n * `loadingMore` counts as loading here too: a consumer that retries a failed first page through the same\n * flag it uses for every page would otherwise render \"no rows\" with `aria-busy` set and the live region\n * announcing a fetch.\n */\n protected readonly showEmptyState = computed(\n () => !this.loading() && !this.loadingMore() && !this.error() && !this.hasData()\n );\n protected readonly showErrorState = computed(() => !this.loading() && this.error() && !this.hasData());\n protected readonly showErrorFooter = computed(() => !this.loading() && this.error() && this.hasData());\n /**\n * The negative clauses keep this out of slots other states own, and `!loadingMore()` closes a one-tick\n * flash: a fetch completing and the consumer flipping `hasMore` need not land in the same cycle.\n */\n protected readonly showEndOfList = computed(\n () => this.hasData() && !this.hasMore() && !this.loading() && !this.loadingMore() && !this.error()\n );\n\n /**\n * CSS `min()` because the cap mixes units. The scrollbar reserve stops a short list from growing a\n * spurious vertical scrollbar; fill mode returns `null` so flex owns the sizing and the reserve is moot.\n */\n protected readonly viewportHeight = computed<string | null>(() => {\n if (this.fillHeight()) {\n return null;\n }\n const contentHeight = this.renderRows().length * this.rowHeight();\n const scrollbarReserve = this.horizontalScroll() ? this.hScrollbarHeight() : 0;\n return `min(${contentHeight + scrollbarReserve}px, ${this.maxHeight()})`;\n });\n\n protected readonly translationContext = 'INFINITE_SCROLL_TABLE.';\n\n /** A translation key, resolved in the template: screen-reader users are not all English speakers. */\n protected readonly statusMessageKey = computed(() => {\n if (this.loading()) {\n return `${this.translationContext}LOADING`;\n }\n if (this.loadingMore()) {\n return `${this.translationContext}LOADING_MORE`;\n }\n return '';\n });\n\n protected readonly errorContext: InfiniteScrollTableErrorContext = {\n $implicit: () => this.emitRetry(),\n retry: () => this.emitRetry(),\n };\n\n protected readonly renderRowTrackBy: TrackByFunction<RenderRow<T>> = (index, row): unknown => {\n if (row.kind === 'skeleton') {\n return row.id;\n }\n return this.rowIdentity(row.item, row.index);\n };\n\n constructor() {\n // (Re-)attaches scroll listeners as the viewport enters or leaves the DOM. The setup reads other\n // signals, so it is `untracked()` — otherwise every data change would tear the listeners down.\n effect(onCleanup => {\n const viewport = this.viewport();\n if (!viewport) {\n return;\n }\n untracked(() => {\n // A freshly created CdkVirtualScrollViewport always mounts scrolled to the top, and this field\n // carries across viewport instances (`@if (showViewport())` destroys and recreates one when `data`\n // empties and repopulates). Leaving it stale would let `checkLoadMore` fire off a scroll position\n // belonging to the OLD viewport.\n this.firstVisibleIndex = 0;\n\n const element = viewport.elementRef.nativeElement;\n\n // Both patch CDK divs that would otherwise break the ARIA table structure: its content wrapper\n // sits between `role=\"rowgroup\"` and the rows, its spacer is an unlabeled child of the rowgroup.\n // Both selectors are CDK internals, so the optional chaining would swallow a CDK restructure\n // silently. The spec asserts both attributes after mount, which is what turns such a change into a\n // failing test rather than a quietly invalid accessibility tree.\n element.querySelector('.cdk-virtual-scroll-content-wrapper')?.setAttribute('role', 'presentation');\n element.querySelector('.cdk-virtual-scroll-spacer')?.setAttribute('aria-hidden', 'true');\n\n const subscription = new Subscription();\n // Audited to one animation frame, matching CDK's own scroll handler, so `measureScrollOffset`'s\n // forced reflow can't run several times per frame and interleave with CDK's DOM writes.\n subscription.add(\n viewport\n .elementScrolled()\n .pipe(auditTime(0, animationFrameScheduler))\n .subscribe(() => this.syncHorizontalScroll())\n );\n // Neither trigger is redundant: an append changes the rendered range without a scroll, and a scroll\n // inside the read-ahead buffer moves `firstVisibleIndex` without changing the range.\n subscription.add(viewport.renderedRangeStream.subscribe(() => this.checkLoadMore()));\n subscription.add(\n viewport.scrolledIndexChange.subscribe(index => {\n this.firstVisibleIndex = index;\n this.checkLoadMore();\n })\n );\n\n // `offsetWidth - clientWidth` also counts borders: pure scrollbar only because `.ui-ist__body`\n // has none, and it must stay borderless.\n const measureScrollbar = (): void => {\n this.scrollbarWidth.set(element.offsetWidth - element.clientWidth);\n this.hScrollbarHeight.set(element.offsetHeight - element.clientHeight);\n };\n subscription.add(viewport.renderedRangeStream.subscribe(() => measureScrollbar()));\n\n // Covers box changes no signal captures: a flex parent resizing, or a relative `maxHeight`\n // reacting to its container. Signal-driven height changes are the effect below.\n let resizeObserver: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n resizeObserver = new ResizeObserver(() => {\n measureScrollbar();\n // A resize can cross into or out of horizontal overflow without a scroll event, leaving the\n // sticky shadows and `viewportHeight()`'s scrollbar reserve stale.\n this.syncHorizontalScroll();\n this.scheduleViewportRemeasure();\n });\n resizeObserver.observe(element);\n }\n\n measureScrollbar();\n this.syncHorizontalScroll();\n this.checkLoadMore();\n\n // The sync above runs before CDK lays out its rows, so the overflow measurement is stale until\n // the next frame. Guarded because requestAnimationFrame is browser-only (SSR).\n let scrollSyncFrame: number | undefined;\n if (typeof requestAnimationFrame !== 'undefined') {\n scrollSyncFrame = requestAnimationFrame(() => this.syncHorizontalScroll());\n }\n\n onCleanup(() => {\n subscription.unsubscribe();\n resizeObserver?.disconnect();\n // Pending frames must not fire after the viewport leaves the DOM.\n if (scrollSyncFrame !== undefined) {\n cancelAnimationFrame(scrollSyncFrame);\n }\n if (this.remeasureFrame !== undefined) {\n cancelAnimationFrame(this.remeasureFrame);\n this.remeasureFrame = undefined;\n }\n });\n });\n });\n\n // CDK caches its measured size and re-measures only on scroll or window resize, so any signal-driven\n // height change here (`fillHeight` included: it swaps the `min()` cap for a flex-driven height) would\n // leave the new space empty with the tail rows unrendered. Read individually rather than via\n // `viewportHeight()`, to keep the dependency off horizontal-scroll state. `loadingColumnCount` changes\n // content WIDTH not the box, so the ResizeObserver misses it and only the deferred\n // `syncHorizontalScroll()` keeps the horizontal-overflow state current.\n effect(() => {\n this.renderRows();\n this.rowHeight();\n this.maxHeight();\n this.columns();\n this.fillHeight();\n this.loadingColumnCount();\n // Adds a 56px checkbox column: content width changes, the box does not.\n this.selectable();\n this.scheduleViewportRemeasure();\n });\n\n // A `data` change is the one signal that a requested page landed, so it is where the latch gets its\n // second chance. See `rearmLoadMoreIfUnreachable` for which cases that covers and why.\n effect(() => {\n this.data();\n untracked(() => this.rearmLoadMoreIfUnreachable());\n });\n\n // Dev-only: with selection on and no stable id, identity falls back to the data index, so selection\n // state can silently attach to the wrong row after a reorder/prepend.\n effect(() => {\n if (isDevMode() && this.selectable() && !this.trackBy() && !this.rowIdKey()) {\n console.warn(\n '[ui-infinite-scroll-table] `selectable` is enabled without `trackBy` or `rowIdKey`. ' +\n 'Row identity falls back to the data index, so selection can attach to the wrong row ' +\n 'when rows are reordered or prepended. Provide `trackBy` or `rowIdKey` for stable identity.'\n );\n }\n });\n\n // Dev-only: `isSticky` reads like a per-column capability, so name the columns being ignored.\n effect(() => {\n if (!isDevMode()) {\n return;\n }\n const columns = this.columns();\n const lastIndex = columns.length - 1;\n const ignored = columns\n .filter((column, index) => column.isSticky && index !== 0 && index !== lastIndex)\n .map(column => column.key);\n if (ignored.length > 0) {\n console.warn(\n '[ui-infinite-scroll-table] `isSticky` is only honoured on the first and last column. ' +\n `Ignoring it on: ${ignored.join(', ')}.`\n );\n }\n });\n\n // Dev-only: the in-place-append tell is a fetch completing with the SAME array reference AND a GROWN\n // length. Length is the discriminator — a failed or empty final fetch keeps the reference but not the\n // growth, and those are legitimate outcomes that must stay silent.\n effect(() => {\n const loadingMore = this.loadingMore();\n const data = this.data();\n const completedFetch = this.wasLoadingMore && !loadingMore;\n const sameReference = this.lastDataReference === data;\n const grew = data.length > this.lastDataLength;\n\n this.wasLoadingMore = loadingMore;\n this.lastDataReference = data;\n this.lastDataLength = data.length;\n\n if (isDevMode() && completedFetch && sameReference && grew) {\n console.warn(\n '[ui-infinite-scroll-table] `loadingMore` completed without `data` changing reference. ' +\n 'Append pages with a new array (`[...rows, ...page]`) — a signal input cannot observe an ' +\n 'in-place `push`, so the new rows will not render and `loadMore` will not fire again.'\n );\n }\n });\n\n // Two ways a reset is recognised. Entering `loading` is the earlier and better one: the body becomes\n // skeletons, so the scroll belongs at the top immediately, and by the time the data lands there is\n // nothing left to jump. The head-identity check then covers a replacement swapped in WITHOUT a loading\n // pass — that one needs `trackBy` or `rowIdKey`, since the index fallback makes the head always `0`.\n // Caveat: a newest-first feed that PREPENDS also resets; those consumers should call `scrollToTop()`.\n effect(onCleanup => {\n onCleanup(() => this.cancelResetScrollFrame());\n\n const data = this.data();\n const loading = this.loading();\n const startedLoading = loading && !this.wasLoading;\n this.wasLoading = loading;\n\n const headIdentity = data.length > 0 ? untracked(() => this.rowIdentity(data[0], 0)) : undefined;\n const replaced = this.hasSeenHead && data.length > 0 && headIdentity !== this.previousHeadIdentity;\n\n this.previousHeadIdentity = headIdentity;\n // Latches once and never clears: a reset usually passes through empty + `loading`, which keeps the\n // viewport (and its scroll offset) alive, so clearing here would make the repopulation look like a\n // first render and skip the reset.\n this.hasSeenHead = this.hasSeenHead || data.length > 0;\n\n if (!startedLoading && !replaced) {\n // A shrink that isn't recognised as a replacement still strands the index past the new end, where\n // it reads as \"at the bottom\" and fires `loadMore` for a list the user hasn't seen.\n this.firstVisibleIndex = Math.min(this.firstVisibleIndex, Math.max(0, data.length - 1));\n return;\n }\n // Synchronously, ahead of the deferred scroll: CDK updates its rendered range for the new length\n // during this change detection, and that runs `checkLoadMore` while the index still points into the\n // old, longer list.\n this.firstVisibleIndex = 0;\n // Deferred a frame: CDK clamps a scroll request against the size it has already measured. Tracked so\n // it can be cancelled — a frame must not fire after the viewport leaves the DOM.\n if (typeof requestAnimationFrame === 'undefined') {\n untracked(() => this.scrollToTop());\n return;\n }\n this.cancelResetScrollFrame();\n this.resetScrollFrame = requestAnimationFrame(() => {\n this.resetScrollFrame = undefined;\n untracked(() => this.scrollToTop());\n });\n });\n }\n\n private cancelResetScrollFrame(): void {\n if (this.resetScrollFrame !== undefined) {\n cancelAnimationFrame(this.resetScrollFrame);\n this.resetScrollFrame = undefined;\n }\n }\n\n /** No-ops only when no rows are rendered: the empty state, or an error with no rows. */\n scrollToIndex(index: number, behavior: ScrollBehavior = 'auto'): void {\n this.viewport()?.scrollToIndex(index, behavior);\n }\n\n scrollToTop(behavior: ScrollBehavior = 'auto'): void {\n this.viewport()?.scrollToIndex(0, behavior);\n }\n\n /**\n * The single place `T` is widened to its structural contract. Every field read on a row goes through\n * here, so the assertion exists once instead of at each call site.\n */\n private asRowLike(item: T): InfiniteScrollTableRowLike {\n return item as InfiniteScrollTableRowLike;\n }\n\n protected getCellValue(item: T, key: string): unknown {\n return this.asRowLike(item)[key];\n }\n\n /** Applied as `flex-basis`, `min-width` AND `max-width` on header and body cells alike — see the SCSS. */\n protected columnWidth(column: InfiniteScrollTableColumn<T>): string {\n return column.styles?.width ?? DEFAULT_COLUMN_WIDTH;\n }\n\n protected emitRowClick(event: Event, row: RenderRow<T>): void {\n if (!this.rowsClickable() || row.kind !== 'data') {\n return;\n }\n if (this.isInteractiveTarget(event) || this.hasTextSelection()) {\n return;\n }\n this.rowClick.emit({ row: row.item, index: row.index });\n }\n\n protected isRowSelected(row: RenderRow<T>): boolean {\n return this.selectable() && row.kind === 'data' && Boolean(this.asRowLike(row.item).selected);\n }\n\n protected emitSelectionChange(row: RenderRow<T>, selected: boolean): void {\n if (row.kind !== 'data') {\n return;\n }\n this.selectionChange.emit({ row: row.item, index: row.index, selected });\n }\n\n /** Reads `--ui-ist-checkbox-width` so the offset cannot drift from the checkbox column's own width. */\n protected stickyStartLeft(column: InfiniteScrollTableColumn<T>): string | null {\n if (column.key !== this.stickyStartKey()) {\n return null;\n }\n return this.selectable() ? 'var(--ui-ist-checkbox-width)' : '0px';\n }\n\n /**\n * Only the outermost start-pinned cell may cast the sticky shadow: the checkbox cell is pinned too, and\n * shadowing both would drop a shadow across the column beside it.\n */\n protected isStickyStartEdge(column: InfiniteScrollTableColumn<T>): boolean {\n return column.key === this.stickyStartKey();\n }\n\n protected activateRow(event: Event, row: RenderRow<T>): void {\n if (!this.rowsClickable() || row.kind !== 'data') {\n return;\n }\n if (this.isInteractiveTarget(event)) {\n return;\n }\n // Only after the guards, so a non-clickable table never swallows page-scroll-by-space.\n event.preventDefault();\n this.rowClick.emit({ row: row.item, index: row.index });\n }\n\n /** A clickable row matches `[tabindex]` itself, so `currentTarget` must be excluded explicitly. */\n private isInteractiveTarget(event: Event): boolean {\n const target = event.target;\n if (!(target instanceof Element)) {\n return false;\n }\n const interactive = target.closest(INTERACTIVE_TARGET_SELECTOR);\n return interactive !== null && interactive !== event.currentTarget;\n }\n\n /** Whether the user is selecting text, in which case a click is a selection gesture, not activation. */\n private hasTextSelection(): boolean {\n const selection = typeof window !== 'undefined' ? window.getSelection() : null;\n return Boolean(selection && !selection.isCollapsed && selection.toString().length > 0);\n }\n\n /**\n * Deferred a frame to read the settled layout and never trip \"ResizeObserver loop limit exceeded\";\n * repeated triggers coalesce to one measure.\n */\n private scheduleViewportRemeasure(): void {\n if (typeof requestAnimationFrame === 'undefined') {\n this.viewport()?.checkViewportSize();\n this.settleLoadMore();\n return;\n }\n if (this.remeasureFrame !== undefined) {\n cancelAnimationFrame(this.remeasureFrame);\n }\n this.remeasureFrame = requestAnimationFrame(() => {\n this.remeasureFrame = undefined;\n this.viewport()?.checkViewportSize();\n this.syncHorizontalScroll();\n this.settleLoadMore();\n });\n }\n\n /**\n * The third `checkLoadMore` trigger, and the only one that survives a page landing without a rendered-range\n * change. CDK emits a range only when the virtual-for LENGTH changes, so a page whose row count exactly\n * replaces the load-more skeletons (`data + skeletons` before, `data` after) moves nothing CDK watches —\n * and when the new rows add no scrollable height, no scroll event can ever arrive either. Runs after the\n * re-measure so the zone is tested against the size CDK just settled on.\n */\n private settleLoadMore(): void {\n this.rearmLoadMoreIfUnreachable();\n this.checkLoadMore();\n }\n\n private emitRetry(): void {\n this.retry.emit();\n }\n\n /**\n * The index fallback is identity-in-name-only — it cannot tell rows apart after a reorder — which is why\n * the automatic scroll reset cannot work without `trackBy` or `rowIdKey`.\n */\n private rowIdentity(item: T, index: number): unknown {\n const explicitTrackBy = this.trackBy();\n if (explicitTrackBy) {\n return explicitTrackBy(index, item) as unknown;\n }\n const key = this.rowIdKey();\n return key ? this.asRowLike(item)[key] : index;\n }\n\n /**\n * Assigning an absolute `scrollLeft` is drift-free by construction: it self-corrects every scroll event\n * and the browser clamps when the header's maximum is momentarily smaller. A progress-normalized CSS\n * scroll-timeline cannot guarantee that, which is why it was removed — do not reintroduce one.\n */\n private syncHorizontalScroll(): void {\n const viewport = this.viewport();\n if (!viewport) {\n return;\n }\n const left = viewport.measureScrollOffset('left');\n const right = viewport.measureScrollOffset('right');\n\n const header = this.headerScroll();\n if (header) {\n // Rounded: columns are pixel-identical, so a sub-pixel offset misaligns every one of them.\n header.nativeElement.scrollLeft = Math.round(left);\n }\n this.scrollStart.set(left <= 1);\n this.scrollEnd.set(right <= 1);\n this.horizontalScroll.set(left + right > 1);\n }\n\n /**\n * How many rows the viewport shows. Zero until CDK has measured, which callers must treat as\n * \"unknown\" rather than \"none\".\n */\n private visibleRowCount(): number {\n return Math.ceil((this.viewport()?.getViewportSize() ?? 0) / this.rowHeight());\n }\n\n /**\n * Rows from the end that count as \"approaching it\". Capped at a screenful: a threshold wider than the\n * viewport cannot mean approaching, and uncapped it made the zone unleavable at every scroll position,\n * which is how an oversized `loadMoreThreshold` used to walk a whole dataset unattended. Clamped at 0 so\n * a negative value can't push the trigger point past the end and disable paging outright.\n */\n private triggerZoneRows(visibleRows: number): number {\n const threshold = Math.max(0, this.loadMoreThreshold());\n // Capped only once the viewport is measured — before that there is no screenful to compare against,\n // and capping at 0 would silently disable paging on the first pass.\n return visibleRows > 0 ? Math.min(threshold, visibleRows) : threshold;\n }\n\n /**\n * The rendered range includes CDK's read-ahead buffer, so measuring it conflates the user reaching the\n * end with CDK merely pre-rendering it. The visible end has no such slack, so it tracks the user's\n * actual scroll position instead.\n */\n private isInTriggerZone(dataLength: number, visibleRows: number): boolean {\n return this.firstVisibleIndex + visibleRows >= dataLength - this.triggerZoneRows(visibleRows);\n }\n\n /**\n * Re-arms the latch when something other than scrolling has to do it. Two cases, both of which used to\n * be terminal stalls:\n *\n * - **The requested page landed.** `data` grew past its length at the last emission, so that emission is\n * spent. Without this, re-arming needed the user to scroll *out* of the zone and back — impossible when\n * the page was smaller than the threshold, and impossible to even attempt when the new rows added no\n * scrollable height.\n * - **The zone can't be left.** `visibleEnd` bottoms out at `visibleRows`, so while that floor sits\n * inside the zone no amount of scrolling re-arms anything. Also covers a not-yet-measured viewport,\n * which must count as unleavable or the first fill never starts.\n *\n * Deliberately not driven by `loadingMore` or `error`: a failed fetch clears `loadingMore` without\n * growing `data`, and must stay disarmed rather than re-fire in a loop.\n */\n private rearmLoadMoreIfUnreachable(): void {\n const dataLength = this.data().length;\n const visibleRows = this.visibleRowCount();\n\n if (dataLength > this.dataLengthAtEmit) {\n this.isLoadMoreArmed = true;\n return;\n }\n if (visibleRows === 0 || visibleRows >= dataLength - this.triggerZoneRows(visibleRows)) {\n this.isLoadMoreArmed = true;\n }\n }\n\n /** Emits at most once per page that lands while the user is inside the trigger zone. */\n private checkLoadMore(): void {\n const viewport = this.viewport();\n // `error()` pauses auto-loading until the consumer clears it, rather than instantly re-firing.\n if (!viewport || !this.hasMore() || this.loading() || this.loadingMore() || this.error()) {\n return;\n }\n\n const dataLength = this.data().length;\n if (dataLength === 0) {\n return;\n }\n\n if (!this.isInTriggerZone(dataLength, this.visibleRowCount())) {\n this.isLoadMoreArmed = true;\n return;\n }\n\n if (this.isLoadMoreArmed) {\n this.isLoadMoreArmed = false;\n this.dataLengthAtEmit = dataLength;\n this.loadMore.emit();\n }\n }\n}\n","<!-- role=\"table\", not \"grid\": row access is Tab-only with no arrow-key cell traversal, so \"grid\" would\n promise 2D keyboard navigation this does not implement. Selection is conveyed by the row's checkbox,\n not `aria-selected` — which is valid only on grid/treegrid anyway. -->\n<div\n class=\"ui-ist\"\n role=\"table\"\n [class.ui-ist--condensed]=\"isCondensed()\"\n [class.ui-ist--scrolled-start]=\"!scrollStart()\"\n [class.ui-ist--scrolled-end]=\"horizontalScroll() && !scrollEnd()\"\n [class.ui-ist--fill-height]=\"fillHeight()\"\n [attr.aria-rowcount]=\"hasMore() ? -1 : data().length + 1\"\n [attr.aria-busy]=\"loading() || loadingMore()\"\n>\n <!-- Pinned header, outside the viewport so it never scrolls vertically. The outer element reserves the\n body's scrollbar width as padding (keeping the background and border across that strip); the inner\n one carries the horizontal scrollLeft synced from the body. -->\n <div class=\"ui-ist__header\" [style.padding-right.px]=\"scrollbarWidth()\" role=\"presentation\">\n <div #headerScroll class=\"ui-ist__header-scroll\" role=\"presentation\">\n <div class=\"ui-ist__row ui-ist__row--header\" role=\"row\" aria-rowindex=\"1\">\n @if (selectable()) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"columnheader\"\n ></div>\n }\n @for (column of columns(); track column.key; let colIndex = $index) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header\"\n role=\"columnheader\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n >\n @if (column.headerCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.headerCellTemplate; context: { $implicit: column.title, column, colIndex }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ column.title }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </div>\n </div>\n\n <!-- The CDK viewport owns BOTH vertical (virtualized) and horizontal scroll, so sticky columns pin\n against it and the horizontal scrollbar sits at the viewport bottom. -->\n @if (showViewport()) {\n <cdk-virtual-scroll-viewport\n class=\"ui-ist__body\"\n role=\"rowgroup\"\n [itemSize]=\"rowHeight()\"\n [minBufferPx]=\"effectiveMinBufferPx()\"\n [maxBufferPx]=\"effectiveMaxBufferPx()\"\n [style.height]=\"viewportHeight()\"\n [style.max-height]=\"fillHeight() ? maxHeight() : null\"\n >\n <div\n *cdkVirtualFor=\"let row of renderRows(); let rowIndex = index; trackBy: renderRowTrackBy\"\n class=\"ui-ist__row\"\n role=\"row\"\n [class.ui-ist__row--clickable]=\"rowsClickable() && row.kind === 'data'\"\n [class.ui-ist__row--selected]=\"isRowSelected(row)\"\n [attr.aria-rowindex]=\"row.kind === 'data' ? row.index + 2 : null\"\n [attr.aria-hidden]=\"row.kind === 'skeleton' ? true : null\"\n [attr.tabindex]=\"rowsClickable() && row.kind === 'data' ? 0 : null\"\n [style.height.px]=\"rowHeight()\"\n (click)=\"emitRowClick($event, row)\"\n (keydown.enter)=\"activateRow($event, row)\"\n (keydown.space)=\"activateRow($event, row)\"\n >\n @if (selectable()) {\n <!-- This `stopPropagation` is what actually stops a checkbox click activating the row: it runs\n before the click reaches the row's listener, so `isInteractiveTarget` is never consulted on\n this path. That guard is a real second line of defence (`ui-checkbox` renders a focusable\n wrapper and a native input, both matching INTERACTIVE_TARGET_SELECTOR), not a substitute. -->\n <div\n class=\"ui-ist__cell ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"cell\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n >\n @if (row.kind === 'data') {\n <ui-checkbox\n [checked]=\"isRowSelected(row)\"\n [ariaLabel]=\"'Select row ' + (row.index + 1)\"\n (changed)=\"emitSelectionChange(row, $event)\"\n ></ui-checkbox>\n }\n </div>\n }\n @for (column of columns(); track column.key) {\n <div\n class=\"ui-ist__cell\"\n role=\"cell\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n >\n @if (row.kind === 'skeleton') {\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n } @else if (column.rowCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.rowCellTemplate; context: { $implicit: row.item, rowIndex: row.index }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ getCellValue(row.item, column.key) }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- `showErrorFooter()` and `showErrorState()` differ only on `hasData()`, so they are mutually\n exclusive and safe to merge here. Both fall back to a plain-language message, so a failed fetch is\n never a silent blank box. -->\n @if (showErrorFooter() || showErrorState()) {\n <div class=\"ui-ist__state\" role=\"alert\">\n @if (errorTemplate(); as errorTpl) {\n <ng-container *ngTemplateOutlet=\"errorTpl; context: errorContext\"></ng-container>\n } @else {\n <span>{{ translationContext + 'LOAD_ERROR' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n @if (showEmptyState()) {\n <div class=\"ui-ist__state\">\n @if (noDataTemplate(); as emptyTpl) {\n <ng-container *ngTemplateOutlet=\"emptyTpl\"></ng-container>\n } @else {\n <span>{{ translationContext + 'NO_ROWS' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n <!-- Opt-in, with no fallback (see `endOfListTemplate`). Not role=\"alert\": reaching the end is not an\n alert, and `aria-rowcount` already conveys completeness to assistive tech. -->\n @if (showEndOfList() && endOfListTemplate(); as endTpl) {\n <div class=\"ui-ist__state\">\n <ng-container *ngTemplateOutlet=\"endTpl\"></ng-container>\n </div>\n }\n\n <span class=\"ui-ist__sr-only\" role=\"status\" aria-live=\"polite\">\n @if (statusMessageKey(); as statusKey) {\n {{ statusKey | uiTranslate | async }}\n }\n </span>\n</div>\n","import { ScrollingModule } from '@angular/cdk/scrolling';\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\nimport { InfiniteScrollTableComponent } from './infinite-scroll-table.component';\n\n@NgModule({\n imports: [CommonModule, ScrollingModule, InfiniteScrollTableComponent],\n exports: [InfiniteScrollTableComponent],\n})\nexport class InfiniteScrollTableComponentModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"testgorilla-tgo-ui-components-infinite-scroll-table.mjs","sources":["../../../components/infinite-scroll-table/infinite-scroll-table.component.ts","../../../components/infinite-scroll-table/infinite-scroll-table.component.html","../../../components/infinite-scroll-table/infinite-scroll-table.component.module.ts","../../../components/infinite-scroll-table/testgorilla-tgo-ui-components-infinite-scroll-table.ts"],"sourcesContent":["import { CdkFixedSizeVirtualScroll, CdkVirtualForOf, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';\nimport { AsyncPipe, NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n ElementRef,\n input,\n isDevMode,\n numberAttribute,\n output,\n signal,\n TemplateRef,\n TrackByFunction,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { animationFrameScheduler, Subscription } from 'rxjs';\nimport { auditTime } from 'rxjs/operators';\n\nimport { CheckboxComponent } from '@testgorilla/tgo-ui/components/checkbox';\nimport { UiTranslatePipe } from '@testgorilla/tgo-ui/components/core';\nimport { SkeletonComponent } from '@testgorilla/tgo-ui/components/skeleton';\n\nimport {\n InfiniteScrollTableColumn,\n InfiniteScrollTableErrorContext,\n InfiniteScrollTableRowClick,\n InfiniteScrollTableRowLike,\n InfiniteScrollTableRowSelection,\n} from './infinite-scroll-table.model';\n\n/** Internal row wrapper so real rows and skeleton placeholders flow through one virtual list. */\ntype RenderRow<T> = { kind: 'data'; item: T; index: number } | { kind: 'skeleton'; id: string };\n\nconst DEFAULT_FIRST_LOAD_SKELETON_COUNT = 10;\nconst DEFAULT_LOAD_MORE_SKELETON_COUNT = 3;\nconst DEFAULT_LOAD_MORE_THRESHOLD = 5;\n\n/**\n * Fallback width for a column that declares none, shared with placeholder columns so both resolve to one\n * identical width — header/body alignment depends on that.\n */\nconst DEFAULT_COLUMN_WIDTH = '160px';\n\n/** Elements owning their own click semantics: a click inside one must not also activate the row. */\nconst INTERACTIVE_TARGET_SELECTOR = 'a, button, input, select, textarea, [role=\"button\"], [tabindex]';\n\n/**\n * A generic, virtualized table with scroll-driven infinite loading. Independent of `ui-table`: it reuses\n * only stable leaf primitives (`ui-skeleton`) and duplicates the column/context type shapes so consumers\n * can migrate with a selector swap.\n */\n@Component({\n selector: 'ui-infinite-scroll-table',\n templateUrl: './infinite-scroll-table.component.html',\n styleUrls: ['./infinite-scroll-table.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n // `:host` cannot be class-bound from the template, so the fill-mode host class is set here instead.\n host: {\n '[class.ui-ist--fill-host]': 'fillHeight()',\n },\n imports: [\n AsyncPipe,\n NgTemplateOutlet,\n CdkVirtualScrollViewport,\n CdkFixedSizeVirtualScroll,\n CdkVirtualForOf,\n SkeletonComponent,\n CheckboxComponent,\n UiTranslatePipe,\n ],\n})\nexport class InfiniteScrollTableComponent<T> {\n /**\n * Rows loaded so far. **Must change by reference** (`[...rows, ...page]`): a signal input cannot observe\n * `rows.push(...)`, so an in-place append renders nothing and leaves `loadMore` disarmed.\n */\n readonly data = input.required<readonly T[]>();\n\n readonly columns = input.required<InfiniteScrollTableColumn<T>[]>();\n\n /** Fixed row height in px (the virtualization `itemSize`). Variable row heights are unsupported. */\n readonly rowHeight = input.required<number>();\n\n /** Stable row identity so recycled rows re-render correctly. Takes precedence over `rowIdKey`. */\n readonly trackBy = input<TrackByFunction<T>>();\n /** Key on each row holding a stable id. Used when `trackBy` is not provided. */\n readonly rowIdKey = input<string>();\n\n /**\n * CDK's rendered buffers. Both default to a multiple of `rowHeight` (~5 and ~10 rows) rather than a\n * fixed px value, which would mean a different row count at every `rowHeight`.\n */\n readonly minBufferPx = input<number | undefined>(undefined);\n readonly maxBufferPx = input<number | undefined>(undefined);\n\n /** Max height of the internal scroll region (e.g. `'70vh'`). The body shrinks to fit fewer rows. */\n readonly maxHeight = input<string>('70vh');\n\n /** Stretch to the parent's height instead of the content's; `maxHeight` becomes a cap, not the target. */\n readonly fillHeight = input(false, { transform: booleanAttribute });\n\n readonly isCondensed = input(false, { transform: booleanAttribute });\n\n /**\n * Prepends a left-pinned checkbox column driven by each row's `selected` property. Consumer-managed\n * (like `ui-table`): toggling only emits `selectionChange`.\n */\n readonly selectable = input(false, { transform: booleanAttribute });\n\n /**\n * Makes rows focusable and activatable by click or Enter/Space. Off by default: a read-only table\n * must not create a tab stop per rendered row or imply interactivity it does not have.\n */\n readonly rowsClickable = input(false, { transform: booleanAttribute });\n\n /** First-load state: renders a full body of skeleton rows. */\n readonly loading = input(false, { transform: booleanAttribute });\n\n /** Appends skeleton rows below the existing rows while the next page is fetched. */\n readonly loadingMore = input(false, { transform: booleanAttribute });\n\n /** Required, not defaulted: a silent \"never load\" default would disable the headline behaviour. */\n readonly hasMore = input.required<boolean, unknown>({ transform: booleanAttribute });\n\n readonly skeletonRowCount = input<number>(DEFAULT_FIRST_LOAD_SKELETON_COUNT);\n\n /** Number of skeleton rows appended below the loaded rows while `loadingMore` is true. */\n readonly loadMoreSkeletonCount = input<number>(DEFAULT_LOAD_MORE_SKELETON_COUNT);\n\n /**\n * Skeleton placeholder columns for a lazily-loaded column set. They deliberately sit OUTSIDE `columns`,\n * so they cannot change which column is last and unpin a sticky last column.\n */\n readonly loadingColumnCount = input(0, { transform: numberAttribute });\n\n readonly loadMoreThreshold = input<number>(DEFAULT_LOAD_MORE_THRESHOLD);\n\n /** Shown when `data` is empty and not loading. */\n readonly noDataTemplate = input<TemplateRef<unknown>>();\n\n /** Shown when `error` is `true`. Receives `{ $implicit: retry, retry }` as context. */\n readonly errorTemplate = input<TemplateRef<InfiniteScrollTableErrorContext>>();\n\n readonly error = input(false, { transform: booleanAttribute });\n\n /**\n * Shown once `hasMore` goes `false` with rows loaded. Deliberately has NO built-in fallback (unlike\n * `noDataTemplate` / `errorTemplate`): a single-page list would otherwise flash \"no more results\".\n */\n readonly endOfListTemplate = input<TemplateRef<unknown>>();\n\n readonly testId = input<string | null>(null);\n\n readonly ariaLabel = input<string>('');\n\n /** Guarded: only when `hasMore && !loading && !loadingMore`, and only once per approach to the end. */\n readonly loadMore = output<void>();\n\n readonly retry = output<void>();\n\n readonly rowClick = output<InfiniteScrollTableRowClick<T>>();\n\n /** The consumer is expected to apply `selected` back onto its own data. */\n readonly selectionChange = output<InfiniteScrollTableRowSelection<T>>();\n\n protected readonly viewport = viewChild(CdkVirtualScrollViewport);\n protected readonly headerScroll = viewChild<ElementRef<HTMLElement>>('headerScroll');\n\n protected readonly scrollStart = signal(true);\n protected readonly scrollEnd = signal(false);\n protected readonly horizontalScroll = signal(false);\n\n /** Reserved as right padding on the header, so its content width exactly equals the body's. */\n protected readonly scrollbarWidth = signal(0);\n\n /** Added to the viewport height so on a short list the scrollbar doesn't eat into the rows. */\n protected readonly hScrollbarHeight = signal(0);\n\n /**\n * Paging latch. Three fields, one rule: `loadMore` emits at most once per page that lands while the\n * user is inside the trigger zone. `isLoadMoreArmed` is the latch itself, written here and by\n * `checkLoadMore`; `dataLengthAtEmit` records how long `data` was when the last emission went out, so\n * \"the requested page arrived\" is a length comparison rather than a guess about scroll positions;\n * `firstVisibleIndex` is where the user actually is.\n *\n * The invariant that matters: arming and firing must read the SAME trigger zone. They used to derive it\n * from two different thresholds, which opened bands the latch could never leave.\n */\n private isLoadMoreArmed = true;\n private dataLengthAtEmit = 0;\n\n /** In-place-mutation detector; see the effect that reads these for the discriminator. */\n private wasLoadingMore = false;\n private lastDataReference: readonly T[] | undefined;\n private lastDataLength = 0;\n\n /** Pending frame for a deferred CDK viewport re-measure, so repeated triggers coalesce to one. */\n private remeasureFrame: number | undefined;\n\n /** Pending frame for the deferred scroll reset. Cancelled on destroy, like every other frame here. */\n private resetScrollFrame: number | undefined;\n\n private previousHeadIdentity: unknown;\n /** Latches once any non-empty `data` is seen, so only the very first render is exempt from resetting. */\n private hasSeenHead = false;\n /** Previous `loading` value, for spotting the false -> true edge that starts a reset. */\n private wasLoading = false;\n\n /**\n * First visible row index, kept current from `viewport.scrolledIndexChange` (no layout read) rather\n * than `viewport.getRenderedRange().start`, which includes CDK's read-ahead buffer.\n */\n private firstVisibleIndex = 0;\n\n protected readonly skeletonTheme = {\n background: 'var(--ui-ist-skeleton-bg)',\n 'border-radius': '4px',\n height: '24px',\n 'margin-bottom': '0',\n };\n\n // Pinning is positional by contract: only the FIRST column pins left, only the LAST pins right.\n // `isSticky` elsewhere is ignored (with a dev warning), not applied as `left: 0` — that would overlay\n // the columns before it.\n protected readonly stickyStartKey = computed(() => {\n const columns = this.columns();\n return columns[0]?.isSticky ? columns[0].key : undefined;\n });\n\n protected readonly stickyEndKey = computed(() => {\n const columns = this.columns();\n const lastIndex = columns.length - 1;\n // `lastIndex > 0` so a single sticky column pins to the start, not the end.\n return lastIndex > 0 && columns[lastIndex]?.isSticky ? columns[lastIndex].key : undefined;\n });\n\n protected readonly defaultColumnWidth = DEFAULT_COLUMN_WIDTH;\n\n protected readonly effectiveMinBufferPx = computed(() => this.minBufferPx() ?? this.rowHeight() * 5);\n\n /**\n * The `Math.max` is load-bearing: CDK throws in dev mode when `maxBufferPx < minBufferPx`, which a\n * consumer triggers just by raising `minBufferPx` above the derived default.\n */\n protected readonly effectiveMaxBufferPx = computed(() =>\n Math.max(this.maxBufferPx() ?? this.rowHeight() * 10, this.effectiveMinBufferPx())\n );\n\n /** Stable keys for the placeholder columns, so `@for` can track them across renders. */\n protected readonly loadingColumns = computed(() =>\n Array.from({ length: Math.max(0, this.loadingColumnCount()) }, (_, index) => `loading-column-${index}`)\n );\n\n protected readonly renderRows = computed<RenderRow<T>[]>(() => {\n if (this.loading()) {\n return Array.from({ length: Math.max(1, this.skeletonRowCount()) }, (_, i) => ({\n kind: 'skeleton' as const,\n id: `skeleton-first-${i}`,\n }));\n }\n\n const rows: RenderRow<T>[] = this.data().map((item, index) => ({ kind: 'data' as const, item, index }));\n\n if (this.loadingMore() && this.hasMore()) {\n for (let i = 0; i < Math.max(1, this.loadMoreSkeletonCount()); i++) {\n rows.push({ kind: 'skeleton' as const, id: `skeleton-more-${i}` });\n }\n }\n\n return rows;\n });\n\n protected readonly hasData = computed(() => this.data().length > 0);\n protected readonly showViewport = computed(() => this.loading() || this.hasData());\n /**\n * `loadingMore` counts as loading here too: a consumer that retries a failed first page through the same\n * flag it uses for every page would otherwise render \"no rows\" with `aria-busy` set and the live region\n * announcing a fetch.\n */\n protected readonly showEmptyState = computed(\n () => !this.loading() && !this.loadingMore() && !this.error() && !this.hasData()\n );\n protected readonly showErrorState = computed(() => !this.loading() && this.error() && !this.hasData());\n protected readonly showErrorFooter = computed(() => !this.loading() && this.error() && this.hasData());\n /**\n * The negative clauses keep this out of slots other states own, and `!loadingMore()` closes a one-tick\n * flash: a fetch completing and the consumer flipping `hasMore` need not land in the same cycle.\n */\n protected readonly showEndOfList = computed(\n () => this.hasData() && !this.hasMore() && !this.loading() && !this.loadingMore() && !this.error()\n );\n\n /**\n * CSS `min()` because the cap mixes units. The scrollbar reserve stops a short list from growing a\n * spurious vertical scrollbar; fill mode returns `null` so flex owns the sizing and the reserve is moot.\n */\n protected readonly viewportHeight = computed<string | null>(() => {\n if (this.fillHeight()) {\n return null;\n }\n const contentHeight = this.renderRows().length * this.rowHeight();\n const scrollbarReserve = this.horizontalScroll() ? this.hScrollbarHeight() : 0;\n return `min(${contentHeight + scrollbarReserve}px, ${this.maxHeight()})`;\n });\n\n protected readonly translationContext = 'INFINITE_SCROLL_TABLE.';\n\n /** A translation key, resolved in the template: screen-reader users are not all English speakers. */\n protected readonly statusMessageKey = computed(() => {\n if (this.loading()) {\n return `${this.translationContext}LOADING`;\n }\n if (this.loadingMore()) {\n return `${this.translationContext}LOADING_MORE`;\n }\n return '';\n });\n\n protected readonly errorContext: InfiniteScrollTableErrorContext = {\n $implicit: () => this.emitRetry(),\n retry: () => this.emitRetry(),\n };\n\n protected readonly renderRowTrackBy: TrackByFunction<RenderRow<T>> = (index, row): unknown => {\n if (row.kind === 'skeleton') {\n return row.id;\n }\n return this.rowIdentity(row.item, row.index);\n };\n\n constructor() {\n // (Re-)attaches scroll listeners as the viewport enters or leaves the DOM. The setup reads other\n // signals, so it is `untracked()` — otherwise every data change would tear the listeners down.\n effect(onCleanup => {\n const viewport = this.viewport();\n if (!viewport) {\n return;\n }\n untracked(() => {\n // A freshly created CdkVirtualScrollViewport always mounts scrolled to the top, and this field\n // carries across viewport instances (`@if (showViewport())` destroys and recreates one when `data`\n // empties and repopulates). Leaving it stale would let `checkLoadMore` fire off a scroll position\n // belonging to the OLD viewport.\n this.firstVisibleIndex = 0;\n\n const element = viewport.elementRef.nativeElement;\n\n // Both patch CDK divs that would otherwise break the ARIA table structure: its content wrapper\n // sits between `role=\"rowgroup\"` and the rows, its spacer is an unlabeled child of the rowgroup.\n // Both selectors are CDK internals, so the optional chaining would swallow a CDK restructure\n // silently. The spec asserts both attributes after mount, which is what turns such a change into a\n // failing test rather than a quietly invalid accessibility tree.\n element.querySelector('.cdk-virtual-scroll-content-wrapper')?.setAttribute('role', 'presentation');\n element.querySelector('.cdk-virtual-scroll-spacer')?.setAttribute('aria-hidden', 'true');\n\n const subscription = new Subscription();\n // Audited to one animation frame, matching CDK's own scroll handler, so `measureScrollOffset`'s\n // forced reflow can't run several times per frame and interleave with CDK's DOM writes.\n subscription.add(\n viewport\n .elementScrolled()\n .pipe(auditTime(0, animationFrameScheduler))\n .subscribe(() => this.syncHorizontalScroll())\n );\n // Neither trigger is redundant: an append changes the rendered range without a scroll, and a scroll\n // inside the read-ahead buffer moves `firstVisibleIndex` without changing the range.\n subscription.add(viewport.renderedRangeStream.subscribe(() => this.checkLoadMore()));\n subscription.add(\n viewport.scrolledIndexChange.subscribe(index => {\n this.firstVisibleIndex = index;\n this.checkLoadMore();\n })\n );\n\n // `offsetWidth - clientWidth` also counts borders: pure scrollbar only because `.ui-ist__body`\n // has none, and it must stay borderless.\n const measureScrollbar = (): void => {\n this.scrollbarWidth.set(element.offsetWidth - element.clientWidth);\n this.hScrollbarHeight.set(element.offsetHeight - element.clientHeight);\n };\n subscription.add(viewport.renderedRangeStream.subscribe(() => measureScrollbar()));\n\n // Covers box changes no signal captures: a flex parent resizing, or a relative `maxHeight`\n // reacting to its container. Signal-driven height changes are the effect below.\n let resizeObserver: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n resizeObserver = new ResizeObserver(() => {\n measureScrollbar();\n // A resize can cross into or out of horizontal overflow without a scroll event, leaving the\n // sticky shadows and `viewportHeight()`'s scrollbar reserve stale.\n this.syncHorizontalScroll();\n this.scheduleViewportRemeasure();\n });\n resizeObserver.observe(element);\n }\n\n measureScrollbar();\n this.syncHorizontalScroll();\n this.checkLoadMore();\n\n // The sync above runs before CDK lays out its rows, so the overflow measurement is stale until\n // the next frame. Guarded because requestAnimationFrame is browser-only (SSR).\n let scrollSyncFrame: number | undefined;\n if (typeof requestAnimationFrame !== 'undefined') {\n scrollSyncFrame = requestAnimationFrame(() => this.syncHorizontalScroll());\n }\n\n onCleanup(() => {\n subscription.unsubscribe();\n resizeObserver?.disconnect();\n // Pending frames must not fire after the viewport leaves the DOM.\n if (scrollSyncFrame !== undefined) {\n cancelAnimationFrame(scrollSyncFrame);\n }\n if (this.remeasureFrame !== undefined) {\n cancelAnimationFrame(this.remeasureFrame);\n this.remeasureFrame = undefined;\n }\n });\n });\n });\n\n // CDK caches its measured size and re-measures only on scroll or window resize, so any signal-driven\n // height change here (`fillHeight` included: it swaps the `min()` cap for a flex-driven height) would\n // leave the new space empty with the tail rows unrendered. Read individually rather than via\n // `viewportHeight()`, to keep the dependency off horizontal-scroll state. `loadingColumnCount` changes\n // content WIDTH not the box, so the ResizeObserver misses it and only the deferred\n // `syncHorizontalScroll()` keeps the horizontal-overflow state current.\n effect(() => {\n this.renderRows();\n this.rowHeight();\n this.maxHeight();\n this.columns();\n this.fillHeight();\n this.loadingColumnCount();\n // Adds a 56px checkbox column: content width changes, the box does not.\n this.selectable();\n this.scheduleViewportRemeasure();\n });\n\n // A `data` change is the one signal that a requested page landed, so it is where the latch gets its\n // second chance. See `rearmLoadMoreIfUnreachable` for which cases that covers and why.\n effect(() => {\n this.data();\n untracked(() => this.rearmLoadMoreIfUnreachable());\n });\n\n // Dev-only: with selection on and no stable id, identity falls back to the data index, so selection\n // state can silently attach to the wrong row after a reorder/prepend.\n effect(() => {\n if (isDevMode() && this.selectable() && !this.trackBy() && !this.rowIdKey()) {\n console.warn(\n '[ui-infinite-scroll-table] `selectable` is enabled without `trackBy` or `rowIdKey`. ' +\n 'Row identity falls back to the data index, so selection can attach to the wrong row ' +\n 'when rows are reordered or prepended. Provide `trackBy` or `rowIdKey` for stable identity.'\n );\n }\n });\n\n // Dev-only: `isSticky` reads like a per-column capability, so name the columns being ignored.\n effect(() => {\n if (!isDevMode()) {\n return;\n }\n const columns = this.columns();\n const lastIndex = columns.length - 1;\n const ignored = columns\n .filter((column, index) => column.isSticky && index !== 0 && index !== lastIndex)\n .map(column => column.key);\n if (ignored.length > 0) {\n console.warn(\n '[ui-infinite-scroll-table] `isSticky` is only honoured on the first and last column. ' +\n `Ignoring it on: ${ignored.join(', ')}.`\n );\n }\n });\n\n // Dev-only: the in-place-append tell is a fetch completing with the SAME array reference AND a GROWN\n // length. Length is the discriminator — a failed or empty final fetch keeps the reference but not the\n // growth, and those are legitimate outcomes that must stay silent.\n effect(() => {\n const loadingMore = this.loadingMore();\n const data = this.data();\n const completedFetch = this.wasLoadingMore && !loadingMore;\n const sameReference = this.lastDataReference === data;\n const grew = data.length > this.lastDataLength;\n\n this.wasLoadingMore = loadingMore;\n this.lastDataReference = data;\n this.lastDataLength = data.length;\n\n if (isDevMode() && completedFetch && sameReference && grew) {\n console.warn(\n '[ui-infinite-scroll-table] `loadingMore` completed without `data` changing reference. ' +\n 'Append pages with a new array (`[...rows, ...page]`) — a signal input cannot observe an ' +\n 'in-place `push`, so the new rows will not render and `loadMore` will not fire again.'\n );\n }\n });\n\n // Two ways a reset is recognised. Entering `loading` is the earlier and better one: the body becomes\n // skeletons, so the scroll belongs at the top immediately, and by the time the data lands there is\n // nothing left to jump. The head-identity check then covers a replacement swapped in WITHOUT a loading\n // pass — that one needs `trackBy` or `rowIdKey`, since the index fallback makes the head always `0`.\n // Caveat: a newest-first feed that PREPENDS also resets; those consumers should call `scrollToTop()`.\n effect(onCleanup => {\n onCleanup(() => this.cancelResetScrollFrame());\n\n const data = this.data();\n const loading = this.loading();\n const startedLoading = loading && !this.wasLoading;\n this.wasLoading = loading;\n\n const headIdentity = data.length > 0 ? untracked(() => this.rowIdentity(data[0], 0)) : undefined;\n const replaced = this.hasSeenHead && data.length > 0 && headIdentity !== this.previousHeadIdentity;\n\n this.previousHeadIdentity = headIdentity;\n // Latches once and never clears: a reset usually passes through empty + `loading`, which keeps the\n // viewport (and its scroll offset) alive, so clearing here would make the repopulation look like a\n // first render and skip the reset.\n this.hasSeenHead = this.hasSeenHead || data.length > 0;\n\n if (!startedLoading && !replaced) {\n // A shrink that isn't recognised as a replacement still strands the index past the new end, where\n // it reads as \"at the bottom\" and fires `loadMore` for a list the user hasn't seen.\n this.firstVisibleIndex = Math.min(this.firstVisibleIndex, Math.max(0, data.length - 1));\n return;\n }\n // Synchronously, ahead of the deferred scroll: CDK updates its rendered range for the new length\n // during this change detection, and that runs `checkLoadMore` while the index still points into the\n // old, longer list.\n this.firstVisibleIndex = 0;\n // Deferred a frame: CDK clamps a scroll request against the size it has already measured. Tracked so\n // it can be cancelled — a frame must not fire after the viewport leaves the DOM.\n if (typeof requestAnimationFrame === 'undefined') {\n untracked(() => this.scrollToTop());\n return;\n }\n this.cancelResetScrollFrame();\n this.resetScrollFrame = requestAnimationFrame(() => {\n this.resetScrollFrame = undefined;\n untracked(() => this.scrollToTop());\n });\n });\n }\n\n private cancelResetScrollFrame(): void {\n if (this.resetScrollFrame !== undefined) {\n cancelAnimationFrame(this.resetScrollFrame);\n this.resetScrollFrame = undefined;\n }\n }\n\n /** No-ops only when no rows are rendered: the empty state, or an error with no rows. */\n scrollToIndex(index: number, behavior: ScrollBehavior = 'auto'): void {\n this.viewport()?.scrollToIndex(index, behavior);\n }\n\n scrollToTop(behavior: ScrollBehavior = 'auto'): void {\n this.viewport()?.scrollToIndex(0, behavior);\n }\n\n /**\n * The single place `T` is widened to its structural contract. Every field read on a row goes through\n * here, so the assertion exists once instead of at each call site.\n */\n private asRowLike(item: T): InfiniteScrollTableRowLike {\n return item as InfiniteScrollTableRowLike;\n }\n\n protected getCellValue(item: T, key: string): unknown {\n return this.asRowLike(item)[key];\n }\n\n /** Applied as `flex-basis`, `min-width` AND `max-width` on header and body cells alike — see the SCSS. */\n protected columnWidth(column: InfiniteScrollTableColumn<T>): string {\n return column.styles?.width ?? DEFAULT_COLUMN_WIDTH;\n }\n\n protected emitRowClick(event: Event, row: RenderRow<T>): void {\n if (!this.rowsClickable() || row.kind !== 'data') {\n return;\n }\n if (this.isInteractiveTarget(event) || this.hasTextSelection()) {\n return;\n }\n this.rowClick.emit({ row: row.item, index: row.index });\n }\n\n protected rowTestId(row: RenderRow<T>): string | null {\n const testId = this.testId();\n return testId && row.kind === 'data' ? `${testId}-row-${row.index}` : null;\n }\n\n protected cellTestId(row: RenderRow<T>, columnKey: string): string | null {\n const testId = this.testId();\n return testId && row.kind === 'data' ? `${testId}-cell-${row.index}-${columnKey}` : null;\n }\n\n protected rowCheckboxTestId(row: RenderRow<T>): string | null {\n const rowTestId = this.rowTestId(row);\n return rowTestId ? `${rowTestId}-select` : null;\n }\n\n protected isRowSelected(row: RenderRow<T>): boolean {\n return this.selectable() && row.kind === 'data' && Boolean(this.asRowLike(row.item).selected);\n }\n\n protected emitSelectionChange(row: RenderRow<T>, selected: boolean): void {\n if (row.kind !== 'data') {\n return;\n }\n this.selectionChange.emit({ row: row.item, index: row.index, selected });\n }\n\n /** Reads `--ui-ist-checkbox-width` so the offset cannot drift from the checkbox column's own width. */\n protected stickyStartLeft(column: InfiniteScrollTableColumn<T>): string | null {\n if (column.key !== this.stickyStartKey()) {\n return null;\n }\n return this.selectable() ? 'var(--ui-ist-checkbox-width)' : '0px';\n }\n\n /**\n * Only the outermost start-pinned cell may cast the sticky shadow: the checkbox cell is pinned too, and\n * shadowing both would drop a shadow across the column beside it.\n */\n protected isStickyStartEdge(column: InfiniteScrollTableColumn<T>): boolean {\n return column.key === this.stickyStartKey();\n }\n\n protected activateRow(event: Event, row: RenderRow<T>): void {\n if (!this.rowsClickable() || row.kind !== 'data') {\n return;\n }\n if (this.isInteractiveTarget(event)) {\n return;\n }\n // Only after the guards, so a non-clickable table never swallows page-scroll-by-space.\n event.preventDefault();\n this.rowClick.emit({ row: row.item, index: row.index });\n }\n\n /** A clickable row matches `[tabindex]` itself, so `currentTarget` must be excluded explicitly. */\n private isInteractiveTarget(event: Event): boolean {\n const target = event.target;\n if (!(target instanceof Element)) {\n return false;\n }\n const interactive = target.closest(INTERACTIVE_TARGET_SELECTOR);\n return interactive !== null && interactive !== event.currentTarget;\n }\n\n /** Whether the user is selecting text, in which case a click is a selection gesture, not activation. */\n private hasTextSelection(): boolean {\n const selection = typeof window !== 'undefined' ? window.getSelection() : null;\n return Boolean(selection && !selection.isCollapsed && selection.toString().length > 0);\n }\n\n /**\n * Deferred a frame to read the settled layout and never trip \"ResizeObserver loop limit exceeded\";\n * repeated triggers coalesce to one measure.\n */\n private scheduleViewportRemeasure(): void {\n if (typeof requestAnimationFrame === 'undefined') {\n this.viewport()?.checkViewportSize();\n this.settleLoadMore();\n return;\n }\n if (this.remeasureFrame !== undefined) {\n cancelAnimationFrame(this.remeasureFrame);\n }\n this.remeasureFrame = requestAnimationFrame(() => {\n this.remeasureFrame = undefined;\n this.viewport()?.checkViewportSize();\n this.syncHorizontalScroll();\n this.settleLoadMore();\n });\n }\n\n /**\n * The third `checkLoadMore` trigger, and the only one that survives a page landing without a rendered-range\n * change. CDK emits a range only when the virtual-for LENGTH changes, so a page whose row count exactly\n * replaces the load-more skeletons (`data + skeletons` before, `data` after) moves nothing CDK watches —\n * and when the new rows add no scrollable height, no scroll event can ever arrive either. Runs after the\n * re-measure so the zone is tested against the size CDK just settled on.\n */\n private settleLoadMore(): void {\n this.rearmLoadMoreIfUnreachable();\n this.checkLoadMore();\n }\n\n private emitRetry(): void {\n this.retry.emit();\n }\n\n /**\n * The index fallback is identity-in-name-only — it cannot tell rows apart after a reorder — which is why\n * the automatic scroll reset cannot work without `trackBy` or `rowIdKey`.\n */\n private rowIdentity(item: T, index: number): unknown {\n const explicitTrackBy = this.trackBy();\n if (explicitTrackBy) {\n return explicitTrackBy(index, item) as unknown;\n }\n const key = this.rowIdKey();\n return key ? this.asRowLike(item)[key] : index;\n }\n\n /**\n * Assigning an absolute `scrollLeft` is drift-free by construction: it self-corrects every scroll event\n * and the browser clamps when the header's maximum is momentarily smaller. A progress-normalized CSS\n * scroll-timeline cannot guarantee that, which is why it was removed — do not reintroduce one.\n */\n private syncHorizontalScroll(): void {\n const viewport = this.viewport();\n if (!viewport) {\n return;\n }\n const left = viewport.measureScrollOffset('left');\n const right = viewport.measureScrollOffset('right');\n\n const header = this.headerScroll();\n if (header) {\n // Rounded: columns are pixel-identical, so a sub-pixel offset misaligns every one of them.\n header.nativeElement.scrollLeft = Math.round(left);\n }\n this.scrollStart.set(left <= 1);\n this.scrollEnd.set(right <= 1);\n this.horizontalScroll.set(left + right > 1);\n }\n\n /**\n * How many rows the viewport shows. Zero until CDK has measured, which callers must treat as\n * \"unknown\" rather than \"none\".\n */\n private visibleRowCount(): number {\n return Math.ceil((this.viewport()?.getViewportSize() ?? 0) / this.rowHeight());\n }\n\n /**\n * Rows from the end that count as \"approaching it\". Capped at a screenful: a threshold wider than the\n * viewport cannot mean approaching, and uncapped it made the zone unleavable at every scroll position,\n * which is how an oversized `loadMoreThreshold` used to walk a whole dataset unattended. Clamped at 0 so\n * a negative value can't push the trigger point past the end and disable paging outright.\n */\n private triggerZoneRows(visibleRows: number): number {\n const threshold = Math.max(0, this.loadMoreThreshold());\n // Capped only once the viewport is measured — before that there is no screenful to compare against,\n // and capping at 0 would silently disable paging on the first pass.\n return visibleRows > 0 ? Math.min(threshold, visibleRows) : threshold;\n }\n\n /**\n * The rendered range includes CDK's read-ahead buffer, so measuring it conflates the user reaching the\n * end with CDK merely pre-rendering it. The visible end has no such slack, so it tracks the user's\n * actual scroll position instead.\n */\n private isInTriggerZone(dataLength: number, visibleRows: number): boolean {\n return this.firstVisibleIndex + visibleRows >= dataLength - this.triggerZoneRows(visibleRows);\n }\n\n /**\n * Re-arms the latch when something other than scrolling has to do it. Two cases, both of which used to\n * be terminal stalls:\n *\n * - **The requested page landed.** `data` grew past its length at the last emission, so that emission is\n * spent. Without this, re-arming needed the user to scroll *out* of the zone and back — impossible when\n * the page was smaller than the threshold, and impossible to even attempt when the new rows added no\n * scrollable height.\n * - **The zone can't be left.** `visibleEnd` bottoms out at `visibleRows`, so while that floor sits\n * inside the zone no amount of scrolling re-arms anything. Also covers a not-yet-measured viewport,\n * which must count as unleavable or the first fill never starts.\n *\n * Deliberately not driven by `loadingMore` or `error`: a failed fetch clears `loadingMore` without\n * growing `data`, and must stay disarmed rather than re-fire in a loop.\n */\n private rearmLoadMoreIfUnreachable(): void {\n const dataLength = this.data().length;\n const visibleRows = this.visibleRowCount();\n\n if (dataLength > this.dataLengthAtEmit) {\n this.isLoadMoreArmed = true;\n return;\n }\n if (visibleRows === 0 || visibleRows >= dataLength - this.triggerZoneRows(visibleRows)) {\n this.isLoadMoreArmed = true;\n }\n }\n\n /** Emits at most once per page that lands while the user is inside the trigger zone. */\n private checkLoadMore(): void {\n const viewport = this.viewport();\n // `error()` pauses auto-loading until the consumer clears it, rather than instantly re-firing.\n if (!viewport || !this.hasMore() || this.loading() || this.loadingMore() || this.error()) {\n return;\n }\n\n const dataLength = this.data().length;\n if (dataLength === 0) {\n return;\n }\n\n if (!this.isInTriggerZone(dataLength, this.visibleRowCount())) {\n this.isLoadMoreArmed = true;\n return;\n }\n\n if (this.isLoadMoreArmed) {\n this.isLoadMoreArmed = false;\n this.dataLengthAtEmit = dataLength;\n this.loadMore.emit();\n }\n }\n}\n","<!-- role=\"table\", not \"grid\": row access is Tab-only with no arrow-key cell traversal, so \"grid\" would\n promise 2D keyboard navigation this does not implement. Selection is conveyed by the row's checkbox,\n not `aria-selected` — which is valid only on grid/treegrid anyway. -->\n<div\n class=\"ui-ist\"\n role=\"table\"\n [class.ui-ist--condensed]=\"isCondensed()\"\n [class.ui-ist--scrolled-start]=\"!scrollStart()\"\n [class.ui-ist--scrolled-end]=\"horizontalScroll() && !scrollEnd()\"\n [class.ui-ist--fill-height]=\"fillHeight()\"\n [attr.aria-rowcount]=\"hasMore() ? -1 : data().length + 1\"\n [attr.aria-busy]=\"loading() || loadingMore()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.data-testid]=\"testId()\"\n>\n <!-- Pinned header, outside the viewport so it never scrolls vertically. The outer element reserves the\n body's scrollbar width as padding (keeping the background and border across that strip); the inner\n one carries the horizontal scrollLeft synced from the body. -->\n <div class=\"ui-ist__header\" [style.padding-right.px]=\"scrollbarWidth()\" role=\"presentation\">\n <div #headerScroll class=\"ui-ist__header-scroll\" role=\"presentation\">\n <div class=\"ui-ist__row ui-ist__row--header\" role=\"row\" aria-rowindex=\"1\">\n @if (selectable()) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"columnheader\"\n ></div>\n }\n @for (column of columns(); track column.key; let colIndex = $index) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header\"\n role=\"columnheader\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n >\n @if (column.headerCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.headerCellTemplate; context: { $implicit: column.title, column, colIndex }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ column.title }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--header ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </div>\n </div>\n\n <!-- The CDK viewport owns BOTH vertical (virtualized) and horizontal scroll, so sticky columns pin\n against it and the horizontal scrollbar sits at the viewport bottom. -->\n @if (showViewport()) {\n <cdk-virtual-scroll-viewport\n class=\"ui-ist__body\"\n role=\"rowgroup\"\n [itemSize]=\"rowHeight()\"\n [minBufferPx]=\"effectiveMinBufferPx()\"\n [maxBufferPx]=\"effectiveMaxBufferPx()\"\n [style.height]=\"viewportHeight()\"\n [style.max-height]=\"fillHeight() ? maxHeight() : null\"\n >\n <div\n *cdkVirtualFor=\"let row of renderRows(); let rowIndex = index; trackBy: renderRowTrackBy\"\n class=\"ui-ist__row\"\n role=\"row\"\n [class.ui-ist__row--clickable]=\"rowsClickable() && row.kind === 'data'\"\n [class.ui-ist__row--selected]=\"isRowSelected(row)\"\n [attr.aria-rowindex]=\"row.kind === 'data' ? row.index + 2 : null\"\n [attr.aria-hidden]=\"row.kind === 'skeleton' ? true : null\"\n [attr.tabindex]=\"rowsClickable() && row.kind === 'data' ? 0 : null\"\n [style.height.px]=\"rowHeight()\"\n [attr.data-testid]=\"rowTestId(row)\"\n (click)=\"emitRowClick($event, row)\"\n (keydown.enter)=\"activateRow($event, row)\"\n (keydown.space)=\"activateRow($event, row)\"\n >\n @if (selectable()) {\n <!-- This `stopPropagation` is what actually stops a checkbox click activating the row: it runs\n before the click reaches the row's listener, so `isInteractiveTarget` is never consulted on\n this path. That guard is a real second line of defence (`ui-checkbox` renders a focusable\n wrapper and a native input, both matching INTERACTIVE_TARGET_SELECTOR), not a substitute. -->\n <div\n class=\"ui-ist__cell ui-ist__cell--checkbox ui-ist__cell--sticky-start\"\n [class.ui-ist__cell--sticky-start-edge]=\"!stickyStartKey()\"\n role=\"cell\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"\n >\n @if (row.kind === 'data') {\n <ui-checkbox\n [checked]=\"isRowSelected(row)\"\n [ariaLabel]=\"'Select row ' + (row.index + 1)\"\n [testId]=\"rowCheckboxTestId(row)\"\n (changed)=\"emitSelectionChange(row, $event)\"\n ></ui-checkbox>\n }\n </div>\n }\n @for (column of columns(); track column.key) {\n <div\n class=\"ui-ist__cell\"\n role=\"cell\"\n [class.ui-ist__cell--sticky-start]=\"column.key === stickyStartKey()\"\n [class.ui-ist__cell--sticky-start-edge]=\"isStickyStartEdge(column)\"\n [class.ui-ist__cell--sticky-end]=\"column.key === stickyEndKey()\"\n [class.ui-ist__cell--right]=\"column.styles?.alignment === 'right'\"\n [class.ui-ist__cell--center]=\"column.styles?.alignment === 'center'\"\n [style.flex-basis]=\"columnWidth(column)\"\n [style.min-width]=\"columnWidth(column)\"\n [style.max-width]=\"columnWidth(column)\"\n [style.left]=\"stickyStartLeft(column)\"\n [attr.data-testid]=\"cellTestId(row, column.key)\"\n >\n @if (row.kind === 'skeleton') {\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n } @else if (column.rowCellTemplate) {\n <ng-container\n *ngTemplateOutlet=\"column.rowCellTemplate; context: { $implicit: row.item, rowIndex: row.index }\"\n ></ng-container>\n } @else {\n <span class=\"ui-ist__cell-text\">{{ getCellValue(row.item, column.key) }}</span>\n }\n </div>\n }\n @for (loadingKey of loadingColumns(); track loadingKey) {\n <div\n class=\"ui-ist__cell ui-ist__cell--loading\"\n role=\"presentation\"\n aria-hidden=\"true\"\n [style.flex-basis]=\"defaultColumnWidth\"\n [style.min-width]=\"defaultColumnWidth\"\n [style.max-width]=\"defaultColumnWidth\"\n >\n <ui-skeleton class=\"ui-ist__skeleton\" [count]=\"1\" [theme]=\"skeletonTheme\" appearance=\"line\"></ui-skeleton>\n </div>\n }\n <div class=\"ui-ist__cell ui-ist__cell--spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n </div>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- `showErrorFooter()` and `showErrorState()` differ only on `hasData()`, so they are mutually\n exclusive and safe to merge here. Both fall back to a plain-language message, so a failed fetch is\n never a silent blank box. -->\n @if (showErrorFooter() || showErrorState()) {\n <div class=\"ui-ist__state\" role=\"alert\">\n @if (errorTemplate(); as errorTpl) {\n <ng-container *ngTemplateOutlet=\"errorTpl; context: errorContext\"></ng-container>\n } @else {\n <span>{{ translationContext + 'LOAD_ERROR' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n @if (showEmptyState()) {\n <div class=\"ui-ist__state\">\n @if (noDataTemplate(); as emptyTpl) {\n <ng-container *ngTemplateOutlet=\"emptyTpl\"></ng-container>\n } @else {\n <span>{{ translationContext + 'NO_ROWS' | uiTranslate | async }}</span>\n }\n </div>\n }\n\n <!-- Opt-in, with no fallback (see `endOfListTemplate`). Not role=\"alert\": reaching the end is not an\n alert, and `aria-rowcount` already conveys completeness to assistive tech. -->\n @if (showEndOfList() && endOfListTemplate(); as endTpl) {\n <div class=\"ui-ist__state\">\n <ng-container *ngTemplateOutlet=\"endTpl\"></ng-container>\n </div>\n }\n\n <span class=\"ui-ist__sr-only\" role=\"status\" aria-live=\"polite\">\n @if (statusMessageKey(); as statusKey) {\n {{ statusKey | uiTranslate | async }}\n }\n </span>\n</div>\n","import { ScrollingModule } from '@angular/cdk/scrolling';\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\n\nimport { InfiniteScrollTableComponent } from './infinite-scroll-table.component';\n\n@NgModule({\n imports: [CommonModule, ScrollingModule, InfiniteScrollTableComponent],\n exports: [InfiniteScrollTableComponent],\n})\nexport class InfiniteScrollTableComponentModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|