For AI agents: the complete documentation index is available at https://gultyayev.github.io/ngx-virtual-dnd/llms.txt, the full documentation bundle is available at https://gultyayev.github.io/ngx-virtual-dnd/llms-full.txt, and this page is available as Markdown at https://gultyayev.github.io/ngx-virtual-dnd/api/types.md.

Types, tokens and strategies

Configuration

interface AutoScrollConfig {
  threshold: number; // distance from the edge that starts scrolling (px). Default 50
  maxSpeed: number; // max speed in px per 60 fps frame. Default 15
  accelerate: boolean; // faster closer to the edge. Default true
}

interface VdndAnimationConfig {
  shiftDuration?: number; // slide duration in ms. Default 200; 0 turns it off
  shiftEasing?: string; // CSS easing. Default 'cubic-bezier(0.2, 0, 0, 1)'
  dropDuration?: number; // drop animation duration in ms. Default 200; 0 turns it off
  dropEasing?: string; // CSS easing. Default 'cubic-bezier(0.2, 0, 0, 1)'
}

VdndAnimationConfig is provided through VDND_ANIMATION_CONFIG (added in 3.2.0). See Animations and haptics.

Template contexts

// <vdnd-sortable-list> / <vdnd-virtual-scroll> itemTemplate
interface VirtualScrollItemContext<T> {
  $implicit: T;
  index: number;
  isSticky: boolean;
}

// *vdndVirtualFor
interface VirtualForContext<T> {
  $implicit: T;
  index: number;
  first: boolean;
  last: boolean;
  count: number;
}

// <vdnd-drag-preview [previewTemplate]>
interface DragPreviewContext<T = unknown> {
  $implicit: T;
  draggableId: string;
  droppableId: string;
}

// <vdnd-placeholder [template]>
interface PlaceholderContext {
  $implicit: number; // height in px
  height: number;
}

Drag state

interface DraggedItem {
  draggableId: string;
  droppableId: string;
  element: HTMLElement;
  clonedElement?: HTMLElement;
  height: number;
  width: number;
  data?: unknown;
}

interface CursorPosition {
  x: number;
  y: number;
}

interface GrabOffset {
  x: number;
  y: number;
}

interface DragState {
  isDragging: boolean;
  draggedItem: DraggedItem | null;
  sourceDroppableId: string | null;
  sourceIndex: number | null;
  activeDroppableId: string | null;
  placeholderId: string | null; // deprecated: always END_OF_LIST or null, use placeholderIndex
  placeholderIndex: number | null;
  cursorPosition: CursorPosition | null;
  grabOffset: GrabOffset | null;
  initialPosition: CursorPosition | null;
  lockAxis: 'x' | 'y' | null;
  isKeyboardDrag: boolean;
  keyboardTargetIndex: number | null;
}

Strategies

Virtual scroll math is pluggable. The components pick a strategy from dynamicItemHeight, so you only need these to build your own container.

interface VirtualScrollStrategy {
  readonly version: Signal<number>;
  getTotalHeight(itemCount: number): number;
  getFirstVisibleIndex(scrollTop: number): number;
  getVisibleCount(startIndex: number, containerHeight: number): number;
  getOffsetForIndex(index: number): number;
  getItemHeight(index: number): number;
  setMeasuredHeight(key: unknown, height: number): void;
  setItemKeys(keys: unknown[]): void;
  setExcludedIndex(index: number | null): void;
  findIndexAtOffset(offset: number): number;
  getItemCount(): number;
}
ClassConstructorBehavior
FixedHeightStrategynew FixedHeightStrategy(itemHeight)index * itemHeight; the default
DynamicHeightStrategynew DynamicHeightStrategy(estimate)Measured heights, prefix sums and binary search (O(log n) lookups)

Injection tokens

TokenProvidesProvided by
VDND_SCROLL_CONTAINERVdndScrollContainerVirtualViewportComponent, VirtualContentComponent, ScrollableDirective
VDND_VIRTUAL_VIEWPORTVdndVirtualViewportVirtualViewportComponent, VirtualContentComponent
VDND_GROUP_TOKENVdndGroupContextDroppableGroupDirective
VDND_ANIMATION_CONFIGVdndAnimationConfigYou (opt-in), app-wide or in a component's providers
interface VdndScrollContainer {
  readonly nativeElement: HTMLElement;
  scrollTop(): number;
  containerHeight(): number;
  scrollTo(options: ScrollToOptions): void;
}

interface VdndVirtualViewport {
  scrollTop(): number;
  containerHeight(): number;
  itemHeight(): number;
  contentOffset(): number;
  readonly nativeElement: HTMLElement;
  setRenderStartIndex(index: number): void;
  getOffsetForIndex(index: number): number;
  readonly strategy: VirtualScrollStrategy | null;
}

interface VdndGroupContext {
  readonly group: Signal<string>;
}

scrollTop() on both interfaces is the rendered scroll position, a reactive value for computing what to render. The built-in containers commit it once per animation frame, after a move of 5px or more, so it can lag the scrolling element. To compute a position (for example a scroll target), read that element's scrollTop. For VirtualViewportComponent and ScrollableDirective it is nativeElement. VirtualContentComponent's host does not scroll, and its scrollTop() is relative to where its list starts: take the parent scroll container's element scrollTop, subtract the content offset, and clamp at 0.

Constants

const END_OF_LIST = 'END_OF_LIST'; // deprecated: the value of every placeholderId; positions are indexes
const INITIAL_DRAG_STATE: DragState; // the idle state