@one-paragon/angular-utilities 2.0.4-beta.1 → 2.0.5

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.
@@ -26,6 +26,6 @@ export interface State extends EntityState<ActionStatus> {
26
26
  }
27
27
  export declare const initialState: StatusState;
28
28
  export declare const getStatusState: import("@ngrx/store").MemoizedSelector<object, State, import("@ngrx/store").DefaultProjectorFn<State>>;
29
- export declare const selectIds: import("@ngrx/store").MemoizedSelector<object, string[] | number[], (entityState: EntityState<ActionStatus>) => string[] | number[]>, selectEntities: import("@ngrx/store").MemoizedSelector<object, import("@ngrx/entity").Dictionary<ActionStatus>, (entityState: EntityState<ActionStatus>) => import("@ngrx/entity").Dictionary<ActionStatus>>, selectAll: import("@ngrx/store").MemoizedSelector<object, ActionStatus[], (entityState: EntityState<ActionStatus>) => ActionStatus[]>, selectTotal: import("@ngrx/store").MemoizedSelector<object, number, (entityState: EntityState<ActionStatus>) => number>;
29
+ export declare const selectIds: import("@ngrx/store").MemoizedSelector<object, number[] | string[], (entityState: EntityState<ActionStatus>) => string[] | number[]>, selectEntities: import("@ngrx/store").MemoizedSelector<object, import("@ngrx/entity").Dictionary<ActionStatus>, (entityState: EntityState<ActionStatus>) => import("@ngrx/entity").Dictionary<ActionStatus>>, selectAll: import("@ngrx/store").MemoizedSelector<object, ActionStatus[], (entityState: EntityState<ActionStatus>) => ActionStatus[]>, selectTotal: import("@ngrx/store").MemoizedSelector<object, number, (entityState: EntityState<ActionStatus>) => number>;
30
30
  export declare const selectEntity: (id: string) => import("@ngrx/store").MemoizedSelector<object, any, (s1: import("@ngrx/entity").Dictionary<ActionStatus>) => any>;
31
31
  export declare function actionStatusReducer(state: StatusState | undefined, action: Action): StatusState;
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Directive, Input, inject, Injector, TemplateRef, ViewContainerRef, NgModule, assertInInjectionContext, DestroyRef, computed, isSignal, Injectable, Pipe, input, signal, Renderer2, ElementRef, booleanAttribute, InjectionToken, makeEnvironmentProviders, Component, ChangeDetectionStrategy, HostListener, EventEmitter, untracked, Output, ContentChildren, ChangeDetectorRef, output, ViewChild, EnvironmentInjector, createComponent, viewChild, linkedSignal, effect, contentChild, forwardRef, contentChildren, model, runInInjectionContext, provideAppInitializer } from '@angular/core';
3
- import { shareReplay, switchAll, map, filter, tap, catchError, startWith, switchMap, mergeMap, concatMap as concatMap$1, takeUntil, distinctUntilChanged, debounceTime, scan as scan$1, timestamp as timestamp$1, first as first$1 } from 'rxjs/operators';
3
+ import { shareReplay, switchAll, map, filter, tap, catchError, startWith, switchMap, mergeMap, concatMap as concatMap$1, takeUntil, distinctUntilChanged, observeOn, debounceTime, scan as scan$1, timestamp as timestamp$1, first as first$1 } from 'rxjs/operators';
4
4
  import * as i1 from 'rxjs';
5
- import { Subject, isObservable, of, ReplaySubject, filter as filter$1, first, map as map$1, Observable, combineLatest, Subscription, startWith as startWith$1, pairwise, concatMap, merge, delay, fromEvent, takeUntil as takeUntil$1, tap as tap$1, switchMap as switchMap$1, scan, timestamp, BehaviorSubject } from 'rxjs';
5
+ import { Subject, isObservable, of, ReplaySubject, filter as filter$1, first, map as map$1, Observable, combineLatest, Subscription, startWith as startWith$1, pairwise, concatMap, merge, delay, fromEvent, takeUntil as takeUntil$1, tap as tap$1, switchMap as switchMap$1, scan, timestamp, animationFrameScheduler, debounceTime as debounceTime$1, BehaviorSubject } from 'rxjs';
6
6
  import { ComponentStore } from '@ngrx/component-store';
7
7
  import { toObservable, toSignal, outputFromObservable } from '@angular/core/rxjs-interop';
8
8
  import { DatePipe, CurrencyPipe, KeyValuePipe, NgTemplateOutlet, DecimalPipe, CommonModule, AsyncPipe } from '@angular/common';
@@ -887,6 +887,10 @@ class VirtualScrollOptions {
887
887
  * If `maxViewPortHeight` is set that will be the max table size
888
888
  */
889
889
  dynamicHeight = false;
890
+ /**
891
+ * If `dynamicHeight` is set to true, we will try to add this amount of space from the bottom of view port
892
+ */
893
+ dynamicalHeightBuffer = 0;
890
894
  }
891
895
  class PaginatorOptions {
892
896
  pageSize = undefined;
@@ -3857,10 +3861,8 @@ class GenericTableComponent {
3857
3861
  });
3858
3862
  $usePaginator = computed(() => this.state.$tableSettings().usePaginator);
3859
3863
  $useVirtualScroll = computed(() => this.state.$viewType().includes('virtual'));
3860
- $virtualStart = this.dataStore.selectSignal(d => d.virtualEnds.start);
3861
3864
  $offsetIndex = computed(() => {
3862
- const virtualStart = this.$virtualStart();
3863
- console.log({ virtualStart });
3865
+ const virtualStart = this.dataStore.selectSignal(d => d.virtualEnds.start)();
3864
3866
  const pageSize = this.state.$pageSize();
3865
3867
  const currentPage = this.state.$currentPage();
3866
3868
  if (this.$useVirtualScroll()) {
@@ -4030,14 +4032,14 @@ class GenericTableComponent {
4030
4032
  });
4031
4033
  $stickyFooter = computed(() => this.state.$props().stickyFooter || this.state.$isVirtual());
4032
4034
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenericTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4033
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GenericTableComponent, isStandalone: true, selector: "tb-generic-table", inputs: { $displayDataLength: { classPropertyName: "$displayDataLength", publicName: "displayDataLength", isSignal: true, isRequired: true, transformFunction: null }, $data: { classPropertyName: "$data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, $rows: { classPropertyName: "$rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, $columnInfos: { classPropertyName: "$columnInfos", publicName: "columnInfos", isSignal: true, isRequired: true, transformFunction: null }, $dataSource: { classPropertyName: "$dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, $trackBy: { classPropertyName: "$trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection$: "selection" }, viewQueries: [{ propertyName: "$headerRow", first: true, predicate: MatHeaderRowDef, descendants: true, isSignal: true }, { propertyName: "$footerRow", first: true, predicate: MatFooterRowDef, descendants: true, isSignal: true }, { propertyName: "$table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "$dropList", first: true, predicate: CdkDropList, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index; let t\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }} {{i}} {{$offsetIndex()}}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row [style.height]=\"$rowHeight()\" [style.min-height]=\"$rowHeight()\"\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"/>\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$6.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$6.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i1$6.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: FunctionPipe, name: "func" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4035
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.0", type: GenericTableComponent, isStandalone: true, selector: "tb-generic-table", inputs: { $displayDataLength: { classPropertyName: "$displayDataLength", publicName: "displayDataLength", isSignal: true, isRequired: true, transformFunction: null }, $data: { classPropertyName: "$data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, $rows: { classPropertyName: "$rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, $columnInfos: { classPropertyName: "$columnInfos", publicName: "columnInfos", isSignal: true, isRequired: true, transformFunction: null }, $dataSource: { classPropertyName: "$dataSource", publicName: "dataSource", isSignal: true, isRequired: true, transformFunction: null }, $trackBy: { classPropertyName: "$trackBy", publicName: "trackBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection$: "selection" }, viewQueries: [{ propertyName: "$headerRow", first: true, predicate: MatHeaderRowDef, descendants: true, isSignal: true }, { propertyName: "$footerRow", first: true, predicate: MatFooterRowDef, descendants: true, isSignal: true }, { propertyName: "$table", first: true, predicate: MatTable, descendants: true, isSignal: true }, { propertyName: "$dropList", first: true, predicate: CdkDropList, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index;\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row [style.height]=\"$rowHeight()\" [style.min-height]=\"$rowHeight()\"\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"/>\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$6.MatFooterCellDef, selector: "[matFooterCellDef]" }, { kind: "directive", type: i1$6.MatFooterRowDef, selector: "[matFooterRowDef]", inputs: ["matFooterRowDef", "matFooterRowDefSticky"] }, { kind: "directive", type: i1$6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "directive", type: i1$6.MatFooterCell, selector: "mat-footer-cell, td[mat-footer-cell]" }, { kind: "component", type: i1$6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i1$6.MatFooterRow, selector: "mat-footer-row, tr[mat-footer-row]", exportAs: ["matFooterRow"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i5.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$2.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "pipe", type: FunctionPipe, name: "func" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4034
4036
  }
4035
4037
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: GenericTableComponent, decorators: [{
4036
4038
  type: Component,
4037
4039
  args: [{ selector: 'tb-generic-table', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
4038
4040
  MatTableModule, DragDropModule, MatCheckboxModule, MatButtonModule, MatIconModule, NgTemplateOutlet,
4039
4041
  MatTooltipModule, FunctionPipe,
4040
- ], template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index; let t\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }} {{i}} {{$offsetIndex()}}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row [style.height]=\"$rowHeight()\" [style.min-height]=\"$rowHeight()\"\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"/>\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"] }]
4042
+ ], template: "<mat-table\r\n cdkDropList\r\n cdkDropListLockAxis='x'\r\n cdkDropListOrientation=\"horizontal\"\r\n (cdkDropListDropped)=\"drop($event)\"\r\n class=\"table-drag-list\"\r\n #table\r\n [dataSource]=\"$dataSource()\"\r\n [trackBy]=\"$trackByFunction()\"\r\n [style]=\"$tableWidth()\"\r\n>\r\n\r\n <!-- select column -->\r\n <ng-container matColumnDef=\"select\">\r\n @let selection = $selection();\r\n <mat-header-cell *matHeaderCellDef class=\"select-column\">\r\n <mat-checkbox (change)=\"$event ? masterToggle() : null\"\r\n [checked]=\"!!($masterToggleChecked())\"\r\n [indeterminate]=\"$masterToggleIndeterminate()\">\r\n </mat-checkbox>\r\n </mat-header-cell>\r\n\r\n <mat-cell *matCellDef=\"let row\" class=\"select-column\">\r\n <mat-checkbox\r\n (click)=\"$event.stopPropagation()\"\r\n (change)=\"$event ? selection.toggle(row) : null\"\r\n [checked]=\"selection.isSelected(row)\"/>\r\n </mat-cell>\r\n\r\n <mat-footer-cell *matFooterCellDef class=\"select-column\">\r\n {{ selection.selected.length }}\r\n </mat-footer-cell>\r\n </ng-container>\r\n\r\n\r\n <!-- index column -->\r\n <ng-container matColumnDef=\"index\">\r\n <mat-header-cell *matHeaderCellDef class=\"f-mat-header-cell\" class=\"index-column\">#\r\n </mat-header-cell>\r\n <mat-cell *matCellDef=\"let i = index;\" class=\"index-column\">\r\n {{ 1 + i + $offsetIndex() }}\r\n </mat-cell>\r\n <mat-footer-cell *matFooterCellDef class=\"index-column\"></mat-footer-cell>\r\n </ng-container>\r\n\r\n <!-- Grouping -->\r\n <ng-container matColumnDef=\"groupHeader\">\r\n <mat-cell *matCellDef=\"let row\">\r\n @let expanded = (state.$getIsExpanded | func : row.key : row.groupName );\r\n <div [style.paddingLeft]=\"row.padding + 'px !important'\">\r\n <button mat-icon-button (click)=\"setExpanded(row.key, row.groupName, !expanded());\">\r\n @if (!expanded()) {\r\n <mat-icon>chevron_right</mat-icon>\r\n } @else {\r\n <mat-icon>expand_more</mat-icon>\r\n }\r\n </button>\r\n {{ getTransform | func : row.key : row.groupHeaderDisplay }} ({{ row.length }})\r\n </div>\r\n <div style=\"flex-grow: 1\">\r\n <ng-container *ngTemplateOutlet=\"state.$props().groupHeaderTemplate!; context: { element: row }\"></ng-container>\r\n </div>\r\n </mat-cell>\r\n </ng-container>\r\n\r\n <mat-row [style.height]=\"$rowHeight()\" [style.min-height]=\"$rowHeight()\"\r\n *matRowDef=\"let row; columns: $keys(); let i = index\"/>\r\n <mat-row [style.height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n [style.min-height]=\"state.$props().groupHeaderHeight ? state.$props().groupHeaderHeight + 'px' : $groupHeaderHeight()\"\r\n *matRowDef=\"let row; columns: ['groupHeader']; when: isGroupHeader\" style=\"background-color: white;\"/>\r\n</mat-table>\r\n\r\n<mat-header-row [style.height]=\"$headerHeight()\" [style.min-height]=\"$headerHeight()\"\r\n *matHeaderRowDef=\"$keys(); sticky: state.$props().isSticky\" [style.top.px]=\"($offset()! * -1)\"/>\r\n<mat-footer-row [style.height]=\"$footerHeight()\" [style.min-height]=\"$footerHeight()\"\r\n *matFooterRowDef=\"$keys(); sticky: $stickyFooter() \"\r\n [style.bottom.px]=\"$stickyFooter() ? ($offset()) : undefined\"/>\r\n", styles: [":host{--mat-paginator-container-size: initial}.select-column{min-width:var(--tb-min-select-column-width, 42px)}.index-column{min-width:var(--tb-min-index-column-width, 42px)}.mat-mdc-row:nth-child(odd){background-color:var(--tb-odd-row-background-color, #cdeefe)}.page-amounts{color:#0000008a;font-family:Roboto,Helvetica Neue,sans-serif;font-size:12px;margin-right:.2rem}:host::ng-deep .table-drag-list.cdk-drop-list-dragging .drag-header:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}:host::ng-deep .mdc-data-table__cell,:host::ng-deep .mdc-data-table__header-cell{padding:var(--tb-cell-padding, 0 0 0 .2rem);line-height:var(--tb-cell-line-height, normal)}::ng-deep .op-date-time-input{line-height:3rem;font-size:.9rem;font-family:Roboto,Helvetica Neue,sans-serif;padding-left:.2rem;width:12rem}\n"] }]
4041
4043
  }] });
4042
4044
 
4043
4045
  function downloadData(data, filename, mimeType) {
@@ -4746,7 +4748,7 @@ class TableBuilderDataSource extends MatTableDataSource {
4746
4748
  const $pageSize = state.$pageSize;
4747
4749
  const $virtualEnds = data.selectSignal(d => d.virtualEnds);
4748
4750
  const $dataLength = computed(() => this.#$dataSrc().length);
4749
- this.$dataSize = computed(() => {
4751
+ const $dataSize = computed(() => {
4750
4752
  const viewType = state.$viewType();
4751
4753
  const dataLength = $dataLength();
4752
4754
  const currentPage = $currentPage();
@@ -4764,6 +4766,7 @@ class TableBuilderDataSource extends MatTableDataSource {
4764
4766
  }
4765
4767
  return ({ start: virtualEnds.start, end: virtualEnds.end });
4766
4768
  });
4769
+ this.$dataSize = $dataSize;
4767
4770
  }
4768
4771
  connect() {
4769
4772
  return super.connect();
@@ -5066,144 +5069,93 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.0", ngImpor
5066
5069
  }] });
5067
5070
 
5068
5071
  class TableVirtualScrollStrategy {
5069
- constructor(scrollContainer, dataStore) {
5070
- this.$rowHeight = scrollContainer.computedRowHeight;
5071
- this.$headerHeight = scrollContainer.computedHeaderHeight;
5072
- this.viewport = scrollContainer.viewport;
5073
- this.dataStore = dataStore;
5074
- this.$dataLength = scrollContainer.$dataLength;
5075
- }
5076
- dataStore;
5072
+ scrolledIndexChange;
5073
+ dataLength = 0;
5077
5074
  indexChange = new Subject();
5078
- scrolledIndexChange = this.indexChange.pipe(distinctUntilChanged());
5079
5075
  viewport;
5080
- $dataLength;
5081
- $dataLengthChange = linkedSignal({
5082
- source: () => this.$dataLength(),
5083
- computation: (curr, previous) => ({ curr, previous: previous == undefined ? curr : previous.source })
5084
- });
5085
5076
  $rowHeight;
5086
5077
  $rowHeightChange = linkedSignal({
5087
5078
  source: () => this.$rowHeight(),
5088
- computation: (curr, previous) => {
5089
- return ({ curr, previous: previous == undefined ? curr : previous.source });
5090
- }
5079
+ computation: (curr, previous) => ({ curr, previous: previous?.source || curr })
5091
5080
  });
5092
5081
  $headerHeight;
5093
- $headerHeightChange = linkedSignal({
5094
- source: () => this.$headerHeight(),
5095
- computation: (curr, previous) => ({ curr, previous: previous == undefined ? curr : previous.source })
5096
- });
5082
+ constructor(scrollContainer) {
5083
+ this.scrolledIndexChange = this.indexChange.pipe(distinctUntilChanged());
5084
+ this.$rowHeight = scrollContainer.computedRowHeight;
5085
+ this.$headerHeight = scrollContainer.computedHeaderHeight;
5086
+ }
5087
+ attach(viewport) {
5088
+ this.viewport = viewport;
5089
+ this.onDataLengthChanged();
5090
+ }
5097
5091
  contentScrolled$ = new Subject();
5098
- sub = subscriber(this.contentScrolled$.pipe(debounceTime(20), distinctUntilChanged()), offset => {
5092
+ sub = subscriber(this.contentScrolled$.pipe(observeOn(animationFrameScheduler), debounceTime(20)), () => {
5099
5093
  this.updateContent('scroll');
5100
5094
  });
5101
5095
  onContentScrolled() {
5102
- this.contentScrolled$.next(this.viewport().measureScrollOffset());
5096
+ this.contentScrolled$.next();
5097
+ }
5098
+ onDataLengthChanged() {
5099
+ }
5100
+ setDataLength(length) {
5101
+ this.dataLength = length;
5102
+ if (this.viewport && this.$rowHeight) {
5103
+ this.viewport.setTotalContentSize(this.dataLength * this.$rowHeight());
5104
+ // this.updateContent('data ' + dataTrigger);
5105
+ }
5106
+ this.updateContent('data ');
5107
+ }
5108
+ detach() { }
5109
+ onContentRendered() { }
5110
+ onRenderedOffsetChanged() {
5111
+ }
5112
+ scrollToIndex(index, behavior) {
5103
5113
  }
5104
- #onDataLengthChange = effect(() => {
5105
- const dataLengthChange = this.$dataLengthChange();
5106
- untracked(() => {
5107
- console.log('data', dataLengthChange);
5108
- if (dataLengthChange.curr === dataLengthChange.previous)
5109
- return;
5110
- this.updateContent('data length');
5111
- });
5112
- });
5113
5114
  #onHeaderChange = effect(() => {
5114
- const headerHeightChange = this.$headerHeightChange();
5115
- untracked(() => {
5116
- if (headerHeightChange.curr === headerHeightChange.previous)
5117
- return;
5118
- this.updateContent('header height');
5119
- });
5115
+ this.$headerHeight && this.$headerHeight();
5116
+ this.updateContent('header height');
5120
5117
  });
5121
5118
  #onRowChange = effect(() => {
5122
- const rowHeightChange = this.$rowHeightChange();
5123
- untracked(() => {
5124
- if (rowHeightChange.curr === rowHeightChange.previous)
5125
- return;
5126
- this.updateContent('row height');
5127
- });
5119
+ this.$rowHeight && this.$rowHeight();
5120
+ this.updateContent('row height');
5128
5121
  });
5129
- $currentRange = signal({ start: 0, end: 0 });
5130
5122
  updateContent(trigger) {
5131
- console.log('scroll - ', trigger);
5132
- const viewport = this.viewport && this.viewport();
5133
- if (!viewport || !this.$rowHeight) {
5123
+ if (!this.viewport || !this.$rowHeight) {
5134
5124
  return;
5135
5125
  }
5136
- const currentContentHeight = +viewport._totalContentHeight.replace('px', '');
5137
- const newContentHeight = this.$dataLength() * this.$rowHeight();
5126
+ const currentContentHeight = +this.viewport._totalContentHeight.replace('px', '');
5127
+ const newContentHeight = this.dataLength * this.$rowHeight();
5138
5128
  if (currentContentHeight !== newContentHeight) {
5139
- viewport.setTotalContentSize(newContentHeight);
5140
- this.update(trigger, viewport, true);
5129
+ this.viewport.setTotalContentSize(newContentHeight);
5130
+ setTimeout(() => {
5131
+ this.update(trigger);
5132
+ }, 0);
5141
5133
  return;
5142
5134
  }
5143
- this.update(trigger, viewport);
5135
+ this.update(trigger);
5144
5136
  }
5145
- update(trigger, viewport, needsScroll = false) {
5146
- if (!viewport.getViewportSize())
5137
+ update(trigger) {
5138
+ if (!this.viewport || !this.$rowHeight) {
5147
5139
  return;
5148
- // console.log(trigger, {
5149
- // rowHeight: this.$rowHeight(),
5150
- // rowHeightChange: this.$rowHeightChange().curr !== this.$rowHeightChange().previous,
5151
- // headerHeight: this.$headerHeight(),
5152
- // dataLength: this.$dataLength(),
5153
- // viewportSize: viewport.getViewportSize(),
5154
- // scrollOffset: viewport.measureScrollOffset(),
5155
- // renderedRange: viewport.getRenderedRange(),
5156
- // totalContentSize: viewport._totalContentHeight
5157
- // });
5140
+ }
5158
5141
  const rowHeightChangeEvent = this.$rowHeightChange();
5159
5142
  const rowHeight = rowHeightChangeEvent.curr;
5160
5143
  const rowHeightAdjustment = trigger === 'row height' ? rowHeightChangeEvent.curr / rowHeightChangeEvent.previous : 1;
5161
- const amountOfRows = Math.ceil((viewport.getViewportSize() - this.$headerHeight()) / rowHeight);
5162
- const f = viewport.measureScrollOffset();
5163
- const offset = viewport.measureScrollOffset() * rowHeightAdjustment;
5164
- const buffer = 35 + Math.round((40 - rowHeight) / 10);
5165
- console.log({ buffer });
5144
+ const amountOfRows = Math.ceil((this.viewport.getViewportSize() - this.$headerHeight()) / rowHeight);
5145
+ const f = this.viewport.measureScrollOffset();
5146
+ const offset = this.viewport.measureScrollOffset() * rowHeightAdjustment;
5147
+ if (offset !== f) {
5148
+ this.viewport.scrollToOffset(offset);
5149
+ }
5150
+ const buffer = 35;
5166
5151
  const skip = Math.round(offset / rowHeight);
5167
5152
  const index = skip % 2 === 0 ? skip : skip - 1;
5168
5153
  const start = Math.max(0, index - buffer);
5169
- const end = Math.min(this.$dataLength(), index + amountOfRows + buffer);
5170
- // console.log({
5171
- // start,
5172
- // end,
5173
- // index,
5174
- // skip,
5175
- // amountOfRows,
5176
- // offset: rowHeight * start
5177
- // });
5178
- if (start > this.$dataLength()) {
5179
- this.viewport().scrollToOffset(0);
5180
- }
5181
- else if (f !== offset) {
5182
- console.log('adjust scroll');
5183
- if (offset < f)
5184
- viewport.scrollToOffset(offset);
5185
- else
5186
- setTimeout(() => {
5187
- viewport.scrollToOffset(offset);
5188
- }, 0);
5189
- }
5190
- if (this.$currentRange().start === start && this.$currentRange().end === end) {
5191
- return;
5192
- }
5193
- this.$currentRange.set({ start, end });
5194
- console.log('setting range');
5195
- console.log({ offset, contentOffset: rowHeight * start });
5196
- viewport.setRenderedContentOffset(rowHeight * start);
5197
- this.dataStore.patchState({ virtualScrollOffset: offset });
5198
- viewport.setRenderedRange({ start, end });
5154
+ const end = Math.min(this.dataLength, index + amountOfRows + buffer);
5155
+ this.viewport.setRenderedContentOffset(rowHeight * start);
5156
+ this.viewport.setRenderedRange({ start, end });
5199
5157
  this.indexChange.next(index);
5200
5158
  }
5201
- attach(viewport) { }
5202
- onDataLengthChanged() { }
5203
- detach() { }
5204
- onContentRendered() { }
5205
- onRenderedOffsetChanged() { }
5206
- scrollToIndex(index, behavior) { }
5207
5159
  }
5208
5160
 
5209
5161
  class VirtualScrollContainer {
@@ -5221,13 +5173,7 @@ class VirtualScrollContainer {
5221
5173
  viewPort$ = toObservable(this.viewport).pipe(notNull());
5222
5174
  $scrolledIndexChange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.scrolledIndexChange)));
5223
5175
  $renderedRange = toSignal(this.viewPort$.pipe(switchMap$1(v => v.renderedRangeStream)));
5224
- $virtualScrollOptions = computed(() => {
5225
- if (this.state.$initializationState() >= InitializationState.Ready)
5226
- return this.state.$tableSettings().virtualSettings;
5227
- else
5228
- return undefined;
5229
- });
5230
- $optionsSet = computed(() => !!this.$virtualScrollOptions());
5176
+ $virtualScrollOptions = computed(() => this.state.$tableSettings().virtualSettings);
5231
5177
  $dataLength = computed(() => {
5232
5178
  const paginated = this.$usePaginator() && !this.$showAll();
5233
5179
  const pageSize = this.$pageSize();
@@ -5240,41 +5186,58 @@ class VirtualScrollContainer {
5240
5186
  constructor() {
5241
5187
  addEventListener('resize', this.resizeHandler);
5242
5188
  }
5243
- #setViewportEffect = effect(() => {
5189
+ setViewportEffect = effect(() => {
5244
5190
  const viewport = this.viewport();
5245
- const options = this.$optionsSet();
5246
5191
  untracked(() => {
5247
- if (!!viewport && !!options) {
5248
- this.setSize(this.viewport().elementRef, 'initial');
5192
+ if (!!viewport) {
5193
+ this.setSize(this.viewport().elementRef);
5249
5194
  }
5250
5195
  ;
5251
5196
  });
5252
5197
  });
5198
+ subscriber = subscriber();
5253
5199
  #onRenderedRangeEffect = effect(() => {
5254
5200
  const renderedRange = this.$renderedRange();
5255
- const viewport = this.viewport();
5256
5201
  if (!renderedRange)
5257
5202
  return;
5258
5203
  untracked(() => {
5259
5204
  this.dataStore.patchState({
5260
5205
  virtualEnds: {
5261
5206
  start: renderedRange.start,
5262
- end: renderedRange.end,
5207
+ end: renderedRange.end + 25,
5263
5208
  }
5264
5209
  });
5265
- if (!viewport)
5266
- return;
5267
- this.setSize(viewport.elementRef, 'rendered range');
5210
+ this.setSize(this.viewport().elementRef);
5211
+ });
5212
+ });
5213
+ #onDataLengthEffect = effect(() => {
5214
+ const dataLength = this.$dataLength();
5215
+ untracked(() => {
5216
+ const renderedRange = this.$renderedRange();
5217
+ this.scrollStrategy.setDataLength(dataLength);
5218
+ if ((renderedRange?.start || 0) > dataLength) {
5219
+ this.viewport().scrollToOffset(0);
5220
+ }
5221
+ });
5222
+ });
5223
+ #onOffsetEffect = effect(() => {
5224
+ const offset = this.$offset();
5225
+ untracked(() => {
5226
+ this.dataStore.patchState({ virtualScrollOffset: offset });
5268
5227
  });
5269
5228
  });
5229
+ $offset = computed(() => {
5230
+ const viewport = this.viewport();
5231
+ const scrolledIndexChange = this.$scrolledIndexChange();
5232
+ if (!scrolledIndexChange || !viewport)
5233
+ return 0;
5234
+ return viewport.getOffsetToRenderedContentStart() ?? 0;
5235
+ });
5270
5236
  ngOnDestroy() {
5271
5237
  removeEventListener('resize', this.resizeHandler);
5272
5238
  }
5273
- setSize(el, trigger) {
5274
- console.log('size - ', trigger);
5239
+ setSize(el) {
5275
5240
  const virtualScrollOptions = this.$virtualScrollOptions();
5276
- if (!virtualScrollOptions)
5277
- return;
5278
5241
  if (virtualScrollOptions.dynamicHeight) {
5279
5242
  this.calcDynamic(el);
5280
5243
  return;
@@ -5291,33 +5254,45 @@ class VirtualScrollContainer {
5291
5254
  height = maxViewPortHeightPx;
5292
5255
  this.setHeight(height, el);
5293
5256
  }
5257
+ calcDynamic$ = new Subject();
5258
+ $calcDynamic = toSignal(this.calcDynamic$.pipe(debounceTime$1(300)));
5259
+ #onCalcDynamicEffect = effect(() => {
5260
+ const el = this.$calcDynamic();
5261
+ if (!el)
5262
+ return;
5263
+ untracked(() => {
5264
+ this.calcDynamic(el);
5265
+ });
5266
+ });
5294
5267
  calcDynamic(el) {
5295
5268
  const virtualScrollOptions = this.$virtualScrollOptions();
5296
- if (!virtualScrollOptions)
5297
- return;
5298
5269
  const t = this.tableContainer.elementRef.nativeElement.querySelector(`#${TableContainerComponent.headerId}`);
5299
5270
  const rect = t?.getBoundingClientRect();
5300
- const viewportHeight = window.innerHeight;
5301
- const distanceFromBottom = viewportHeight - rect.bottom;
5271
+ const windowHeight = window.innerHeight;
5272
+ const distanceFromBottom = windowHeight - rect.bottom;
5302
5273
  const rowHeight = this.computedRowHeight();
5303
5274
  const footerHeight = this.computedFooterHeight();
5304
5275
  const headerHeight = this.computedHeaderHeight();
5276
+ const buffer = this.computedBuffer();
5277
+ const horizontalScrollPadding = el.nativeElement.scrollWidth > el.nativeElement.clientWidth ? 17 : 0;
5305
5278
  const maxViewPortHeightPx = parseTbSizeToPixels(virtualScrollOptions.maxViewPortHeight) || 0;
5306
5279
  let tableSize = distanceFromBottom;
5307
5280
  if (virtualScrollOptions?.maxViewPortHeight && maxViewPortHeightPx < tableSize) {
5308
5281
  tableSize = maxViewPortHeightPx;
5309
5282
  }
5310
- const available = (distanceFromBottom - footerHeight) - headerHeight - (this.$usePaginator() ? 20 : 0);
5283
+ const available = (distanceFromBottom - footerHeight)
5284
+ - headerHeight
5285
+ - (this.$usePaginator() ? 20 : 0)
5286
+ - buffer
5287
+ - horizontalScrollPadding;
5311
5288
  const amountOfRowsThatWillFit = Math.floor(available / rowHeight);
5312
5289
  const minAmountOfRows = virtualScrollOptions?.amountOfVisibleItems || this.defaultOptions.amountOfVisibleItems;
5313
5290
  const amountOfVisibleItems = Math.min(Math.max(amountOfRowsThatWillFit, minAmountOfRows), this.$dataLength());
5314
- console.log(amountOfRowsThatWillFit, amountOfVisibleItems);
5315
5291
  let height = (rowHeight * amountOfVisibleItems);
5316
- height += (footerHeight + headerHeight);
5292
+ height += (footerHeight + headerHeight + horizontalScrollPadding);
5317
5293
  this.setHeight(height, el);
5318
5294
  }
5319
5295
  setHeight(height, el) {
5320
- console.log('height - ', height);
5321
5296
  const vsViewport = el.nativeElement;
5322
5297
  vsViewport.setAttribute('style', `height: ${height}px !important;`);
5323
5298
  this.viewport()?.checkViewportSize();
@@ -5325,8 +5300,8 @@ class VirtualScrollContainer {
5325
5300
  this.dataStore.patchState({ virtualScrollOffset });
5326
5301
  }
5327
5302
  resizeHandler = () => {
5328
- if (this.viewport() && this.$virtualScrollOptions()?.dynamicHeight) {
5329
- this.setSize(this.viewport().elementRef, 'resize');
5303
+ if (this.viewport() && this.$virtualScrollOptions().dynamicHeight) {
5304
+ this.setSize(this.viewport().elementRef);
5330
5305
  }
5331
5306
  };
5332
5307
  computedRowHeight = computed(() => {
@@ -5344,7 +5319,13 @@ class VirtualScrollContainer {
5344
5319
  computedFooterHeight = computed(() => {
5345
5320
  return parseFloat(this.genericTable()?.$footerHeight()?.replace('px', '') || '0');
5346
5321
  });
5347
- scrollStrategy = new TableVirtualScrollStrategy(this, this.dataStore);
5322
+ computedBuffer = computed(() => {
5323
+ const virtualScrollOptions = this.state.$tableSettings().virtualSettings;
5324
+ if (!virtualScrollOptions.dynamicalHeightBuffer)
5325
+ return 0;
5326
+ return parseTbSizeToPixels(virtualScrollOptions.dynamicalHeightBuffer) || 0;
5327
+ });
5328
+ scrollStrategy = new TableVirtualScrollStrategy(this);
5348
5329
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.0", ngImport: i0, type: VirtualScrollContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
5349
5330
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.0", type: VirtualScrollContainer, isStandalone: true, selector: "tb-virtual-scroll-container", queries: [{ propertyName: "genericTable", first: true, predicate: GenericTableComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }], ngImport: i0, template: `
5350
5331
  <cdk-virtual-scroll-viewport>