@libs-ui/components-scroll-measure-items-direction-vertical 0.2.356-21

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 ADDED
@@ -0,0 +1,3 @@
1
+ # scroll-measure-items-direction-vertical
2
+
3
+ This library was generated with [Nx](https://nx.dev).
@@ -0,0 +1,32 @@
1
+ import { AfterViewInit } from '@angular/core';
2
+ import { IScrollMeasureItemDirectionVerticalFunctionsControl } from './interfaces/direction-vertical.interface';
3
+ import * as i0 from "@angular/core";
4
+ export declare class LibsUiScrollMeasureItemDirectionVerticalDirective implements AfterViewInit {
5
+ private viewPortItems;
6
+ private start;
7
+ private end;
8
+ private storeItems;
9
+ private divVirtual;
10
+ readonly elementScroll: import("@angular/core").InputSignal<HTMLElement>;
11
+ readonly functionGetHeightItem: import("@angular/core").InputSignal<(item: any) => Promise<number>>;
12
+ readonly items: import("@angular/core").InputSignal<any[]>;
13
+ readonly outViewPortItem: import("@angular/core").OutputEmitterRef<any[]>;
14
+ readonly outFunctionControl: import("@angular/core").OutputEmitterRef<IScrollMeasureItemDirectionVerticalFunctionsControl>;
15
+ readonly outDivVirtual: import("@angular/core").OutputEmitterRef<HTMLDivElement>;
16
+ readonly outPaddingTop: import("@angular/core").OutputEmitterRef<number>;
17
+ private readonly elementRef;
18
+ private readonly destroyRef;
19
+ constructor();
20
+ ngAfterViewInit(): void;
21
+ get FunctionsControl(): IScrollMeasureItemDirectionVerticalFunctionsControl;
22
+ private get ScrollContainer();
23
+ private findStartIndex;
24
+ private findEndIndex;
25
+ private handlerScroll;
26
+ private scrollInto;
27
+ private scrollToPosition;
28
+ private scrollToIndex;
29
+ private reCalculatorViewPort;
30
+ static ɵfac: i0.ɵɵFactoryDeclaration<LibsUiScrollMeasureItemDirectionVerticalDirective, never>;
31
+ static ɵdir: i0.ɵɵDirectiveDeclaration<LibsUiScrollMeasureItemDirectionVerticalDirective, "[LibsUiScrollMeasureItemDirectionVerticalDirective]", never, { "elementScroll": { "alias": "elementScroll"; "required": true; "isSignal": true; }; "functionGetHeightItem": { "alias": "functionGetHeightItem"; "required": true; "isSignal": true; }; "items": { "alias": "items"; "required": true; "isSignal": true; }; }, { "outViewPortItem": "outViewPortItem"; "outFunctionControl": "outFunctionControl"; "outDivVirtual": "outDivVirtual"; "outPaddingTop": "outPaddingTop"; }, never, never, true, never>;
32
+ }
@@ -0,0 +1,197 @@
1
+ // CONVENTION-EXCEPT: any — Generic directive works with unknown item types from consumer
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ import { DestroyRef, Directive, ElementRef, effect, inject, input, output, signal, untracked } from '@angular/core';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
5
+ import { get } from '@libs-ui/utils';
6
+ import { fromEvent } from 'rxjs';
7
+ import * as i0 from "@angular/core";
8
+ export class LibsUiScrollMeasureItemDirectionVerticalDirective {
9
+ // #region PROPERTY
10
+ viewPortItems = signal([]);
11
+ start = signal(0);
12
+ end = signal(0);
13
+ storeItems = signal([]);
14
+ divVirtual = document.createElement('div');
15
+ // #region INPUT
16
+ elementScroll = input.required();
17
+ functionGetHeightItem = input.required();
18
+ items = input.required();
19
+ // #region OUTPUT
20
+ outViewPortItem = output();
21
+ outFunctionControl = output();
22
+ outDivVirtual = output();
23
+ outPaddingTop = output();
24
+ // #region INJECT
25
+ elementRef = inject(ElementRef);
26
+ destroyRef = inject(DestroyRef);
27
+ constructor() {
28
+ effect(() => {
29
+ const scrollEl = untracked(() => this.ScrollContainer);
30
+ if (!scrollEl || !untracked(() => this.functionGetHeightItem())) {
31
+ return;
32
+ }
33
+ const items = this.items();
34
+ untracked(async () => {
35
+ this.start.set(0);
36
+ const scrollTop = scrollEl.scrollTop;
37
+ const containerHeight = scrollEl.getBoundingClientRect().height;
38
+ let height = 0;
39
+ const newItems = [];
40
+ for (let i = 0; i < items.length; i++) {
41
+ const item = items[i];
42
+ const newItem = { ref: item, itemHeight: 0, start: 0, end: 0 };
43
+ const itemHeight = await this.functionGetHeightItem()(item);
44
+ newItem.itemHeight = itemHeight;
45
+ newItem.start = height;
46
+ height += itemHeight;
47
+ newItem.end = height;
48
+ if (newItem.end <= containerHeight + scrollTop) {
49
+ this.end.set(i);
50
+ }
51
+ newItems.push(newItem);
52
+ }
53
+ this.storeItems.set(newItems);
54
+ this.viewPortItems.set(this.storeItems()
55
+ .slice(this.start(), this.end() + 3)
56
+ .map((item) => item.ref));
57
+ this.outViewPortItem.emit(this.viewPortItems());
58
+ this.outPaddingTop.emit(get(this.storeItems(), `[${this.start()}].start`, 0));
59
+ this.divVirtual.style.position = 'absolute';
60
+ this.divVirtual.style.top = '0px';
61
+ this.divVirtual.style.left = '0px';
62
+ this.divVirtual.style.height = `${height}px`;
63
+ this.divVirtual.style.width = '1px';
64
+ this.divVirtual.style.visibility = 'hidden'; // Đảm bảo an toàn không hiển thị
65
+ this.elementRef.nativeElement.classList.add('relative');
66
+ this.elementRef.nativeElement.classList.remove('h-full');
67
+ this.elementRef.nativeElement.style.paddingTop = '0px';
68
+ scrollEl.append(this.divVirtual);
69
+ this.outDivVirtual.emit(this.divVirtual);
70
+ });
71
+ });
72
+ this.destroyRef.onDestroy(() => {
73
+ this.divVirtual.remove();
74
+ });
75
+ }
76
+ ngAfterViewInit() {
77
+ setTimeout(() => {
78
+ fromEvent(this.ScrollContainer, 'scroll')
79
+ .pipe(takeUntilDestroyed(this.destroyRef))
80
+ .subscribe(() => this.handlerScroll());
81
+ this.outFunctionControl.emit(this.FunctionsControl);
82
+ });
83
+ }
84
+ // #region PUBLIC API
85
+ get FunctionsControl() {
86
+ return {
87
+ scrollInto: this.scrollInto.bind(this),
88
+ scrollToPosition: this.scrollToPosition.bind(this),
89
+ scrollToIndex: this.scrollToIndex.bind(this),
90
+ reCalculatorViewPort: this.reCalculatorViewPort.bind(this),
91
+ getViewPortItems: () => this.viewPortItems(),
92
+ };
93
+ }
94
+ // #region PRIVATE METHODS
95
+ get ScrollContainer() {
96
+ return this.elementScroll() || this.elementRef.nativeElement;
97
+ }
98
+ findStartIndex(store, scrollTop) {
99
+ let low = 0;
100
+ let high = store.length - 1;
101
+ let ans = store.length - 1; // Default to last item if scrolled past bottom (rubber band effect)
102
+ while (low <= high) {
103
+ const mid = Math.floor((low + high) / 2);
104
+ if (store[mid].end >= scrollTop) {
105
+ ans = mid;
106
+ high = mid - 1; // Try to find earlier
107
+ }
108
+ else {
109
+ low = mid + 1;
110
+ }
111
+ }
112
+ return ans;
113
+ }
114
+ findEndIndex(store, scrollBottom) {
115
+ let low = 0;
116
+ let high = store.length - 1;
117
+ let ans = 0; // Default to first item if rubber-banded above the top
118
+ while (low <= high) {
119
+ const mid = Math.floor((low + high) / 2);
120
+ if (store[mid].start <= scrollBottom) {
121
+ ans = mid;
122
+ low = mid + 1; // Try to find later
123
+ }
124
+ else {
125
+ high = mid - 1;
126
+ }
127
+ }
128
+ return ans;
129
+ }
130
+ handlerScroll() {
131
+ const store = this.storeItems();
132
+ if (!store?.length) {
133
+ return;
134
+ }
135
+ const scrollEl = this.ScrollContainer;
136
+ const scrollTop = scrollEl.scrollTop;
137
+ const containerHeight = scrollEl.getBoundingClientRect().height;
138
+ // Utilize Binary Search for optimal O(log N) discovery
139
+ const start = this.findStartIndex(store, scrollTop);
140
+ const end = this.findEndIndex(store, scrollTop + containerHeight);
141
+ this.end.set(end);
142
+ if (start !== this.start()) {
143
+ this.start.set(start);
144
+ // Use logical OR for fallback when start is invalid. But binary search guarantees valid index.
145
+ const paddingTop = store[start]?.start || 0;
146
+ this.elementRef.nativeElement.style.paddingTop = `${paddingTop}px`;
147
+ this.outPaddingTop.emit(paddingTop);
148
+ }
149
+ if (this.start() < 0) {
150
+ this.start.set(0);
151
+ }
152
+ this.viewPortItems.set(store.slice(this.start(), this.end() + 3).map((item) => item.ref));
153
+ this.outViewPortItem.emit(this.viewPortItems());
154
+ }
155
+ async scrollInto(itemScroll) {
156
+ const itemFound = this.storeItems().find((item) => item.ref === itemScroll);
157
+ if (!itemFound) {
158
+ return;
159
+ }
160
+ this.ScrollContainer.scrollTop = itemFound.start;
161
+ }
162
+ async scrollToPosition(position) {
163
+ this.ScrollContainer.scrollTop = position;
164
+ }
165
+ async scrollToIndex(index) {
166
+ const itemOfIndex = this.storeItems()[index];
167
+ if (!itemOfIndex) {
168
+ return;
169
+ }
170
+ this.ScrollContainer.scrollTop = itemOfIndex.start;
171
+ }
172
+ async reCalculatorViewPort() {
173
+ let height = 0;
174
+ const items = this.storeItems();
175
+ for (const item of items) {
176
+ const itemHeight = await this.functionGetHeightItem()(item.ref);
177
+ item.itemHeight = itemHeight;
178
+ item.start = height;
179
+ height += itemHeight;
180
+ item.end = height;
181
+ }
182
+ this.storeItems.set([...items]);
183
+ this.divVirtual.style.height = `${height}px`;
184
+ this.handlerScroll();
185
+ }
186
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiScrollMeasureItemDirectionVerticalDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
187
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.14", type: LibsUiScrollMeasureItemDirectionVerticalDirective, isStandalone: true, selector: "[LibsUiScrollMeasureItemDirectionVerticalDirective]", inputs: { elementScroll: { classPropertyName: "elementScroll", publicName: "elementScroll", isSignal: true, isRequired: true, transformFunction: null }, functionGetHeightItem: { classPropertyName: "functionGetHeightItem", publicName: "functionGetHeightItem", isSignal: true, isRequired: true, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { outViewPortItem: "outViewPortItem", outFunctionControl: "outFunctionControl", outDivVirtual: "outDivVirtual", outPaddingTop: "outPaddingTop" }, ngImport: i0 });
188
+ }
189
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiScrollMeasureItemDirectionVerticalDirective, decorators: [{
190
+ type: Directive,
191
+ args: [{
192
+ // eslint-disable-next-line @angular-eslint/directive-selector
193
+ selector: '[LibsUiScrollMeasureItemDirectionVerticalDirective]',
194
+ standalone: true,
195
+ }]
196
+ }], ctorParameters: () => [] });
197
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0aW9uLXZlcnRpY2FsLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9zY3JvbGwtbWVhc3VyZS1pdGVtcy9kaXJlY3Rpb24tdmVydGljYWwvc3JjL2RpcmVjdGlvbi12ZXJ0aWNhbC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseUZBQXlGO0FBQ3pGLHVEQUF1RDtBQUN2RCxPQUFPLEVBQWlCLFVBQVUsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25JLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQVFqQyxNQUFNLE9BQU8saURBQWlEO0lBQzVELG1CQUFtQjtJQUNYLGFBQWEsR0FBRyxNQUFNLENBQWEsRUFBRSxDQUFDLENBQUM7SUFDdkMsS0FBSyxHQUFHLE1BQU0sQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUMxQixHQUFHLEdBQUcsTUFBTSxDQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3hCLFVBQVUsR0FBRyxNQUFNLENBQWdELEVBQUUsQ0FBQyxDQUFDO0lBQ3ZFLFVBQVUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRW5ELGdCQUFnQjtJQUNQLGFBQWEsR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFlLENBQUM7SUFDOUMscUJBQXFCLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBa0MsQ0FBQztJQUN6RSxLQUFLLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBYyxDQUFDO0lBRTlDLGlCQUFpQjtJ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LElBQUksS0FBSyxFQUFFLENBQUM7WUFDekIsTUFBTSxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDaEUsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7WUFDN0IsSUFBSSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7WUFDcEIsTUFBTSxJQUFJLFVBQVUsQ0FBQztZQUNyQixJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztRQUNwQixDQUFDO1FBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUM7UUFDN0MsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7d0dBek1VLGlEQUFpRDs0RkFBakQsaURBQWlEOzs0RkFBakQsaURBQWlEO2tCQUw3RCxTQUFTO21CQUFDO29CQUNULDhEQUE4RDtvQkFDOUQsUUFBUSxFQUFFLHFEQUFxRDtvQkFDL0QsVUFBVSxFQUFFLElBQUk7aUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ09OVkVOVElPTi1FWENFUFQ6IGFueSDigJQgR2VuZXJpYyBkaXJlY3RpdmUgd29ya3Mgd2l0aCB1bmtub3duIGl0ZW0gdHlwZXMgZnJvbSBjb25zdW1lclxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xuaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgRGVzdHJveVJlZiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBlZmZlY3QsIGluamVjdCwgaW5wdXQsIG91dHB1dCwgc2lnbmFsLCB1bnRyYWNrZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IGdldCB9IGZyb20gJ0BsaWJzLXVpL3V0aWxzJztcbmltcG9ydCB7IGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSVNjcm9sbE1lYXN1cmVJdGVtRGlyZWN0aW9uVmVydGljYWxGdW5jdGlvbnNDb250cm9sLCBJU2Nyb2xsTWVhc3VyZVN0b3JlSXRlbVZlcnRpY2FsQ29udmVydCB9IGZyb20gJy4vaW50ZXJmYWNlcy9kaXJlY3Rpb24tdmVydGljYWwuaW50ZXJmYWNlJztcblxuQERpcmVjdGl2ZSh7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvZGlyZWN0aXZlLXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnW0xpYnNVaVNjcm9sbE1lYXN1cmVJdGVtRGlyZWN0aW9uVmVydGljYWxEaXJlY3RpdmVdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgTGlic1VpU2Nyb2xsTWVhc3VyZUl0ZW1EaXJlY3Rpb25WZXJ0aWNhbERpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuICAvLyAjcmVnaW9uIFBST1BFUlRZXG4gIHByaXZhdGUgdmlld1BvcnRJdGVtcyA9IHNpZ25hbDxBcnJheTxhbnk+PihbXSk7XG4gIHByaXZhdGUgc3RhcnQgPSBzaWduYWw8bnVtYmVyPigwKTtcbiAgcHJpdmF0ZSBlbmQgPSBzaWduYWw8bnVtYmVyPigwKTtcbiAgcHJpdmF0ZSBzdG9yZUl0ZW1zID0gc2lnbmFsPEFycmF5PElTY3JvbGxNZWFzdXJlU3RvcmVJdGVtVmVydGljYWxDb252ZXJ0Pj4oW10pO1xuICBwcml2YXRlIGRpdlZpcnR1YWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblxuICAvLyAjcmVnaW9uIElOUFVUXG4gIHJlYWRvbmx5IGVsZW1lbnRTY3JvbGwgPSBpbnB1dC5yZXF1aXJlZDxIVE1MRWxlbWVudD4oKTtcbiAgcmVhZG9ubHkgZnVuY3Rpb25HZXRIZWlnaHRJdGVtID0gaW5wdXQucmVxdWlyZWQ8KGl0ZW06IGFueSkgPT4gUHJvbWlzZTxudW1iZXI+PigpO1xuICByZWFkb25seSBpdGVtcyA9IGlucHV0LnJlcXVpcmVkPEFycmF5PGFueT4+KCk7XG5cbiAgLy8gI3JlZ2lvbiBPVVRQVVRcbiAgcmVhZG9ubHkgb3V0Vmlld1BvcnRJdGVtID0gb3V0cHV0PEFycmF5PGFueT4+KCk7XG4gIHJlYWRvbmx5IG91dEZ1bmN0aW9uQ29udHJvbCA9IG91dHB1dDxJU2Nyb2xsTWVhc3VyZUl0ZW1EaXJlY3Rpb25WZXJ0aWNhbEZ1bmN0aW9uc0NvbnRyb2w+KCk7XG4gIHJlYWRvbmx5IG91dERpdlZpcnR1YWwgPSBvdXRwdXQ8SFRNTERpdkVsZW1lbnQ+KCk7XG4gIHJlYWRvbmx5IG91dFBhZGRpbmdUb3AgPSBvdXRwdXQ8bnVtYmVyPigpO1xuXG4gIC8vICNyZWdpb24gSU5KRUNUXG4gIHByaXZhdGUgcmVhZG9ubHkgZWxlbWVudFJlZiA9IGluamVjdChFbGVtZW50UmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCBzY3JvbGxFbCA9IHVudHJhY2tlZCgoKSA9PiB0aGlzLlNjcm9sbENvbnRhaW5lcik7XG4gICAgICBpZiAoIXNjcm9sbEVsIHx8ICF1bnRyYWNrZWQoKCkgPT4gdGhpcy5mdW5jdGlvbkdldEhlaWdodEl0ZW0oKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zKCk7XG4gICAgICB1bnRyYWNrZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICB0aGlzLnN0YXJ0LnNldCgwKTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsVG9wID0gc2Nyb2xsRWwuc2Nyb2xsVG9wO1xuICAgICAgICBjb25zdCBjb250YWluZXJIZWlnaHQgPSBzY3JvbGxFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7XG4gICAgICAgIGxldCBoZWlnaHQgPSAwO1xuICAgICAgICBjb25zdCBuZXdJdGVtczogQXJyYXk8SVNjcm9sbE1lYXN1cmVTdG9yZUl0ZW1WZXJ0aWNhbENvbnZlcnQ+ID0gW107XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtc1tpXTtcbiAgICAgICAgICBjb25zdCBuZXdJdGVtOiBJU2Nyb2xsTWVhc3VyZVN0b3JlSXRlbVZlcnRpY2FsQ29udmVydCA9IHsgcmVmOiBpdGVtLCBpdGVtSGVpZ2h0OiAwLCBzdGFydDogMCwgZW5kOiAwIH07XG4gICAgICAgICAgY29uc3QgaXRlbUhlaWdodCA9IGF3YWl0IHRoaXMuZnVuY3Rpb25HZXRIZWlnaHRJdGVtKCkoaXRlbSk7XG4gICAgICAgICAgbmV3SXRlbS5pdGVtSGVpZ2h0ID0gaXRlbUhlaWdodDtcbiAgICAgICAgICBuZXdJdGVtLnN0YXJ0ID0gaGVpZ2h0O1xuICAgICAgICAgIGhlaWdodCArPSBpdGVtSGVpZ2h0O1xuICAgICAgICAgIG5ld0l0ZW0uZW5kID0gaGVpZ2h0O1xuICAgICAgICAgIGlmIChuZXdJdGVtLmVuZCA8PSBjb250YWluZXJIZWlnaHQgKyBzY3JvbGxUb3ApIHtcbiAgICAgICAgICAgIHRoaXMuZW5kLnNldChpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbmV3SXRlbXMucHVzaChuZXdJdGVtKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RvcmVJdGVtcy5zZXQobmV3SXRlbXMpO1xuICAgICAgICB0aGlzLnZpZXdQb3J0SXRlbXMuc2V0KFxuICAgICAgICAgIHRoaXMuc3RvcmVJdGVtcygpXG4gICAgICAgICAgICAuc2xpY2UodGhpcy5zdGFydCgpLCB0aGlzLmVuZCgpICsgMylcbiAgICAgICAgICAgIC5tYXAoKGl0ZW0pID0+IGl0ZW0ucmVmKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLm91dFZpZXdQb3J0SXRlbS5lbWl0KHRoaXMudmlld1BvcnRJdGVtcygpKTtcbiAgICAgICAgdGhpcy5vdXRQYWRkaW5nVG9wLmVtaXQoZ2V0KHRoaXMuc3RvcmVJdGVtcygpLCBgWyR7dGhpcy5zdGFydCgpfV0uc3RhcnRgLCAwKSk7XG5cbiAgICAgICAgdGhpcy5kaXZWaXJ0dWFsLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICAgICAgdGhpcy5kaXZWaXJ0dWFsLnN0eWxlLnRvcCA9ICcwcHgnO1xuICAgICAgICB0aGlzLmRpdlZpcnR1YWwuc3R5bGUubGVmdCA9ICcwcHgnO1xuICAgICAgICB0aGlzLmRpdlZpcnR1YWwuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcbiAgICAgICAgdGhpcy5kaXZWaXJ0dWFsLnN0eWxlLndpZHRoID0gJzFweCc7XG4gICAgICAgIHRoaXMuZGl2VmlydHVhbC5zdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7IC8vIMSQ4bqjbSBi4bqjbyBhbiB0b8OgbiBraMO0bmcgaGnhu4NuIHRo4buLXG4gICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3JlbGF0aXZlJyk7XG4gICAgICAgIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2gtZnVsbCcpO1xuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zdHlsZS5wYWRkaW5nVG9wID0gJzBweCc7XG4gICAgICAgIHNjcm9sbEVsLmFwcGVuZCh0aGlzLmRpdlZpcnR1YWwpO1xuICAgICAgICB0aGlzLm91dERpdlZpcnR1YWwuZW1pdCh0aGlzLmRpdlZpcnR1YWwpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmRlc3Ryb3lSZWYub25EZXN0cm95KCgpID0+IHtcbiAgICAgIHRoaXMuZGl2VmlydHVhbC5yZW1vdmUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGZyb21FdmVudDxFdmVudD4odGhpcy5TY3JvbGxDb250YWluZXIsICdzY3JvbGwnKVxuICAgICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLmhhbmRsZXJTY3JvbGwoKSk7XG4gICAgICB0aGlzLm91dEZ1bmN0aW9uQ29udHJvbC5lbWl0KHRoaXMuRnVuY3Rpb25zQ29udHJvbCk7XG4gICAgfSk7XG4gIH1cblxuICAvLyAjcmVnaW9uIFBVQkxJQyBBUElcbiAgcHVibGljIGdldCBGdW5jdGlvbnNDb250cm9sKCk6IElTY3JvbGxNZWFzdXJlSXRlbURpcmVjdGlvblZlcnRpY2FsRnVuY3Rpb25zQ29udHJvbCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNjcm9sbEludG86IHRoaXMuc2Nyb2xsSW50by5iaW5kKHRoaXMpLFxuICAgICAgc2Nyb2xsVG9Qb3NpdGlvbjogdGhpcy5zY3JvbGxUb1Bvc2l0aW9uLmJpbmQodGhpcyksXG4gICAgICBzY3JvbGxUb0luZGV4OiB0aGlzLnNjcm9sbFRvSW5kZXguYmluZCh0aGlzKSxcbiAgICAgIHJlQ2FsY3VsYXRvclZpZXdQb3J0OiB0aGlzLnJlQ2FsY3VsYXRvclZpZXdQb3J0LmJpbmQodGhpcyksXG4gICAgICBnZXRWaWV3UG9ydEl0ZW1zOiAoKSA9PiB0aGlzLnZpZXdQb3J0SXRlbXMoKSxcbiAgICB9O1xuICB9XG5cbiAgLy8gI3JlZ2lvbiBQUklWQVRFIE1FVEhPRFNcbiAgcHJpdmF0ZSBnZXQgU2Nyb2xsQ29udGFpbmVyKCk6IEhUTUxFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50U2Nyb2xsKCkgfHwgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIGZpbmRTdGFydEluZGV4KHN0b3JlOiBBcnJheTxJU2Nyb2xsTWVhc3VyZVN0b3JlSXRlbVZlcnRpY2FsQ29udmVydD4sIHNjcm9sbFRvcDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBsZXQgbG93ID0gMDtcbiAgICBsZXQgaGlnaCA9IHN0b3JlLmxlbmd0aCAtIDE7XG4gICAgbGV0IGFucyA9IHN0b3JlLmxlbmd0aCAtIDE7IC8vIERlZmF1bHQgdG8gbGFzdCBpdGVtIGlmIHNjcm9sbGVkIHBhc3QgYm90dG9tIChydWJiZXIgYmFuZCBlZmZlY3QpXG4gICAgd2hpbGUgKGxvdyA8PSBoaWdoKSB7XG4gICAgICBjb25zdCBtaWQgPSBNYXRoLmZsb29yKChsb3cgKyBoaWdoKSAvIDIpO1xuICAgICAgaWYgKHN0b3JlW21pZF0uZW5kID49IHNjcm9sbFRvcCkge1xuICAgICAgICBhbnMgPSBtaWQ7XG4gICAgICAgIGhpZ2ggPSBtaWQgLSAxOyAvLyBUcnkgdG8gZmluZCBlYXJsaWVyXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb3cgPSBtaWQgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYW5zO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kRW5kSW5kZXgoc3RvcmU6IEFycmF5PElTY3JvbGxNZWFzdXJlU3RvcmVJdGVtVmVydGljYWxDb252ZXJ0Piwgc2Nyb2xsQm90dG9tOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBsb3cgPSAwO1xuICAgIGxldCBoaWdoID0gc3RvcmUubGVuZ3RoIC0gMTtcbiAgICBsZXQgYW5zID0gMDsgLy8gRGVmYXVsdCB0byBmaXJzdCBpdGVtIGlmIHJ1YmJlci1iYW5kZWQgYWJvdmUgdGhlIHRvcFxuICAgIHdoaWxlIChsb3cgPD0gaGlnaCkge1xuICAgICAgY29uc3QgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKTtcbiAgICAgIGlmIChzdG9yZVttaWRdLnN0YXJ0IDw9IHNjcm9sbEJvdHRvbSkge1xuICAgICAgICBhbnMgPSBtaWQ7XG4gICAgICAgIGxvdyA9IG1pZCArIDE7IC8vIFRyeSB0byBmaW5kIGxhdGVyXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdoID0gbWlkIC0gMTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFucztcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlclNjcm9sbCgpIHtcbiAgICBjb25zdCBzdG9yZSA9IHRoaXMuc3RvcmVJdGVtcygpO1xuICAgIGlmICghc3RvcmU/Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzY3JvbGxFbCA9IHRoaXMuU2Nyb2xsQ29udGFpbmVyO1xuICAgIGNvbnN0IHNjcm9sbFRvcCA9IHNjcm9sbEVsLnNjcm9sbFRvcDtcbiAgICBjb25zdCBjb250YWluZXJIZWlnaHQgPSBzY3JvbGxFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQ7XG4gICAgXG4gICAgLy8gVXRpbGl6ZSBCaW5hcnkgU2VhcmNoIGZvciBvcHRpbWFsIE8obG9nIE4pIGRpc2NvdmVyeVxuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5maW5kU3RhcnRJbmRleChzdG9yZSwgc2Nyb2xsVG9wKTtcbiAgICBjb25zdCBlbmQgPSB0aGlzLmZpbmRFbmRJbmRleChzdG9yZSwgc2Nyb2xsVG9wICsgY29udGFpbmVySGVpZ2h0KTtcblxuICAgIHRoaXMuZW5kLnNldChlbmQpO1xuXG4gICAgaWYgKHN0YXJ0ICE9PSB0aGlzLnN0YXJ0KCkpIHtcbiAgICAgIHRoaXMuc3RhcnQuc2V0KHN0YXJ0KTtcbiAgICAgIC8vIFVzZSBsb2dpY2FsIE9SIGZvciBmYWxsYmFjayB3aGVuIHN0YXJ0IGlzIGludmFsaWQuIEJ1dCBiaW5hcnkgc2VhcmNoIGd1YXJhbnRlZXMgdmFsaWQgaW5kZXguXG4gICAgICBjb25zdCBwYWRkaW5nVG9wID0gc3RvcmVbc3RhcnRdPy5zdGFydCB8fCAwO1xuICAgICAgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuc3R5bGUucGFkZGluZ1RvcCA9IGAke3BhZGRpbmdUb3B9cHhgO1xuICAgICAgdGhpcy5vdXRQYWRkaW5nVG9wLmVtaXQocGFkZGluZ1RvcCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuc3RhcnQoKSA8IDApIHtcbiAgICAgIHRoaXMuc3RhcnQuc2V0KDApO1xuICAgIH1cbiAgICB0aGlzLnZpZXdQb3J0SXRlbXMuc2V0KHN0b3JlLnNsaWNlKHRoaXMuc3RhcnQoKSwgdGhpcy5lbmQoKSArIDMpLm1hcCgoaXRlbSkgPT4gaXRlbS5yZWYpKTtcbiAgICB0aGlzLm91dFZpZXdQb3J0SXRlbS5lbWl0KHRoaXMudmlld1BvcnRJdGVtcygpKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2Nyb2xsSW50byhpdGVtU2Nyb2xsOiBhbnkpIHtcbiAgICBjb25zdCBpdGVtRm91bmQgPSB0aGlzLnN0b3JlSXRlbXMoKS5maW5kKChpdGVtKSA9PiBpdGVtLnJlZiA9PT0gaXRlbVNjcm9sbCk7XG4gICAgaWYgKCFpdGVtRm91bmQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5TY3JvbGxDb250YWluZXIuc2Nyb2xsVG9wID0gaXRlbUZvdW5kLnN0YXJ0O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzY3JvbGxUb1Bvc2l0aW9uKHBvc2l0aW9uOiBudW1iZXIpIHtcbiAgICB0aGlzLlNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBwb3NpdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2Nyb2xsVG9JbmRleChpbmRleDogbnVtYmVyKSB7XG4gICAgY29uc3QgaXRlbU9mSW5kZXggPSB0aGlzLnN0b3JlSXRlbXMoKVtpbmRleF07XG4gICAgaWYgKCFpdGVtT2ZJbmRleCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLlNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSBpdGVtT2ZJbmRleC5zdGFydDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVDYWxjdWxhdG9yVmlld1BvcnQoKSB7XG4gICAgbGV0IGhlaWdodCA9IDA7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLnN0b3JlSXRlbXMoKTtcblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgY29uc3QgaXRlbUhlaWdodCA9IGF3YWl0IHRoaXMuZnVuY3Rpb25HZXRIZWlnaHRJdGVtKCkoaXRlbS5yZWYpO1xuICAgICAgaXRlbS5pdGVtSGVpZ2h0ID0gaXRlbUhlaWdodDtcbiAgICAgIGl0ZW0uc3RhcnQgPSBoZWlnaHQ7XG4gICAgICBoZWlnaHQgKz0gaXRlbUhlaWdodDtcbiAgICAgIGl0ZW0uZW5kID0gaGVpZ2h0O1xuICAgIH1cblxuICAgIHRoaXMuc3RvcmVJdGVtcy5zZXQoWy4uLml0ZW1zXSk7XG4gICAgdGhpcy5kaXZWaXJ0dWFsLnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGA7XG4gICAgdGhpcy5oYW5kbGVyU2Nyb2xsKCk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,3 @@
1
+ export * from './direction-vertical.directive';
2
+ export * from './interfaces/direction-vertical.interface';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvc2Nyb2xsLW1lYXN1cmUtaXRlbXMvZGlyZWN0aW9uLXZlcnRpY2FsL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGdDQUFnQyxDQUFDO0FBQy9DLGNBQWMsMkNBQTJDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2RpcmVjdGlvbi12ZXJ0aWNhbC5kaXJlY3RpdmUnO1xuZXhwb3J0ICogZnJvbSAnLi9pbnRlcmZhY2VzL2RpcmVjdGlvbi12ZXJ0aWNhbC5pbnRlcmZhY2UnO1xuIl19
@@ -0,0 +1,4 @@
1
+ // CONVENTION-EXCEPT: any — Generic data structures from consumers
2
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3
+ export {};
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0aW9uLXZlcnRpY2FsLmludGVyZmFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9zY3JvbGwtbWVhc3VyZS1pdGVtcy9kaXJlY3Rpb24tdmVydGljYWwvc3JjL2ludGVyZmFjZXMvZGlyZWN0aW9uLXZlcnRpY2FsLmludGVyZmFjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxrRUFBa0U7QUFDbEUsdURBQXVEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ09OVkVOVElPTi1FWENFUFQ6IGFueSDigJQgR2VuZXJpYyBkYXRhIHN0cnVjdHVyZXMgZnJvbSBjb25zdW1lcnNcbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cblxuZXhwb3J0IGludGVyZmFjZSBJU2Nyb2xsTWVhc3VyZVN0b3JlSXRlbVZlcnRpY2FsQ29udmVydCB7XG4gIHJlZjogYW55O1xuICBpdGVtSGVpZ2h0OiBudW1iZXI7XG4gIHN0YXJ0OiBudW1iZXI7IC8vIFThu41hIMSR4buZIFkgKHB4KSBi4bqvdCDEkeG6p3UgY+G7p2EgaXRlbVxuICBlbmQ6IG51bWJlcjsgICAvLyBU4buNYSDEkeG7mSBZIChweCkga+G6v3QgdGjDumMgY+G7p2EgaXRlbVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIElTY3JvbGxNZWFzdXJlSXRlbURpcmVjdGlvblZlcnRpY2FsRnVuY3Rpb25zQ29udHJvbCB7XG4gIHNjcm9sbEludG86IChpdGVtOiBhbnkpID0+IFByb21pc2U8dm9pZD47XG4gIHNjcm9sbFRvUG9zaXRpb246IChwb3NpdGlvbjogbnVtYmVyKSA9PiBQcm9taXNlPHZvaWQ+O1xuICBzY3JvbGxUb0luZGV4OiAoaW5kZXg6IG51bWJlcikgPT4gUHJvbWlzZTx2b2lkPjtcbiAgcmVDYWxjdWxhdG9yVmlld1BvcnQ6ICgpID0+IFByb21pc2U8dm9pZD47XG4gIGdldFZpZXdQb3J0SXRlbXM6ICgpID0+IEFycmF5PGFueT47XG59XG4iXX0=
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './index';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlicy11aS1jb21wb25lbnRzLXNjcm9sbC1tZWFzdXJlLWl0ZW1zLWRpcmVjdGlvbi12ZXJ0aWNhbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9zY3JvbGwtbWVhc3VyZS1pdGVtcy9kaXJlY3Rpb24tdmVydGljYWwvc3JjL2xpYnMtdWktY29tcG9uZW50cy1zY3JvbGwtbWVhc3VyZS1pdGVtcy1kaXJlY3Rpb24tdmVydGljYWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLFNBQVMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9pbmRleCc7XG4iXX0=
@@ -0,0 +1,207 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, input, output, inject, ElementRef, DestroyRef, effect, untracked, Directive } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
+ import { get } from '@libs-ui/utils';
5
+ import { fromEvent } from 'rxjs';
6
+
7
+ // CONVENTION-EXCEPT: any — Generic directive works with unknown item types from consumer
8
+ /* eslint-disable @typescript-eslint/no-explicit-any */
9
+ class LibsUiScrollMeasureItemDirectionVerticalDirective {
10
+ // #region PROPERTY
11
+ viewPortItems = signal([]);
12
+ start = signal(0);
13
+ end = signal(0);
14
+ storeItems = signal([]);
15
+ divVirtual = document.createElement('div');
16
+ // #region INPUT
17
+ elementScroll = input.required();
18
+ functionGetHeightItem = input.required();
19
+ items = input.required();
20
+ // #region OUTPUT
21
+ outViewPortItem = output();
22
+ outFunctionControl = output();
23
+ outDivVirtual = output();
24
+ outPaddingTop = output();
25
+ // #region INJECT
26
+ elementRef = inject(ElementRef);
27
+ destroyRef = inject(DestroyRef);
28
+ constructor() {
29
+ effect(() => {
30
+ const scrollEl = untracked(() => this.ScrollContainer);
31
+ if (!scrollEl || !untracked(() => this.functionGetHeightItem())) {
32
+ return;
33
+ }
34
+ const items = this.items();
35
+ untracked(async () => {
36
+ this.start.set(0);
37
+ const scrollTop = scrollEl.scrollTop;
38
+ const containerHeight = scrollEl.getBoundingClientRect().height;
39
+ let height = 0;
40
+ const newItems = [];
41
+ for (let i = 0; i < items.length; i++) {
42
+ const item = items[i];
43
+ const newItem = { ref: item, itemHeight: 0, start: 0, end: 0 };
44
+ const itemHeight = await this.functionGetHeightItem()(item);
45
+ newItem.itemHeight = itemHeight;
46
+ newItem.start = height;
47
+ height += itemHeight;
48
+ newItem.end = height;
49
+ if (newItem.end <= containerHeight + scrollTop) {
50
+ this.end.set(i);
51
+ }
52
+ newItems.push(newItem);
53
+ }
54
+ this.storeItems.set(newItems);
55
+ this.viewPortItems.set(this.storeItems()
56
+ .slice(this.start(), this.end() + 3)
57
+ .map((item) => item.ref));
58
+ this.outViewPortItem.emit(this.viewPortItems());
59
+ this.outPaddingTop.emit(get(this.storeItems(), `[${this.start()}].start`, 0));
60
+ this.divVirtual.style.position = 'absolute';
61
+ this.divVirtual.style.top = '0px';
62
+ this.divVirtual.style.left = '0px';
63
+ this.divVirtual.style.height = `${height}px`;
64
+ this.divVirtual.style.width = '1px';
65
+ this.divVirtual.style.visibility = 'hidden'; // Đảm bảo an toàn không hiển thị
66
+ this.elementRef.nativeElement.classList.add('relative');
67
+ this.elementRef.nativeElement.classList.remove('h-full');
68
+ this.elementRef.nativeElement.style.paddingTop = '0px';
69
+ scrollEl.append(this.divVirtual);
70
+ this.outDivVirtual.emit(this.divVirtual);
71
+ });
72
+ });
73
+ this.destroyRef.onDestroy(() => {
74
+ this.divVirtual.remove();
75
+ });
76
+ }
77
+ ngAfterViewInit() {
78
+ setTimeout(() => {
79
+ fromEvent(this.ScrollContainer, 'scroll')
80
+ .pipe(takeUntilDestroyed(this.destroyRef))
81
+ .subscribe(() => this.handlerScroll());
82
+ this.outFunctionControl.emit(this.FunctionsControl);
83
+ });
84
+ }
85
+ // #region PUBLIC API
86
+ get FunctionsControl() {
87
+ return {
88
+ scrollInto: this.scrollInto.bind(this),
89
+ scrollToPosition: this.scrollToPosition.bind(this),
90
+ scrollToIndex: this.scrollToIndex.bind(this),
91
+ reCalculatorViewPort: this.reCalculatorViewPort.bind(this),
92
+ getViewPortItems: () => this.viewPortItems(),
93
+ };
94
+ }
95
+ // #region PRIVATE METHODS
96
+ get ScrollContainer() {
97
+ return this.elementScroll() || this.elementRef.nativeElement;
98
+ }
99
+ findStartIndex(store, scrollTop) {
100
+ let low = 0;
101
+ let high = store.length - 1;
102
+ let ans = store.length - 1; // Default to last item if scrolled past bottom (rubber band effect)
103
+ while (low <= high) {
104
+ const mid = Math.floor((low + high) / 2);
105
+ if (store[mid].end >= scrollTop) {
106
+ ans = mid;
107
+ high = mid - 1; // Try to find earlier
108
+ }
109
+ else {
110
+ low = mid + 1;
111
+ }
112
+ }
113
+ return ans;
114
+ }
115
+ findEndIndex(store, scrollBottom) {
116
+ let low = 0;
117
+ let high = store.length - 1;
118
+ let ans = 0; // Default to first item if rubber-banded above the top
119
+ while (low <= high) {
120
+ const mid = Math.floor((low + high) / 2);
121
+ if (store[mid].start <= scrollBottom) {
122
+ ans = mid;
123
+ low = mid + 1; // Try to find later
124
+ }
125
+ else {
126
+ high = mid - 1;
127
+ }
128
+ }
129
+ return ans;
130
+ }
131
+ handlerScroll() {
132
+ const store = this.storeItems();
133
+ if (!store?.length) {
134
+ return;
135
+ }
136
+ const scrollEl = this.ScrollContainer;
137
+ const scrollTop = scrollEl.scrollTop;
138
+ const containerHeight = scrollEl.getBoundingClientRect().height;
139
+ // Utilize Binary Search for optimal O(log N) discovery
140
+ const start = this.findStartIndex(store, scrollTop);
141
+ const end = this.findEndIndex(store, scrollTop + containerHeight);
142
+ this.end.set(end);
143
+ if (start !== this.start()) {
144
+ this.start.set(start);
145
+ // Use logical OR for fallback when start is invalid. But binary search guarantees valid index.
146
+ const paddingTop = store[start]?.start || 0;
147
+ this.elementRef.nativeElement.style.paddingTop = `${paddingTop}px`;
148
+ this.outPaddingTop.emit(paddingTop);
149
+ }
150
+ if (this.start() < 0) {
151
+ this.start.set(0);
152
+ }
153
+ this.viewPortItems.set(store.slice(this.start(), this.end() + 3).map((item) => item.ref));
154
+ this.outViewPortItem.emit(this.viewPortItems());
155
+ }
156
+ async scrollInto(itemScroll) {
157
+ const itemFound = this.storeItems().find((item) => item.ref === itemScroll);
158
+ if (!itemFound) {
159
+ return;
160
+ }
161
+ this.ScrollContainer.scrollTop = itemFound.start;
162
+ }
163
+ async scrollToPosition(position) {
164
+ this.ScrollContainer.scrollTop = position;
165
+ }
166
+ async scrollToIndex(index) {
167
+ const itemOfIndex = this.storeItems()[index];
168
+ if (!itemOfIndex) {
169
+ return;
170
+ }
171
+ this.ScrollContainer.scrollTop = itemOfIndex.start;
172
+ }
173
+ async reCalculatorViewPort() {
174
+ let height = 0;
175
+ const items = this.storeItems();
176
+ for (const item of items) {
177
+ const itemHeight = await this.functionGetHeightItem()(item.ref);
178
+ item.itemHeight = itemHeight;
179
+ item.start = height;
180
+ height += itemHeight;
181
+ item.end = height;
182
+ }
183
+ this.storeItems.set([...items]);
184
+ this.divVirtual.style.height = `${height}px`;
185
+ this.handlerScroll();
186
+ }
187
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiScrollMeasureItemDirectionVerticalDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
188
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.14", type: LibsUiScrollMeasureItemDirectionVerticalDirective, isStandalone: true, selector: "[LibsUiScrollMeasureItemDirectionVerticalDirective]", inputs: { elementScroll: { classPropertyName: "elementScroll", publicName: "elementScroll", isSignal: true, isRequired: true, transformFunction: null }, functionGetHeightItem: { classPropertyName: "functionGetHeightItem", publicName: "functionGetHeightItem", isSignal: true, isRequired: true, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { outViewPortItem: "outViewPortItem", outFunctionControl: "outFunctionControl", outDivVirtual: "outDivVirtual", outPaddingTop: "outPaddingTop" }, ngImport: i0 });
189
+ }
190
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: LibsUiScrollMeasureItemDirectionVerticalDirective, decorators: [{
191
+ type: Directive,
192
+ args: [{
193
+ // eslint-disable-next-line @angular-eslint/directive-selector
194
+ selector: '[LibsUiScrollMeasureItemDirectionVerticalDirective]',
195
+ standalone: true,
196
+ }]
197
+ }], ctorParameters: () => [] });
198
+
199
+ // CONVENTION-EXCEPT: any — Generic data structures from consumers
200
+ /* eslint-disable @typescript-eslint/no-explicit-any */
201
+
202
+ /**
203
+ * Generated bundle index. Do not edit.
204
+ */
205
+
206
+ export { LibsUiScrollMeasureItemDirectionVerticalDirective };
207
+ //# sourceMappingURL=libs-ui-components-scroll-measure-items-direction-vertical.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"libs-ui-components-scroll-measure-items-direction-vertical.mjs","sources":["../../../../../../libs-ui/components/scroll-measure-items/direction-vertical/src/direction-vertical.directive.ts","../../../../../../libs-ui/components/scroll-measure-items/direction-vertical/src/interfaces/direction-vertical.interface.ts","../../../../../../libs-ui/components/scroll-measure-items/direction-vertical/src/libs-ui-components-scroll-measure-items-direction-vertical.ts"],"sourcesContent":["// CONVENTION-EXCEPT: any — Generic directive works with unknown item types from consumer\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { AfterViewInit, DestroyRef, Directive, ElementRef, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { get } from '@libs-ui/utils';\nimport { fromEvent } from 'rxjs';\nimport { IScrollMeasureItemDirectionVerticalFunctionsControl, IScrollMeasureStoreItemVerticalConvert } from './interfaces/direction-vertical.interface';\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[LibsUiScrollMeasureItemDirectionVerticalDirective]',\n standalone: true,\n})\nexport class LibsUiScrollMeasureItemDirectionVerticalDirective implements AfterViewInit {\n // #region PROPERTY\n private viewPortItems = signal<Array<any>>([]);\n private start = signal<number>(0);\n private end = signal<number>(0);\n private storeItems = signal<Array<IScrollMeasureStoreItemVerticalConvert>>([]);\n private divVirtual = document.createElement('div');\n\n // #region INPUT\n readonly elementScroll = input.required<HTMLElement>();\n readonly functionGetHeightItem = input.required<(item: any) => Promise<number>>();\n readonly items = input.required<Array<any>>();\n\n // #region OUTPUT\n readonly outViewPortItem = output<Array<any>>();\n readonly outFunctionControl = output<IScrollMeasureItemDirectionVerticalFunctionsControl>();\n readonly outDivVirtual = output<HTMLDivElement>();\n readonly outPaddingTop = output<number>();\n\n // #region INJECT\n private readonly elementRef = inject(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n effect(() => {\n const scrollEl = untracked(() => this.ScrollContainer);\n if (!scrollEl || !untracked(() => this.functionGetHeightItem())) {\n return;\n }\n const items = this.items();\n untracked(async () => {\n this.start.set(0);\n const scrollTop = scrollEl.scrollTop;\n const containerHeight = scrollEl.getBoundingClientRect().height;\n let height = 0;\n const newItems: Array<IScrollMeasureStoreItemVerticalConvert> = [];\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const newItem: IScrollMeasureStoreItemVerticalConvert = { ref: item, itemHeight: 0, start: 0, end: 0 };\n const itemHeight = await this.functionGetHeightItem()(item);\n newItem.itemHeight = itemHeight;\n newItem.start = height;\n height += itemHeight;\n newItem.end = height;\n if (newItem.end <= containerHeight + scrollTop) {\n this.end.set(i);\n }\n newItems.push(newItem);\n }\n\n this.storeItems.set(newItems);\n this.viewPortItems.set(\n this.storeItems()\n .slice(this.start(), this.end() + 3)\n .map((item) => item.ref)\n );\n this.outViewPortItem.emit(this.viewPortItems());\n this.outPaddingTop.emit(get(this.storeItems(), `[${this.start()}].start`, 0));\n\n this.divVirtual.style.position = 'absolute';\n this.divVirtual.style.top = '0px';\n this.divVirtual.style.left = '0px';\n this.divVirtual.style.height = `${height}px`;\n this.divVirtual.style.width = '1px';\n this.divVirtual.style.visibility = 'hidden'; // Đảm bảo an toàn không hiển thị\n this.elementRef.nativeElement.classList.add('relative');\n this.elementRef.nativeElement.classList.remove('h-full');\n this.elementRef.nativeElement.style.paddingTop = '0px';\n scrollEl.append(this.divVirtual);\n this.outDivVirtual.emit(this.divVirtual);\n });\n });\n\n this.destroyRef.onDestroy(() => {\n this.divVirtual.remove();\n });\n }\n\n ngAfterViewInit() {\n setTimeout(() => {\n fromEvent<Event>(this.ScrollContainer, 'scroll')\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe(() => this.handlerScroll());\n this.outFunctionControl.emit(this.FunctionsControl);\n });\n }\n\n // #region PUBLIC API\n public get FunctionsControl(): IScrollMeasureItemDirectionVerticalFunctionsControl {\n return {\n scrollInto: this.scrollInto.bind(this),\n scrollToPosition: this.scrollToPosition.bind(this),\n scrollToIndex: this.scrollToIndex.bind(this),\n reCalculatorViewPort: this.reCalculatorViewPort.bind(this),\n getViewPortItems: () => this.viewPortItems(),\n };\n }\n\n // #region PRIVATE METHODS\n private get ScrollContainer(): HTMLElement {\n return this.elementScroll() || this.elementRef.nativeElement;\n }\n\n private findStartIndex(store: Array<IScrollMeasureStoreItemVerticalConvert>, scrollTop: number): number {\n let low = 0;\n let high = store.length - 1;\n let ans = store.length - 1; // Default to last item if scrolled past bottom (rubber band effect)\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n if (store[mid].end >= scrollTop) {\n ans = mid;\n high = mid - 1; // Try to find earlier\n } else {\n low = mid + 1;\n }\n }\n return ans;\n }\n\n private findEndIndex(store: Array<IScrollMeasureStoreItemVerticalConvert>, scrollBottom: number): number {\n let low = 0;\n let high = store.length - 1;\n let ans = 0; // Default to first item if rubber-banded above the top\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n if (store[mid].start <= scrollBottom) {\n ans = mid;\n low = mid + 1; // Try to find later\n } else {\n high = mid - 1;\n }\n }\n return ans;\n }\n\n private handlerScroll() {\n const store = this.storeItems();\n if (!store?.length) {\n return;\n }\n const scrollEl = this.ScrollContainer;\n const scrollTop = scrollEl.scrollTop;\n const containerHeight = scrollEl.getBoundingClientRect().height;\n \n // Utilize Binary Search for optimal O(log N) discovery\n const start = this.findStartIndex(store, scrollTop);\n const end = this.findEndIndex(store, scrollTop + containerHeight);\n\n this.end.set(end);\n\n if (start !== this.start()) {\n this.start.set(start);\n // Use logical OR for fallback when start is invalid. But binary search guarantees valid index.\n const paddingTop = store[start]?.start || 0;\n this.elementRef.nativeElement.style.paddingTop = `${paddingTop}px`;\n this.outPaddingTop.emit(paddingTop);\n }\n\n if (this.start() < 0) {\n this.start.set(0);\n }\n this.viewPortItems.set(store.slice(this.start(), this.end() + 3).map((item) => item.ref));\n this.outViewPortItem.emit(this.viewPortItems());\n }\n\n private async scrollInto(itemScroll: any) {\n const itemFound = this.storeItems().find((item) => item.ref === itemScroll);\n if (!itemFound) {\n return;\n }\n this.ScrollContainer.scrollTop = itemFound.start;\n }\n\n private async scrollToPosition(position: number) {\n this.ScrollContainer.scrollTop = position;\n }\n\n private async scrollToIndex(index: number) {\n const itemOfIndex = this.storeItems()[index];\n if (!itemOfIndex) {\n return;\n }\n this.ScrollContainer.scrollTop = itemOfIndex.start;\n }\n\n private async reCalculatorViewPort() {\n let height = 0;\n const items = this.storeItems();\n\n for (const item of items) {\n const itemHeight = await this.functionGetHeightItem()(item.ref);\n item.itemHeight = itemHeight;\n item.start = height;\n height += itemHeight;\n item.end = height;\n }\n\n this.storeItems.set([...items]);\n this.divVirtual.style.height = `${height}px`;\n this.handlerScroll();\n }\n}\n","// CONVENTION-EXCEPT: any — Generic data structures from consumers\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport interface IScrollMeasureStoreItemVerticalConvert {\n ref: any;\n itemHeight: number;\n start: number; // Tọa độ Y (px) bắt đầu của item\n end: number; // Tọa độ Y (px) kết thúc của item\n}\n\nexport interface IScrollMeasureItemDirectionVerticalFunctionsControl {\n scrollInto: (item: any) => Promise<void>;\n scrollToPosition: (position: number) => Promise<void>;\n scrollToIndex: (index: number) => Promise<void>;\n reCalculatorViewPort: () => Promise<void>;\n getViewPortItems: () => Array<any>;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './direction-vertical.directive';
2
+ export * from './interfaces/direction-vertical.interface';
@@ -0,0 +1,13 @@
1
+ export interface IScrollMeasureStoreItemVerticalConvert {
2
+ ref: any;
3
+ itemHeight: number;
4
+ start: number;
5
+ end: number;
6
+ }
7
+ export interface IScrollMeasureItemDirectionVerticalFunctionsControl {
8
+ scrollInto: (item: any) => Promise<void>;
9
+ scrollToPosition: (position: number) => Promise<void>;
10
+ scrollToIndex: (index: number) => Promise<void>;
11
+ reCalculatorViewPort: () => Promise<void>;
12
+ getViewPortItems: () => Array<any>;
13
+ }
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@libs-ui/components-scroll-measure-items-direction-vertical",
3
+ "version": "0.2.356-21",
4
+ "peerDependencies": {
5
+ "@angular/core": "^18.2.0",
6
+ "@libs-ui/utils": "0.2.356-21",
7
+ "rxjs": "~7.8.0"
8
+ },
9
+ "sideEffects": false,
10
+ "module": "fesm2022/libs-ui-components-scroll-measure-items-direction-vertical.mjs",
11
+ "typings": "index.d.ts",
12
+ "exports": {
13
+ "./package.json": {
14
+ "default": "./package.json"
15
+ },
16
+ ".": {
17
+ "types": "./index.d.ts",
18
+ "esm2022": "./esm2022/libs-ui-components-scroll-measure-items-direction-vertical.mjs",
19
+ "esm": "./esm2022/libs-ui-components-scroll-measure-items-direction-vertical.mjs",
20
+ "default": "./fesm2022/libs-ui-components-scroll-measure-items-direction-vertical.mjs"
21
+ }
22
+ },
23
+ "dependencies": {
24
+ "tslib": "^2.3.0"
25
+ }
26
+ }