@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 +23 -0
- package/LICENSE-COMMERCIAL +71 -0
- package/LICENSE-MIT +22 -0
- package/README.md +24 -0
- package/esm2022/ceriousdevtech-ngx-cerious-scroll.mjs +5 -0
- package/esm2022/lib/cerious-scroll-item-template.directive.mjs +29 -0
- package/esm2022/lib/cerious-scroll.component.mjs +48 -0
- package/esm2022/lib/cerious-scroll.directive.mjs +172 -0
- package/esm2022/lib/cerious-scroll.observable.mjs +22 -0
- package/esm2022/lib/cerious-scroll.service.mjs +56 -0
- package/esm2022/lib/cerious-scroll.types.mjs +2 -0
- package/esm2022/public-api.mjs +12 -0
- package/fesm2022/ceriousdevtech-ngx-cerious-scroll.mjs +328 -0
- package/fesm2022/ceriousdevtech-ngx-cerious-scroll.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/cerious-scroll-item-template.directive.d.ts +28 -0
- package/lib/cerious-scroll.component.d.ts +13 -0
- package/lib/cerious-scroll.directive.d.ts +46 -0
- package/lib/cerious-scroll.observable.d.ts +8 -0
- package/lib/cerious-scroll.service.d.ts +17 -0
- package/lib/cerious-scroll.types.d.ts +25 -0
- package/package.json +27 -0
- package/public-api.d.ts +7 -0
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,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
|
+
}
|
package/public-api.d.ts
ADDED
|
@@ -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';
|