first commit
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
<div #sentinel class="w-full h-10 flex items-center justify-center">
|
||||
<div class="text-slate-400 text-sm" aria-live="polite">
|
||||
<!-- The parent can show a spinner near the bottom; this anchor is the sentinel only. -->
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,42 @@
|
||||
import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, OnDestroy, Output, ViewChild } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-infinite-anchor',
|
||||
standalone: true,
|
||||
templateUrl: './infinite-anchor.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [CommonModule]
|
||||
})
|
||||
export class InfiniteAnchorComponent implements AfterViewInit, OnDestroy {
|
||||
@ViewChild('sentinel', { static: true }) sentinelRef!: ElementRef<HTMLDivElement>;
|
||||
|
||||
@Input() disabled = false;
|
||||
@Input() busy = false;
|
||||
@Input() rootMargin = '300px 0px 300px 0px';
|
||||
@Input() threshold: number | number[] = 0.01;
|
||||
|
||||
@Output() loadMore = new EventEmitter<void>();
|
||||
|
||||
private observer?: IntersectionObserver;
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.observer = new IntersectionObserver((entries) => {
|
||||
for (const entry of entries) {
|
||||
if (entry.isIntersecting && !this.disabled && !this.busy) {
|
||||
this.loadMore.emit();
|
||||
}
|
||||
}
|
||||
}, {
|
||||
root: null,
|
||||
rootMargin: this.rootMargin,
|
||||
threshold: this.threshold,
|
||||
});
|
||||
|
||||
this.observer.observe(this.sentinelRef.nativeElement);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.observer?.disconnect();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user