@ceriousdevtech/ngx-cerious-scroll 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ ngx-cerious-scroll
4
+
5
+ Copyright (c) 2024–2026 Cerious DevTech LLC
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
@@ -0,0 +1,71 @@
1
+ ngx-cerious-scroll Commercial License
2
+
3
+ Copyright © 2024–2026 Cerious DevTech LLC.
4
+ All rights reserved.
5
+
6
+ This Commercial License governs use of ngx-cerious-scroll only when you have
7
+ entered into a separately executed commercial agreement with Cerious DevTech LLC.
8
+
9
+ If you do not have such an agreement, you may use this software under the
10
+ MIT license (see LICENSE).
11
+
12
+ A commercial agreement is commonly used when ngx-cerious-scroll is:
13
+
14
+ - Redistributed as part of a commercial product
15
+ - Bundled with a proprietary SDK, framework, or component library
16
+ - Integrated into a low-code / no-code platform
17
+ - Used in OEM, white-label, or downstream resale offerings
18
+ - Included in internal frameworks or platforms sold or licensed to third parties
19
+
20
+ This license grants the Licensee a non-exclusive, non-transferable,
21
+ non-sublicensable right to use, modify, and distribute ngx-cerious-scroll
22
+ solely under the terms of that commercial agreement.
23
+
24
+ ### Restrictions
25
+
26
+ Except as explicitly permitted in a written commercial agreement, the Licensee
27
+ may not:
28
+
29
+ - Redistribute ngx-cerious-scroll as a standalone product
30
+ - Offer ngx-cerious-scroll as part of a competing scrolling, virtualization,
31
+ or UI infrastructure library
32
+ - Remove or obscure copyright, trademark, or patent notices
33
+ - Grant sublicenses or derivative commercial licenses
34
+
35
+ ### Ownership
36
+
37
+ ngx-cerious-scroll and all associated intellectual property rights, including
38
+ but not limited to copyrights, patents, and trademarks, remain the exclusive
39
+ property of Cerious DevTech LLC.
40
+
41
+ No rights are granted except those expressly stated in this license.
42
+
43
+ ### Patent Rights
44
+
45
+ ngx-cerious-scroll includes technology covered by one or more pending patent
46
+ applications owned by Cerious DevTech LLC.
47
+
48
+ This license grants only those patent rights explicitly provided in a
49
+ commercial agreement. No implied patent licenses are granted.
50
+
51
+ ### Termination
52
+
53
+ Any violation of this license immediately terminates the rights granted herein
54
+ without notice.
55
+
56
+ Upon termination, the Licensee must cease all use and distribution of
57
+ ngx-cerious-scroll.
58
+
59
+ ### Warranty Disclaimer
60
+
61
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63
+ FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
64
+
65
+ ### Limitation of Liability
66
+
67
+ IN NO EVENT SHALL CERIOUS DEVTECH LLC BE LIABLE FOR ANY CLAIM, DAMAGES, OR
68
+ OTHER LIABILITY ARISING FROM THE USE OF THE SOFTWARE.
69
+
70
+ For commercial licensing inquiries, contact:
71
+ info@ceriousdevtech.com
package/LICENSE-MIT ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ ngx-cerious-scroll
4
+
5
+ Copyright (c) 2024–2026 Cerious DevTech LLC
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # NgxCeriousScroll
2
+
3
+ This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.0.
4
+
5
+ ## Code scaffolding
6
+
7
+ Run `ng generate component component-name --project ngx-cerious-scroll` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ngx-cerious-scroll`.
8
+ > Note: Don't forget to add `--project ngx-cerious-scroll` or else it will be added to the default project in your `angular.json` file.
9
+
10
+ ## Build
11
+
12
+ Run `ng build ngx-cerious-scroll` to build the project. The build artifacts will be stored in the `dist/` directory.
13
+
14
+ ## Publishing
15
+
16
+ After building your library with `ng build ngx-cerious-scroll`, go to the dist folder `cd dist/ngx-cerious-scroll` and run `npm publish`.
17
+
18
+ ## Running unit tests
19
+
20
+ Run `ng test ngx-cerious-scroll` to execute the unit tests via [Karma](https://karma-runner.github.io).
21
+
22
+ ## Further help
23
+
24
+ To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './public-api';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91c2RldnRlY2gtbmd4LWNlcmlvdXMtc2Nyb2xsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9jZXJpb3VzZGV2dGVjaC1uZ3gtY2VyaW91cy1zY3JvbGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
@@ -0,0 +1,29 @@
1
+ import { Directive } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Marks an `ng-template` as the row template for `CeriousScrollComponent`.
5
+ *
6
+ * Usage:
7
+ * ```html
8
+ * <cerious-scroll [items]="items">
9
+ * <ng-template ceriousScrollItem let-item let-index="index">
10
+ * {{ index }} - {{ item.name }}
11
+ * </ng-template>
12
+ * </cerious-scroll>
13
+ * ```
14
+ */
15
+ export class CeriousScrollItemTemplateDirective {
16
+ constructor(templateRef) {
17
+ this.templateRef = templateRef;
18
+ }
19
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollItemTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
20
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: CeriousScrollItemTemplateDirective, isStandalone: true, selector: "ng-template[ceriousScrollItem]", ngImport: i0 }); }
21
+ }
22
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollItemTemplateDirective, decorators: [{
23
+ type: Directive,
24
+ args: [{
25
+ selector: 'ng-template[ceriousScrollItem]',
26
+ standalone: true,
27
+ }]
28
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwtaXRlbS10ZW1wbGF0ZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtY2VyaW91cy1zY3JvbGwvc3JjL2xpYi9jZXJpb3VzLXNjcm9sbC1pdGVtLXRlbXBsYXRlLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFlLE1BQU0sZUFBZSxDQUFDOztBQVd2RDs7Ozs7Ozs7Ozs7R0FXRztBQUtILE1BQU0sT0FBTyxrQ0FBa0M7SUFDN0MsWUFBNEIsV0FBaUU7UUFBakUsZ0JBQVcsR0FBWCxXQUFXLENBQXNEO0lBQUcsQ0FBQzsrR0FEdEYsa0NBQWtDO21HQUFsQyxrQ0FBa0M7OzRGQUFsQyxrQ0FBa0M7a0JBSjlDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGdDQUFnQztvQkFDMUMsVUFBVSxFQUFFLElBQUk7aUJBQ2pCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlyZWN0aXZlLCBUZW1wbGF0ZVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtID0gdW5rbm93bj4ge1xuICAvKiogVGhlIGl0ZW0gZm9yIHRoaXMgcm93IChhbHNvIGF2YWlsYWJsZSBhcyBgJGltcGxpY2l0YCkuICovXG4gICRpbXBsaWNpdDogVEl0ZW07XG4gIC8qKiBSb3cgaW5kZXguICovXG4gIGluZGV4OiBudW1iZXI7XG4gIC8qKiBTYW1lIGFzIGAkaW1wbGljaXRgIGZvciBuYW1lZCBhY2Nlc3MuICovXG4gIGl0ZW06IFRJdGVtO1xufVxuXG4vKipcbiAqIE1hcmtzIGFuIGBuZy10ZW1wbGF0ZWAgYXMgdGhlIHJvdyB0ZW1wbGF0ZSBmb3IgYENlcmlvdXNTY3JvbGxDb21wb25lbnRgLlxuICpcbiAqIFVzYWdlOlxuICogYGBgaHRtbFxuICogPGNlcmlvdXMtc2Nyb2xsIFtpdGVtc109XCJpdGVtc1wiPlxuICogICA8bmctdGVtcGxhdGUgY2VyaW91c1Njcm9sbEl0ZW0gbGV0LWl0ZW0gbGV0LWluZGV4PVwiaW5kZXhcIj5cbiAqICAgICB7eyBpbmRleCB9fSAtIHt7IGl0ZW0ubmFtZSB9fVxuICogICA8L25nLXRlbXBsYXRlPlxuICogPC9jZXJpb3VzLXNjcm9sbD5cbiAqIGBgYFxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICduZy10ZW1wbGF0ZVtjZXJpb3VzU2Nyb2xsSXRlbV0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlRGlyZWN0aXZlPFRJdGVtID0gdW5rbm93bj4ge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgdGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPENlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVDb250ZXh0PFRJdGVtPj4pIHt9XG59XG4iXX0=
@@ -0,0 +1,48 @@
1
+ import { ChangeDetectionStrategy, Component, ContentChild, } from '@angular/core';
2
+ import { CeriousScrollDirective } from './cerious-scroll.directive';
3
+ import { CeriousScrollItemTemplateDirective, } from './cerious-scroll-item-template.directive';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "./cerious-scroll.directive";
6
+ export class CeriousScrollComponent {
7
+ constructor(ceriousScroll) {
8
+ this.ceriousScroll = ceriousScroll;
9
+ }
10
+ ngAfterContentInit() {
11
+ if (this.ceriousScroll.ceriousScrollItemTemplate)
12
+ return;
13
+ if (!this.projectedItemTemplate)
14
+ return;
15
+ this.ceriousScroll.ceriousScrollItemTemplate =
16
+ this.projectedItemTemplate.templateRef;
17
+ if (this.ceriousScroll.ceriousScrollAutoRender) {
18
+ queueMicrotask(() => this.ceriousScroll.render());
19
+ }
20
+ }
21
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollComponent, deps: [{ token: i1.CeriousScrollDirective }], target: i0.ɵɵFactoryTarget.Component }); }
22
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CeriousScrollComponent, isStandalone: true, selector: "cerious-scroll", queries: [{ propertyName: "projectedItemTemplate", first: true, predicate: CeriousScrollItemTemplateDirective, descendants: true }], hostDirectives: [{ directive: i1.CeriousScrollDirective, inputs: ["ceriousScrollTotalElements", "totalElements", "ceriousScrollItems", "items", "ceriousScrollGetItem", "getItem", "ceriousScrollItemTemplate", "itemTemplate", "ceriousScrollOptions", "options", "ceriousScrollAutoRender", "autoRender"], outputs: ["ceriousScrollViewportChange", "viewportChange", "ceriousScrollMeasuredViewport", "measuredViewport", "ceriousScrollReady", "scrollerReady"] }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
23
+ }
24
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollComponent, decorators: [{
25
+ type: Component,
26
+ args: [{ selector: 'cerious-scroll', standalone: true, imports: [], hostDirectives: [
27
+ {
28
+ directive: CeriousScrollDirective,
29
+ inputs: [
30
+ 'ceriousScrollTotalElements: totalElements',
31
+ 'ceriousScrollItems: items',
32
+ 'ceriousScrollGetItem: getItem',
33
+ 'ceriousScrollItemTemplate: itemTemplate',
34
+ 'ceriousScrollOptions: options',
35
+ 'ceriousScrollAutoRender: autoRender',
36
+ ],
37
+ outputs: [
38
+ 'ceriousScrollViewportChange: viewportChange',
39
+ 'ceriousScrollMeasuredViewport: measuredViewport',
40
+ 'ceriousScrollReady: scrollerReady',
41
+ ],
42
+ },
43
+ ], template: `<ng-content />`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
44
+ }], ctorParameters: () => [{ type: i1.CeriousScrollDirective }], propDecorators: { projectedItemTemplate: [{
45
+ type: ContentChild,
46
+ args: [CeriousScrollItemTemplateDirective]
47
+ }] } });
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9saWIvY2VyaW91cy1zY3JvbGwuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksR0FFYixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQ0wsa0NBQWtDLEdBRW5DLE1BQU0sMENBQTBDLENBQUM7OztBQWdDbEQsTUFBTSxPQUFPLHNCQUFzQjtJQUtqQyxZQUE2QixhQUE0QztRQUE1QyxrQkFBYSxHQUFiLGFBQWEsQ0FBK0I7SUFBRyxDQUFDO0lBRTdFLGtCQUFrQjtRQUNoQixJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMseUJBQXlCO1lBQUUsT0FBTztRQUN6RCxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQjtZQUFFLE9BQU87UUFFeEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyx5QkFBeUI7WUFDMUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQW1FLENBQUM7UUFFakcsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDL0MsY0FBYyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNwRCxDQUFDO0lBQ0gsQ0FBQzsrR0FqQlUsc0JBQXNCO21HQUF0QixzQkFBc0IsNkhBRW5CLGtDQUFrQyx3ZkFWdEMsZ0JBQWdCOzs0RkFRZixzQkFBc0I7a0JBOUJsQyxTQUFTOytCQUNFLGdCQUFnQixjQUNkLElBQUksV0FDUCxFQUFFLGtCQUNLO3dCQUNkOzRCQUNFLFNBQVMsRUFBRSxzQkFBc0I7NEJBQ2pDLE1BQU0sRUFBRTtnQ0FDTiwyQ0FBMkM7Z0NBQzNDLDJCQUEyQjtnQ0FDM0IsK0JBQStCO2dDQUMvQix5Q0FBeUM7Z0NBQ3pDLCtCQUErQjtnQ0FDL0IscUNBQXFDOzZCQUN0Qzs0QkFDRCxPQUFPLEVBQUU7Z0NBQ1AsNkNBQTZDO2dDQUM3QyxpREFBaUQ7Z0NBQ2pELG1DQUFtQzs2QkFDcEM7eUJBQ0Y7cUJBQ0YsWUFDUyxnQkFBZ0IsbUJBTVQsdUJBQXVCLENBQUMsTUFBTTsyRkFLOUIscUJBQXFCO3NCQURyQyxZQUFZO3VCQUFDLGtDQUFrQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgVGVtcGxhdGVSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBDZXJpb3VzU2Nyb2xsRGlyZWN0aXZlIH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC5kaXJlY3RpdmUnO1xuaW1wb3J0IHtcbiAgQ2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZURpcmVjdGl2ZSxcbiAgdHlwZSBDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dCxcbn0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC1pdGVtLXRlbXBsYXRlLmRpcmVjdGl2ZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2NlcmlvdXMtc2Nyb2xsJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW10sXG4gIGhvc3REaXJlY3RpdmVzOiBbXG4gICAge1xuICAgICAgZGlyZWN0aXZlOiBDZXJpb3VzU2Nyb2xsRGlyZWN0aXZlLFxuICAgICAgaW5wdXRzOiBbXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50czogdG90YWxFbGVtZW50cycsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsSXRlbXM6IGl0ZW1zJyxcbiAgICAgICAgJ2NlcmlvdXNTY3JvbGxHZXRJdGVtOiBnZXRJdGVtJyxcbiAgICAgICAgJ2NlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGU6IGl0ZW1UZW1wbGF0ZScsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsT3B0aW9uczogb3B0aW9ucycsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcjogYXV0b1JlbmRlcicsXG4gICAgICBdLFxuICAgICAgb3V0cHV0czogW1xuICAgICAgICAnY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlOiB2aWV3cG9ydENoYW5nZScsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsTWVhc3VyZWRWaWV3cG9ydDogbWVhc3VyZWRWaWV3cG9ydCcsXG4gICAgICAgICdjZXJpb3VzU2Nyb2xsUmVhZHk6IHNjcm9sbGVyUmVhZHknLFxuICAgICAgXSxcbiAgICB9LFxuICBdLFxuICB0ZW1wbGF0ZTogYDxuZy1jb250ZW50IC8+YCxcbiAgc3R5bGVzOiBgXG4gICAgOmhvc3Qge1xuICAgICAgZGlzcGxheTogYmxvY2s7XG4gICAgfVxuICBgLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgQ2VyaW91c1Njcm9sbENvbXBvbmVudDxUSXRlbSA9IHVua25vd24+IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCB7XG4gIC8qKiBPcHRpb25hbCBjb252ZW5pZW5jZSB0ZW1wbGF0ZSBtYXJrZXI6IDxuZy10ZW1wbGF0ZSBjZXJpb3VzU2Nyb2xsSXRlbSBsZXQtaXRlbSBsZXQtaW5kZXg9XCJpbmRleFwiPi4uLjwvbmctdGVtcGxhdGU+ICovXG4gIEBDb250ZW50Q2hpbGQoQ2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZURpcmVjdGl2ZSlcbiAgcHJpdmF0ZSByZWFkb25seSBwcm9qZWN0ZWRJdGVtVGVtcGxhdGU/OiBDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlRGlyZWN0aXZlPFRJdGVtPjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGNlcmlvdXNTY3JvbGw6IENlcmlvdXNTY3JvbGxEaXJlY3RpdmU8VEl0ZW0+KSB7fVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsLmNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGUpIHJldHVybjtcbiAgICBpZiAoIXRoaXMucHJvamVjdGVkSXRlbVRlbXBsYXRlKSByZXR1cm47XG5cbiAgICB0aGlzLmNlcmlvdXNTY3JvbGwuY2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZSA9XG4gICAgICB0aGlzLnByb2plY3RlZEl0ZW1UZW1wbGF0ZS50ZW1wbGF0ZVJlZiBhcyBUZW1wbGF0ZVJlZjxDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dDxUSXRlbT4+O1xuXG4gICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbC5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5jZXJpb3VzU2Nyb2xsLnJlbmRlcigpKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,172 @@
1
+ import { Directive, EventEmitter, Input, Output, } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "./cerious-scroll.service";
4
+ function coerceTotalElements(explicitTotal, itemsLen) {
5
+ const candidate = typeof explicitTotal === 'number' ? explicitTotal : typeof itemsLen === 'number' ? itemsLen : undefined;
6
+ if (candidate === undefined || Number.isNaN(candidate)) {
7
+ throw new Error('CeriousScrollDirective: provide `ceriousScrollTotalElements` or `ceriousScrollItems`.');
8
+ }
9
+ // CeriousScroll currently requires >= 1
10
+ return Math.max(1, candidate);
11
+ }
12
+ export class CeriousScrollDirective {
13
+ constructor(host, appRef, ngZone, cerious) {
14
+ this.host = host;
15
+ this.appRef = appRef;
16
+ this.ngZone = ngZone;
17
+ this.cerious = cerious;
18
+ /** Total number of items. If omitted, derived from `ceriousScrollItems.length`. */
19
+ this.ceriousScrollTotalElements = null;
20
+ /** Optional items array (enables `let-item`). */
21
+ this.ceriousScrollItems = null;
22
+ /** Optional getter for large datasets (alternative to passing full `items`). */
23
+ this.ceriousScrollGetItem = null;
24
+ /** Template used to render each row. */
25
+ this.ceriousScrollItemTemplate = null;
26
+ /** Options passed to `new CeriousScroll(...)`. */
27
+ this.ceriousScrollOptions = {};
28
+ /** Automatically call render after each scroll event. Default: true */
29
+ this.ceriousScrollAutoRender = true;
30
+ /** Emits `cerious-viewport-change` detail. */
31
+ this.ceriousScrollViewportChange = new EventEmitter();
32
+ /** Emits the last measured viewport after each render pass. */
33
+ this.ceriousScrollMeasuredViewport = new EventEmitter();
34
+ /** Emits once the underlying `CeriousScroll` instance is ready. */
35
+ this.ceriousScrollReady = new EventEmitter();
36
+ this.hostRef = null;
37
+ this.viewportSub = null;
38
+ this.viewByContainer = new Map();
39
+ }
40
+ ngAfterViewInit() {
41
+ this.ensureInitialized();
42
+ }
43
+ ngOnChanges(changes) {
44
+ if (!this.hostRef)
45
+ return;
46
+ if (changes['ceriousScrollItems'] || changes['ceriousScrollTotalElements']) {
47
+ const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
48
+ this.hostRef.scroller.totalElements = total;
49
+ this.hostRef.scroller.clearAllCaches();
50
+ if (this.ceriousScrollAutoRender)
51
+ this.render();
52
+ }
53
+ if (changes['ceriousScrollOptions'] && !changes['ceriousScrollOptions'].firstChange) {
54
+ // Options are consumed primarily at construction time.
55
+ this.recreate();
56
+ }
57
+ }
58
+ ngOnDestroy() {
59
+ this.viewportSub?.unsubscribe();
60
+ this.viewportSub = null;
61
+ this.destroyAllViews();
62
+ this.hostRef?.destroy();
63
+ this.hostRef = null;
64
+ }
65
+ /** Imperatively trigger a render pass (uses `ceriousScrollItemTemplate`). */
66
+ render() {
67
+ if (!this.hostRef)
68
+ return null;
69
+ const template = this.ceriousScrollItemTemplate;
70
+ if (!template)
71
+ return null;
72
+ const hostContainer = this.host.nativeElement;
73
+ const height = hostContainer.clientHeight || hostContainer.offsetHeight;
74
+ const contentContainer = this.hostRef.contentElement;
75
+ const renderer = (index, elementContainer) => {
76
+ // Rendering must create Angular views inside the Angular zone.
77
+ this.ngZone.run(() => {
78
+ this.renderTemplateIntoContainer(template, index, elementContainer);
79
+ });
80
+ };
81
+ const range = this.hostRef.scroller.renderViewport(height, contentContainer, renderer);
82
+ this.ngZone.run(() => this.ceriousScrollMeasuredViewport.emit(range));
83
+ return range;
84
+ }
85
+ recreate() {
86
+ this.viewportSub?.unsubscribe();
87
+ this.viewportSub = null;
88
+ this.destroyAllViews();
89
+ this.hostRef?.destroy();
90
+ this.hostRef = null;
91
+ this.ensureInitialized();
92
+ }
93
+ ensureInitialized() {
94
+ if (this.hostRef)
95
+ return;
96
+ const container = this.host.nativeElement;
97
+ const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
98
+ this.hostRef = this.cerious.createHost(container, total, this.ceriousScrollOptions, this.ngZone, () => {
99
+ if (this.ceriousScrollAutoRender)
100
+ this.render();
101
+ });
102
+ this.viewportSub = this.hostRef.viewportChanges$.subscribe((detail) => {
103
+ this.ngZone.run(() => this.ceriousScrollViewportChange.emit(detail));
104
+ });
105
+ this.ceriousScrollReady.emit(this.hostRef.scroller);
106
+ if (this.ceriousScrollAutoRender) {
107
+ queueMicrotask(() => this.render());
108
+ }
109
+ }
110
+ getItemForIndex(index) {
111
+ const getter = this.ceriousScrollGetItem;
112
+ if (getter)
113
+ return getter(index);
114
+ const items = this.ceriousScrollItems;
115
+ if (!items)
116
+ return undefined;
117
+ return items[index];
118
+ }
119
+ renderTemplateIntoContainer(template, index, elementContainer) {
120
+ const previous = this.viewByContainer.get(elementContainer);
121
+ if (previous) {
122
+ this.appRef.detachView(previous);
123
+ previous.destroy();
124
+ this.viewByContainer.delete(elementContainer);
125
+ }
126
+ // Clear prior DOM (CeriousScroll may recycle containers).
127
+ elementContainer.textContent = '';
128
+ const item = this.getItemForIndex(index);
129
+ const view = template.createEmbeddedView({ $implicit: item, item, index });
130
+ this.appRef.attachView(view);
131
+ view.detectChanges();
132
+ for (const node of view.rootNodes) {
133
+ elementContainer.appendChild(node);
134
+ }
135
+ this.viewByContainer.set(elementContainer, view);
136
+ }
137
+ destroyAllViews() {
138
+ for (const view of this.viewByContainer.values()) {
139
+ this.appRef.detachView(view);
140
+ view.destroy();
141
+ }
142
+ this.viewByContainer.clear();
143
+ }
144
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollDirective, deps: [{ token: i0.ElementRef }, { token: i0.ApplicationRef }, { token: i0.NgZone }, { token: i1.CeriousScrollService }], target: i0.ɵɵFactoryTarget.Directive }); }
145
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: CeriousScrollDirective, isStandalone: true, selector: "[ceriousScroll]", inputs: { ceriousScrollTotalElements: "ceriousScrollTotalElements", ceriousScrollItems: "ceriousScrollItems", ceriousScrollGetItem: "ceriousScrollGetItem", ceriousScrollItemTemplate: "ceriousScrollItemTemplate", ceriousScrollOptions: "ceriousScrollOptions", ceriousScrollAutoRender: "ceriousScrollAutoRender" }, outputs: { ceriousScrollViewportChange: "ceriousScrollViewportChange", ceriousScrollMeasuredViewport: "ceriousScrollMeasuredViewport", ceriousScrollReady: "ceriousScrollReady" }, usesOnChanges: true, ngImport: i0 }); }
146
+ }
147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollDirective, decorators: [{
148
+ type: Directive,
149
+ args: [{
150
+ selector: '[ceriousScroll]',
151
+ standalone: true,
152
+ }]
153
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ApplicationRef }, { type: i0.NgZone }, { type: i1.CeriousScrollService }], propDecorators: { ceriousScrollTotalElements: [{
154
+ type: Input
155
+ }], ceriousScrollItems: [{
156
+ type: Input
157
+ }], ceriousScrollGetItem: [{
158
+ type: Input
159
+ }], ceriousScrollItemTemplate: [{
160
+ type: Input
161
+ }], ceriousScrollOptions: [{
162
+ type: Input
163
+ }], ceriousScrollAutoRender: [{
164
+ type: Input
165
+ }], ceriousScrollViewportChange: [{
166
+ type: Output
167
+ }], ceriousScrollMeasuredViewport: [{
168
+ type: Output
169
+ }], ceriousScrollReady: [{
170
+ type: Output
171
+ }] } });
172
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWNlcmlvdXMtc2Nyb2xsL3NyYy9saWIvY2VyaW91cy1zY3JvbGwuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFHTCxTQUFTLEVBR1QsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEdBR1AsTUFBTSxlQUFlLENBQUM7OztBQWF2QixTQUFTLG1CQUFtQixDQUFDLGFBQXdDLEVBQUUsUUFBbUM7SUFDeEcsTUFBTSxTQUFTLEdBQUcsT0FBTyxhQUFhLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLE9BQU8sUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDMUgsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLHVGQUF1RixDQUFDLENBQUM7SUFDM0csQ0FBQztJQUNELHdDQUF3QztJQUN4QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFNRCxNQUFNLE9BQU8sc0JBQXNCO0lBaUNqQyxZQUNtQixJQUE2QixFQUM3QixNQUFzQixFQUN0QixNQUFjLEVBQ2QsT0FBNkI7UUFIN0IsU0FBSSxHQUFKLElBQUksQ0FBeUI7UUFDN0IsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQXNCO1FBcENoRCxtRkFBbUY7UUFDMUUsK0JBQTBCLEdBQWtCLElBQUksQ0FBQztRQUUxRCxpREFBaUQ7UUFDeEMsdUJBQWtCLEdBQTRCLElBQUksQ0FB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LG9CQUFvQjtzQkFBNUIsS0FBSztnQkFHRyx1QkFBdUI7c0JBQS9CLEtBQUs7Z0JBR0ksMkJBQTJCO3NCQUFwQyxNQUFNO2dCQUdHLDZCQUE2QjtzQkFBdEMsTUFBTTtnQkFHRyxrQkFBa0I7c0JBQTNCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBBcHBsaWNhdGlvblJlZixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFbWJlZGRlZFZpZXdSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVGVtcGxhdGVSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQge1xuICB0eXBlIENlcmlvdXNTY3JvbGxPcHRpb25zLFxuICB0eXBlIEVsZW1lbnRSZW5kZXJlcixcbiAgdHlwZSBNZWFzdXJlZFZpZXdwb3J0UmFuZ2UsXG59IGZyb20gJ0BjZXJpb3VzZGV2dGVjaC9jZXJpb3VzLXNjcm9sbCc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHR5cGUgeyBDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWwgfSBmcm9tICcuL2NlcmlvdXMtc2Nyb2xsLnR5cGVzJztcbmltcG9ydCB0eXBlIHsgQ2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQgfSBmcm9tICcuL2NlcmlvdXMtc2Nyb2xsLWl0ZW0tdGVtcGxhdGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IHR5cGUgQ2VyaW91c1Njcm9sbEhvc3RSZWYsIENlcmlvdXNTY3JvbGxTZXJ2aWNlIH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC5zZXJ2aWNlJztcblxuZnVuY3Rpb24gY29lcmNlVG90YWxFbGVtZW50cyhleHBsaWNpdFRvdGFsOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkLCBpdGVtc0xlbjogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCk6IG51bWJlciB7XG4gIGNvbnN0IGNhbmRpZGF0ZSA9IHR5cGVvZiBleHBsaWNpdFRvdGFsID09PSAnbnVtYmVyJyA/IGV4cGxpY2l0VG90YWwgOiB0eXBlb2YgaXRlbXNMZW4gPT09ICdudW1iZXInID8gaXRlbXNMZW4gOiB1bmRlZmluZWQ7XG4gIGlmIChjYW5kaWRhdGUgPT09IHVuZGVmaW5lZCB8fCBOdW1iZXIuaXNOYU4oY2FuZGlkYXRlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ2VyaW91c1Njcm9sbERpcmVjdGl2ZTogcHJvdmlkZSBgY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHNgIG9yIGBjZXJpb3VzU2Nyb2xsSXRlbXNgLicpO1xuICB9XG4gIC8vIENlcmlvdXNTY3JvbGwgY3VycmVudGx5IHJlcXVpcmVzID49IDFcbiAgcmV0dXJuIE1hdGgubWF4KDEsIGNhbmRpZGF0ZSk7XG59XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tjZXJpb3VzU2Nyb2xsXScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIENlcmlvdXNTY3JvbGxEaXJlY3RpdmU8VEl0ZW0gPSB1bmtub3duPiBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgLyoqIFRvdGFsIG51bWJlciBvZiBpdGVtcy4gSWYgb21pdHRlZCwgZGVyaXZlZCBmcm9tIGBjZXJpb3VzU2Nyb2xsSXRlbXMubGVuZ3RoYC4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHM6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBPcHRpb25hbCBpdGVtcyBhcnJheSAoZW5hYmxlcyBgbGV0LWl0ZW1gKS4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEl0ZW1zOiByZWFkb25seSBUSXRlbVtdIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIE9wdGlvbmFsIGdldHRlciBmb3IgbGFyZ2UgZGF0YXNldHMgKGFsdGVybmF0aXZlIHRvIHBhc3NpbmcgZnVsbCBgaXRlbXNgKS4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEdldEl0ZW06ICgoaW5kZXg6IG51bWJlcikgPT4gVEl0ZW0pIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIFRlbXBsYXRlIHVzZWQgdG8gcmVuZGVyIGVhY2ggcm93LiAqL1xuICBASW5wdXQoKSBjZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dDxUSXRlbT4+IHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIE9wdGlvbnMgcGFzc2VkIHRvIGBuZXcgQ2VyaW91c1Njcm9sbCguLi4pYC4gKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbE9wdGlvbnM6IENlcmlvdXNTY3JvbGxPcHRpb25zID0ge307XG5cbiAgLyoqIEF1dG9tYXRpY2FsbHkgY2FsbCByZW5kZXIgYWZ0ZXIgZWFjaCBzY3JvbGwgZXZlbnQuIERlZmF1bHQ6IHRydWUgKi9cbiAgQElucHV0KCkgY2VyaW91c1Njcm9sbEF1dG9SZW5kZXIgPSB0cnVlO1xuXG4gIC8qKiBFbWl0cyBgY2VyaW91cy12aWV3cG9ydC1jaGFuZ2VgIGRldGFpbC4gKi9cbiAgQE91dHB1dCgpIGNlcmlvdXNTY3JvbGxWaWV3cG9ydENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2VyaW91c1ZpZXdwb3J0Q2hhbmdlRGV0YWlsPigpO1xuXG4gIC8qKiBFbWl0cyB0aGUgbGFzdCBtZWFzdXJlZCB2aWV3cG9ydCBhZnRlciBlYWNoIHJlbmRlciBwYXNzLiAqL1xuICBAT3V0cHV0KCkgY2VyaW91c1Njcm9sbE1lYXN1cmVkVmlld3BvcnQgPSBuZXcgRXZlbnRFbWl0dGVyPE1lYXN1cmVkVmlld3BvcnRSYW5nZT4oKTtcblxuICAvKiogRW1pdHMgb25jZSB0aGUgdW5kZXJseWluZyBgQ2VyaW91c1Njcm9sbGAgaW5zdGFuY2UgaXMgcmVhZHkuICovXG4gIEBPdXRwdXQoKSBjZXJpb3VzU2Nyb2xsUmVhZHkgPSBuZXcgRXZlbnRFbWl0dGVyPENlcmlvdXNTY3JvbGxIb3N0UmVmWydzY3JvbGxlciddPigpO1xuXG4gIHByaXZhdGUgaG9zdFJlZjogQ2VyaW91c1Njcm9sbEhvc3RSZWYgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB2aWV3cG9ydFN1YjogU3Vic2NyaXB0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB2aWV3QnlDb250YWluZXIgPSBuZXcgTWFwPEhUTUxFbGVtZW50LCBFbWJlZGRlZFZpZXdSZWY8Q2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZUNvbnRleHQ8VEl0ZW0+Pj4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhvc3Q6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXBwUmVmOiBBcHBsaWNhdGlvblJlZixcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2VyaW91czogQ2VyaW91c1Njcm9sbFNlcnZpY2VcbiAgKSB7fVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmVuc3VyZUluaXRpYWxpemVkKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmhvc3RSZWYpIHJldHVybjtcblxuICAgIGlmIChjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsSXRlbXMnXSB8fCBjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50cyddKSB7XG4gICAgICBjb25zdCB0b3RhbCA9IGNvZXJjZVRvdGFsRWxlbWVudHModGhpcy5jZXJpb3VzU2Nyb2xsVG90YWxFbGVtZW50cywgdGhpcy5jZXJpb3VzU2Nyb2xsSXRlbXM/Lmxlbmd0aCA/PyBudWxsKTtcbiAgICAgIHRoaXMuaG9zdFJlZi5zY3JvbGxlci50b3RhbEVsZW1lbnRzID0gdG90YWw7XG4gICAgICB0aGlzLmhvc3RSZWYuc2Nyb2xsZXIuY2xlYXJBbGxDYWNoZXMoKTtcbiAgICAgIGlmICh0aGlzLmNlcmlvdXNTY3JvbGxBdXRvUmVuZGVyKSB0aGlzLnJlbmRlcigpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddICYmICFjaGFuZ2VzWydjZXJpb3VzU2Nyb2xsT3B0aW9ucyddLmZpcnN0Q2hhbmdlKSB7XG4gICAgICAvLyBPcHRpb25zIGFyZSBjb25zdW1lZCBwcmltYXJpbHkgYXQgY29uc3RydWN0aW9uIHRpbWUuXG4gICAgICB0aGlzLnJlY3JlYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy52aWV3cG9ydFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLnZpZXdwb3J0U3ViID0gbnVsbDtcblxuICAgIHRoaXMuZGVzdHJveUFsbFZpZXdzKCk7XG5cbiAgICB0aGlzLmhvc3RSZWY/LmRlc3Ryb3koKTtcbiAgICB0aGlzLmhvc3RSZWYgPSBudWxsO1xuICB9XG5cbiAgLyoqIEltcGVyYXRpdmVseSB0cmlnZ2VyIGEgcmVuZGVyIHBhc3MgKHVzZXMgYGNlcmlvdXNTY3JvbGxJdGVtVGVtcGxhdGVgKS4gKi9cbiAgcmVuZGVyKCk6IE1lYXN1cmVkVmlld3BvcnRSYW5nZSB8IG51bGwge1xuICAgIGlmICghdGhpcy5ob3N0UmVmKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1UZW1wbGF0ZTtcbiAgICBpZiAoIXRlbXBsYXRlKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGhvc3RDb250YWluZXIgPSB0aGlzLmhvc3QubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBoZWlnaHQgPSBob3N0Q29udGFpbmVyLmNsaWVudEhlaWdodCB8fCBob3N0Q29udGFpbmVyLm9mZnNldEhlaWdodDtcbiAgICBjb25zdCBjb250ZW50Q29udGFpbmVyID0gdGhpcy5ob3N0UmVmLmNvbnRlbnRFbGVtZW50O1xuXG4gICAgY29uc3QgcmVuZGVyZXI6IEVsZW1lbnRSZW5kZXJlciA9IChpbmRleCwgZWxlbWVudENvbnRhaW5lcikgPT4ge1xuICAgICAgLy8gUmVuZGVyaW5nIG11c3QgY3JlYXRlIEFuZ3VsYXIgdmlld3MgaW5zaWRlIHRoZSBBbmd1bGFyIHpvbmUuXG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbmRlclRlbXBsYXRlSW50b0NvbnRhaW5lcih0ZW1wbGF0ZSwgaW5kZXgsIGVsZW1lbnRDb250YWluZXIpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGNvbnN0IHJhbmdlID0gdGhpcy5ob3N0UmVmLnNjcm9sbGVyLnJlbmRlclZpZXdwb3J0KGhlaWdodCwgY29udGVudENvbnRhaW5lciwgcmVuZGVyZXIpO1xuICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB0aGlzLmNlcmlvdXNTY3JvbGxNZWFzdXJlZFZpZXdwb3J0LmVtaXQocmFuZ2UpKTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH1cblxuICBwcml2YXRlIHJlY3JlYXRlKCk6IHZvaWQge1xuICAgIHRoaXMudmlld3BvcnRTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy52aWV3cG9ydFN1YiA9IG51bGw7XG5cbiAgICB0aGlzLmRlc3Ryb3lBbGxWaWV3cygpO1xuXG4gICAgdGhpcy5ob3N0UmVmPy5kZXN0cm95KCk7XG4gICAgdGhpcy5ob3N0UmVmID0gbnVsbDtcblxuICAgIHRoaXMuZW5zdXJlSW5pdGlhbGl6ZWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5zdXJlSW5pdGlhbGl6ZWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaG9zdFJlZikgcmV0dXJuO1xuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5ob3N0Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgdG90YWwgPSBjb2VyY2VUb3RhbEVsZW1lbnRzKHRoaXMuY2VyaW91c1Njcm9sbFRvdGFsRWxlbWVudHMsIHRoaXMuY2VyaW91c1Njcm9sbEl0ZW1zPy5sZW5ndGggPz8gbnVsbCk7XG5cbiAgICB0aGlzLmhvc3RSZWYgPSB0aGlzLmNlcmlvdXMuY3JlYXRlSG9zdChjb250YWluZXIsIHRvdGFsLCB0aGlzLmNlcmlvdXNTY3JvbGxPcHRpb25zLCB0aGlzLm5nWm9uZSwgKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuY2VyaW91c1Njcm9sbEF1dG9SZW5kZXIpIHRoaXMucmVuZGVyKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnZpZXdwb3J0U3ViID0gdGhpcy5ob3N0UmVmLnZpZXdwb3J0Q2hhbmdlcyQuc3Vic2NyaWJlKChkZXRhaWw6IENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbCkgPT4ge1xuICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuY2VyaW91c1Njcm9sbFZpZXdwb3J0Q2hhbmdlLmVtaXQoZGV0YWlsKSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmNlcmlvdXNTY3JvbGxSZWFkeS5lbWl0KHRoaXMuaG9zdFJlZi5zY3JvbGxlcik7XG5cbiAgICBpZiAodGhpcy5jZXJpb3VzU2Nyb2xsQXV0b1JlbmRlcikge1xuICAgICAgcXVldWVNaWNyb3Rhc2soKCkgPT4gdGhpcy5yZW5kZXIoKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRJdGVtRm9ySW5kZXgoaW5kZXg6IG51bWJlcik6IFRJdGVtIHtcbiAgICBjb25zdCBnZXR0ZXIgPSB0aGlzLmNlcmlvdXNTY3JvbGxHZXRJdGVtO1xuICAgIGlmIChnZXR0ZXIpIHJldHVybiBnZXR0ZXIoaW5kZXgpO1xuXG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLmNlcmlvdXNTY3JvbGxJdGVtcztcbiAgICBpZiAoIWl0ZW1zKSByZXR1cm4gdW5kZWZpbmVkIGFzIFRJdGVtO1xuXG4gICAgcmV0dXJuIGl0ZW1zW2luZGV4XTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyVGVtcGxhdGVJbnRvQ29udGFpbmVyKFxuICAgIHRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxDZXJpb3VzU2Nyb2xsSXRlbVRlbXBsYXRlQ29udGV4dDxUSXRlbT4+LFxuICAgIGluZGV4OiBudW1iZXIsXG4gICAgZWxlbWVudENvbnRhaW5lcjogSFRNTEVsZW1lbnRcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgcHJldmlvdXMgPSB0aGlzLnZpZXdCeUNvbnRhaW5lci5nZXQoZWxlbWVudENvbnRhaW5lcik7XG4gICAgaWYgKHByZXZpb3VzKSB7XG4gICAgICB0aGlzLmFwcFJlZi5kZXRhY2hWaWV3KHByZXZpb3VzKTtcbiAgICAgIHByZXZpb3VzLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMudmlld0J5Q29udGFpbmVyLmRlbGV0ZShlbGVtZW50Q29udGFpbmVyKTtcbiAgICB9XG5cbiAgICAvLyBDbGVhciBwcmlvciBET00gKENlcmlvdXNTY3JvbGwgbWF5IHJlY3ljbGUgY29udGFpbmVycykuXG4gICAgZWxlbWVudENvbnRhaW5lci50ZXh0Q29udGVudCA9ICcnO1xuXG4gICAgY29uc3QgaXRlbSA9IHRoaXMuZ2V0SXRlbUZvckluZGV4KGluZGV4KTtcbiAgICBjb25zdCB2aWV3ID0gdGVtcGxhdGUuY3JlYXRlRW1iZWRkZWRWaWV3KHsgJGltcGxpY2l0OiBpdGVtLCBpdGVtLCBpbmRleCB9KTtcbiAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHZpZXcpO1xuICAgIHZpZXcuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIHZpZXcucm9vdE5vZGVzKSB7XG4gICAgICBlbGVtZW50Q29udGFpbmVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIH1cblxuICAgIHRoaXMudmlld0J5Q29udGFpbmVyLnNldChlbGVtZW50Q29udGFpbmVyLCB2aWV3KTtcbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveUFsbFZpZXdzKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgdmlldyBvZiB0aGlzLnZpZXdCeUNvbnRhaW5lci52YWx1ZXMoKSkge1xuICAgICAgdGhpcy5hcHBSZWYuZGV0YWNoVmlldyh2aWV3KTtcbiAgICAgIHZpZXcuZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLnZpZXdCeUNvbnRhaW5lci5jbGVhcigpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,22 @@
1
+ import { fromEvent, map, merge, share } from 'rxjs';
2
+ /**
3
+ * Observable wrapper around the `cerious-viewport-change` CustomEvent emitted by `@ceriousdevtech/cerious-scroll`.
4
+ *
5
+ * Note: this event is emitted when wheel/touch/keyboard handlers are enabled (defaults are enabled).
6
+ */
7
+ export function ceriousViewportChange$(container) {
8
+ const fromCerious = fromEvent(container, 'cerious-viewport-change').pipe(map((evt) => evt.detail));
9
+ // Native scrollbar integration in the upstream package dispatches `viewport-change`.
10
+ // Normalize it into the same shape as `cerious-viewport-change`.
11
+ const fromScrollbar = fromEvent(container, 'viewport-change').pipe(map((evt) => {
12
+ const result = { element: evt.detail.element, offset: evt.detail.scrollOffset };
13
+ return {
14
+ percentage: evt.detail.percentage,
15
+ currentElement: evt.detail.element,
16
+ scrollOffset: evt.detail.scrollOffset,
17
+ result,
18
+ };
19
+ }));
20
+ return merge(fromCerious, fromScrollbar).pipe(share());
21
+ }
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwub2JzZXJ2YWJsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1jZXJpb3VzLXNjcm9sbC9zcmMvbGliL2NlcmlvdXMtc2Nyb2xsLm9ic2VydmFibGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFjLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQVVoRTs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLHNCQUFzQixDQUFDLFNBQXNCO0lBQzNELE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBNkIsU0FBUyxFQUFFLHlCQUF5QixDQUFDLENBQUMsSUFBSSxDQUNsRyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FDekIsQ0FBQztJQUVGLHFGQUFxRjtJQUNyRixpRUFBaUU7SUFDakUsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUE0QyxTQUFTLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxJQUFJLENBQzNHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1FBQ1YsTUFBTSxNQUFNLEdBQWlCLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzlGLE9BQU87WUFDTCxVQUFVLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxVQUFVO1lBQ2pDLGNBQWMsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU87WUFDbEMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWTtZQUNyQyxNQUFNO1NBQytCLENBQUM7SUFDMUMsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUVGLE9BQU8sS0FBSyxDQUFDLFdBQVcsRUFBRSxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUN6RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZnJvbUV2ZW50LCBtYXAsIG1lcmdlLCBPYnNlcnZhYmxlLCBzaGFyZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgdHlwZSB7IFNjcm9sbFJlc3VsdCB9IGZyb20gJ0BjZXJpb3VzZGV2dGVjaC9jZXJpb3VzLXNjcm9sbCc7XG5cbmltcG9ydCB7XG4gIENlcmlvdXNOYXRpdmVTY3JvbGxiYXJWaWV3cG9ydENoYW5nZUV2ZW50LFxuICBDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWwsXG4gIENlcmlvdXNWaWV3cG9ydENoYW5nZUV2ZW50LFxufSBmcm9tICcuL2NlcmlvdXMtc2Nyb2xsLnR5cGVzJztcblxuLyoqXG4gKiBPYnNlcnZhYmxlIHdyYXBwZXIgYXJvdW5kIHRoZSBgY2VyaW91cy12aWV3cG9ydC1jaGFuZ2VgIEN1c3RvbUV2ZW50IGVtaXR0ZWQgYnkgYEBjZXJpb3VzZGV2dGVjaC9jZXJpb3VzLXNjcm9sbGAuXG4gKlxuICogTm90ZTogdGhpcyBldmVudCBpcyBlbWl0dGVkIHdoZW4gd2hlZWwvdG91Y2gva2V5Ym9hcmQgaGFuZGxlcnMgYXJlIGVuYWJsZWQgKGRlZmF1bHRzIGFyZSBlbmFibGVkKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNlcmlvdXNWaWV3cG9ydENoYW5nZSQoY29udGFpbmVyOiBIVE1MRWxlbWVudCk6IE9ic2VydmFibGU8Q2VyaW91c1ZpZXdwb3J0Q2hhbmdlRGV0YWlsPiB7XG4gIGNvbnN0IGZyb21DZXJpb3VzID0gZnJvbUV2ZW50PENlcmlvdXNWaWV3cG9ydENoYW5nZUV2ZW50Pihjb250YWluZXIsICdjZXJpb3VzLXZpZXdwb3J0LWNoYW5nZScpLnBpcGUoXG4gICAgbWFwKChldnQpID0+IGV2dC5kZXRhaWwpXG4gICk7XG5cbiAgLy8gTmF0aXZlIHNjcm9sbGJhciBpbnRlZ3JhdGlvbiBpbiB0aGUgdXBzdHJlYW0gcGFja2FnZSBkaXNwYXRjaGVzIGB2aWV3cG9ydC1jaGFuZ2VgLlxuICAvLyBOb3JtYWxpemUgaXQgaW50byB0aGUgc2FtZSBzaGFwZSBhcyBgY2VyaW91cy12aWV3cG9ydC1jaGFuZ2VgLlxuICBjb25zdCBmcm9tU2Nyb2xsYmFyID0gZnJvbUV2ZW50PENlcmlvdXNOYXRpdmVTY3JvbGxiYXJWaWV3cG9ydENoYW5nZUV2ZW50Pihjb250YWluZXIsICd2aWV3cG9ydC1jaGFuZ2UnKS5waXBlKFxuICAgIG1hcCgoZXZ0KSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQ6IFNjcm9sbFJlc3VsdCA9IHsgZWxlbWVudDogZXZ0LmRldGFpbC5lbGVtZW50LCBvZmZzZXQ6IGV2dC5kZXRhaWwuc2Nyb2xsT2Zmc2V0IH07XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwZXJjZW50YWdlOiBldnQuZGV0YWlsLnBlcmNlbnRhZ2UsXG4gICAgICAgIGN1cnJlbnRFbGVtZW50OiBldnQuZGV0YWlsLmVsZW1lbnQsXG4gICAgICAgIHNjcm9sbE9mZnNldDogZXZ0LmRldGFpbC5zY3JvbGxPZmZzZXQsXG4gICAgICAgIHJlc3VsdCxcbiAgICAgIH0gc2F0aXNmaWVzIENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbDtcbiAgICB9KVxuICApO1xuXG4gIHJldHVybiBtZXJnZShmcm9tQ2VyaW91cywgZnJvbVNjcm9sbGJhcikucGlwZShzaGFyZSgpKTtcbn1cbiJdfQ==
@@ -0,0 +1,56 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { CeriousScroll } from '@ceriousdevtech/cerious-scroll';
3
+ import { ceriousViewportChange$ } from './cerious-scroll.observable';
4
+ import * as i0 from "@angular/core";
5
+ const CONTENT_ATTR = 'data-cerious-scroll-content';
6
+ function ensureContentElement(container) {
7
+ const existing = container.querySelector(`[${CONTENT_ATTR}]`);
8
+ if (existing)
9
+ return existing;
10
+ const el = document.createElement('div');
11
+ el.setAttribute(CONTENT_ATTR, '');
12
+ el.style.position = 'relative';
13
+ el.style.width = '100%';
14
+ el.style.height = '100%';
15
+ el.style.overflow = 'hidden';
16
+ container.appendChild(el);
17
+ return el;
18
+ }
19
+ export class CeriousScrollService {
20
+ createHost(container, totalElements, options, ngZone, onScrollHook) {
21
+ const contentElement = ensureContentElement(container);
22
+ let scroller;
23
+ ngZone.runOutsideAngular(() => {
24
+ const userOnScroll = options?.onScroll;
25
+ const mergedOptions = {
26
+ ...options,
27
+ onScroll: () => {
28
+ userOnScroll?.();
29
+ onScrollHook?.();
30
+ },
31
+ };
32
+ scroller = new CeriousScroll(container, totalElements, mergedOptions);
33
+ });
34
+ const viewportChanges$ = ceriousViewportChange$(container);
35
+ return {
36
+ scroller,
37
+ contentElement,
38
+ viewportChanges$,
39
+ destroy: () => {
40
+ // Remove rendered rows content first; keep container stable.
41
+ contentElement.textContent = '';
42
+ scroller.detachScrollbar(container);
43
+ scroller.dispose();
44
+ },
45
+ };
46
+ }
47
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
48
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollService, providedIn: 'root' }); }
49
+ }
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollService, decorators: [{
51
+ type: Injectable,
52
+ args: [{
53
+ providedIn: 'root'
54
+ }]
55
+ }] });
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1jZXJpb3VzLXNjcm9sbC9zcmMvbGliL2NlcmlvdXMtc2Nyb2xsLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQUUsYUFBYSxFQUE2QixNQUFNLGdDQUFnQyxDQUFDO0FBRzFGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDOztBQUdyRSxNQUFNLFlBQVksR0FBRyw2QkFBNkIsQ0FBQztBQUVuRCxTQUFTLG9CQUFvQixDQUFDLFNBQXNCO0lBQ2xELE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxhQUFhLENBQWMsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO0lBQzNFLElBQUksUUFBUTtRQUFFLE9BQU8sUUFBUSxDQUFDO0lBRTlCLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekMsRUFBRSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDbEMsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDO0lBQy9CLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQztJQUN4QixFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDekIsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO0lBQzdCLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDMUIsT0FBTyxFQUFFLENBQUM7QUFDWixDQUFDO0FBS0QsTUFBTSxPQUFPLG9CQUFvQjtJQUMvQixVQUFVLENBQ1IsU0FBc0IsRUFDdEIsYUFBcUIsRUFDckIsT0FBNkIsRUFDN0IsTUFBYyxFQUNkLFlBQXlCO1FBRXpCLE1BQU0sY0FBYyxHQUFHLG9CQUFvQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZELElBQUksUUFBd0IsQ0FBQztRQUU3QixNQUFNLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1lBQzVCLE1BQU0sWUFBWSxHQUFHLE9BQU8sRUFBRSxRQUFRLENBQUM7WUFDdkMsTUFBTSxhQUFhLEdBQXlCO2dCQUMxQyxHQUFHLE9BQU87Z0JBQ1YsUUFBUSxFQUFFLEdBQUcsRUFBRTtvQkFDYixZQUFZLEVBQUUsRUFBRSxDQUFDO29CQUNqQixZQUFZLEVBQUUsRUFBRSxDQUFDO2dCQUNuQixDQUFDO2FBQ0YsQ0FBQztZQUVGLFFBQVEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxTQUFTLEVBQUUsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxnQkFBZ0IsR0FBRyxzQkFBc0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUUzRCxPQUFPO1lBQ0wsUUFBUTtZQUNSLGNBQWM7WUFDZCxnQkFBZ0I7WUFDaEIsT0FBTyxFQUFFLEdBQUcsRUFBRTtnQkFDWiw2REFBNkQ7Z0JBQzdELGNBQWMsQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO2dCQUNoQyxRQUFRLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUNwQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDckIsQ0FBQztTQUNGLENBQUM7SUFDSixDQUFDOytHQXJDVSxvQkFBb0I7bUhBQXBCLG9CQUFvQixjQUZuQixNQUFNOzs0RkFFUCxvQkFBb0I7a0JBSGhDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IENlcmlvdXNTY3JvbGwsIHR5cGUgQ2VyaW91c1Njcm9sbE9wdGlvbnMgfSBmcm9tICdAY2VyaW91c2RldnRlY2gvY2VyaW91cy1zY3JvbGwnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBjZXJpb3VzVmlld3BvcnRDaGFuZ2UkIH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC5vYnNlcnZhYmxlJztcbmltcG9ydCB0eXBlIHsgQ2VyaW91c1ZpZXdwb3J0Q2hhbmdlRGV0YWlsIH0gZnJvbSAnLi9jZXJpb3VzLXNjcm9sbC50eXBlcyc7XG5cbmNvbnN0IENPTlRFTlRfQVRUUiA9ICdkYXRhLWNlcmlvdXMtc2Nyb2xsLWNvbnRlbnQnO1xuXG5mdW5jdGlvbiBlbnN1cmVDb250ZW50RWxlbWVudChjb250YWluZXI6IEhUTUxFbGVtZW50KTogSFRNTEVsZW1lbnQge1xuICBjb25zdCBleGlzdGluZyA9IGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yPEhUTUxFbGVtZW50PihgWyR7Q09OVEVOVF9BVFRSfV1gKTtcbiAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3Rpbmc7XG5cbiAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgZWwuc2V0QXR0cmlidXRlKENPTlRFTlRfQVRUUiwgJycpO1xuICBlbC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gIGVsLnN0eWxlLndpZHRoID0gJzEwMCUnO1xuICBlbC5zdHlsZS5oZWlnaHQgPSAnMTAwJSc7XG4gIGVsLnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChlbCk7XG4gIHJldHVybiBlbDtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQ2VyaW91c1Njcm9sbFNlcnZpY2Uge1xuICBjcmVhdGVIb3N0KFxuICAgIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQsXG4gICAgdG90YWxFbGVtZW50czogbnVtYmVyLFxuICAgIG9wdGlvbnM6IENlcmlvdXNTY3JvbGxPcHRpb25zLFxuICAgIG5nWm9uZTogTmdab25lLFxuICAgIG9uU2Nyb2xsSG9vaz86ICgpID0+IHZvaWRcbiAgKTogQ2VyaW91c1Njcm9sbEhvc3RSZWYge1xuICAgIGNvbnN0IGNvbnRlbnRFbGVtZW50ID0gZW5zdXJlQ29udGVudEVsZW1lbnQoY29udGFpbmVyKTtcbiAgICBsZXQgc2Nyb2xsZXIhOiBDZXJpb3VzU2Nyb2xsO1xuXG4gICAgbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXJPblNjcm9sbCA9IG9wdGlvbnM/Lm9uU2Nyb2xsO1xuICAgICAgY29uc3QgbWVyZ2VkT3B0aW9uczogQ2VyaW91c1Njcm9sbE9wdGlvbnMgPSB7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIG9uU2Nyb2xsOiAoKSA9PiB7XG4gICAgICAgICAgdXNlck9uU2Nyb2xsPy4oKTtcbiAgICAgICAgICBvblNjcm9sbEhvb2s/LigpO1xuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgc2Nyb2xsZXIgPSBuZXcgQ2VyaW91c1Njcm9sbChjb250YWluZXIsIHRvdGFsRWxlbWVudHMsIG1lcmdlZE9wdGlvbnMpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgdmlld3BvcnRDaGFuZ2VzJCA9IGNlcmlvdXNWaWV3cG9ydENoYW5nZSQoY29udGFpbmVyKTtcblxuICAgIHJldHVybiB7XG4gICAgICBzY3JvbGxlcixcbiAgICAgIGNvbnRlbnRFbGVtZW50LFxuICAgICAgdmlld3BvcnRDaGFuZ2VzJCxcbiAgICAgIGRlc3Ryb3k6ICgpID0+IHtcbiAgICAgICAgLy8gUmVtb3ZlIHJlbmRlcmVkIHJvd3MgY29udGVudCBmaXJzdDsga2VlcCBjb250YWluZXIgc3RhYmxlLlxuICAgICAgICBjb250ZW50RWxlbWVudC50ZXh0Q29udGVudCA9ICcnO1xuICAgICAgICBzY3JvbGxlci5kZXRhY2hTY3JvbGxiYXIoY29udGFpbmVyKTtcbiAgICAgICAgc2Nyb2xsZXIuZGlzcG9zZSgpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2VyaW91c1Njcm9sbEhvc3RSZWYge1xuICByZWFkb25seSBzY3JvbGxlcjogQ2VyaW91c1Njcm9sbDtcbiAgLyoqIERlZGljYXRlZCBlbGVtZW50IHVzZWQgZm9yIHJvdyByZW5kZXJpbmcgKHByZXZlbnRzIHNjcm9sbGJhciBET00gZnJvbSBiZWluZyBjbGVhcmVkKS4gKi9cbiAgcmVhZG9ubHkgY29udGVudEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICByZWFkb25seSB2aWV3cG9ydENoYW5nZXMkOiBPYnNlcnZhYmxlPENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbD47XG4gIGRlc3Ryb3koKTogdm9pZDtcbn1cbiJdfQ==
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VyaW91cy1zY3JvbGwudHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtY2VyaW91cy1zY3JvbGwvc3JjL2xpYi9jZXJpb3VzLXNjcm9sbC50eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBTY3JvbGxSZXN1bHQgfSBmcm9tICdAY2VyaW91c2RldnRlY2gvY2VyaW91cy1zY3JvbGwnO1xuXG4vKipcbiAqIERldGFpbCBwYXlsb2FkIGZvciB0aGUgYGNlcmlvdXMtdmlld3BvcnQtY2hhbmdlYCBDdXN0b21FdmVudCBkaXNwYXRjaGVkIGJ5IGBAY2VyaW91c2RldnRlY2gvY2VyaW91cy1zY3JvbGxgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENlcmlvdXNWaWV3cG9ydENoYW5nZURldGFpbCB7XG4gIC8qKiBTY3JvbGwgcGVyY2VudGFnZSBmcm9tIDAuLjEwMCAqL1xuICBwZXJjZW50YWdlOiBudW1iZXI7XG5cbiAgLyoqIEN1cnJlbnQgdG9wLW1vc3QgZWxlbWVudCBpbmRleCAoYXMgdHJhY2tlZCBieSBDZXJpb3VzU2Nyb2xsKSAqL1xuICBjdXJyZW50RWxlbWVudDogbnVtYmVyO1xuXG4gIC8qKiBQaXhlbCBvZmZzZXQgd2l0aGluIGBjdXJyZW50RWxlbWVudGAgKi9cbiAgc2Nyb2xsT2Zmc2V0OiBudW1iZXI7XG5cbiAgLyoqIFNjcm9sbCBvcGVyYXRpb24gcmVzdWx0IChlbGVtZW50ICsgb2Zmc2V0KSAqL1xuICByZXN1bHQ6IFNjcm9sbFJlc3VsdDtcbn1cblxuZXhwb3J0IHR5cGUgQ2VyaW91c1ZpZXdwb3J0Q2hhbmdlRXZlbnQgPSBDdXN0b21FdmVudDxDZXJpb3VzVmlld3BvcnRDaGFuZ2VEZXRhaWw+O1xuXG4vKipcbiAqIFBheWxvYWQgdXNlZCBieSBDZXJpb3VzU2Nyb2xsJ3MgbmF0aXZlIHNjcm9sbGJhciBpbnRlZ3JhdGlvbi5cbiAqIChEaXNwYXRjaGVkIGFzIGB2aWV3cG9ydC1jaGFuZ2VgIGluIHRoZSB1cHN0cmVhbSBwYWNrYWdlLilcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZXJpb3VzTmF0aXZlU2Nyb2xsYmFyVmlld3BvcnRDaGFuZ2VEZXRhaWwge1xuICBwZXJjZW50YWdlOiBudW1iZXI7XG4gIGVsZW1lbnQ6IG51bWJlcjtcbiAgc2Nyb2xsT2Zmc2V0OiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIENlcmlvdXNOYXRpdmVTY3JvbGxiYXJWaWV3cG9ydENoYW5nZUV2ZW50ID0gQ3VzdG9tRXZlbnQ8Q2VyaW91c05hdGl2ZVNjcm9sbGJhclZpZXdwb3J0Q2hhbmdlRGV0YWlsPjtcbiJdfQ==
@@ -0,0 +1,12 @@
1
+ /*
2
+ * Public API Surface of ngx-cerious-scroll
3
+ */
4
+ export * from './lib/cerious-scroll.types';
5
+ export * from './lib/cerious-scroll.observable';
6
+ export * from './lib/cerious-scroll-item-template.directive';
7
+ export * from './lib/cerious-scroll.directive';
8
+ export * from './lib/cerious-scroll.component';
9
+ export * from './lib/cerious-scroll.service';
10
+ // Re-export upstream types/classes for convenience
11
+ export * from '@ceriousdevtech/cerious-scroll';
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25neC1jZXJpb3VzLXNjcm9sbC9zcmMvcHVibGljLWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILGNBQWMsNEJBQTRCLENBQUM7QUFDM0MsY0FBYyxpQ0FBaUMsQ0FBQztBQUNoRCxjQUFjLDhDQUE4QyxDQUFDO0FBQzdELGNBQWMsZ0NBQWdDLENBQUM7QUFDL0MsY0FBYyxnQ0FBZ0MsQ0FBQztBQUMvQyxjQUFjLDhCQUE4QixDQUFDO0FBRTdDLG1EQUFtRDtBQUNuRCxjQUFjLGdDQUFnQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIFB1YmxpYyBBUEkgU3VyZmFjZSBvZiBuZ3gtY2VyaW91cy1zY3JvbGxcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jZXJpb3VzLXNjcm9sbC50eXBlcyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jZXJpb3VzLXNjcm9sbC5vYnNlcnZhYmxlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NlcmlvdXMtc2Nyb2xsLWl0ZW0tdGVtcGxhdGUuZGlyZWN0aXZlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2NlcmlvdXMtc2Nyb2xsLmRpcmVjdGl2ZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jZXJpb3VzLXNjcm9sbC5jb21wb25lbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvY2VyaW91cy1zY3JvbGwuc2VydmljZSc7XG5cbi8vIFJlLWV4cG9ydCB1cHN0cmVhbSB0eXBlcy9jbGFzc2VzIGZvciBjb252ZW5pZW5jZVxuZXhwb3J0ICogZnJvbSAnQGNlcmlvdXNkZXZ0ZWNoL2NlcmlvdXMtc2Nyb2xsJztcbiJdfQ==
@@ -0,0 +1,328 @@
1
+ import { fromEvent, map, merge, share } from 'rxjs';
2
+ import * as i0 from '@angular/core';
3
+ import { Directive, Injectable, EventEmitter, Output, Input, ContentChild, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { CeriousScroll } from '@ceriousdevtech/cerious-scroll';
5
+ export * from '@ceriousdevtech/cerious-scroll';
6
+
7
+ /**
8
+ * Observable wrapper around the `cerious-viewport-change` CustomEvent emitted by `@ceriousdevtech/cerious-scroll`.
9
+ *
10
+ * Note: this event is emitted when wheel/touch/keyboard handlers are enabled (defaults are enabled).
11
+ */
12
+ function ceriousViewportChange$(container) {
13
+ const fromCerious = fromEvent(container, 'cerious-viewport-change').pipe(map((evt) => evt.detail));
14
+ // Native scrollbar integration in the upstream package dispatches `viewport-change`.
15
+ // Normalize it into the same shape as `cerious-viewport-change`.
16
+ const fromScrollbar = fromEvent(container, 'viewport-change').pipe(map((evt) => {
17
+ const result = { element: evt.detail.element, offset: evt.detail.scrollOffset };
18
+ return {
19
+ percentage: evt.detail.percentage,
20
+ currentElement: evt.detail.element,
21
+ scrollOffset: evt.detail.scrollOffset,
22
+ result,
23
+ };
24
+ }));
25
+ return merge(fromCerious, fromScrollbar).pipe(share());
26
+ }
27
+
28
+ /**
29
+ * Marks an `ng-template` as the row template for `CeriousScrollComponent`.
30
+ *
31
+ * Usage:
32
+ * ```html
33
+ * <cerious-scroll [items]="items">
34
+ * <ng-template ceriousScrollItem let-item let-index="index">
35
+ * {{ index }} - {{ item.name }}
36
+ * </ng-template>
37
+ * </cerious-scroll>
38
+ * ```
39
+ */
40
+ class CeriousScrollItemTemplateDirective {
41
+ constructor(templateRef) {
42
+ this.templateRef = templateRef;
43
+ }
44
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollItemTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
45
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: CeriousScrollItemTemplateDirective, isStandalone: true, selector: "ng-template[ceriousScrollItem]", ngImport: i0 }); }
46
+ }
47
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollItemTemplateDirective, decorators: [{
48
+ type: Directive,
49
+ args: [{
50
+ selector: 'ng-template[ceriousScrollItem]',
51
+ standalone: true,
52
+ }]
53
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
54
+
55
+ const CONTENT_ATTR = 'data-cerious-scroll-content';
56
+ function ensureContentElement(container) {
57
+ const existing = container.querySelector(`[${CONTENT_ATTR}]`);
58
+ if (existing)
59
+ return existing;
60
+ const el = document.createElement('div');
61
+ el.setAttribute(CONTENT_ATTR, '');
62
+ el.style.position = 'relative';
63
+ el.style.width = '100%';
64
+ el.style.height = '100%';
65
+ el.style.overflow = 'hidden';
66
+ container.appendChild(el);
67
+ return el;
68
+ }
69
+ class CeriousScrollService {
70
+ createHost(container, totalElements, options, ngZone, onScrollHook) {
71
+ const contentElement = ensureContentElement(container);
72
+ let scroller;
73
+ ngZone.runOutsideAngular(() => {
74
+ const userOnScroll = options?.onScroll;
75
+ const mergedOptions = {
76
+ ...options,
77
+ onScroll: () => {
78
+ userOnScroll?.();
79
+ onScrollHook?.();
80
+ },
81
+ };
82
+ scroller = new CeriousScroll(container, totalElements, mergedOptions);
83
+ });
84
+ const viewportChanges$ = ceriousViewportChange$(container);
85
+ return {
86
+ scroller,
87
+ contentElement,
88
+ viewportChanges$,
89
+ destroy: () => {
90
+ // Remove rendered rows content first; keep container stable.
91
+ contentElement.textContent = '';
92
+ scroller.detachScrollbar(container);
93
+ scroller.dispose();
94
+ },
95
+ };
96
+ }
97
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
98
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollService, providedIn: 'root' }); }
99
+ }
100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollService, decorators: [{
101
+ type: Injectable,
102
+ args: [{
103
+ providedIn: 'root'
104
+ }]
105
+ }] });
106
+
107
+ function coerceTotalElements(explicitTotal, itemsLen) {
108
+ const candidate = typeof explicitTotal === 'number' ? explicitTotal : typeof itemsLen === 'number' ? itemsLen : undefined;
109
+ if (candidate === undefined || Number.isNaN(candidate)) {
110
+ throw new Error('CeriousScrollDirective: provide `ceriousScrollTotalElements` or `ceriousScrollItems`.');
111
+ }
112
+ // CeriousScroll currently requires >= 1
113
+ return Math.max(1, candidate);
114
+ }
115
+ class CeriousScrollDirective {
116
+ constructor(host, appRef, ngZone, cerious) {
117
+ this.host = host;
118
+ this.appRef = appRef;
119
+ this.ngZone = ngZone;
120
+ this.cerious = cerious;
121
+ /** Total number of items. If omitted, derived from `ceriousScrollItems.length`. */
122
+ this.ceriousScrollTotalElements = null;
123
+ /** Optional items array (enables `let-item`). */
124
+ this.ceriousScrollItems = null;
125
+ /** Optional getter for large datasets (alternative to passing full `items`). */
126
+ this.ceriousScrollGetItem = null;
127
+ /** Template used to render each row. */
128
+ this.ceriousScrollItemTemplate = null;
129
+ /** Options passed to `new CeriousScroll(...)`. */
130
+ this.ceriousScrollOptions = {};
131
+ /** Automatically call render after each scroll event. Default: true */
132
+ this.ceriousScrollAutoRender = true;
133
+ /** Emits `cerious-viewport-change` detail. */
134
+ this.ceriousScrollViewportChange = new EventEmitter();
135
+ /** Emits the last measured viewport after each render pass. */
136
+ this.ceriousScrollMeasuredViewport = new EventEmitter();
137
+ /** Emits once the underlying `CeriousScroll` instance is ready. */
138
+ this.ceriousScrollReady = new EventEmitter();
139
+ this.hostRef = null;
140
+ this.viewportSub = null;
141
+ this.viewByContainer = new Map();
142
+ }
143
+ ngAfterViewInit() {
144
+ this.ensureInitialized();
145
+ }
146
+ ngOnChanges(changes) {
147
+ if (!this.hostRef)
148
+ return;
149
+ if (changes['ceriousScrollItems'] || changes['ceriousScrollTotalElements']) {
150
+ const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
151
+ this.hostRef.scroller.totalElements = total;
152
+ this.hostRef.scroller.clearAllCaches();
153
+ if (this.ceriousScrollAutoRender)
154
+ this.render();
155
+ }
156
+ if (changes['ceriousScrollOptions'] && !changes['ceriousScrollOptions'].firstChange) {
157
+ // Options are consumed primarily at construction time.
158
+ this.recreate();
159
+ }
160
+ }
161
+ ngOnDestroy() {
162
+ this.viewportSub?.unsubscribe();
163
+ this.viewportSub = null;
164
+ this.destroyAllViews();
165
+ this.hostRef?.destroy();
166
+ this.hostRef = null;
167
+ }
168
+ /** Imperatively trigger a render pass (uses `ceriousScrollItemTemplate`). */
169
+ render() {
170
+ if (!this.hostRef)
171
+ return null;
172
+ const template = this.ceriousScrollItemTemplate;
173
+ if (!template)
174
+ return null;
175
+ const hostContainer = this.host.nativeElement;
176
+ const height = hostContainer.clientHeight || hostContainer.offsetHeight;
177
+ const contentContainer = this.hostRef.contentElement;
178
+ const renderer = (index, elementContainer) => {
179
+ // Rendering must create Angular views inside the Angular zone.
180
+ this.ngZone.run(() => {
181
+ this.renderTemplateIntoContainer(template, index, elementContainer);
182
+ });
183
+ };
184
+ const range = this.hostRef.scroller.renderViewport(height, contentContainer, renderer);
185
+ this.ngZone.run(() => this.ceriousScrollMeasuredViewport.emit(range));
186
+ return range;
187
+ }
188
+ recreate() {
189
+ this.viewportSub?.unsubscribe();
190
+ this.viewportSub = null;
191
+ this.destroyAllViews();
192
+ this.hostRef?.destroy();
193
+ this.hostRef = null;
194
+ this.ensureInitialized();
195
+ }
196
+ ensureInitialized() {
197
+ if (this.hostRef)
198
+ return;
199
+ const container = this.host.nativeElement;
200
+ const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);
201
+ this.hostRef = this.cerious.createHost(container, total, this.ceriousScrollOptions, this.ngZone, () => {
202
+ if (this.ceriousScrollAutoRender)
203
+ this.render();
204
+ });
205
+ this.viewportSub = this.hostRef.viewportChanges$.subscribe((detail) => {
206
+ this.ngZone.run(() => this.ceriousScrollViewportChange.emit(detail));
207
+ });
208
+ this.ceriousScrollReady.emit(this.hostRef.scroller);
209
+ if (this.ceriousScrollAutoRender) {
210
+ queueMicrotask(() => this.render());
211
+ }
212
+ }
213
+ getItemForIndex(index) {
214
+ const getter = this.ceriousScrollGetItem;
215
+ if (getter)
216
+ return getter(index);
217
+ const items = this.ceriousScrollItems;
218
+ if (!items)
219
+ return undefined;
220
+ return items[index];
221
+ }
222
+ renderTemplateIntoContainer(template, index, elementContainer) {
223
+ const previous = this.viewByContainer.get(elementContainer);
224
+ if (previous) {
225
+ this.appRef.detachView(previous);
226
+ previous.destroy();
227
+ this.viewByContainer.delete(elementContainer);
228
+ }
229
+ // Clear prior DOM (CeriousScroll may recycle containers).
230
+ elementContainer.textContent = '';
231
+ const item = this.getItemForIndex(index);
232
+ const view = template.createEmbeddedView({ $implicit: item, item, index });
233
+ this.appRef.attachView(view);
234
+ view.detectChanges();
235
+ for (const node of view.rootNodes) {
236
+ elementContainer.appendChild(node);
237
+ }
238
+ this.viewByContainer.set(elementContainer, view);
239
+ }
240
+ destroyAllViews() {
241
+ for (const view of this.viewByContainer.values()) {
242
+ this.appRef.detachView(view);
243
+ view.destroy();
244
+ }
245
+ this.viewByContainer.clear();
246
+ }
247
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollDirective, deps: [{ token: i0.ElementRef }, { token: i0.ApplicationRef }, { token: i0.NgZone }, { token: CeriousScrollService }], target: i0.ɵɵFactoryTarget.Directive }); }
248
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: CeriousScrollDirective, isStandalone: true, selector: "[ceriousScroll]", inputs: { ceriousScrollTotalElements: "ceriousScrollTotalElements", ceriousScrollItems: "ceriousScrollItems", ceriousScrollGetItem: "ceriousScrollGetItem", ceriousScrollItemTemplate: "ceriousScrollItemTemplate", ceriousScrollOptions: "ceriousScrollOptions", ceriousScrollAutoRender: "ceriousScrollAutoRender" }, outputs: { ceriousScrollViewportChange: "ceriousScrollViewportChange", ceriousScrollMeasuredViewport: "ceriousScrollMeasuredViewport", ceriousScrollReady: "ceriousScrollReady" }, usesOnChanges: true, ngImport: i0 }); }
249
+ }
250
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollDirective, decorators: [{
251
+ type: Directive,
252
+ args: [{
253
+ selector: '[ceriousScroll]',
254
+ standalone: true,
255
+ }]
256
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ApplicationRef }, { type: i0.NgZone }, { type: CeriousScrollService }], propDecorators: { ceriousScrollTotalElements: [{
257
+ type: Input
258
+ }], ceriousScrollItems: [{
259
+ type: Input
260
+ }], ceriousScrollGetItem: [{
261
+ type: Input
262
+ }], ceriousScrollItemTemplate: [{
263
+ type: Input
264
+ }], ceriousScrollOptions: [{
265
+ type: Input
266
+ }], ceriousScrollAutoRender: [{
267
+ type: Input
268
+ }], ceriousScrollViewportChange: [{
269
+ type: Output
270
+ }], ceriousScrollMeasuredViewport: [{
271
+ type: Output
272
+ }], ceriousScrollReady: [{
273
+ type: Output
274
+ }] } });
275
+
276
+ class CeriousScrollComponent {
277
+ constructor(ceriousScroll) {
278
+ this.ceriousScroll = ceriousScroll;
279
+ }
280
+ ngAfterContentInit() {
281
+ if (this.ceriousScroll.ceriousScrollItemTemplate)
282
+ return;
283
+ if (!this.projectedItemTemplate)
284
+ return;
285
+ this.ceriousScroll.ceriousScrollItemTemplate =
286
+ this.projectedItemTemplate.templateRef;
287
+ if (this.ceriousScroll.ceriousScrollAutoRender) {
288
+ queueMicrotask(() => this.ceriousScroll.render());
289
+ }
290
+ }
291
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollComponent, deps: [{ token: CeriousScrollDirective }], target: i0.ɵɵFactoryTarget.Component }); }
292
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CeriousScrollComponent, isStandalone: true, selector: "cerious-scroll", queries: [{ propertyName: "projectedItemTemplate", first: true, predicate: CeriousScrollItemTemplateDirective, descendants: true }], hostDirectives: [{ directive: CeriousScrollDirective, inputs: ["ceriousScrollTotalElements", "totalElements", "ceriousScrollItems", "items", "ceriousScrollGetItem", "getItem", "ceriousScrollItemTemplate", "itemTemplate", "ceriousScrollOptions", "options", "ceriousScrollAutoRender", "autoRender"], outputs: ["ceriousScrollViewportChange", "viewportChange", "ceriousScrollMeasuredViewport", "measuredViewport", "ceriousScrollReady", "scrollerReady"] }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [":host{display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
293
+ }
294
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CeriousScrollComponent, decorators: [{
295
+ type: Component,
296
+ args: [{ selector: 'cerious-scroll', standalone: true, imports: [], hostDirectives: [
297
+ {
298
+ directive: CeriousScrollDirective,
299
+ inputs: [
300
+ 'ceriousScrollTotalElements: totalElements',
301
+ 'ceriousScrollItems: items',
302
+ 'ceriousScrollGetItem: getItem',
303
+ 'ceriousScrollItemTemplate: itemTemplate',
304
+ 'ceriousScrollOptions: options',
305
+ 'ceriousScrollAutoRender: autoRender',
306
+ ],
307
+ outputs: [
308
+ 'ceriousScrollViewportChange: viewportChange',
309
+ 'ceriousScrollMeasuredViewport: measuredViewport',
310
+ 'ceriousScrollReady: scrollerReady',
311
+ ],
312
+ },
313
+ ], template: `<ng-content />`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
314
+ }], ctorParameters: () => [{ type: CeriousScrollDirective }], propDecorators: { projectedItemTemplate: [{
315
+ type: ContentChild,
316
+ args: [CeriousScrollItemTemplateDirective]
317
+ }] } });
318
+
319
+ /*
320
+ * Public API Surface of ngx-cerious-scroll
321
+ */
322
+
323
+ /**
324
+ * Generated bundle index. Do not edit.
325
+ */
326
+
327
+ export { CeriousScrollComponent, CeriousScrollDirective, CeriousScrollItemTemplateDirective, CeriousScrollService, ceriousViewportChange$ };
328
+ //# sourceMappingURL=ceriousdevtech-ngx-cerious-scroll.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ceriousdevtech-ngx-cerious-scroll.mjs","sources":["../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.observable.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll-item-template.directive.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.service.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.directive.ts","../../../projects/ngx-cerious-scroll/src/lib/cerious-scroll.component.ts","../../../projects/ngx-cerious-scroll/src/public-api.ts","../../../projects/ngx-cerious-scroll/src/ceriousdevtech-ngx-cerious-scroll.ts"],"sourcesContent":["import { fromEvent, map, merge, Observable, share } from 'rxjs';\n\nimport type { ScrollResult } from '@ceriousdevtech/cerious-scroll';\n\nimport {\n CeriousNativeScrollbarViewportChangeEvent,\n CeriousViewportChangeDetail,\n CeriousViewportChangeEvent,\n} from './cerious-scroll.types';\n\n/**\n * Observable wrapper around the `cerious-viewport-change` CustomEvent emitted by `@ceriousdevtech/cerious-scroll`.\n *\n * Note: this event is emitted when wheel/touch/keyboard handlers are enabled (defaults are enabled).\n */\nexport function ceriousViewportChange$(container: HTMLElement): Observable<CeriousViewportChangeDetail> {\n const fromCerious = fromEvent<CeriousViewportChangeEvent>(container, 'cerious-viewport-change').pipe(\n map((evt) => evt.detail)\n );\n\n // Native scrollbar integration in the upstream package dispatches `viewport-change`.\n // Normalize it into the same shape as `cerious-viewport-change`.\n const fromScrollbar = fromEvent<CeriousNativeScrollbarViewportChangeEvent>(container, 'viewport-change').pipe(\n map((evt) => {\n const result: ScrollResult = { element: evt.detail.element, offset: evt.detail.scrollOffset };\n return {\n percentage: evt.detail.percentage,\n currentElement: evt.detail.element,\n scrollOffset: evt.detail.scrollOffset,\n result,\n } satisfies CeriousViewportChangeDetail;\n })\n );\n\n return merge(fromCerious, fromScrollbar).pipe(share());\n}\n","import { Directive, TemplateRef } from '@angular/core';\n\nexport interface CeriousScrollItemTemplateContext<TItem = unknown> {\n /** The item for this row (also available as `$implicit`). */\n $implicit: TItem;\n /** Row index. */\n index: number;\n /** Same as `$implicit` for named access. */\n item: TItem;\n}\n\n/**\n * Marks an `ng-template` as the row template for `CeriousScrollComponent`.\n *\n * Usage:\n * ```html\n * <cerious-scroll [items]=\"items\">\n * <ng-template ceriousScrollItem let-item let-index=\"index\">\n * {{ index }} - {{ item.name }}\n * </ng-template>\n * </cerious-scroll>\n * ```\n */\n@Directive({\n selector: 'ng-template[ceriousScrollItem]',\n standalone: true,\n})\nexport class CeriousScrollItemTemplateDirective<TItem = unknown> {\n constructor(public readonly templateRef: TemplateRef<CeriousScrollItemTemplateContext<TItem>>) {}\n}\n","import { Injectable, NgZone } from '@angular/core';\n\nimport { CeriousScroll, type CeriousScrollOptions } from '@ceriousdevtech/cerious-scroll';\nimport { Observable } from 'rxjs';\n\nimport { ceriousViewportChange$ } from './cerious-scroll.observable';\nimport type { CeriousViewportChangeDetail } from './cerious-scroll.types';\n\nconst CONTENT_ATTR = 'data-cerious-scroll-content';\n\nfunction ensureContentElement(container: HTMLElement): HTMLElement {\n const existing = container.querySelector<HTMLElement>(`[${CONTENT_ATTR}]`);\n if (existing) return existing;\n\n const el = document.createElement('div');\n el.setAttribute(CONTENT_ATTR, '');\n el.style.position = 'relative';\n el.style.width = '100%';\n el.style.height = '100%';\n el.style.overflow = 'hidden';\n container.appendChild(el);\n return el;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class CeriousScrollService {\n createHost(\n container: HTMLElement,\n totalElements: number,\n options: CeriousScrollOptions,\n ngZone: NgZone,\n onScrollHook?: () => void\n ): CeriousScrollHostRef {\n const contentElement = ensureContentElement(container);\n let scroller!: CeriousScroll;\n\n ngZone.runOutsideAngular(() => {\n const userOnScroll = options?.onScroll;\n const mergedOptions: CeriousScrollOptions = {\n ...options,\n onScroll: () => {\n userOnScroll?.();\n onScrollHook?.();\n },\n };\n\n scroller = new CeriousScroll(container, totalElements, mergedOptions);\n });\n\n const viewportChanges$ = ceriousViewportChange$(container);\n\n return {\n scroller,\n contentElement,\n viewportChanges$,\n destroy: () => {\n // Remove rendered rows content first; keep container stable.\n contentElement.textContent = '';\n scroller.detachScrollbar(container);\n scroller.dispose();\n },\n };\n }\n}\n\nexport interface CeriousScrollHostRef {\n readonly scroller: CeriousScroll;\n /** Dedicated element used for row rendering (prevents scrollbar DOM from being cleared). */\n readonly contentElement: HTMLElement;\n readonly viewportChanges$: Observable<CeriousViewportChangeDetail>;\n destroy(): void;\n}\n","import {\n AfterViewInit,\n ApplicationRef,\n Directive,\n ElementRef,\n EmbeddedViewRef,\n EventEmitter,\n Input,\n NgZone,\n OnChanges,\n OnDestroy,\n Output,\n SimpleChanges,\n TemplateRef,\n} from '@angular/core';\n\nimport {\n type CeriousScrollOptions,\n type ElementRenderer,\n type MeasuredViewportRange,\n} from '@ceriousdevtech/cerious-scroll';\nimport { Subscription } from 'rxjs';\n\nimport type { CeriousViewportChangeDetail } from './cerious-scroll.types';\nimport type { CeriousScrollItemTemplateContext } from './cerious-scroll-item-template.directive';\nimport { type CeriousScrollHostRef, CeriousScrollService } from './cerious-scroll.service';\n\nfunction coerceTotalElements(explicitTotal: number | null | undefined, itemsLen: number | null | undefined): number {\n const candidate = typeof explicitTotal === 'number' ? explicitTotal : typeof itemsLen === 'number' ? itemsLen : undefined;\n if (candidate === undefined || Number.isNaN(candidate)) {\n throw new Error('CeriousScrollDirective: provide `ceriousScrollTotalElements` or `ceriousScrollItems`.');\n }\n // CeriousScroll currently requires >= 1\n return Math.max(1, candidate);\n}\n\n@Directive({\n selector: '[ceriousScroll]',\n standalone: true,\n})\nexport class CeriousScrollDirective<TItem = unknown> implements AfterViewInit, OnChanges, OnDestroy {\n /** Total number of items. If omitted, derived from `ceriousScrollItems.length`. */\n @Input() ceriousScrollTotalElements: number | null = null;\n\n /** Optional items array (enables `let-item`). */\n @Input() ceriousScrollItems: readonly TItem[] | null = null;\n\n /** Optional getter for large datasets (alternative to passing full `items`). */\n @Input() ceriousScrollGetItem: ((index: number) => TItem) | null = null;\n\n /** Template used to render each row. */\n @Input() ceriousScrollItemTemplate: TemplateRef<CeriousScrollItemTemplateContext<TItem>> | null = null;\n\n /** Options passed to `new CeriousScroll(...)`. */\n @Input() ceriousScrollOptions: CeriousScrollOptions = {};\n\n /** Automatically call render after each scroll event. Default: true */\n @Input() ceriousScrollAutoRender = true;\n\n /** Emits `cerious-viewport-change` detail. */\n @Output() ceriousScrollViewportChange = new EventEmitter<CeriousViewportChangeDetail>();\n\n /** Emits the last measured viewport after each render pass. */\n @Output() ceriousScrollMeasuredViewport = new EventEmitter<MeasuredViewportRange>();\n\n /** Emits once the underlying `CeriousScroll` instance is ready. */\n @Output() ceriousScrollReady = new EventEmitter<CeriousScrollHostRef['scroller']>();\n\n private hostRef: CeriousScrollHostRef | null = null;\n private viewportSub: Subscription | null = null;\n\n private readonly viewByContainer = new Map<HTMLElement, EmbeddedViewRef<CeriousScrollItemTemplateContext<TItem>>>();\n\n constructor(\n private readonly host: ElementRef<HTMLElement>,\n private readonly appRef: ApplicationRef,\n private readonly ngZone: NgZone,\n private readonly cerious: CeriousScrollService\n ) {}\n\n ngAfterViewInit(): void {\n this.ensureInitialized();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (!this.hostRef) return;\n\n if (changes['ceriousScrollItems'] || changes['ceriousScrollTotalElements']) {\n const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);\n this.hostRef.scroller.totalElements = total;\n this.hostRef.scroller.clearAllCaches();\n if (this.ceriousScrollAutoRender) this.render();\n }\n\n if (changes['ceriousScrollOptions'] && !changes['ceriousScrollOptions'].firstChange) {\n // Options are consumed primarily at construction time.\n this.recreate();\n }\n }\n\n ngOnDestroy(): void {\n this.viewportSub?.unsubscribe();\n this.viewportSub = null;\n\n this.destroyAllViews();\n\n this.hostRef?.destroy();\n this.hostRef = null;\n }\n\n /** Imperatively trigger a render pass (uses `ceriousScrollItemTemplate`). */\n render(): MeasuredViewportRange | null {\n if (!this.hostRef) return null;\n const template = this.ceriousScrollItemTemplate;\n if (!template) return null;\n\n const hostContainer = this.host.nativeElement;\n const height = hostContainer.clientHeight || hostContainer.offsetHeight;\n const contentContainer = this.hostRef.contentElement;\n\n const renderer: ElementRenderer = (index, elementContainer) => {\n // Rendering must create Angular views inside the Angular zone.\n this.ngZone.run(() => {\n this.renderTemplateIntoContainer(template, index, elementContainer);\n });\n };\n\n const range = this.hostRef.scroller.renderViewport(height, contentContainer, renderer);\n this.ngZone.run(() => this.ceriousScrollMeasuredViewport.emit(range));\n return range;\n }\n\n private recreate(): void {\n this.viewportSub?.unsubscribe();\n this.viewportSub = null;\n\n this.destroyAllViews();\n\n this.hostRef?.destroy();\n this.hostRef = null;\n\n this.ensureInitialized();\n }\n\n private ensureInitialized(): void {\n if (this.hostRef) return;\n\n const container = this.host.nativeElement;\n const total = coerceTotalElements(this.ceriousScrollTotalElements, this.ceriousScrollItems?.length ?? null);\n\n this.hostRef = this.cerious.createHost(container, total, this.ceriousScrollOptions, this.ngZone, () => {\n if (this.ceriousScrollAutoRender) this.render();\n });\n\n this.viewportSub = this.hostRef.viewportChanges$.subscribe((detail: CeriousViewportChangeDetail) => {\n this.ngZone.run(() => this.ceriousScrollViewportChange.emit(detail));\n });\n\n this.ceriousScrollReady.emit(this.hostRef.scroller);\n\n if (this.ceriousScrollAutoRender) {\n queueMicrotask(() => this.render());\n }\n }\n\n private getItemForIndex(index: number): TItem {\n const getter = this.ceriousScrollGetItem;\n if (getter) return getter(index);\n\n const items = this.ceriousScrollItems;\n if (!items) return undefined as TItem;\n\n return items[index];\n }\n\n private renderTemplateIntoContainer(\n template: TemplateRef<CeriousScrollItemTemplateContext<TItem>>,\n index: number,\n elementContainer: HTMLElement\n ): void {\n const previous = this.viewByContainer.get(elementContainer);\n if (previous) {\n this.appRef.detachView(previous);\n previous.destroy();\n this.viewByContainer.delete(elementContainer);\n }\n\n // Clear prior DOM (CeriousScroll may recycle containers).\n elementContainer.textContent = '';\n\n const item = this.getItemForIndex(index);\n const view = template.createEmbeddedView({ $implicit: item, item, index });\n this.appRef.attachView(view);\n view.detectChanges();\n\n for (const node of view.rootNodes) {\n elementContainer.appendChild(node);\n }\n\n this.viewByContainer.set(elementContainer, view);\n }\n\n private destroyAllViews(): void {\n for (const view of this.viewByContainer.values()) {\n this.appRef.detachView(view);\n view.destroy();\n }\n this.viewByContainer.clear();\n }\n}\n","import {\n AfterContentInit,\n ChangeDetectionStrategy,\n Component,\n ContentChild,\n TemplateRef,\n} from '@angular/core';\n\nimport { CeriousScrollDirective } from './cerious-scroll.directive';\nimport {\n CeriousScrollItemTemplateDirective,\n type CeriousScrollItemTemplateContext,\n} from './cerious-scroll-item-template.directive';\n\n@Component({\n selector: 'cerious-scroll',\n standalone: true,\n imports: [],\n hostDirectives: [\n {\n directive: CeriousScrollDirective,\n inputs: [\n 'ceriousScrollTotalElements: totalElements',\n 'ceriousScrollItems: items',\n 'ceriousScrollGetItem: getItem',\n 'ceriousScrollItemTemplate: itemTemplate',\n 'ceriousScrollOptions: options',\n 'ceriousScrollAutoRender: autoRender',\n ],\n outputs: [\n 'ceriousScrollViewportChange: viewportChange',\n 'ceriousScrollMeasuredViewport: measuredViewport',\n 'ceriousScrollReady: scrollerReady',\n ],\n },\n ],\n template: `<ng-content />`,\n styles: `\n :host {\n display: block;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CeriousScrollComponent<TItem = unknown> implements AfterContentInit {\n /** Optional convenience template marker: <ng-template ceriousScrollItem let-item let-index=\"index\">...</ng-template> */\n @ContentChild(CeriousScrollItemTemplateDirective)\n private readonly projectedItemTemplate?: CeriousScrollItemTemplateDirective<TItem>;\n\n constructor(private readonly ceriousScroll: CeriousScrollDirective<TItem>) {}\n\n ngAfterContentInit(): void {\n if (this.ceriousScroll.ceriousScrollItemTemplate) return;\n if (!this.projectedItemTemplate) return;\n\n this.ceriousScroll.ceriousScrollItemTemplate =\n this.projectedItemTemplate.templateRef as TemplateRef<CeriousScrollItemTemplateContext<TItem>>;\n\n if (this.ceriousScroll.ceriousScrollAutoRender) {\n queueMicrotask(() => this.ceriousScroll.render());\n }\n }\n}\n","/*\n * Public API Surface of ngx-cerious-scroll\n */\n\nexport * from './lib/cerious-scroll.types';\nexport * from './lib/cerious-scroll.observable';\nexport * from './lib/cerious-scroll-item-template.directive';\nexport * from './lib/cerious-scroll.directive';\nexport * from './lib/cerious-scroll.component';\nexport * from './lib/cerious-scroll.service';\n\n// Re-export upstream types/classes for convenience\nexport * from '@ceriousdevtech/cerious-scroll';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.CeriousScrollService","i1.CeriousScrollDirective"],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@ceriousdevtech/ngx-cerious-scroll" />
5
+ export * from './public-api';
@@ -0,0 +1,28 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export interface CeriousScrollItemTemplateContext<TItem = unknown> {
4
+ /** The item for this row (also available as `$implicit`). */
5
+ $implicit: TItem;
6
+ /** Row index. */
7
+ index: number;
8
+ /** Same as `$implicit` for named access. */
9
+ item: TItem;
10
+ }
11
+ /**
12
+ * Marks an `ng-template` as the row template for `CeriousScrollComponent`.
13
+ *
14
+ * Usage:
15
+ * ```html
16
+ * <cerious-scroll [items]="items">
17
+ * <ng-template ceriousScrollItem let-item let-index="index">
18
+ * {{ index }} - {{ item.name }}
19
+ * </ng-template>
20
+ * </cerious-scroll>
21
+ * ```
22
+ */
23
+ export declare class CeriousScrollItemTemplateDirective<TItem = unknown> {
24
+ readonly templateRef: TemplateRef<CeriousScrollItemTemplateContext<TItem>>;
25
+ constructor(templateRef: TemplateRef<CeriousScrollItemTemplateContext<TItem>>);
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<CeriousScrollItemTemplateDirective<any>, never>;
27
+ static ɵdir: i0.ɵɵDirectiveDeclaration<CeriousScrollItemTemplateDirective<any>, "ng-template[ceriousScrollItem]", never, {}, {}, never, never, true, never>;
28
+ }
@@ -0,0 +1,13 @@
1
+ import { AfterContentInit } from '@angular/core';
2
+ import { CeriousScrollDirective } from './cerious-scroll.directive';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "./cerious-scroll.directive";
5
+ export declare class CeriousScrollComponent<TItem = unknown> implements AfterContentInit {
6
+ private readonly ceriousScroll;
7
+ /** Optional convenience template marker: <ng-template ceriousScrollItem let-item let-index="index">...</ng-template> */
8
+ private readonly projectedItemTemplate?;
9
+ constructor(ceriousScroll: CeriousScrollDirective<TItem>);
10
+ ngAfterContentInit(): void;
11
+ static ɵfac: i0.ɵɵFactoryDeclaration<CeriousScrollComponent<any>, never>;
12
+ static ɵcmp: i0.ɵɵComponentDeclaration<CeriousScrollComponent<any>, "cerious-scroll", never, {}, {}, ["projectedItemTemplate"], ["*"], true, [{ directive: typeof i1.CeriousScrollDirective; inputs: { "ceriousScrollTotalElements": "totalElements"; "ceriousScrollItems": "items"; "ceriousScrollGetItem": "getItem"; "ceriousScrollItemTemplate": "itemTemplate"; "ceriousScrollOptions": "options"; "ceriousScrollAutoRender": "autoRender"; }; outputs: { "ceriousScrollViewportChange": "viewportChange"; "ceriousScrollMeasuredViewport": "measuredViewport"; "ceriousScrollReady": "scrollerReady"; }; }]>;
13
+ }
@@ -0,0 +1,46 @@
1
+ import { AfterViewInit, ApplicationRef, ElementRef, EventEmitter, NgZone, OnChanges, OnDestroy, SimpleChanges, TemplateRef } from '@angular/core';
2
+ import { type CeriousScrollOptions, type MeasuredViewportRange } from '@ceriousdevtech/cerious-scroll';
3
+ import type { CeriousViewportChangeDetail } from './cerious-scroll.types';
4
+ import type { CeriousScrollItemTemplateContext } from './cerious-scroll-item-template.directive';
5
+ import { CeriousScrollService } from './cerious-scroll.service';
6
+ import * as i0 from "@angular/core";
7
+ export declare class CeriousScrollDirective<TItem = unknown> implements AfterViewInit, OnChanges, OnDestroy {
8
+ private readonly host;
9
+ private readonly appRef;
10
+ private readonly ngZone;
11
+ private readonly cerious;
12
+ /** Total number of items. If omitted, derived from `ceriousScrollItems.length`. */
13
+ ceriousScrollTotalElements: number | null;
14
+ /** Optional items array (enables `let-item`). */
15
+ ceriousScrollItems: readonly TItem[] | null;
16
+ /** Optional getter for large datasets (alternative to passing full `items`). */
17
+ ceriousScrollGetItem: ((index: number) => TItem) | null;
18
+ /** Template used to render each row. */
19
+ ceriousScrollItemTemplate: TemplateRef<CeriousScrollItemTemplateContext<TItem>> | null;
20
+ /** Options passed to `new CeriousScroll(...)`. */
21
+ ceriousScrollOptions: CeriousScrollOptions;
22
+ /** Automatically call render after each scroll event. Default: true */
23
+ ceriousScrollAutoRender: boolean;
24
+ /** Emits `cerious-viewport-change` detail. */
25
+ ceriousScrollViewportChange: EventEmitter<CeriousViewportChangeDetail>;
26
+ /** Emits the last measured viewport after each render pass. */
27
+ ceriousScrollMeasuredViewport: EventEmitter<MeasuredViewportRange>;
28
+ /** Emits once the underlying `CeriousScroll` instance is ready. */
29
+ ceriousScrollReady: EventEmitter<import("@ceriousdevtech/cerious-scroll").CeriousScroll>;
30
+ private hostRef;
31
+ private viewportSub;
32
+ private readonly viewByContainer;
33
+ constructor(host: ElementRef<HTMLElement>, appRef: ApplicationRef, ngZone: NgZone, cerious: CeriousScrollService);
34
+ ngAfterViewInit(): void;
35
+ ngOnChanges(changes: SimpleChanges): void;
36
+ ngOnDestroy(): void;
37
+ /** Imperatively trigger a render pass (uses `ceriousScrollItemTemplate`). */
38
+ render(): MeasuredViewportRange | null;
39
+ private recreate;
40
+ private ensureInitialized;
41
+ private getItemForIndex;
42
+ private renderTemplateIntoContainer;
43
+ private destroyAllViews;
44
+ static ɵfac: i0.ɵɵFactoryDeclaration<CeriousScrollDirective<any>, never>;
45
+ static ɵdir: i0.ɵɵDirectiveDeclaration<CeriousScrollDirective<any>, "[ceriousScroll]", never, { "ceriousScrollTotalElements": { "alias": "ceriousScrollTotalElements"; "required": false; }; "ceriousScrollItems": { "alias": "ceriousScrollItems"; "required": false; }; "ceriousScrollGetItem": { "alias": "ceriousScrollGetItem"; "required": false; }; "ceriousScrollItemTemplate": { "alias": "ceriousScrollItemTemplate"; "required": false; }; "ceriousScrollOptions": { "alias": "ceriousScrollOptions"; "required": false; }; "ceriousScrollAutoRender": { "alias": "ceriousScrollAutoRender"; "required": false; }; }, { "ceriousScrollViewportChange": "ceriousScrollViewportChange"; "ceriousScrollMeasuredViewport": "ceriousScrollMeasuredViewport"; "ceriousScrollReady": "ceriousScrollReady"; }, never, never, true, never>;
46
+ }
@@ -0,0 +1,8 @@
1
+ import { Observable } from 'rxjs';
2
+ import { CeriousViewportChangeDetail } from './cerious-scroll.types';
3
+ /**
4
+ * Observable wrapper around the `cerious-viewport-change` CustomEvent emitted by `@ceriousdevtech/cerious-scroll`.
5
+ *
6
+ * Note: this event is emitted when wheel/touch/keyboard handlers are enabled (defaults are enabled).
7
+ */
8
+ export declare function ceriousViewportChange$(container: HTMLElement): Observable<CeriousViewportChangeDetail>;
@@ -0,0 +1,17 @@
1
+ import { NgZone } from '@angular/core';
2
+ import { CeriousScroll, type CeriousScrollOptions } from '@ceriousdevtech/cerious-scroll';
3
+ import { Observable } from 'rxjs';
4
+ import type { CeriousViewportChangeDetail } from './cerious-scroll.types';
5
+ import * as i0 from "@angular/core";
6
+ export declare class CeriousScrollService {
7
+ createHost(container: HTMLElement, totalElements: number, options: CeriousScrollOptions, ngZone: NgZone, onScrollHook?: () => void): CeriousScrollHostRef;
8
+ static ɵfac: i0.ɵɵFactoryDeclaration<CeriousScrollService, never>;
9
+ static ɵprov: i0.ɵɵInjectableDeclaration<CeriousScrollService>;
10
+ }
11
+ export interface CeriousScrollHostRef {
12
+ readonly scroller: CeriousScroll;
13
+ /** Dedicated element used for row rendering (prevents scrollbar DOM from being cleared). */
14
+ readonly contentElement: HTMLElement;
15
+ readonly viewportChanges$: Observable<CeriousViewportChangeDetail>;
16
+ destroy(): void;
17
+ }
@@ -0,0 +1,25 @@
1
+ import type { ScrollResult } from '@ceriousdevtech/cerious-scroll';
2
+ /**
3
+ * Detail payload for the `cerious-viewport-change` CustomEvent dispatched by `@ceriousdevtech/cerious-scroll`.
4
+ */
5
+ export interface CeriousViewportChangeDetail {
6
+ /** Scroll percentage from 0..100 */
7
+ percentage: number;
8
+ /** Current top-most element index (as tracked by CeriousScroll) */
9
+ currentElement: number;
10
+ /** Pixel offset within `currentElement` */
11
+ scrollOffset: number;
12
+ /** Scroll operation result (element + offset) */
13
+ result: ScrollResult;
14
+ }
15
+ export type CeriousViewportChangeEvent = CustomEvent<CeriousViewportChangeDetail>;
16
+ /**
17
+ * Payload used by CeriousScroll's native scrollbar integration.
18
+ * (Dispatched as `viewport-change` in the upstream package.)
19
+ */
20
+ export interface CeriousNativeScrollbarViewportChangeDetail {
21
+ percentage: number;
22
+ element: number;
23
+ scrollOffset: number;
24
+ }
25
+ export type CeriousNativeScrollbarViewportChangeEvent = CustomEvent<CeriousNativeScrollbarViewportChangeDetail>;
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@ceriousdevtech/ngx-cerious-scroll",
3
+ "version": "1.0.0",
4
+ "license": "(MIT OR LicenseRef-CeriousScroll-Commercial)",
5
+ "peerDependencies": {
6
+ "@angular/common": "^17.3.0",
7
+ "@angular/core": "^17.3.0",
8
+ "@ceriousdevtech/cerious-scroll": "^1.0.0"
9
+ },
10
+ "dependencies": {
11
+ "tslib": "^2.3.0"
12
+ },
13
+ "sideEffects": false,
14
+ "module": "fesm2022/ceriousdevtech-ngx-cerious-scroll.mjs",
15
+ "typings": "index.d.ts",
16
+ "exports": {
17
+ "./package.json": {
18
+ "default": "./package.json"
19
+ },
20
+ ".": {
21
+ "types": "./index.d.ts",
22
+ "esm2022": "./esm2022/ceriousdevtech-ngx-cerious-scroll.mjs",
23
+ "esm": "./esm2022/ceriousdevtech-ngx-cerious-scroll.mjs",
24
+ "default": "./fesm2022/ceriousdevtech-ngx-cerious-scroll.mjs"
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,7 @@
1
+ export * from './lib/cerious-scroll.types';
2
+ export * from './lib/cerious-scroll.observable';
3
+ export * from './lib/cerious-scroll-item-template.directive';
4
+ export * from './lib/cerious-scroll.directive';
5
+ export * from './lib/cerious-scroll.component';
6
+ export * from './lib/cerious-scroll.service';
7
+ export * from '@ceriousdevtech/cerious-scroll';