Skip to main content
cngx-src documentation

CngxInfiniteScroll

DirectivePrimaryv0.1.0WCAG AA

projects/common/layout/scroll/infinite-scroll.directive.ts

Import#

import { CngxInfiniteScroll } from '@cngx/common/layout'

Description#

Infinite scroll trigger using IntersectionObserver.

Place on a sentinel element at the bottom of a list. Fires loadMore when the sentinel enters the viewport. Includes a debounce guard and a loading input to prevent re-triggers during fetch.

The observer is automatically recreated when root, rootMargin, or threshold inputs change, and disconnected on destroy or when enabled is set to false. When loading settles back to false the sentinel is re-observed, so a fetched page that did not push the sentinel out of view still re-fires loadMore instead of stalling the list.

Basic infinite list

<div class="item-list">
  @for (item of items(); track item.id) {
    <app-item [data]="item" />
  }
  <div cngxInfiniteScroll [loading]="isFetching()" (loadMore)="fetchNext()">
    @if (scroll.isLoading()) { <mat-spinner diameter="24" /> }
  </div>
</div>

Disable when all loaded

<div cngxInfiniteScroll
     [enabled]="hasNextPage()"
     [loading]="isFetching()"
     (loadMore)="fetchNext()">
  @if (!hasNextPage()) { <p>All items loaded</p> }
</div>

Custom scroll container with pre-fetch margin

<div cngxInfiniteScroll
     [root]="'.scroll-container'"
     [rootMargin]="'0px 0px 400px 0px'"
     [loading]="loading()"
     (loadMore)="loadMore()">
</div>

https://cngxjs.github.io/cngx/examples/#/common/layout/infinite-scroll/scrollable-list

Metadata#

Host#

Relationships

Index#

Inputs#

debounceMs#number
input()

Minimum ms between consecutive loadMore emissions.

default 200
enabled#boolean
input()

When false, the observer disconnects entirely. Use to stop loading when all items are fetched.

default true
loading#boolean
input()

Set to true while fetching. Prevents re-trigger until the fetch completes.

default false
root#string | null
input()

CSS selector for a custom scroll container root. null uses the viewport.

default null
rootMargin#string
input()

Pre-fetch margin. '0px 0px 200px 0px' triggers 200px before the sentinel is visible.

default '0px 0px 200px 0px'
threshold#number
input()

IntersectionObserver threshold (0–1).

default 0

Outputs#

loadMore#void
output()

Emitted when the sentinel is visible, not loading, and debounce has elapsed.

HostBindings#

BindingExpression
[class.cngx-infinite-scroll--loading]isLoading()
[attr.aria-busy]isLoading() || null