listine
Version:
Angular virtual scroll component supporting variable item heights.
98 lines (95 loc) • 5.88 kB
TypeScript
import * as _angular_core from '@angular/core';
import { TemplateRef, ElementRef } from '@angular/core';
/**
* `s73-variable-virtual-scroll`
*
* A lightweight, customizable virtual scroll component that supports variable item heights.
* Efficiently renders only visible items to improve performance for large lists.
*
* ## Inputs:
* - `items`: List of data items to display
* - `viewportHeight`: Height of the scrollable container (default: 400px)
* - `buffer`: Number of extra items rendered above and below the viewport for smooth scrolling (default: 5)
* - `itemTemplate`: Angular template for rendering each item
* - `initialItemHeight`: Default item height before measurement (default: 50px)
* - `scrollResetTrigger`: Increment (or any new value) to run `scrollToTop()` when the list should jump back to the top (e.g. after filter/search).
*
* ## Outputs:
* - `scrollEmitter`: Emits scroll position on every scroll event
*/
declare class VariableVirtualScrollComponent {
private ngZone;
private destroyRef;
private changeDetectorRef;
/**
* Running maximum of measured row heights. Used when `items` is replaced so new estimates
* are not stuck at `initialItemHeight` while real rows are taller (prevents overlap during fast filter).
*/
private peakMeasuredItemHeight;
/** List of all items to render */
readonly items: _angular_core.InputSignal<any[]>;
/** Height of the scrollable viewport in pixels */
readonly viewportHeight: _angular_core.InputSignal<number>;
/** Number of extra items to render above and below the viewport */
readonly buffer: _angular_core.InputSignal<number>;
/** Template reference for rendering each item */
readonly itemTemplate: _angular_core.InputSignal<TemplateRef<any>>;
/** Flag to track if panel is open */
readonly panelOpen: _angular_core.InputSignal<boolean>;
/** Initial estimated height of each item before actual measurement */
readonly initialItemHeight: _angular_core.InputSignal<number>;
/**
* Bump this value whenever the list should reset to the top (calls `scrollToTop()`).
* Does not scroll on the initial value; only when the bound value changes.
*/
readonly scrollToTopTrigger: _angular_core.InputSignal<number>;
/** Emits scroll position whenever user scrolls */
readonly scrollEmitter: _angular_core.OutputEmitterRef<any>;
/** Emits when user scrolls to the end of the list */
readonly scrollToEnd: _angular_core.OutputEmitterRef<void>;
/** Reference to the scrolling container */
readonly scrollerRef: _angular_core.Signal<ElementRef<HTMLDivElement>>;
/** Rendered item elements (used for height measurement) */
readonly itemElements: _angular_core.Signal<readonly ElementRef<HTMLDivElement>[]>;
/** Stores measured heights of items */
readonly itemHeights: _angular_core.WritableSignal<number[]>;
/** Stores calculated top offset for each item */
readonly itemTops: _angular_core.WritableSignal<number[]>;
/** Total height of all items (used to simulate full scrollable area) */
readonly totalContentHeight: _angular_core.WritableSignal<number>;
/** Index of the first visible item (including buffer) */
readonly visibleStart: _angular_core.WritableSignal<number>;
/** Index of the last visible item (including buffer) */
readonly visibleEnd: _angular_core.WritableSignal<number>;
/** Items currently visible in the viewport */
readonly visibleItems: _angular_core.WritableSignal<any[]>;
/** ResizeObserver to watch for item height changes (deferred measure, matching legacy pattern). */
protected resizeObserver: ResizeObserver;
/** Previous scroll position to detect actual scrolling */
private previousScrollTop;
/** Last seen `scrollResetTrigger` to detect changes without firing on first run */
private previousScrollResetTrigger;
constructor();
/** Initializes item height and position tracking arrays from `items` (`itemHeights.length` matches `items.length`). */
protected initializeHeights(): void;
/** Resets scroll to top and rebuilds height estimates (e.g. after filter/search). */
scrollToTop(): void;
/** Recalculates item top positions and content height */
protected calculateHeights(): void;
/** Updates top positions of all items based on their current heights */
protected updateItemTops(): void;
/**
* Returns the top position of an item by index
* @param index - index of the item
*/
protected getItemTop(index: number): number;
/** Scroll event handler: calculates which items should be visible */
protected onScroll(): void;
/** Updates the list of items to be rendered based on scroll position */
protected updateVisibleItems(): void;
/** Measures actual heights of rendered DOM elements and updates tracking */
measureItemHeights(): void;
static ɵfac: _angular_core.ɵɵFactoryDeclaration<VariableVirtualScrollComponent, never>;
static ɵcmp: _angular_core.ɵɵComponentDeclaration<VariableVirtualScrollComponent, "listine-variable-virtual-scroll", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "viewportHeight": { "alias": "viewportHeight"; "required": false; "isSignal": true; }; "buffer": { "alias": "buffer"; "required": false; "isSignal": true; }; "itemTemplate": { "alias": "itemTemplate"; "required": true; "isSignal": true; }; "panelOpen": { "alias": "panelOpen"; "required": false; "isSignal": true; }; "initialItemHeight": { "alias": "initialItemHeight"; "required": false; "isSignal": true; }; "scrollToTopTrigger": { "alias": "scrollToTopTrigger"; "required": false; "isSignal": true; }; }, { "scrollEmitter": "scrollEmitter"; "scrollToEnd": "scrollToEnd"; }, never, never, true, never>;
}
export { VariableVirtualScrollComponent };